GEMC  2.3
Geant4 Monte-Carlo Framework
gsignal.cc
Go to the documentation of this file.
1 // Qt headers
2 #include <QtWidgets>
3 
4 // gemc headers
5 #include "gsignal.h"
6 #include "Hit.h"
7 #include "string_utilities.h"
8 
9 // CLHEP units
10 #include "CLHEP/Units/PhysicalConstants.h"
11 using namespace CLHEP;
12 
13 gsignal::gsignal(QWidget *parent, goptions *Opts, map<string, sensitiveDetector*> SD_Map) : QWidget(parent)
14 {
15  gemcOpt = Opts;
16  WRITE_INTRAW = replaceCharWithChars(gemcOpt->optMap["INTEGRATEDRAW"].args, ",", " ");
17  SAVE_ALL_MOTHERS = gemcOpt->optMap["SAVE_ALL_MOTHERS"].arg;
18 
19  SeDe_Map = SD_Map;
20 
21  availableSignals.push_back("E Dep.");
22  availableSignals.push_back("Trk ID");
23  availableSignals.push_back("Orig. Trk");
24  availableSignals.push_back("Mom");
25  availableSignals.push_back("<x>");
26  availableSignals.push_back("<y>");
27  availableSignals.push_back("<z>");
28  availableSignals.push_back("<lx>");
29  availableSignals.push_back("<ly>");
30  availableSignals.push_back("<lz>");
31  availableSignals.push_back("<vx>");
32  availableSignals.push_back("<vy>");
33  availableSignals.push_back("<vz>");
34  availableSignals.push_back("<mvx>");
35  availableSignals.push_back("<mvy>");
36  availableSignals.push_back("<mvz>");
37  availableSignals.push_back("Voltage");
38 
39 
40  // Layout done witt splitters
41  //
42  // +---------------------------+
43  // | Combo Var Choice |
44  // +------------+--------------+
45  // | | |
46  // | | |
47  // | Hit | Signal |
48  // | Choice | Data |
49  // | | |
50  // +------------+--------------+
51  // +---------------------------+
52  // | |
53  // | Graph |
54  // +---------------------------|
55 
56  // Combo Box on Top to choose which variable to plot
57  qcsignal = new QComboBox;
58  for(unsigned v=0; v<availableSignals.size(); v++)
59  qcsignal->addItem(tr(availableSignals[v].c_str()));
60 
61  connect ( qcsignal , SIGNAL( currentIndexChanged (int) ), this, SLOT( chooseVariable(int) ) );
62 
63 
64  // Middle Left: The list of hits hits tree
65  hitList = new QTreeWidget();
67 
68  // Middle Right: The data
69  hitData = new QTreeWidget();
71 
72  // horizontal splitter in the middle to display hits and data
73  QSplitter *dataSplitter = new QSplitter(this);
74  if(hitList)
75  dataSplitter->addWidget(hitList);
76  if(hitData)
77  dataSplitter->addWidget(hitData);
78 
79 
80  // bottom: the graph
81  graphView = new graph(this);
82 
83  // Graph axis origins and legth, number of ticks each axis
84  // xorig yorig xlength ylength nticksx nticksy
85  graphView->setAxis(40, 310, 465, 300, 5, 5);
86  // inside shift of the axis ticks, and factor that multiplies the ticks size
87  graphView->setInside(20, 2, 2);
88 
89 
90  // putting all together in the main splitter
91  QSplitter *vMainsplitter = new QSplitter(this);
92  vMainsplitter->setOrientation(Qt::Vertical);
93  vMainsplitter->addWidget(qcsignal);
94  vMainsplitter->addWidget(dataSplitter);
95  vMainsplitter->addWidget(graphView);
96  vMainsplitter->setMinimumSize(545, 595);
97  graphView->setMinimumSize(545, 450);
98 
99 
100  // Hit Gradient Color
101  HitGrad = QLinearGradient(QPointF(1, 100), QPointF(180, 20));
102  HitGrad.setColorAt(0, QColor(255, 80, 80));
103  HitGrad.setColorAt(1, QColor(245, 245, 245));
104  HitBrush = QBrush(HitGrad);
105 
106  // initialize signalChoice to Energy deposited
107  signalChoice = "E Dep.";
108 }
109 
111 {
112  hitList->clear();
113  hitList->setSelectionMode(QAbstractItemView::SingleSelection);
114  hitList->setHeaderLabels(QStringList("Hits List"));
115 
116  for(map<string, sensitiveDetector*>::iterator it = SeDe_Map.begin(); it!= SeDe_Map.end(); it++)
117  {
118  MHitCollection *MHC = it->second->GetMHitCollection();
119  int nhits = 0;
120  if(MHC) nhits = MHC->GetSize();
121 
122  // Creating sensitive detectors name tree if it's different than "mirrors"
123  if(it->first != "mirror")
124  {
125  QTreeWidgetItem *newItem = new QTreeWidgetItem(hitList);
126  newItem->setText(0, QString(it->first.c_str()));
127 
128  if(nhits)
129  {
130  newItem->setBackground(0, HitBrush );
131  string snhits = it->first + " " + stringify(nhits) + " hit";
132  if(nhits>1) snhits += "s";
133  newItem->setText(0, QString(snhits.c_str()));
134 
135  // if the last sensitive identifier is nphe then
136  // visualization screen is different:
137  // need to visualize number of photoelectrons only
138  for(int h=0; h<nhits; h++)
139  {
140  MHit *aHit = (*MHC)[h];
141 
142  int nsteps = aHit->GetPos().size();
143  QTreeWidgetItem *newHit = new QTreeWidgetItem(newItem);
144 
145  string hitindex = "Hit n. " + stringify(h+1) + " nsteps: " + stringify(nsteps) ;
146 
147  if(!it->second->SDID.identifiers.size())
148  cout << " !!! Error: no identifiers found for SD >" << it->second->SDID.name << "<" << endl;
149 
150  // if last sensitive element is nphe_pmt then writing number of photo-electrons
151  if(it->second->SDID.identifiers.back().find("nphe") != string::npos)
152  hitindex = "Hit n. " + stringify(h+1) + " nphe: " + stringify(nsteps) ;
153 
154  newHit->setText(0, QString(hitindex.c_str()));
155  }
156  }
157  }
158  }
159  connect(hitList, SIGNAL(itemSelectionChanged() ), this, SLOT(createSignalsTree() ) );
160 }
161 
162 
163 
164 void gsignal::chooseVariable(int index)
165 {
168 }
169 
170 
171 
173 {
174  hitData->clear();
175 
176  hitData->setSelectionMode(QAbstractItemView::SingleSelection);
177  hitData->setHeaderLabels(QStringList("Data"));
178 
179  // QTreeWidgetItem* item = NULL;
180  if(hitList)
181  {
182  QList<QTreeWidgetItem *> list = hitList->selectedItems();
183  if(!list.isEmpty())
184  {
185  QTreeWidgetItem *item = list.first();
186 
187  // trick to look for the index of this item
188  // will return zero if it's the sensitive detector name
189  // this index is also the index of the hit
190 
191  // itext looks like this:
192  // Hit n. 1 nsteps: 6
193  string itext = item->text(0).toStdString();
194 
195  stringstream sitext(itext);
196  string a, b, c;
197 
198  // index is the hit index
199  unsigned int index;
200  sitext >> a >> b >> c;
201  index = atoi(c.c_str());
202 
203  string SD;
204  string sDetector;
205  sensitiveDetector *MSD = NULL;
206  if(index==0)
207  {
208  SD = a;
209  sDetector = SD;
210  MSD = SeDe_Map[SD];
211  }
212  else
213  {
214  stringstream mtext(item->parent()->text(0).toStdString());
215  mtext >> SD;
216  sDetector = SD;
217  MSD = SeDe_Map[SD];
218  SD += " Hit n. " + c;
219  }
220 
221  QTreeWidgetItem * newHit = new QTreeWidgetItem(hitData);
222  newHit->setText(0, QString(SD.c_str()));
223  newHit->setExpanded(1);
224 
225  MHitCollection *MHC = MSD->GetMHitCollection();
226 
227  if(MHC)
228  if(index>0 && index<=MHC->GetSize())
229  {
230  MHit* aHit = (*MHC)[index-1];
231  int nsteps = aHit->GetPos().size();
232 
233  // photo electron tubes are treated differently than
234  // normal sensitive detectors
235  if(MSD->SDID.identifiers.back().find("nphe") != string::npos)
236  {
237  SD += " nphe: " + stringify(nsteps);
238 
239  newHit->setText(0, QString(SD.c_str()));
240 
241  vector<double> ene = aHit->GetEs();
242  vector<double> time = aHit->GetTime();
243  vector<int> pid = aHit->GetPIDs();
244 
245  vector<double> lambda;
246  // 1 nm = 1240 / eV
247  for(unsigned int i=0; i<ene.size(); i++)
248  lambda.push_back(1240.0/(ene[i]/eV));
249 
250 
251  vector<identifier> identi = aHit->GetId();
252  string title = "";
253  for(unsigned int i=0; i<identi.size(); i++)
254  title += identi[i].name + " " + stringify(identi[i].id) + " " ;
255 
256  QTreeWidgetItem * EneI = new QTreeWidgetItem(newHit);
257  EneI->setText(0, QString(" Wavelenght[nm] pid Time[ns] "));
258  EneI->setExpanded(1);
259 
260  QTreeWidgetItem * EneItems;
261  for(int i=0; i<nsteps; i++)
262  {
263  EneItems = new QTreeWidgetItem(EneI);
264  char etext[200];
265  sprintf(etext, " %4.1f %d %5.4f ", lambda[i], pid[i], time[i]);
266  EneItems->setText(0, QString(etext));
267  EneItems->setTextAlignment(1, Qt::AlignJustify);
268  EneItems->setTextAlignment(2, Qt::AlignJustify);
269  }
270  graphView->plots_bg("time [ns]", "Wavelenght [nm]", time, lambda, title);
271  graphView->plot_graph(time, lambda, pid);
272  }
273  else
274  {
275  vector<double> signal;
276  vector<double> time = aHit->GetTime();
277  vector<int> pid = aHit->GetPIDs();
278 
279  if(signalChoice == "E Dep.")
280  signal = aHit->GetEdep();
281 
282  if(signalChoice == "Trk ID")
283  signal = convertVintVdouble(aHit->GetTIds());
284 
285 
286  // this info is available only if WRITE_INTRAW is enabled
287  if(signalChoice == "Orig. Trk")
288  {
289  if(WRITE_INTRAW.find(sDetector) != string::npos)
290  {
291  signal = convertVintVdouble(aHit->GetoTrackIds());
292  }
293  else
294  {
295  vector<int> trks = aHit->GetTIds();
296  for(unsigned int i=0; i<trks.size(); i++)
297  signal.push_back(-1.0);
298  }
299  }
300 
301  if(signalChoice == "<x>")
302  {
303  vector<G4ThreeVector> pos = aHit->GetPos();
304  for(unsigned int i=0; i<pos.size(); i++)
305  signal.push_back(pos[i].x());
306  }
307  if(signalChoice == "<y>")
308  {
309  vector<G4ThreeVector> pos = aHit->GetPos();
310  for(unsigned int i=0; i<pos.size(); i++)
311  signal.push_back(pos[i].y());
312  }
313  if(signalChoice == "<z>")
314  {
315  vector<G4ThreeVector> pos = aHit->GetPos();
316  for(unsigned int i=0; i<pos.size(); i++)
317  signal.push_back(pos[i].z());
318  }
319  if(signalChoice == "<lx>")
320  {
321  vector<G4ThreeVector> pos = aHit->GetLPos();
322  for(unsigned int i=0; i<pos.size(); i++)
323  signal.push_back(pos[i].x());
324  }
325  if(signalChoice == "<ly>")
326  {
327  vector<G4ThreeVector> pos = aHit->GetLPos();
328  for(unsigned int i=0; i<pos.size(); i++)
329  signal.push_back(pos[i].y());
330  }
331  if(signalChoice == "<lz>")
332  {
333  vector<G4ThreeVector> pos = aHit->GetLPos();
334  for(unsigned int i=0; i<pos.size(); i++)
335  signal.push_back(pos[i].z());
336  }
337  if(signalChoice == "<vx>")
338  {
339  vector<G4ThreeVector> pos = aHit->GetVerts();
340  for(unsigned int i=0; i<pos.size(); i++)
341  signal.push_back(pos[i].x());
342  }
343  if(signalChoice == "<vy>")
344  {
345  vector<G4ThreeVector> pos = aHit->GetVerts();
346  for(unsigned int i=0; i<pos.size(); i++)
347  signal.push_back(pos[i].y());
348  }
349  if(signalChoice == "<vz>")
350  {
351  vector<G4ThreeVector> pos = aHit->GetVerts();
352  for(unsigned int i=0; i<pos.size(); i++)
353  signal.push_back(pos[i].z());
354  }
355  if(signalChoice == "<mvx>")
356  {
357  if(SAVE_ALL_MOTHERS)
358  {
359  vector<G4ThreeVector> pos = aHit->GetmVerts();
360  for(unsigned int i=0; i<pos.size(); i++)
361  signal.push_back(pos[i].x());
362  }
363  else
364  {
365  vector<int> trks = aHit->GetTIds();
366  for(unsigned int i=0; i<trks.size(); i++)
367  signal.push_back(0.0);
368  }
369  }
370  if(signalChoice == "<mvy>")
371  {
372  if(SAVE_ALL_MOTHERS)
373  {
374  vector<G4ThreeVector> pos = aHit->GetmVerts();
375  for(unsigned int i=0; i<pos.size(); i++)
376  signal.push_back(pos[i].y());
377  }
378  else
379  {
380  vector<int> trks = aHit->GetTIds();
381  for(unsigned int i=0; i<trks.size(); i++)
382  signal.push_back(0.0);
383  }
384  }
385  if(signalChoice == "<mvz>")
386  {
387  if(SAVE_ALL_MOTHERS)
388  {
389  vector<G4ThreeVector> pos = aHit->GetmVerts();
390  for(unsigned int i=0; i<pos.size(); i++)
391  signal.push_back(pos[i].z());
392  }
393  else
394  {
395  vector<int> trks = aHit->GetTIds();
396  for(unsigned int i=0; i<trks.size(); i++)
397  signal.push_back(0.0);
398  }
399  }
400 
401  if(signalChoice == "Mom")
402  {
403  vector<G4ThreeVector> mom = aHit->GetMoms();
404  for(unsigned int i=0; i<mom.size(); i++)
405  signal.push_back(mom[i].mag());
406  }
407  if(signalChoice == "Voltage")
408  {
409  time = aHit->getSignalT();
410  signal = aHit->getSignalV();
411  nsteps = time.size();
412 
413  pid.clear();
414  // black pen if it's a signal
415  for(unsigned int i=0; i<time.size(); i++)
416  pid.push_back(1000);
417  }
418 
419  SD += " nsteps: " + stringify(nsteps);
420  newHit->setText(0, QString(SD.c_str()));
421 
422  vector<identifier> identi = aHit->GetId();
423  string title = "";
424 
425  for(unsigned int i=0; i<identi.size(); i++)
426  title += identi[i].name + " " + stringify(identi[i].id) + " " ;
427 
428  QTreeWidgetItem * signalI = new QTreeWidgetItem(newHit);
429  char ttext[200];
430  sprintf(ttext, "%s pid Time[ns] ", signalChoice.c_str());
431  signalI->setText(0, QString(ttext));
432  signalI->setExpanded(1);
433 
434  QTreeWidgetItem * signalItems;
435  for(int i=0; i<nsteps; i++)
436  {
437  signalItems = new QTreeWidgetItem(signalI);
438  char etext[200];
439  sprintf(etext, "%6.5f %d %5.4f", signal[i], pid[i], time[i]);
440  signalItems->setText(0, QString(etext));
441  signalItems->setTextAlignment(1, Qt::AlignJustify);
442  signalItems->setTextAlignment(2, Qt::AlignJustify);
443  }
444  graphView->plots_bg("time [ns]", signalChoice.c_str(), time, signal, title);
445  graphView->plot_graph(time, signal, pid);
446 
447  }
448  }
449  }
450  }
451 }
452 
453 
454 
456 {
457  string hd_msg = gemcOpt->optMap["LOG_MSG"].args ;
458  double VERB = gemcOpt->optMap["GEO_VERBOSITY"].arg ;
459  if(VERB>2)
460  cout << hd_msg << " Signal Widget Deleted." << endl;
461 }
462 
463 
464 
465 
466 
467 
468 
469 
470 
map< string, sensitiveDetector * > SeDe_Map
Definition: gsignal.h:38
string WRITE_INTRAW
Definition: gsignal.h:35
sensitiveID SDID
sensitiveID used for identification, hit properties and digitization
int SAVE_ALL_MOTHERS
Definition: gsignal.h:36
void createSignalsTree()
Definition: gsignal.cc:172
QComboBox * qcsignal
Definition: gsignal.h:43
vector< double > getSignalT()
Definition: Hit.h:165
vector< double > convertVintVdouble(vector< int > input)
Definition: utils.cc:362
vector< G4ThreeVector > GetMoms()
Definition: Hit.h:93
vector< identifier > GetId()
Definition: Hit.h:103
void setAxis(int a, int b, int c, int d, int e, int f)
Definition: graph.h:38
vector< double > getSignalV()
Definition: Hit.h:166
string signalChoice
Definition: gsignal.h:41
void createHitListTree()
Definition: gsignal.cc:110
void setInside(double a, double b, double c)
Definition: graph.h:39
string replaceCharWithChars(string input, string x, string y)
goptions * gemcOpt
Definition: gsignal.h:39
vector< G4ThreeVector > GetLPos()
Definition: Hit.h:76
vector< string > availableSignals
Definition: gsignal.h:42
string stringify(double x)
vector< G4ThreeVector > GetPos()
Definition: Hit.h:72
map< string, aopt > optMap
Options map.
Definition: options.h:75
vector< G4ThreeVector > GetmVerts()
Definition: Hit.h:137
G4THitsCollection< MHit > MHitCollection
Definition: Hit.h:194
Definition: Hit.h:22
vector< double > GetEs()
Definition: Hit.h:97
Definition: graph.h:13
vector< double > GetTime()
Definition: Hit.h:89
void plot_graph(vector< double > x, vector< double > y, vector< int > pid)
Definition: graph.cc:132
vector< int > GetTIds()
Definition: Hit.h:101
gsignal(QWidget *parent, goptions *, map< string, sensitiveDetector * >)
Definition: gsignal.cc:13
vector< int > GetPIDs()
Definition: Hit.h:112
vector< string > identifiers
vector of strings that uniquely identify the detector element
Definition: sensitiveID.h:29
vector< double > GetEdep()
Definition: Hit.h:83
vector< int > GetoTrackIds()
Definition: Hit.h:127
vector< G4ThreeVector > GetVerts()
Definition: Hit.h:80
void plots_bg(string xtit, string ytit, vector< double > x, vector< double > y, string title)
Definition: graph.cc:39
void chooseVariable(int)
Definition: gsignal.cc:164
~gsignal()
Definition: gsignal.cc:455
MHitCollection * GetMHitCollection()
returns hit collection