Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SepdMon.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file SepdMon.cc
1 // use #include "" only for your local include and put
2 // those in the first line(s) before any #include <>
3 // otherwise you are asking for weird behavior
4 // (more info - check the difference in include path search when using "" versus <>)
5 
6 #include "SepdMon.h"
7 
8 #include <onlmon/OnlMon.h> // for OnlMon
9 #include <onlmon/OnlMonDB.h>
10 #include <onlmon/OnlMonServer.h>
11 #include <onlmon/pseudoRunningMean.h>
12 
13 #include <Event/msg_profile.h>
14 #include <calobase/TowerInfoDefs.h>
15 #include <caloreco/CaloWaveformFitting.h>
16 
17 #include <Event/Event.h>
18 #include <Event/EventTypes.h>
19 #include <Event/msg_profile.h>
20 
21 #include <TH1.h>
22 #include <TH2.h>
23 #include <TRandom.h>
24 
25 #include <cmath>
26 #include <cstdio> // for printf
27 #include <fstream>
28 #include <iostream>
29 #include <sstream>
30 #include <string> // for allocator, string, char_traits
31 
32 enum
33 {
36 };
37 
39  : OnlMon(name)
40 {
41  // leave ctor fairly empty, its hard to debug if code crashes already
42  // during a new EpdMon()
43  return;
44 }
45 
47 {
48  // you can delete NULL pointers it results in a NOOP (No Operation)
49  std::vector<runningMean *>::iterator rm_it;
50  for (auto iter : rm_packet_number)
51  {
52  delete iter;
53  }
54  for (auto iter : rm_packet_length)
55  {
56  delete iter;
57  }
58  for (auto iter : rm_packet_chans)
59  {
60  delete iter;
61  }
62  return;
63 }
64 
66 {
67  gRandom->SetSeed(rand());
68  // read our calibrations from EpdMonData.dat
69  /*
70  const char *sepdcalib = getenv("SEPDCALIB");
71  if (!sepdcalib)
72  {
73  std::cout << "SEPDCALIB environment variable not set" << std::endl;
74  exit(1);
75  }
76  std::string fullfile = std::string(sepdcalib) + "/" + "SepdMonData.dat";
77  std::ifstream calib(fullfile);
78 
79  calib.close();
80  */
81  // use printf for stuff which should go the screen but not into the message
82  // system (all couts are redirected)
83  printf("doing the Init\n");
84  h_ADC0_s = new TH2F("h_ADC0_s", ";;", nPhi0, -axislimit, axislimit, nRad, -axislimit, axislimit);
85  h_ADC0_n = new TH2F("h_ADC0_n", ";;", nPhi0, -axislimit, axislimit, nRad, -axislimit, axislimit);
86  h_ADC_s = new TH2F("h_ADC_s", ";;", nPhi, -axislimit, axislimit, nRad, -axislimit, axislimit);
87  h_ADC_n = new TH2F("h_ADC_n", ";;", nPhi, -axislimit, axislimit, nRad, -axislimit, axislimit);
88 
89  h_hits0_s = new TH2F("h_hits0_s", ";;", nPhi0, -axislimit, axislimit, nRad, -axislimit, axislimit);
90  h_hits0_n = new TH2F("h_hits0_n", ";;", nPhi0, -axislimit, axislimit, nRad, -axislimit, axislimit);
91  h_hits_s = new TH2F("h_hits_s", ";;", nPhi, -axislimit, axislimit, nRad, -axislimit, axislimit);
92  h_hits_n = new TH2F("h_hits_n", ";;", nPhi, -axislimit, axislimit, nRad, -axislimit, axislimit);
93 
94  int nADCcorr = 600;
95  double ADCcorrmax = 2e4;
96  int nhitscorr = 700;
97  double hitscorrmax = 1000;
98  h_ADC_corr = new TH2F("h_ADC_corr", ";ADC avg sum (south); ADC avg sum (north)", nADCcorr, 0, ADCcorrmax, nADCcorr, 0, ADCcorrmax);
99  h_hits_corr = new TH2F("h_hits_corr", ";ADC avg sum (south); ADC avg sum (north)", nhitscorr, 0, hitscorrmax, nhitscorr, 0, hitscorrmax);
100 
101  h_event = new TH1F("h_event", "", 1, 0, 1);
102 
103  // waveform processing
104  h1_waveform_twrAvg = new TH1F("h1_waveform_twrAvg", "", n_samples_show, 0.5, n_samples_show + 0.5);
105  h1_waveform_time = new TH1F("h1_waveform_time", "", n_samples_show, 0.5, n_samples_show + 0.5);
106  h1_waveform_pedestal = new TH1F("h1_waveform_pedestal", "", 25, 1.2e3, 1.8e3);
107  h2_sepd_waveform = new TH2F("h2_sepd_waveform", "", n_samples_show, 0.5, n_samples_show + 0.5, 1000, 0, 15000);
108 
109  // waveform processing, template vs. fast interpolation
110  h1_sepd_fitting_sigDiff = new TH1F("h1_fitting_sigDiff", "", 50, 0, 2);
111  h1_sepd_fitting_pedDiff = new TH1F("h1_fitting_pedDiff", "", 50, 0, 2);
112  h1_sepd_fitting_timeDiff = new TH1F("h1_fitting_timeDiff", "", 50, -10, 10);
113 
114  // packet stuff
115  h1_packet_number = new TH1F("h1_packet_number", "", 6, packetlow - 0.5, packethigh + 0.5);
116  h1_packet_length = new TH1F("h1_packet_length", "", 6, packetlow - 0.5, packethigh + 0.5);
117  h1_packet_chans = new TH1F("h1_packet_chans", "", 6, packetlow - 0.5, packethigh + 0.5);
118  h1_packet_event = new TH1F("h1_packet_event", "", 6, packetlow - 0.5, packethigh + 0.5);
119 
120  for (int i = 0; i < 6; i++)
121  {
125  }
126 
128  // register histograms with server otherwise client won't get them
129  se->registerHisto(this, h_ADC0_s); // uses the TH1->GetName() as key
130  se->registerHisto(this, h_ADC0_n);
131  se->registerHisto(this, h_ADC_s);
132  se->registerHisto(this, h_ADC_n);
133  se->registerHisto(this, h_hits0_s);
134  se->registerHisto(this, h_hits0_n);
135  se->registerHisto(this, h_hits_s);
136  se->registerHisto(this, h_hits_n);
137  se->registerHisto(this, h_ADC_corr);
138  se->registerHisto(this, h_hits_corr);
139  se->registerHisto(this, h_event);
141  se->registerHisto(this, h1_waveform_time);
143  se->registerHisto(this, h2_sepd_waveform);
144  se->registerHisto(this, h1_packet_number);
145  se->registerHisto(this, h1_packet_length);
146  se->registerHisto(this, h1_packet_chans);
147  se->registerHisto(this, h1_packet_event);
148  // se->registerHisto(this, h1_sepd_fitting_sigDiff);
149  // se->registerHisto(this, h1_sepd_fitting_pedDiff);
150  // se->registerHisto(this, h1_sepd_fitting_timeDiff);
151 
152  // save inidividual channel ADC distribution
153  for (int ichannel = 0; ichannel < nChannels; ichannel++)
154  {
155  h_ADC_channel[ichannel] = new TH1F(Form("h_ADC_channel%d", ichannel), ";ADC;Counts", 1000, 0, 15e3);
156  se->registerHisto(this, h_ADC_channel[ichannel]);
157  }
158 
159  // initialize waveform extraction tool
161 
163 
164  std::string sepdtemplate;
165  if (getenv("SEPDCALIB"))
166  {
167  sepdtemplate = getenv("SEPDCALIB");
168  }
169  else
170  {
171  sepdtemplate = ".";
172  }
173  sepdtemplate += std::string("/testbeam_sepd_template.root");
174  // WaveformProcessingTemp->initialize_processing(sepdtemplate);
175 
176  Reset();
177  return 0;
178 }
179 
180 int SepdMon::BeginRun(const int /* runno */)
181 {
182  // if you need to read calibrations on a run by run basis
183  // this is the place to do it
184  std::vector<runningMean *>::iterator rm_it;
185  for (rm_it = rm_packet_number.begin(); rm_it != rm_packet_number.end(); ++rm_it)
186  {
187  (*rm_it)->Reset();
188  }
189  for (rm_it = rm_packet_length.begin(); rm_it != rm_packet_length.end(); ++rm_it)
190  {
191  (*rm_it)->Reset();
192  }
193  for (rm_it = rm_packet_chans.begin(); rm_it != rm_packet_chans.end(); ++rm_it)
194  {
195  (*rm_it)->Reset();
196  }
197  return 0;
198 }
199 
200 // simple wavefrom analysis for possibe issues with the wavforProcessor
201 std::vector<float> SepdMon::getSignal(Packet *p, const int channel)
202 {
203  double baseline = 0;
204  for (int s = 0; s < 3; s++)
205  {
206  baseline += p->iValue(s, channel);
207  }
208  baseline /= 3.;
209 
210  double signal = 0;
211  float x = 0;
212  for (int s = 3; s < p->iValue(0, "SAMPLES"); s++)
213  {
214  x++;
215  signal += p->iValue(s, channel) - baseline;
216  }
217 
218  signal /= x;
219 
220  // simulate a failure if ( evtcount > 450 && p->getIdentifier() ==6011) return 0;
221 
222  std::vector<float> result;
223  result.push_back(signal);
224  result.push_back(2);
225  result.push_back(1);
226  return result;
227 }
228 
229 std::vector<float> SepdMon::anaWaveformFast(Packet *p, const int channel)
230 {
231  std::vector<float> waveform;
232  for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
233  {
234  waveform.push_back(p->iValue(s, channel));
235  }
236  std::vector<std::vector<float>> multiple_wfs;
237  multiple_wfs.push_back(waveform);
238 
239  std::vector<std::vector<float>> fitresults_sepd;
240  fitresults_sepd = WaveformProcessingFast->calo_processing_fast(multiple_wfs);
241 
242  std::vector<float> result;
243  result = fitresults_sepd.at(0);
244 
245  return result;
246 }
247 
248 std::vector<float> SepdMon::anaWaveformTemp(Packet *p, const int channel)
249 {
250  std::vector<float> waveform;
251  for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
252  {
253  waveform.push_back(p->iValue(s, channel));
254  }
255  std::vector<std::vector<float>> multiple_wfs;
256  multiple_wfs.push_back(waveform);
257 
258  std::vector<std::vector<float>> fitresults_sepd;
259  fitresults_sepd = WaveformProcessingTemp->process_waveform(multiple_wfs);
260 
261  std::vector<float> result;
262  result = fitresults_sepd.at(0);
263 
264  return result;
265 }
266 
268 {
269  evtcnt++;
270  h1_packet_event->Reset();
271  unsigned int ChannelNumber = 0;
272  // float sectorAvg[Nsector] = {0};
273  int phi_in = 0;
274  float phi;
275  float r;
276  int sumhit_s = 0;
277  int sumhit_n = 0;
278  long double sumADC_s = 0;
279  long double sumADC_n = 0;
280  // loop over packets which contain a single sector
281  for (int packet = packetlow; packet <= packethigh; packet++)
282  {
283  Packet *p = e->getPacket(packet);
284  int packet_bin = packet - packetlow + 1;
285  if (p)
286  {
287  int one[1] = {1};
288  rm_packet_number[packet - packetlow]->Add(one);
289  int packet_length[1] = {p->getLength()};
290  rm_packet_length[packet - packetlow]->Add(packet_length);
291 
292  h1_packet_length->SetBinContent(packet_bin, rm_packet_length[packet - packetlow]->getMean(0));
293 
294  h1_packet_event->SetBinContent(packet - packetlow + 1, p->iValue(0, "CLOCK"));
295  int nPacketChannels = p->iValue(0, "CHANNELS");
296  if (nPacketChannels > m_nChannels)
297  {
298  return -1; // packet is corrupted, reports too many channels
299  }
300  else
301  {
302  rm_packet_chans[packet - packetlow]->Add(&nChannels);
303  h1_packet_chans->SetBinContent(packet_bin, rm_packet_chans[packet - packetlow]->getMean(0));
304  }
305  for (int c = 0; c < p->iValue(0, "CHANNELS"); c++)
306  {
307  // msg << "Filling channel: " << c << " for packet: " << packet << std::endl;
308  // se->send_message(this, MSG_SOURCE_UNSPECIFIED, MSG_SEV_INFORMATIONAL, msg.str(), TRGMESSAGE);
309  // record waveform to show the average waveform
310 
311  ChannelNumber++;
312 
313  // std::vector result = getSignal(p,c); // simple peak extraction
314  std::vector<float> resultFast = anaWaveformFast(p, c); // fast waveform fitting
315  float signalFast = resultFast.at(0);
316  float timeFast = resultFast.at(1);
317  float pedestalFast = resultFast.at(2);
318 
319  // std::vector<float> resultTemp = anaWaveformTemp(p, c); // template waveform fitting
320  // float signalTemp = resultTemp.at(0);
321  // float timeTemp = resultTemp.at(1);
322  // float pedestalTemp = resultTemp.at(2);
323  if (signalFast > hit_threshold)
324  {
325  for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
326  {
327  h2_sepd_waveform->Fill(s, p->iValue(s, c) - pedestalFast);
328  }
329  }
330  // channel mapping
331  int ChMap = SepdMapChannel(ChannelNumber - 1);
332  if (ChMap == -1) continue;
333  // if(ChMap == -1){ std::cout << "Unused channel - " << ChMap << "go to next channel" << std::endl;continue;}
334  unsigned int key = TowerInfoDefs::encode_epd(ChMap);
335  int phi_bin = TowerInfoDefs::get_epd_phibin(key);
336  int r_bin = TowerInfoDefs::get_epd_rbin(key);
337  int z_bin = TowerInfoDefs::get_epd_arm(key);
338  // unsigned int phi_bin = TowerInfoDefs::get_epd_phibin(key);
339  // unsigned int r_bin = TowerInfoDefs::get_epd_rbin(key);
340  // unsigned int z_bin = TowerInfoDefs::get_epd_arm(key);
341 
342  // int sectorNumber = (ChannelNumber-1) % 32;
343  h1_waveform_time->Fill(timeFast);
344  h1_waveform_pedestal->Fill(pedestalFast);
345 
346  // h1_sepd_fitting_sigDiff -> Fill(signalFast/signalTemp);
347  // h1_sepd_fitting_pedDiff -> Fill(pedestalFast/pedestalTemp);
348  // h1_sepd_fitting_timeDiff -> Fill(timeFast - timeTemp);
349 
350  float signal = signalFast;
351 
352  h_ADC_channel[ChMap]->Fill(signal);
353 
354  if (z_bin == 0)
355  {
356  sumhit_s++;
357  sumADC_s += signal;
358  if (r_bin == 0)
359  {
360  phi_in = (phi_bin >= nPhi0 / 2) ? phi_bin - nPhi0 / 2 : phi_bin + nPhi0 / 2;
361  phi = -axislimit + axislimit / nPhi0 + 2 * axislimit / nPhi0 * phi_in;
362  r = -axislimit + axislimit / nRad + 2 * axislimit / nRad * r_bin;
363 
364  if (fabs(phi) > axislimit || fabs(r) > axislimit)
365  {
366  std::cout << "Excess of channel range! Wrong mapping -- return -1 " << std::endl;
367  return -1;
368  }
369 
370  h_ADC0_s->Fill(phi, r, signal);
371  h_hits0_s->Fill(phi, r);
372  }
373  else if (r_bin != 0)
374  {
375  phi_in = (phi_bin >= nPhi / 2) ? phi_bin - nPhi / 2 : phi_bin + nPhi / 2;
376  phi = -axislimit + axislimit / nPhi + 2 * axislimit / nPhi * phi_in;
377  r = -axislimit + axislimit / nRad + 2 * axislimit / nRad * r_bin;
378 
379  if (fabs(phi) > axislimit || fabs(r) > axislimit)
380  {
381  std::cout << "Excess of channel range! Wrong mapping -- return -1 " << std::endl;
382  return -1;
383  }
384 
385  h_ADC_s->Fill(phi, r, signal);
386  h_hits_s->Fill(phi, r);
387  }
388  else
389  {
390  std::cout << "r_bin not assigned ... " << std::endl;
391  return -1;
392  }
393  }
394  else if (z_bin == 1)
395  {
396  sumhit_n++;
397  sumADC_n += signal;
398  if (r_bin == 0)
399  {
400  phi_in = (phi_bin >= nPhi0 / 2) ? phi_bin - nPhi0 / 2 : phi_bin + nPhi0 / 2;
401  phi = -axislimit + axislimit / nPhi0 + 2 * axislimit / nPhi0 * phi_in;
402  r = -axislimit + axislimit / nRad + 2 * axislimit / nRad * r_bin;
403 
404  if (fabs(phi) > axislimit || fabs(r) > axislimit)
405  {
406  std::cout << "Excess of channel range! Wrong mapping -- return -1 " << std::endl;
407  return -1;
408  }
409 
410  h_ADC0_n->Fill(phi, r, signal);
411  h_hits0_n->Fill(phi, r);
412  }
413  else if (r_bin != 0)
414  {
415  phi_in = (phi_bin >= nPhi / 2) ? phi_bin - nPhi / 2 : phi_bin + nPhi / 2;
416  phi = -axislimit + axislimit / nPhi + 2 * axislimit / nPhi * phi_in;
417  r = -axislimit + axislimit / nRad + 2 * axislimit / nRad * r_bin;
418 
419  if (fabs(phi) > axislimit || fabs(r) > axislimit)
420  {
421  std::cout << "Excess of channel range! Wrong mapping -- return -1 " << std::endl;
422  return -1;
423  }
424 
425  h_ADC_n->Fill(phi, r, signal);
426  h_hits_n->Fill(phi, r);
427  }
428  else
429  {
430  std::cout << "r_bin not assigned ... " << std::endl;
431  return -1;
432  }
433  }
434  else
435  {
436  std::cout << "z_bin not assigned ... " << std::endl;
437  return -1;
438  }
439 
440  } // channel loop end
441  } // if packet good
442  else
443  {
444  ChannelNumber += 128;
445  int zero[1] = {0};
446  rm_packet_number[packet - packetlow]->Add(zero);
447  }
448  h1_packet_number->SetBinContent(packet_bin, rm_packet_number[packet - packetlow]->getMean(0));
449  delete p;
450 
451  } // packet id loop end
452 
453  h_event->Fill(0);
454  // h1_waveform_twrAvg->Scale(1. / 32. / 48.); // average tower waveform
455  h1_waveform_twrAvg->Scale((float) 1 / ChannelNumber);
456 
457  h_ADC_corr->Fill(sumADC_s / sumhit_s, sumADC_n / sumhit_n);
458  h_hits_corr->Fill(sumhit_s, sumhit_n);
459  return 0;
460 }
461 
463 {
464  // reset our internal counters
465  evtcnt = 0;
466  idummy = 0;
467 
468  return 0;
469 }
470 
472 {
473  int nch = ch / 16;
474  int chmap = -999;
475  if (nch % 2 == 0)
476  {
477  if (ch % 32 == 0)
478  chmap = ch - nch / 2;
479  else
480  {
481  chmap = 2 * (ch - 16 * nch) + 31 * (nch / 2) - 1;
482  }
483  }
484  else if (nch % 2 == 1)
485  {
486  if ((ch - 16) % 32 == 0)
487  chmap = -1;
488  else
489  {
490  chmap = 2 * (ch - 16 * nch) + 31 * ((nch - 1) / 2);
491  }
492  }
493  if (chmap == -999)
494  {
495  std::cout << "WRONG Channel map !!!! " << std::endl;
496  return -1;
497  }
498  return chmap;
499 }