GEMC  1.8
Geant4 Monte-Carlo Framework
gsignal.cc
Go to the documentation of this file.
1 // %%%%%%%%%%
2 // Qt headers
3 // %%%%%%%%%%
4 #include <QtGui>
5 
6 
7 // %%%%%%%%%%%%%
8 // gemc headers
9 // %%%%%%%%%%%%%
10 #include "gsignal.h"
11 #include "MHit.h"
12 #include "string_utilities.h"
13 
14 // %%%%%%%%%%
15 // G4 headers
16 // %%%%%%%%%%
17 #include "G4UIcommandTree.hh"
18 
19 gsignal::gsignal(QWidget *parent, gemc_opts *Opts, map<string, MSensitiveDetector*> SD_Map) : QWidget(parent)
20 {
21  gemcOpt = Opts;
22  UImanager = G4UImanager::GetUIpointer();
23  SeDe_Map = SD_Map;
24 
25  // Layout:
26  //
27  // + +-------------------+ +
28  // | | | | |
29  // | | Tree | Signal | |
30  // | | | Choice | |
31  // | | | | |
32  // | +-------------------+ |
33  // | +-------------------+ |
34  // | | | |
35  // | | Graph | |
36  // | +-------------------+ |
37  // +-----------------------+
38 
39 
40  // Graph axis origins and legth
41  xorig = -190;
42  yorig = 315;
43  xaxil = 505;
44  yaxil = 290;
45  inside = 20;
46  DX = xaxil - 2*inside;
47  DY = yaxil - 2*inside;
48  nticksx = 5; // in reality this is number of ticks - 1
49  nticksy = 5;
50 
51  // particle colors follow gemc settings
52  // red: positive
53  // gray: neutral
54  // green: negative
55  //
56  // second argument of QPen is thickness of pencil
57 
58  pcolors[2112] = QPen(Qt::black, 5); // neutrons: black
59  pcolors[22] = QPen(Qt::blue, 5); // photons: blue
60  pcolors[11] = QPen(Qt::cyan, 5); // electrons: cyan
61  pcolors[2212] = QPen(QColor(240, 80, 80), 5); // protons: orange
62  pcolors[211] = QPen(Qt::magenta, 5); // pi+: magenta
63  pcolors[-211] = QPen(Qt::yellow, 5); // pi-: yellow
64  pcolors[-11] = QPen(Qt::red, 5); // positrons: positive - red
65  pcolors[0] = QPen(Qt::blue, 5); // optical photons: blue
66 
67 
68  // Vertical Splitter - Top and Bottom layouts
69  QSplitter *splitter = new QSplitter(Qt::Vertical);
70 
71 
72 
73  // %%%%%%%%%%
74  // top layout
75  // %%%%%%%%%%
76  QWidget *topWidget = new QWidget(splitter);
77  QSplitter *treesplitter = new QSplitter(Qt::Horizontal);
78 
79 
80  QVBoxLayout *topLayout = new QVBoxLayout(treesplitter);
81 
82  // Left: The sensitive detectors hits tree
83  s_detectors = new QTreeWidget();
84  s_detectors = CreateSDetsTree();
85  if(s_detectors)
86  topLayout->addWidget(s_detectors);
87 
88 
89  // Right: The individual signals choice
90  gsignals = new QTreeWidget();
91  gsignals = CreateSignalsTree();
92  if(gsignals)
93  topLayout->addWidget(gsignals);
94 
95 
96  // treesplitter size
97  QList<int> tlist;
98  tlist.append( 280 );
99  tlist.append( 520 );
100  treesplitter->setSizes(tlist);
101 
102 
103  QVBoxLayout *layoutTop = new QVBoxLayout(topWidget);
104  layoutTop->addWidget(treesplitter);
105 
106 
107  // %%%%%%%%%%%%%
108  // bottom layout
109  // %%%%%%%%%%%%%
110  QWidget *bottomWidget = new QWidget(splitter);
111  bottomWidget->setMinimumSize(600, 450);
112  bottomWidget->setMaximumSize(600, 450);
113 
114  plots = new QGraphicsView();
115  scene = new QGraphicsScene();
116  plots->setScene(scene);
117 
118 
119 
120  // putting all together
121  QVBoxLayout *layoutBottom = new QVBoxLayout(bottomWidget);
122  layoutBottom->addWidget(new QLabel("Signal:"));
123  layoutBottom->addWidget(plots);
124 
125 
126  // splitter size
127  QList<int> list;
128  list.append( 400 );
129  list.append( 450 );
130  splitter->setSizes(list);
131 
132 
133  // %%%%%%%%%%%
134  // all layouts
135  // %%%%%%%%%%%
136  QVBoxLayout *mainLayout = new QVBoxLayout;
137  mainLayout->addWidget(splitter);
138  setLayout(mainLayout);
139 
140 
141 
142  // Has Hit Gradient Color
143  HitGrad = QLinearGradient(QPointF(1, 100), QPointF(180, 20));
144  HitGrad.setColorAt(0, QColor(255, 80, 80));
145  HitGrad.setColorAt(1, QColor(245, 245, 245));
146  HitBrush = QBrush(HitGrad);
147 
148 }
149 
151 {
152  s_detectors->clear();
153  s_detectors->setSelectionMode(QAbstractItemView::SingleSelection);
154  QStringList labels;
155  labels << QString("Hits List");
156  s_detectors->setHeaderLabels(labels);
157 
158  QTreeWidgetItem * newItem;
159 
160 
161  for(map<string, MSensitiveDetector*>::iterator it = SeDe_Map.begin(); it!= SeDe_Map.end(); it++)
162  {
163  MHitCollection *MHC = it->second->GetMHitCollection();
164  int nhits = 0;
165  if(MHC) nhits = MHC->GetSize();
166  MHit* aHit;
167 
168  // Creating sensitive detectors name tree if it's different than "Mirrors"
169  if(it->first != "Mirrors")
170  {
171  newItem = new QTreeWidgetItem(s_detectors);
172  newItem->setText(0, QString(it->first.c_str()));
173 
174  if(nhits)
175  {
176  newItem->setBackground(0, HitBrush );
177  string snhits = it->first + " " + stringify(nhits) + " hit";
178  if(nhits>1) snhits += "s";
179  newItem->setText(0, QString(snhits.c_str()));
180 
181 
182  QTreeWidgetItem *newHit;
183 
184  // if the sensitive element is nphe_pmt then
185  // visualization screen is different:
186  // need to visualize number of photoelectrons only
187  for(int h=0; h<nhits; h++)
188  {
189  aHit = (*MHC)[h];
190  int nsteps = aHit->GetPos().size();
191  newHit = new QTreeWidgetItem(newItem);
192 
193 
194  string hitindex = "Hit n. " + stringify(h+1) + " nsteps: " + stringify(nsteps) ;
195 
196  // if last sensitive element is nphe_pmt then writing number of photo-electrons
197  if(it->second->SDID.IDnames.back().find("nphe_pmt") != string::npos)
198  hitindex = "Hit n. " + stringify(h+1) + " nphe: " + stringify(nsteps) ;
199 
200  newHit->setText(0, QString(hitindex.c_str()));
201  }
202  }
203  }
204  }
205  connect(s_detectors, SIGNAL(itemSelectionChanged() ), this, SLOT(CreateSignalsTree() ) );
206  return s_detectors;
207 }
208 
209 
211 {
212  gsignals->clear();
213  gsignals->setSelectionMode(QAbstractItemView::SingleSelection);
214  QStringList labels;
215  labels << QString("Signal");
216  gsignals->setHeaderLabels(labels);
217 
218  QTreeWidgetItem* item = NULL;
219  if(s_detectors)
220  {
221  QList<QTreeWidgetItem *> list = s_detectors->selectedItems();
222  if(!list.isEmpty())
223  {
224  item = list.first();
225 
226  // trick to look for the index of this item
227  // will return zero if it's the sensitive detector name
228  // this index is also the index of the hit
229 
230  // itext looks like this:
231  // Hit n. 1 nsteps: 6
232  string itext = item->text(0).toStdString();
233 
234  stringstream sitext(itext);
235  string a, b, c;
236 
237  // index is the hit index
238  unsigned int index;
239  sitext >> a >> b >> c;
240  index = atoi(c.c_str());
241 
242  string SD;
243  MSensitiveDetector *MSD = NULL;
244  if(index==0)
245  {
246  SD = a;
247  MSD = SeDe_Map[SD];
248  }
249  else
250  {
251 
252  stringstream mtext(item->parent()->text(0).toStdString());
253  mtext >> SD;
254  MSD = SeDe_Map[SD];
255  SD += " Hit n. " + c;
256  }
257 
258  QTreeWidgetItem * newHit = new QTreeWidgetItem(gsignals);
259  newHit->setText(0, QString(SD.c_str()));
260  newHit->setExpanded(1);
261 
262  MHitCollection *MHC = MSD->GetMHitCollection();
263 
264  if(MHC)
265  if(index>0 && index<=MHC->GetSize())
266  {
267  MHit* aHit = (*MHC)[index-1];
268  int nsteps = aHit->GetPos().size();
269 
270  // photo electron tubes are treated differently than
271  // normal sensitive detectors
272  if(MSD->SDID.IDnames.back().find("nphe_pmt") != string::npos)
273  {
274  SD += " nphe: " + stringify(nsteps);
275 
276  newHit->setText(0, QString(SD.c_str()));
277 
278  vector<double> ene = aHit->GetEs();
279  vector<double> time = aHit->GetTime();
280  vector<int> pid = aHit->GetPIDs();
281 
282  vector<double> lambda;
283  // 1 nm = 1240 / eV
284  for(unsigned int i=0; i<ene.size(); i++)
285  lambda.push_back(1240.0/(ene[i]/eV));
286 
287 
288  vector<identifier> identi = aHit->GetId();
289  string title = "";
290  for(unsigned int i=0; i<identi.size(); i++)
291  title += identi[i].name + " " + stringify(identi[i].id) + " " ;
292 
293  QTreeWidgetItem * EneI = new QTreeWidgetItem(newHit);
294  EneI->setText(0, QString(" Wavelenght[nm] pid Time[ns] "));
295  EneI->setExpanded(1);
296 
297  QTreeWidgetItem * EneItems;
298  for(int i=0; i<nsteps; i++)
299  {
300  EneItems = new QTreeWidgetItem(EneI);
301  char etext[200];
302  sprintf(etext, " %4.1f %d %5.4f ", lambda[i], pid[i], time[i]);
303  EneItems->setText(0, QString(etext));
304  EneItems->setTextAlignment(1, Qt::AlignJustify);
305  EneItems->setTextAlignment(2, Qt::AlignJustify);
306  }
307  plots_bg("time [ns]", "Wavelenght [nm]", time, lambda, title);
308  plot_graph(time, lambda, pid);
309  }
310  else
311  {
312  SD += " nsteps: " + stringify(nsteps);
313 
314  newHit->setText(0, QString(SD.c_str()));
315 
316  vector<double> edep = aHit->GetEdep();
317  vector<double> time = aHit->GetTime();
318  vector<G4ThreeVector> mom = aHit->GetMoms();
319  vector<int> pid = aHit->GetPIDs();
320  vector<identifier> identi = aHit->GetId();
321  string title = "";
322  for(unsigned int i=0; i<identi.size(); i++)
323  title += identi[i].name + " " + stringify(identi[i].id) + " " ;
324 
325 
326  // calculating max EDEP
327  double max_edep=0;
328  for(unsigned int i=0; i<edep.size(); i++)
329  if(edep[i]>max_edep) max_edep = edep[i];
330 
331  // scale depends on max_edep
332  // to be completed
333  // cout << max_edep << " MAX " << endl;
334 
335  QTreeWidgetItem * EdepI = new QTreeWidgetItem(newHit);
336  EdepI->setText(0, QString(" Edep[MeV] pid Time[ns] p[MeV]"));
337  EdepI->setExpanded(1);
338 
339  QTreeWidgetItem * EdepItems;
340  for(int i=0; i<nsteps; i++)
341  {
342  EdepItems = new QTreeWidgetItem(EdepI);
343  char etext[200];
344  sprintf(etext, "%6.5f %d %5.4f %4.2f", edep[i], pid[i], time[i], mom[i].mag());
345  EdepItems->setText(0, QString(etext));
346  EdepItems->setTextAlignment(1, Qt::AlignJustify);
347  EdepItems->setTextAlignment(2, Qt::AlignJustify);
348  }
349  plots_bg("time [ns]", "EDep [MeV]", time, edep, title);
350  plot_graph(time, edep, pid);
351 
352  }
353  }
354  }
355  }
356  return gsignals;
357 }
358 
359 
360 void gsignal::plots_bg(string xtit, string ytit, vector<double> x, vector<double> y, string title)
361 {
362  scene->clear();
363  // title
364  QGraphicsSimpleTextItem *Title = new QGraphicsSimpleTextItem(QString(title.c_str()));
365  scene->addItem(Title);
366  QFont sansFont("Times", 18);
367  Title->setFont(sansFont);
368  Title->moveBy(20 - (double) title.length()*3.0, 10); // this should more or less center it
369 
370  if(x.size()<1) return;
371 
372  // axis
373  QGraphicsLineItem *xaxis = new QGraphicsLineItem( xorig-4, yorig, xorig+xaxil, yorig);
374  QGraphicsLineItem *xaxisa = new QGraphicsLineItem( xorig+xaxil, yorig, xorig+xaxil - 15, yorig + 4);
375  QGraphicsLineItem *xaxisb = new QGraphicsLineItem( xorig+xaxil, yorig, xorig+xaxil - 15, yorig - 4);
376  xaxis->setPen( QPen(Qt::black, 3));
377  xaxisa->setPen(QPen(Qt::black, 2));
378  xaxisb->setPen(QPen(Qt::black, 2));
379  scene->addItem(xaxis);
380  scene->addItem(xaxisa);
381  scene->addItem(xaxisb);
382 
383 
384  QGraphicsLineItem *yaxis = new QGraphicsLineItem(xorig, yorig+4, xorig, yorig-yaxil);
385  QGraphicsLineItem *yaxisa = new QGraphicsLineItem(xorig, yorig-yaxil, xorig - 4, yorig-yaxil + 15);
386  QGraphicsLineItem *yaxisb = new QGraphicsLineItem(xorig, yorig-yaxil, xorig + 4, yorig-yaxil + 15);
387  yaxis->setPen( QPen(Qt::black, 3));
388  yaxisa->setPen(QPen(Qt::black, 3));
389  yaxisb->setPen(QPen(Qt::black, 3));
390  scene->addItem(yaxis);
391  scene->addItem(yaxisa);
392  scene->addItem(yaxisb);
393 
394 
395  // labels
396  QGraphicsSimpleTextItem *xlab = new QGraphicsSimpleTextItem(QString(xtit.c_str()));
397  QGraphicsSimpleTextItem *ylab = new QGraphicsSimpleTextItem(QString(ytit.c_str()));
398  scene->addItem(xlab);
399  scene->addItem(ylab);
400  xlab->moveBy(xorig+xaxil-60, yorig + 10);
401  ylab->moveBy(xorig-30, yorig-yaxil+50);
402  ylab->setRotation(-90);
403 
404  // calculating minima and maxima
405  xmin = 100000;
406  ymin = 100000;
407  for(unsigned int i=0; i<x.size(); i++) if(x[i] < xmin) xmin = x[i];
408  for(unsigned int i=0; i<y.size(); i++) if(y[i] < ymin) ymin = y[i];
409  xmax = -100000;
410  ymax = -100000;
411  for(unsigned int i=0; i<x.size(); i++) if(x[i] > xmax) xmax = x[i];
412  for(unsigned int i=0; i<y.size(); i++) if(y[i] > ymax) ymax = y[i];
413 
414 
415  // putting 5 vertical axis - dashed lines - between xmin and xmax
416  dx = (xmax - xmin);
417  dy = (ymax - ymin);
418 
419 
420 
421  // lab should be at least size 10
422  char lab[10];
423  QGraphicsSimpleTextItem *alab;
424 
425  QGraphicsLineItem *xtick;
426  for(int a=0; a<nticksx+1; a++)
427  {
428  xtick = new QGraphicsLineItem(xorig + inside + a*DX/nticksx, yorig + 4, xorig + inside + a*DX/nticksx, yorig-yaxil+inside);
429  xtick->setPen( QPen(Qt::blue, 1, Qt::DashDotLine));
430  scene->addItem(xtick);
431  }
432 
433 
434  for(int a=0; a<nticksx; a++)
435  {
436  sprintf(lab, "%4.3f", xmin+ a*dx/nticksx);
437  alab = new QGraphicsSimpleTextItem(QString(lab));
438  QFont sansFont("Helvetica", 12);
439  alab->setFont(sansFont);
440  alab->moveBy(xorig + inside + a*DX/nticksx - 12, yorig + 8);
441  scene->addItem(alab);
442  }
443 
444 
445  QGraphicsLineItem *ytick;
446  for(int a=0; a<nticksy+1; a++)
447  {
448  ytick = new QGraphicsLineItem(xorig - 4, yorig - inside - a*DY/nticksy, xorig + xaxil - inside, yorig - inside - a*DY/nticksy);
449  ytick->setPen( QPen(Qt::blue, 1, Qt::DashDotLine));
450  scene->addItem(ytick);
451  }
452 
453 
454  for(int a=0; a<nticksy; a++)
455  {
456 
457  if (ymin+ a*dy/nticksy < 0.01)
458  sprintf(lab, "%5.4f", ymin+ a*dy/nticksy);
459  else if(ymin+ a*dy/nticksy < 1)
460  sprintf(lab, "%5.3f", ymin+ a*dy/nticksy);
461  else if(ymin+ a*dy/nticksy < 10)
462  sprintf(lab, "%5.2f", ymin+ a*dy/nticksy);
463  else if(ymin+ a*dy/nticksy < 100)
464  sprintf(lab, "%5.1f", ymin+ a*dy/nticksy);
465  else
466  sprintf(lab, "%5.0f", ymin+ a*dy/nticksy);
467 
468  alab = new QGraphicsSimpleTextItem(QString(lab));
469  QFont sansFont("Helvetica", 12);
470  alab->setFont(sansFont);
471  alab->moveBy(xorig - 50, yorig - inside - a*DY/nticksy - 6);
472  scene->addItem(alab);
473  }
474 
475 }
476 
477 void gsignal::plot_graph(vector<double> x, vector<double> y, vector<int> pid)
478 {
479  if(x.size()<2) return;
480 
481  QGraphicsRectItem *rect;
482 
483  for(unsigned int i=0; i<x.size(); i++)
484  {
485  if(pcolors.find(pid[i]) == pcolors.end())
486  cout << " Attention: color not found for: " << pid[i] << endl;
487  else
488  {
489  rect = scene->addRect(0, 0, 6, 6, pcolors[pid[i]]);
490  rect->moveBy(xorig + inside + DX*(x[i]-xmin)/dx, yorig - inside - DY*(y[i]-ymin)/dy);
491  }
492  }
493 }
494 
496 {
497  string hd_msg = gemcOpt->args["LOG_MSG"].args ;
498  double VERB = gemcOpt->args["GEO_VERBOSITY"].arg ;
499  if(VERB>2)
500  cout << hd_msg << " Signal Widget Deleted." << endl;
501 
502 }
503 
504 
505 
506 
507 
508 
509 
510 
511 
512 
513 
514 
515 
516 
517 
518 
519 
520 
double ymax
Definition: gsignal.h:47
double xmax
Definition: gsignal.h:47
SDId SDID
SDId used for identification.
double ymin
Definition: gsignal.h:46
void plots_bg(string xtit, string ytit, vector< double > x, vector< double > y, string title)
Definition: gsignal.cc:360
double xmin
Definition: gsignal.h:46
map< int, QPen > pcolors
Definition: gsignal.h:60
double DY
Definition: gsignal.h:49
int xorig
Definition: gsignal.h:44
vector< G4ThreeVector > GetMoms()
Definition: MHit.h:86
vector< identifier > GetId()
Definition: MHit.h:96
G4THitsCollection< MHit > MHitCollection
Definition: MHit.h:134
gsignal(QWidget *parent, gemc_opts *, map< string, MSensitiveDetector * >)
Definition: gsignal.cc:19
double dx
Definition: gsignal.h:49
vector< string > IDnames
Identifier names as they should be in identifier.
int yaxil
Definition: gsignal.h:45
QTreeWidget * CreateSignalsTree()
Definition: gsignal.cc:210
string stringify(double x)
int yorig
Definition: gsignal.h:44
vector< G4ThreeVector > GetPos()
Definition: MHit.h:65
void plot_graph(vector< double > x, vector< double > y, vector< int > pid)
Definition: gsignal.cc:477
double DX
Definition: gsignal.h:49
map< string, MSensitiveDetector * > SeDe_Map
Definition: gsignal.h:58
G4UImanager * UImanager
Definition: gsignal.h:57
Definition: MHit.h:29
vector< double > GetEs()
Definition: MHit.h:90
MHitCollection * GetMHitCollection()
returns hit collection
int nticksx
Definition: gsignal.h:50
vector< double > GetTime()
Definition: MHit.h:82
map< string, opts > args
Options map.
Definition: usage.h:68
double dy
Definition: gsignal.h:49
QTreeWidget * CreateSDetsTree()
Definition: gsignal.cc:150
vector< int > GetPIDs()
Definition: MHit.h:108
double inside
Definition: gsignal.h:48
vector< double > GetEdep()
Definition: MHit.h:76
int nticksy
Definition: gsignal.h:50
gemc_opts * gemcOpt
Definition: gsignal.h:56
~gsignal()
Definition: gsignal.cc:495
int xaxil
Definition: gsignal.h:45