Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HcalMon.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file HcalMon.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 "HcalMon.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 <calobase/TowerInfoDefs.h>
14 #include <caloreco/CaloWaveformFitting.h>
15 
16 #include <Event/Event.h>
17 #include <Event/msg_profile.h>
18 #include <Event/eventReceiverClient.h>
19 
20 #include <TH1.h>
21 #include <TH2.h>
22 
23 #include <cmath>
24 #include <cstdio> // for printf
25 #include <fstream>
26 #include <iostream>
27 #include <sstream>
28 #include <string> // for allocator, string, char_traits
29 
30 enum
31 {
34 };
35 
37  : OnlMon(name)
38 {
39  // leave ctor fairly empty, its hard to debug if code crashes already
40  // during a new HcalMon()
41  // if name start with O then packetlow = 8001, packethigh = 8008
42  // if name start with I then packetlow = 7001, packethigh = 7008
43  if (name[0] == 'O')
44  {
45  packetlow = 8001;
46  packethigh = 8008;
47  }
48  else if (name[0] == 'I')
49  {
50  packetlow = 7001;
51  packethigh = 7008;
52  }
53  else
54  {
55  std::cout << "HcalMon::HcalMon - unknown name(need to be OHCALMON or IHCALMON to know what packet to run) " << name << std::endl;
56  exit(1);
57  }
58  return;
59 }
60 
62 {
63  // you can delete NULL pointers it results in a NOOP (No Operation)
64  delete WaveformProcessing;
65  for (auto iter : rm_vector_sectAvg)
66  {
67  delete iter;
68  }
69  for (auto iter : rm_vector_twr)
70  {
71  delete iter;
72  }
73  for (auto iter : rm_packet_number)
74  {
75  delete iter;
76  }
77  for (auto iter : rm_packet_length)
78  {
79  delete iter;
80  }
81  for (auto iter : rm_packet_chans)
82  {
83  delete iter;
84  }
85 
86  if ( erc) delete erc;
87 
88  return;
89 }
90 
91 const int depth = 10000;
92 const int packet_depth = 1000;
93 const int historyLength = 100;
94 const int historyScaleDown = 100;
95 const int n_channel = 48;
96 const float hit_threshold = 100;
97 const int n_samples_show = 31;
98 
100 {
101  // read our calibrations from HcalMonData.dat
102  /*
103 
104  const char *hcalcalib = getenv("HCALCALIB");
105  if (!hcalcalib)
106  {
107  std::cout << "HCALCALIB environment variable not set" << std::endl;
108  exit(1);
109  }
110  std::string fullfile = std::string(hcalcalib) + "/" + "HcalMonData.dat";
111  std::ifstream calib(fullfile);
112  calib.close();
113  */
114  // use printf for stuff which should go the screen but not into the message
115  // system (all couts are redirected)
116  printf("doing the Init\n");
117 
118  h2_hcal_hits = new TH2F("h2_hcal_hits", "", 24, 0, 24, 64, 0, 64);
119  h2_hcal_hits_trig = new TH2F("h2_hcal_hits_trig", "", 24, 0, 24, 64, 0, 64);
120  h_hcal_trig = new TH1F("h_hcal_trig", "", 64, 0, 64);
121  h2_hcal_rm = new TH2F("h2_hcal_rm", "", 24, 0, 24, 64, 0, 64);
122  h2_hcal_mean = new TH2F("h2_hcal_mean", "", 24, 0, 24, 64, 0, 64);
123  h2_hcal_waveform = new TH2F("h2_hcal_waveform", "", n_samples_show, 0.5, n_samples_show + 0.5, 1000, 0, 15000);
124  h2_hcal_correlation = new TH2F("h2_hcal_correlation", "", 200, 0, 100000, 200, 0, 150000);
125  h_event = new TH1F("h_event", "", 1, 0, 1);
126  h_waveform_twrAvg = new TH1F("h_waveform_twrAvg", "", n_samples_show, 0.5, n_samples_show + 0.5);
127  h_waveform_time = new TH1F("h_waveform_time", "", n_samples_show, 0.5, n_samples_show + 0.5);
128  h_waveform_pedestal = new TH1F("h_waveform_pedestal", "", 5e3, 0, 5e3);
129  h_sectorAvg_total = new TH1F("h_sectorAvg_total", "", 32, 0.5, 32.5);
130  // number of towers above threshold per event
131  h_ntower = new TH1F("h_ntower", "", 100, 0, 800);
132  // packet stuff
133  h1_packet_number = new TH1F("h1_packet_number", "", 8, packetlow - 0.5, packethigh + 0.5);
134  h1_packet_length = new TH1F("h1_packet_length", "", 8, packetlow - 0.5, packethigh + 0.5);
135  h1_packet_chans = new TH1F("h1_packet_chans", "", 8, packetlow - 0.5, packethigh + 0.5);
136  h1_packet_event = new TH1F("h1_packet_event", "", 8, packetlow - 0.5, packethigh + 0.5);
137  h_caloPack_gl1_clock_diff = new TH2F("h_caloPack_gl1_clock_diff","", 8, packetlow - 0.5, packethigh + 0.5,65536,0,65536);
138 
139  for (int ih = 0; ih < Nsector; ih++)
140  h_rm_sectorAvg[ih] = new TH1F(Form("h_rm_sectorAvg_s%d", ih), "", historyLength, 0, historyLength * historyScaleDown);
141  for (int ieta = 0; ieta < 24; ieta++)
142  {
143  for (int iphi = 0; iphi < 64; iphi++)
144  {
145  h_rm_tower[ieta][iphi] = new TH1F(Form("h_rm_tower_%d_%d", ieta, iphi), Form("running mean of tower ieta=%d, iphi=%d", ieta, iphi), historyLength, 0, historyLength * historyScaleDown);
146  }
147  }
148  // make the per-packet running mean objects
149  // 32 packets and 48 channels for hcal detectors
150  for (int i = 0; i < Nsector; i++)
151  {
152  rm_vector_sectAvg.push_back(new pseudoRunningMean(1, depth));
153  }
154  for (int i = 0; i < Ntower; i++)
155  {
156  rm_vector_twr.push_back(new pseudoRunningMean(1, depth));
157  }
158  for (int i = 0; i < 8; i++)
159  {
163  }
164 
166  // register histograms with server otherwise client won't get them
167  se->registerHisto(this, h2_hcal_hits);
168  se->registerHisto(this, h2_hcal_hits_trig);
169  se->registerHisto(this, h_hcal_trig);
171  se->registerHisto(this, h2_hcal_rm);
172  se->registerHisto(this, h2_hcal_mean);
173  se->registerHisto(this, h2_hcal_waveform);
174  se->registerHisto(this, h_event);
175  se->registerHisto(this, h_sectorAvg_total);
176  se->registerHisto(this, h_waveform_twrAvg);
177  se->registerHisto(this, h_waveform_time);
179  se->registerHisto(this, h_ntower);
180  se->registerHisto(this, h1_packet_number);
181  se->registerHisto(this, h1_packet_length);
182  se->registerHisto(this, h1_packet_chans);
183  se->registerHisto(this, h1_packet_event);
185 
186  for (int ih = 0; ih < Nsector; ih++)
187  se->registerHisto(this, h_rm_sectorAvg[ih]);
188 
189  for (int ieta = 0; ieta < 24; ieta++)
190  {
191  for (int iphi = 0; iphi < 64; iphi++)
192  {
193  se->registerHisto(this, h_rm_tower[ieta][iphi]);
194  }
195  }
196 
197  Reset();
198 
199  // initialize waveform extraction tool
201 
202  std::string hcaltemplate;
203  if (getenv("HCALCALIB"))
204  {
205  hcaltemplate = getenv("HCALCALIB");
206  }
207  else
208  {
209  hcaltemplate = ".";
210  }
211  hcaltemplate += std::string("/testbeam_ohcal_template.root");
213 
214  if (anaGL1){
215  erc = new eventReceiverClient("gl1daq");
216  }
217 
218  return 0;
219 }
220 
221 std::vector<float> HcalMon::getSignal(Packet* p, const int channel)
222 {
223  double baseline = 0;
224  for (int s = 0; s < 3; s++)
225  {
226  baseline += p->iValue(s, channel);
227  }
228  baseline /= 3.;
229 
230  double signal = 0;
231  int sample = 0;
232  for (int s = 3; s < p->iValue(0, "SAMPLES"); s++)
233  {
234  if (signal > p->iValue(s, channel))
235  {
236  signal = p->iValue(s, channel);
237  sample = s;
238  }
239  }
240  signal -= baseline;
241 
242  std::vector<float> result;
243  result.push_back(signal);
244  result.push_back(sample);
245  result.push_back(baseline);
246 
247  return result;
248 }
249 
250 std::vector<float> HcalMon::anaWaveform(Packet* p, const int channel)
251 {
252  std::vector<float> waveform;
253  for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
254  {
255  waveform.push_back(p->iValue(s, channel));
256  }
257  std::vector<std::vector<float>> multiple_wfs;
258  multiple_wfs.push_back(waveform);
259 
260  std::vector<std::vector<float>> fitresults_ohcal;
261  // fitresults_ohcal = WaveformProcessing->process_waveform(multiple_wfs);
262  fitresults_ohcal = WaveformProcessing->calo_processing_fast(multiple_wfs);
263 
264  std::vector<float> result;
265  result = fitresults_ohcal.at(0);
266 
267  return result;
268 }
269 
270 int HcalMon::BeginRun(const int /* runno */)
271 {
272  // if you need to read calibrations on a run by run basis
273  // this is the place to do it
274 
275  std::vector<runningMean*>::iterator rm_it;
276  for (rm_it = rm_vector_sectAvg.begin(); rm_it != rm_vector_sectAvg.end(); ++rm_it)
277  {
278  (*rm_it)->Reset();
279  }
280  for (rm_it = rm_vector_twr.begin(); rm_it != rm_vector_twr.end(); ++rm_it)
281  {
282  (*rm_it)->Reset();
283  }
284  for (rm_it = rm_packet_number.begin(); rm_it != rm_packet_number.end(); ++rm_it)
285  {
286  (*rm_it)->Reset();
287  }
288  for (rm_it = rm_packet_length.begin(); rm_it != rm_packet_length.end(); ++rm_it)
289  {
290  (*rm_it)->Reset();
291  }
292  for (rm_it = rm_packet_chans.begin(); rm_it != rm_packet_chans.end(); ++rm_it)
293  {
294  (*rm_it)->Reset();
295  }
296  return 0;
297 }
298 
300 {
301  if (e->getEvtType() >= 8)
302  {
303  return 0;
304  }
305  evtcnt++;
306  h_waveform_twrAvg->Reset(); // only record the latest event waveform
307  h1_packet_event->Reset();
308  unsigned int towerNumber = 0;
309  float sectorAvg[Nsector] = {0};
310  int npacket1 = 0;
311  int npacket2 = 0;
312  float energy1 = 0;
313  float energy2 = 0;
314 
315 
316  bool trig_fire = false;
317  std::vector<bool> trig_bools;
318  long long int gl1_clock = 0;
319  if (anaGL1){
320  int evtnr = e->getEvtSequence();
321  Event *gl1Event = erc->getEvent(evtnr);
322  if (gl1Event){
323  Packet* p = e->getPacket(14001);
324  if (p){
325  gl1_clock = p->lValue(0,"BCO");
326  int triggervec = p->lValue(0,"TriggerVector");
327  for (int i = 0; i < 64; i++ ) {
328  bool trig_decision = (bool) triggervec & 1;
329  trig_bools.push_back(trig_decision);
330  if (trig_decision) h_hcal_trig->Fill(i);
331  triggervec = triggervec >> 1;
332  }
333  trig_fire = trig_bools[2]; //trigger of interest is 2
334  }
335  }
336  }
337 
338  for (int packet = packetlow; packet <= packethigh; packet++)
339  {
340  Packet* p = e->getPacket(packet);
341  int packet_bin = packet - packetlow + 1;
342  if (p)
343  {
344  int one[1] = {1};
345  rm_packet_number[packet - packetlow]->Add(one);
346  int packet_length[1] = {p->getLength()};
347  rm_packet_length[packet - packetlow]->Add(packet_length);
348 
349  h1_packet_length->SetBinContent(packet_bin, rm_packet_length[packet - packetlow]->getMean(0));
350 
351  h1_packet_event->SetBinContent(packet - packetlow + 1, p->iValue(0, "CLOCK"));
352  long long int p_clock = p->iValue(0,"CLOCK");
353  long long int diff = (p_clock - gl1_clock) % 65536;
354  h_caloPack_gl1_clock_diff->Fill(packet,diff);
355  int nChannels = p->iValue(0, "CHANNELS");
356  if (nChannels > m_nChannels)
357  {
358  return -1; // packet is corrupted, reports too many channels
359  }
360  else
361  {
362  npacket1++;
363  rm_packet_chans[packet - packetlow]->Add(&nChannels);
364  h1_packet_chans->SetBinContent(packet_bin, rm_packet_chans[packet - packetlow]->getMean(0));
365  }
366  for (int c = 0; c < nChannels; c++)
367  {
368  towerNumber++;
369 
370  // std::vector result = getSignal(p,c); // simple peak extraction
371  std::vector<float> result = anaWaveform(p, c); // full waveform fitting
372  float signal = result.at(0);
373  float time = result.at(1);
374  float pedestal = result.at(2);
375  if (signal > 15 && signal< 15000) energy1 += signal;
376 
377  // channel mapping
378  unsigned int key = TowerInfoDefs::encode_hcal(towerNumber - 1);
379  unsigned int phi_bin = TowerInfoDefs::getCaloTowerPhiBin(key);
380  unsigned int eta_bin = TowerInfoDefs::getCaloTowerEtaBin(key);
381  int sectorNumber = phi_bin / 2 + 1;
382  if (signal > hit_threshold) h_waveform_time->Fill(time);
383  h_waveform_pedestal->Fill(pedestal);
384 
385  sectorAvg[sectorNumber - 1] += signal;
386 
387  rm_vector_twr[towerNumber - 1]->Add(&signal);
388 
389  int bin = h2_hcal_mean->FindBin(eta_bin + 0.5, phi_bin + 0.5);
390  h2_hcal_mean->SetBinContent(bin, h2_hcal_mean->GetBinContent(bin) + signal);
391  h2_hcal_rm->SetBinContent(bin, rm_vector_twr[towerNumber - 1]->getMean(0));
392 
393  // fill tower_rm here
395  {
396  //only fill every scaledown event
397  if (evtcnt % historyScaleDown == 0)
398  {
399  h_rm_tower[eta_bin][phi_bin]->SetBinContent(evtcnt / historyScaleDown, rm_vector_twr[towerNumber - 1]->getMean(0));
400  }
401  }
402  else
403  {
404  //only fill every scaledown event
405  if (evtcnt % historyScaleDown == 0)
406  {
407  for (int ib = 1; ib < historyLength; ib++)
408  {
409  h_rm_tower[eta_bin][phi_bin]->SetBinContent(ib, h_rm_tower[eta_bin][phi_bin]->GetBinContent(ib + 1));
410  }
411  h_rm_tower[eta_bin][phi_bin]->SetBinContent(historyLength, rm_vector_twr[towerNumber - 1]->getMean(0));
412  }
413 
414  }
415 
416  if (signal > hit_threshold)
417  {
418  h2_hcal_hits->Fill(eta_bin + 0.5, phi_bin + 0.5);
419  if (trig_fire){
420  h2_hcal_hits_trig->Fill(eta_bin + 0.5, phi_bin + 0.5);
421  }
422  }
423 
424  // record waveform
425  for (int s = 0; s < p->iValue(0, "SAMPLES"); s++)
426  {
427  h_waveform_twrAvg->Fill(s, p->iValue(s, c));
428  if (signal > hit_threshold) h2_hcal_waveform->Fill(s, (p->iValue(s, c) - pedestal));
429  }
430 
431  } // channel loop
432 
433  } // if packet good
434  else
435  {
436  towerNumber += 192;
437  int zero[1] = {0};
438  rm_packet_number[packet - packetlow]->Add(zero);
439  }
440  h1_packet_number->SetBinContent(packet_bin, rm_packet_number[packet - packetlow]->getMean(0));
441  delete p;
442  } // packet loop
443  // if packetlow == 8001, then packetlowdiff = 7001, if packetlow == 7001, then packetlowdiff = 8001
444  int packetlowdiff = 15002 - packetlow;
445  int packethighdiff = 15016 - packethigh;
446 
447  if (npacket1 == 4)
448  {
449  for (int i = packetlowdiff; i <= packethighdiff; i++)
450  {
451  Packet* p = e->getPacket(i);
452  if (p)
453  {
454  int nChannels = p->iValue(0, "CHANNELS");
455  if (nChannels > m_nChannels)
456  {
457  return -1; // packet is corrupted, reports too many channels
458  }
459  else
460  {
461  npacket2++;
462  }
463  for (int c = 0; c < nChannels; c++)
464  {
465  // std::vector result = getSignal(p,c); // simple peak extraction
466  std::vector<float> result = anaWaveform(p, c); // full waveform fitting
467  float signal = result.at(0);
468  if (signal > 15 && signal<15000) energy2 += signal;
469  }
470  }
471  delete p;
472  }
473  }
474  if (npacket1 == 4 && npacket2 == 4)
475  {
476  if (packetlow == 8001)
477  h2_hcal_correlation->Fill(energy1, energy2);
478  else
479  h2_hcal_correlation->Fill(energy2, energy1);
480  }
481  // sector loop
482  for (int isec = 0; isec < Nsector; isec++)
483  {
484  sectorAvg[isec] /= 48;
485  h_sectorAvg_total->Fill(isec + 1, sectorAvg[isec]);
486  rm_vector_sectAvg[isec]->Add(&sectorAvg[isec]);
488  {
489  //only fill every scaledown event
490  if (evtcnt % historyScaleDown == 0)
491  {
492  h_rm_sectorAvg[isec]->SetBinContent(evtcnt / historyScaleDown, rm_vector_sectAvg[isec]->getMean(0));
493  }
494  }
495  else
496  {
497  //only fill every scaledown event
498  if (evtcnt % historyScaleDown == 0)
499  {
500  for (int ib = 1; ib < historyLength; ib++)
501  {
502  h_rm_sectorAvg[isec]->SetBinContent(ib, h_rm_sectorAvg[isec]->GetBinContent(ib + 1));
503  }
504  h_rm_sectorAvg[isec]->SetBinContent(historyLength, rm_vector_sectAvg[isec]->getMean(0));
505  }
506  }
507 
508  } // sector loop
509 
510  h_event->Fill(0);
511  h_waveform_twrAvg->Scale(1. / 32. / 48.); // average tower waveform
512 
513  return 0;
514 }
515 
517 {
518  // reset our internal counters
519  evtcnt = 0;
520  idummy = 0;
521  return 0;
522 }