Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CemcMon.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file CemcMon.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 "CemcMon.h"
7 
8 #include <onlmon/OnlMon.h> // for OnlMon
9 #include <onlmon/OnlMonServer.h>
10 #include <onlmon/pseudoRunningMean.h>
11 
12 #include <caloreco/CaloWaveformFitting.h>
13 #include <calobase/TowerInfoDefs.h>
14 
15 #include <Event/Event.h>
16 #include <Event/EventTypes.h>
17 #include <Event/msg_profile.h>
18 
19 #include <TH1.h>
20 #include <TH2.h>
21 
22 #include <cmath>
23 #include <cstdio> // for printf
24 #include <fstream>
25 #include <iostream>
26 #include <sstream>
27 #include <string> // for allocator, string, char_traits
28 
29 
30 enum
31  {
34  };
35 
36 const int depth = 10000;
37 const int historyLength = 100;
38 const float hit_threshold = 100;
39 
40 
41 using namespace std;
42 
43 
45  : OnlMon(name),
46  eventCounter(0)
47 {
48  // leave ctor fairly empty, its hard to debug if code crashes already
49  // during a new CemcMon()
50 
51  return;
52 }
53 
54 
56 {
57  for (auto iter : rm_vector_sectAvg)
58  {
59  delete iter;
60  }
61  for (auto iter : rm_vector_twr)
62  {
63  delete iter;
64  }
65  for (auto iter : rm_vector)
66  {
67  delete iter;
68  }
71  return;
72 }
73 
75 {
76 
77  // read our calibrations from CemcMonData.dat
78  const char *cemccalib = getenv("CEMCCALIB");
79  if (!cemccalib)
80  {
81  std::cout << "CEMCCALIB environment variable not set" << std::endl;
82  exit(1);
83  }
84  std::string fullfile = std::string(cemccalib) + "/" + "CemcMonData.dat";
85  std::ifstream calib(fullfile);
86  calib.close();
87  // use printf for stuff which should go the screen but not into the message
88  // system (all couts are redirected)
89  printf("CemcMon::Init()\n");
90  // Histograms definitions
91  //tower hit information
92  h2_cemc_hits = new TH2F("h2_cemc_hits", "", 96, 0, 96, 256, 0, 256);
93  h2_cemc_rm = new TH2F("h2_cemc_rm", "" , 96, 0, 96, 256, 0, 256);
94  h2_cemc_mean = new TH2F("h2_cemc_mean", "", 96, 0, 96, 256, 0, 256);
95  h1_cemc_adc = new TH1F("h1_cemc_adc","",1000,0.5,pow(2,14));
96  //event couunter
97  h1_event = new TH1F("h1_event", "", 1, 0, 1);
98 
99  //waveform processing
100  h2_waveform_twrAvg = new TH2F("h2_waveform_twrAvg", "", 16, 0.5, 16.5, 10000,0,15000);
101  h1_waveform_time = new TH1F("h1_waveform_time", "", 16, 0.5, 16.5);
102  h1_waveform_pedestal = new TH1F("h1_waveform_pedestal", "", 25, 1.3e3, 2.0e3);
103 
104  //waveform processing, template vs. fast interpolation
105  h1_cemc_fitting_sigDiff = new TH1F("h1_fitting_sigDiff","",50,0,2);
106  h1_cemc_fitting_pedDiff = new TH1F("h1_fitting_pedDiff","",50,0,2);
107  h1_cemc_fitting_timeDiff = new TH1F("h1_fitting_timeDiff","",50,-10,10);
108 
109  //
110  h1_sectorAvg_total = new TH1F("h1_sectorAvg_total", "", 32, 0.5, 32.5);
111 
112  //packet information
113  h1_packet_number = new TH1F("h1_packet_number","",128,6000.5,6128.5);
114  h1_packet_length = new TH1F("h1_packet_length","",128,6000.5,6128.5);
115  h1_packet_chans = new TH1F("h1_packet_chans","",128,6000.5,6128.5);
116 
117  for (int ih = 0; ih < Nsector; ih++)
118  h1_rm_sectorAvg[ih] = new TH1F(Form("h1_rm_sectorAvg_s%d", ih), "", historyLength, 0, historyLength);
119 
120  // make the per-packet running mean objects
121  // 32 packets and 48 channels for hcal detectors
122  for (int i = 0; i < Nsector; i++)
123  {
124  rm_vector_sectAvg.push_back(new pseudoRunningMean(1, depth));
125  }
126  for (int i = 0; i < Ntower; i++)
127  {
128  rm_vector_twr.push_back(new pseudoRunningMean(1, depth));
129  }
130 
131 
132  std::string h_id = "cemc_occupancy";
133  cemc_occupancy = new TH2F(h_id.c_str(), "cemc_occupancy plot", 48*2 , -48 , 48, 32*8, -0.5, 255.5 );
134  cemc_occupancy->GetXaxis()->SetTitle("eta");
135  cemc_occupancy->GetYaxis()->SetTitle("phi");
136  cemc_occupancy->SetStats(false);
137  //cemc_occupancy->SetMinimum(0);
138  // cemc_occupancy->SetMaximum(1200);
139 
140  h_id = "cemc_runningmean";
141  cemc_runningmean = new TH2F(h_id.c_str(), "Cemc Running Mean Run 0 Event 0", 48*2 , -48 , 48, 32*8, -0.5, 255.5 );
142  cemc_runningmean->GetXaxis()->SetTitle("eta");
143  cemc_runningmean->GetYaxis()->SetTitle("phi");
144  cemc_runningmean->SetStats(false);
145  cemc_runningmean->SetMinimum(0);
146  cemc_runningmean->SetMaximum(700);
147 
148  cemc_signal = new TH1F("cemc_signal", "Signal Distribution", 512 , -200., 4000);
149 
150 
151  // cemchist2 = new TH2F("cemcmon_hist2", "test 2d histo", 101, 0., 100., 101, 0., 100.);
153  // register histograms with server otherwise client won't get them
154  se->registerHisto(this, cemc_occupancy ); // uses the TH1->GetName() as key
155  se->registerHisto(this, cemc_runningmean ); // uses the TH1->GetName() as key
156 
157  se->registerHisto(this, h2_cemc_hits);
158  se->registerHisto(this, h2_cemc_rm);
159  se->registerHisto(this, h2_cemc_mean);
160  se->registerHisto(this, h1_event);
163  se->registerHisto(this, h1_waveform_time);
168  se->registerHisto(this, h1_packet_number);
169  se->registerHisto(this, h1_packet_length);
170  se->registerHisto(this, h1_packet_chans);
171  se->registerHisto(this, h1_cemc_adc);
172 
173  for (int ih = 0; ih < Nsector; ih++)
174  {
175  se->registerHisto(this, h1_rm_sectorAvg[ih]);
176  }
177 
178  // make the per-packet runnumg mean objects
179  for ( int i = 0; i < 64; i++)
180  {
181  rm_vector.push_back( new pseudoRunningMean(192,50));
182  }
183 
184 
185  // initialize waveform extraction tool
187 
189 
190  std::string cemctemplate;
191  if (getenv("CEMCCALIB"))
192  {
193  cemctemplate = getenv("CEMCCALIB");
194  }
195  else
196  {
197  cemctemplate = ".";
198  }
199  cemctemplate += std::string("/testbeam_cemc_template.root");
201 
202  return 0;
203 }
204 
205 int CemcMon::BeginRun(const int /* runno */)
206 {
207  // if you need to read calibrations on a run by run basis
208  // this is the place to do it
209 
210  // reset the running means
211  std::vector<runningMean*>::iterator rm_it;
212  for ( rm_it = rm_vector.begin(); rm_it != rm_vector.end(); ++rm_it)
213  {
214  (*rm_it)->Reset();
215  }
216  for(rm_it = rm_vector_twr.begin(); rm_it != rm_vector_twr.end(); ++rm_it)
217  {
218  (*rm_it)->Reset();
219  }
220 
221  return 0;
222 }
223 
224 
225 // simple wavefrom analysis for possibe issues with the wavforProcessor
226 std::vector<float> CemcMon::getSignal(Packet *p, const int channel)
227 {
228 
229  double baseline = 0;
230  for ( int s = 0; s< 3; s++)
231  {
232  baseline += p->iValue(s,channel);
233  }
234  baseline /= 3.;
235 
236  double signal = 0;
237  float x = 0;
238  for ( int s = 3; s< p->iValue(0,"SAMPLES"); s++)
239  {
240  x++;
241  signal += p->iValue(s,channel) - baseline;
242  }
243 
244  signal /= x;
245 
246  // simulate a failure if ( evtcount > 450 && p->getIdentifier() ==6011) return 0;
247 
248  std::vector<float> result;
249  result.push_back(signal);
250  result.push_back(2);
251  result.push_back(1);
252  return result;
253 }
254 
255 
256 
257 std::vector<float> CemcMon::anaWaveformFast(Packet *p, const int channel)
258 {
259  std::vector<float> waveform;
260  waveform.reserve(m_nSamples);
261  for ( int s = 0; s < m_nSamples/*p->iValue(0,"SAMPLES")*/; s++) {
262  waveform.push_back(p->iValue(s,channel));
263  }
264  std::vector<std::vector<float>> multiple_wfs;
265  multiple_wfs.push_back(waveform);
266 
267  std::vector<std::vector<float>> fitresults_cemc;
268  fitresults_cemc = WaveformProcessingFast->calo_processing_fast(multiple_wfs);
269 
270  std::vector<float> result;
271  result = fitresults_cemc.at(0);
272 
273  return result;
274 }
275 
276 std::vector<float> CemcMon::anaWaveformTemp(Packet *p, const int channel)
277 {
278  std::vector<float> waveform;
279  waveform.reserve(m_nSamples);
280  for ( int s = 0; s < m_nSamples/*p->iValue(0,"SAMPLES")*/; s++) {
281 
282  waveform.push_back(p->iValue(s,channel));
283  }
284  std::vector<std::vector<float>> multiple_wfs;
285  multiple_wfs.push_back(waveform);
286 
287  std::vector<std::vector<float>> fitresults_cemc;
288  fitresults_cemc = WaveformProcessingTemp->process_waveform(multiple_wfs);
289 
290  std::vector<float> result;
291  result = fitresults_cemc.at(0);
292 
293  return result;
294 }
295 
297 {
298  h2_waveform_twrAvg->Reset(); // only record the latest event waveform
299  float sectorAvg[Nsector] = {0};
300  unsigned int towerNumber = 0;
301  // loop over packets which contain a single sector
302  eventCounter++;
303  for (int packet = packetlow; packet <= packethigh; packet++)
304  {
305  Packet* p = e->getPacket(packet);
306 
307  if (p)
308  {
309 
310  h1_packet_number -> Fill(packet);
311 
312  h1_packet_length -> SetBinContent(packet-6000,h1_packet_length->GetBinContent(packet-6000) + p -> getLength());
313 
314  int nChannels = p->iValue(0, "CHANNELS");
315  if(nChannels > m_nChannels)
316  {
317  return -1;//packet is corrupted, reports too many channels
318  }
319  for (int c = 0; c < nChannels; c++)
320  {
321 
322  h1_packet_chans -> Fill(packet);
323 
324  // std::vector result = getSignal(p,c); // simple peak extraction
325  std::vector<float> resultFast = anaWaveformFast(p, c); // fast waveform fitting
326  float signalFast = resultFast.at(0);
327  float timeFast = resultFast.at(1);
328  float pedestalFast = resultFast.at(2);
329 
330  for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
331  {
332  h2_waveform_twrAvg->Fill(s, p->iValue(s, c) - pedestalFast);
333  }
334  towerNumber++;
335 
336 
337 
338 
339 
340  // channel mapping
341  unsigned int key = TowerInfoDefs::encode_emcal(towerNumber - 1);
342  unsigned int phi_bin = TowerInfoDefs::getCaloTowerPhiBin(key);
343  unsigned int eta_bin = TowerInfoDefs::getCaloTowerEtaBin(key);
344  //std::cout << "ieta " << eta_bin << " iphi " << phi_bin<< std::endl;
345  int sectorNumber = phi_bin / 8 + 1;
346  h1_waveform_time->Fill(timeFast);
347  h1_waveform_pedestal->Fill(pedestalFast);
348 
349  int bin = h2_cemc_mean->FindBin(eta_bin + 0.5, phi_bin + 0.5);
350 
351  sectorAvg[sectorNumber - 1] += signalFast;
352 
353  rm_vector_twr[towerNumber - 1] -> Add(&signalFast);
354 
355  h2_cemc_rm->SetBinContent(bin, rm_vector_twr[towerNumber - 1]->getMean(0));
356 
357  //create beginning of run template
358  if(eventCounter < templateDepth /*&& signalFast > hit_threshold*/)h2_cemc_mean->SetBinContent(bin, h2_cemc_mean->GetBinContent(bin) + signalFast);
359 
360  h1_cemc_adc ->Fill(signalFast);
361 
362  // if(!((eventCounter - 2)% 5000))
363  // {
364  // std::vector<float> resultTemp = anaWaveformTemp(p, c); // template waveform fitting
365  // float signalTemp = resultTemp.at(0);
366  // float timeTemp = resultTemp.at(1);
367  // float pedestalTemp = resultTemp.at(2);
368  // h1_cemc_fitting_sigDiff -> Fill(signalFast/signalTemp);
369  // h1_cemc_fitting_pedDiff -> Fill(pedestalFast/pedestalTemp);
370  // h1_cemc_fitting_timeDiff -> Fill(timeFast - timeTemp - 6);
371  // }
372  if (signalFast > hit_threshold)
373  {
374  //h2_cemc_hits->Fill(eta_bin + 0.5, phi_bin + 0.5);
375  h2_cemc_hits -> SetBinContent(bin, h2_cemc_hits -> GetBinContent(bin) + signalFast);
376  }
377  } // channel loop
378  if(nChannels < m_nChannels)
379  {
380  //still need to correctly set bad channels to zero.
381  for(int channel = 0; channel < m_nChannels - nChannels; channel++)
382  {
383  towerNumber++;
384 
385  unsigned int key = TowerInfoDefs::encode_emcal(towerNumber - 1);
386  unsigned int phi_bin = TowerInfoDefs::getCaloTowerPhiBin(key);
387  unsigned int eta_bin = TowerInfoDefs::getCaloTowerEtaBin(key);
388 
389  int sectorNumber = phi_bin / 8 + 1;
390 
391  //h1_waveform_time->Fill(timeFast);
392 
393  //h1_waveform_pedestal->Fill(pedestalFast);
394 
395  int bin = h2_cemc_mean->FindBin(eta_bin + 0.5, phi_bin + 0.5);
396 
397  sectorAvg[sectorNumber -1] += 0.;
398 
399  float signalFast = 0.0;
400 
401  rm_vector_twr[towerNumber -1] -> Add(&signalFast);
402 
403  h2_cemc_rm -> SetBinContent(bin, rm_vector_twr[towerNumber - 1]->getMean(0));
404 
405  h2_cemc_mean -> SetBinContent(bin, h2_cemc_mean->GetBinContent(bin));
406 
407  }
408  }
409  delete p;
410  } // if packet good
411  else //packet is corrupted, treat all channels as zero suppressed
412  {
413 
414  for(int channel = 0; channel < m_nChannels; channel++)
415  {
416  towerNumber++;
417  unsigned int key = TowerInfoDefs::encode_emcal(towerNumber - 1);
418  unsigned int phi_bin = TowerInfoDefs::getCaloTowerPhiBin(key);
419  unsigned int eta_bin = TowerInfoDefs::getCaloTowerEtaBin(key);
420 
421  int sectorNumber = phi_bin / 8 + 1;
422 
423  int bin = h2_cemc_mean->FindBin(eta_bin + 0.5, phi_bin + 0.5);
424 
425  sectorAvg[sectorNumber -1] += 0;
426 
427  float signalFast = 0;
428 
429  rm_vector_twr[towerNumber -1] -> Add(&signalFast);
430 
431  h2_cemc_rm -> SetBinContent(bin, rm_vector_twr[towerNumber - 1]->getMean(0));
432 
433  h2_cemc_mean -> SetBinContent(bin, h2_cemc_mean->GetBinContent(bin));
434  }
435  } //zero filling bad packets
436  } // packet loop
437 
438 
439  // sector loop
440  for (int isec = 0; isec < Nsector; isec++)
441  {
442  sectorAvg[isec] /= 48;
443  h1_sectorAvg_total->Fill(isec + 1, sectorAvg[isec]);
444  rm_vector_sectAvg[isec]->Add(&sectorAvg[isec]);
446  {
447  h1_rm_sectorAvg[isec]->SetBinContent(eventCounter, rm_vector_sectAvg[isec]->getMean(0));
448  }
449  else
450  {
451  for (int ib = 1; ib < historyLength; ib++)
452  {
453  h1_rm_sectorAvg[isec]->SetBinContent(ib, h1_rm_sectorAvg[isec]->GetBinContent(ib + 1));
454  }
455  h1_rm_sectorAvg[isec]->SetBinContent(eventCounter, rm_vector_sectAvg[isec]->getMean(0));
456  }
457  } // sector loop
458 
459  h1_event->Fill(0);
460  //h1_waveform_twrAvg->Scale(1. / 32. / 48.); // average tower waveform
461  h2_waveform_twrAvg->Scale((float)1/towerNumber);
462 
463  return 0;
464 }
465 
466 
468 {
469  // reset our internal counters
470  eventCounter = 0;
471  idummy = 0;
472  return 0;
473 }