Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TpcMon.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TpcMon.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 "TpcMon.h"
7 
8 #include <onlmon/OnlMon.h> // for OnlMon
9 #include <onlmon/OnlMonDB.h>
10 #include <onlmon/OnlMonServer.h>
11 
12 #include <Event/Event.h>
13 #include <Event/msg_profile.h>
14 #include <Event/oncsSubConstants.h>
15 
16 #include <tpc/TpcMap.h>
17 
18 #include <TH1.h>
19 #include <TH2.h>
20 #include <TMath.h>
21 #include <TTree.h>
22 #include <TLatex.h>
23 
24 #include <vector>
25 #include <cmath>
26 #include <algorithm>
27 #include <vector>
28 #include <cstdio> // for printf
29 #include <fstream>
30 #include <iostream>
31 #include <sstream>
32 #include <string> // for allocator, string, char_traits
33 
34 enum
35 {
38 };
39 
41  : OnlMon(name)
42 {
43  // leave ctor fairly empty, its hard to debug if code crashes already
44  // during a new TpcMon()
45 
46  serverid = 0; //default case - initializing in constructor
47  //BCO initialization in TPCMon
48  starting_BCO = -1;
49  rollover_value = 0;
50  current_BCOBIN = 0;
51  M.setMapNames("AutoPad-R1-RevA.sch.ChannelMapping.csv", "AutoPad-R2-RevA-Pads.sch.ChannelMapping.csv", "AutoPad-R3-RevA.sch.ChannelMapping.csv");
52 
53  return;
54 }
55 
57 {
58  // you can delete NULL pointers it results in a NOOP (No Operation)
59  return;
60 }
61 
63 {
64  // read our calibrations from TpcMonData.dat
65  const char *tpccalib = getenv("TPCCALIB");
66  if (!tpccalib)
67  {
68  std::cout << "TPCCALIB environment variable not set" << std::endl;
69  exit(1);
70  }
71  std::string fullfile = std::string(tpccalib) + "/" + "TpcMonData.dat";
72  std::ifstream calib(fullfile);
73  calib.close();
74  // use printf for stuff which should go the screen but not into the message
75  // system (all couts are redirected)
76  printf("doing the Init\n");
77  tpchist1 = new TH1F("tpcmon_hist1", "test 1d histo", 101, 0., 100.);
78  tpchist2 = new TH2F("tpcmon_hist2", "test 2d histo", 101, 0., 100., 101, 0., 100.);
79 
80  //TPC GEM Module Displays
81  NorthSideADC = new TH2F("NorthSideADC" , "ADC Counts North Side", N_thBins, -TMath::Pi()/12. , 23.*TMath::Pi()/12. , N_rBins , rBin_edges );
82  SouthSideADC = new TH2F("SouthSideADC" , "ADC Counts South Side", N_thBins, -TMath::Pi()/12. , 23.*TMath::Pi()/12. , N_rBins , rBin_edges );
83  //
84 
85  //TPC "cluster" XY heat maps WEIGHTED
86  //NorthSideADC_clusterXY_R1 = new TH2F("NorthSideADC_clusterXY_R1" , "ADC Peaks North Side", N_phi_binx_XY_R1, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
87  NorthSideADC_clusterXY_R1 = new TH2F("NorthSideADC_clusterXY_R1" , "(ADC-Pedestal) > 5#sigma North Side", 400, -800, 800, 400, -800, 800);
88  NorthSideADC_clusterXY_R1->SetXTitle("X [mm]");
89  NorthSideADC_clusterXY_R1->SetYTitle("Y [mm]");
90 
91  //NorthSideADC_clusterXY_R2 = new TH2F("NorthSideADC_clusterXY_R2" , "ADC Peaks North Side", N_phi_binx_XY_R2, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
92  NorthSideADC_clusterXY_R2 = new TH2F("NorthSideADC_clusterXY_R2" , "(ADC-Pedestal) > 5#sigma North Side", 400, -800, 800, 400, -800, 800);
93  NorthSideADC_clusterXY_R2->SetXTitle("X [mm]");
94  NorthSideADC_clusterXY_R2->SetYTitle("Y [mm]");
95 
96  //NorthSideADC_clusterXY_R3 = new TH2F("NorthSideADC_clusterXY_R3" , "ADC Peaks North Side", N_phi_binx_XY_R3, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
97  NorthSideADC_clusterXY_R3 = new TH2F("NorthSideADC_clusterXY_R3" , "(ADC-Pedestal) > 5#sigma North Side", 400, -800, 800, 400, -800, 800);
98  NorthSideADC_clusterXY_R3->SetXTitle("X [mm]");
99  NorthSideADC_clusterXY_R3->SetYTitle("Y [mm]");
100 
101 
102  //SouthSideADC_clusterXY_R1 = new TH2F("SouthSideADC_clusterXY_R1" , "ADC Peaks South Side", N_phi_binx_XY_R1, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
103  SouthSideADC_clusterXY_R1 = new TH2F("SouthSideADC_clusterXY_R1" , "(ADC-Pedestal) > 5#sigma South Side", 400, -800, 800, 400, -800, 800);
104  SouthSideADC_clusterXY_R1->SetXTitle("X [mm]");
105  SouthSideADC_clusterXY_R1->SetYTitle("Y [mm]");
106 
107  //SouthSideADC_clusterXY_R2 = new TH2F("SouthSideADC_clusterXY_R2" , "ADC Peaks South Side", N_phi_binx_XY_R2, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
108  SouthSideADC_clusterXY_R2 = new TH2F("SouthSideADC_clusterXY_R2" , "(ADC-Pedestal) > 5#sigma South Side", 400, -800, 800, 400, -800, 800);
109  SouthSideADC_clusterXY_R2->SetXTitle("X [mm]");
110  SouthSideADC_clusterXY_R2->SetYTitle("Y [mm]");
111 
112  //SouthSideADC_clusterXY_R3 = new TH2F("SouthSideADC_clusterXY_R3" , "ADC Peaks South Side", N_phi_binx_XY_R3, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
113  SouthSideADC_clusterXY_R3 = new TH2F("SouthSideADC_clusterXY_R3" , "(ADC-Pedestal) > 5#sigma South Side", 400, -800, 800, 400, -800, 800);
114  SouthSideADC_clusterXY_R3->SetXTitle("X [mm]");
115  SouthSideADC_clusterXY_R3->SetYTitle("Y [mm]");
116 
117  //____________________________________________________________________//
118 
119  //TPC "cluster" XY heat maps UNWEIGHTED
120  //NorthSideADC_clusterXY_R1 = new TH2F("NorthSideADC_clusterXY_R1" , "ADC Peaks North Side", N_phi_binx_XY_R1, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
121  NorthSideADC_clusterXY_R1_unw = new TH2F("NorthSideADC_clusterXY_R1_unw" , "(ADC-Pedestal) > 5#sigma North Side", 400, -800, 800, 400, -800, 800);
122  NorthSideADC_clusterXY_R1_unw->SetXTitle("X [mm]");
123  NorthSideADC_clusterXY_R1_unw->SetYTitle("Y [mm]");
124 
125  //NorthSideADC_clusterXY_R2 = new TH2F("NorthSideADC_clusterXY_R2" , "ADC Peaks North Side", N_phi_binx_XY_R2, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
126  NorthSideADC_clusterXY_R2_unw = new TH2F("NorthSideADC_clusterXY_R2_unw" , "(ADC-Pedestal) > 5#sigma Side", 400, -800, 800, 400, -800, 800);
127  NorthSideADC_clusterXY_R2_unw->SetXTitle("X [mm]");
128  NorthSideADC_clusterXY_R2_unw->SetYTitle("Y [mm]");
129 
130  //NorthSideADC_clusterXY_R3 = new TH2F("NorthSideADC_clusterXY_R3" , "ADC Peaks North Side", N_phi_binx_XY_R3, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
131  NorthSideADC_clusterXY_R3_unw = new TH2F("NorthSideADC_clusterXY_R3_unw" , "(ADC-Pedestal) > 5#sigma Side", 400, -800, 800, 400, -800, 800);
132  NorthSideADC_clusterXY_R3_unw->SetXTitle("X [mm]");
133  NorthSideADC_clusterXY_R3_unw->SetYTitle("Y [mm]");
134 
135 
136  //SouthSideADC_clusterXY_R1 = new TH2F("SouthSideADC_clusterXY_R1" , "ADC Peaks South Side", N_phi_binx_XY_R1, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
137  SouthSideADC_clusterXY_R1_unw = new TH2F("SouthSideADC_clusterXY_R1_unw" , "(ADC-Pedestal) > 5#sigma", 400, -800, 800, 400, -800, 800);
138  SouthSideADC_clusterXY_R1_unw->SetXTitle("X [mm]");
139  SouthSideADC_clusterXY_R1_unw->SetYTitle("Y [mm]");
140 
141  //SouthSideADC_clusterXY_R2 = new TH2F("SouthSideADC_clusterXY_R2" , "ADC Peaks South Side", N_phi_binx_XY_R2, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
142  SouthSideADC_clusterXY_R2_unw = new TH2F("SouthSideADC_clusterXY_R2_unw" , "(ADC-Pedestal) > 5#sigma", 400, -800, 800, 400, -800, 800);
143  SouthSideADC_clusterXY_R2_unw->SetXTitle("X [mm]");
144  SouthSideADC_clusterXY_R2_unw->SetYTitle("Y [mm]");
145 
146  //SouthSideADC_clusterXY_R3 = new TH2F("SouthSideADC_clusterXY_R3" , "ADC Peaks South Side", N_phi_binx_XY_R3, -TMath::Pi(), TMath::Pi(), N_rBins_XY, r_bins);
147  SouthSideADC_clusterXY_R3_unw = new TH2F("SouthSideADC_clusterXY_R3_unw" , "(ADC-Pedestal) > 5#sigma", 400, -800, 800, 400, -800, 800);
148  SouthSideADC_clusterXY_R3_unw->SetXTitle("X [mm]");
149  SouthSideADC_clusterXY_R3_unw->SetYTitle("Y [mm]");
150 
151  //____________________________________________________________________//
152 
153  //TPC "cluster" ZY heat maps WEIGHTED
154  NorthSideADC_clusterZY = new TH2F("NorthSideADC_clusterZY" , "(ADC-Pedestal) > 5#sigma North Side", 206, -1030, 1030, 400, -800, 800);
155  SouthSideADC_clusterZY = new TH2F("SouthSideADC_clusterZY" , "(ADC-Pedestal) > 5#sigma South Side", 206, -1030, 1030, 400, -800, 800);
156 
157  //____________________________________________________________________//
158 
159  //TPC "cluster" ZY heat maps UNWEIGHTED
160  NorthSideADC_clusterZY_unw = new TH2F("NorthSideADC_clusterZY_unw" , "(ADC-Pedestal) > 5#sigma North Side", 206, -1030, 1030, 400, -800, 800);
161  SouthSideADC_clusterZY_unw = new TH2F("SouthSideADC_clusterZY_unw" , "(ADC-Pedestal) > 5#sigma South Side", 206, -1030, 1030, 400, -800, 800);
162 
163  //____________________________________________________________________//
164 
165  //
166 
167  // ADC vs Sample (small)
168  char ADC_vs_SAMPLE_str[100];
169  char ADC_vs_SAMPLE_xaxis_str[100];
170  sprintf(ADC_vs_SAMPLE_str,"ADC Counts vs Sample: SECTOR %i",MonitorServerId());
171  sprintf(ADC_vs_SAMPLE_xaxis_str,"Sector %i: ADC Time bin [1/20MHz]",MonitorServerId());
172  ADC_vs_SAMPLE = new TH2F("ADC_vs_SAMPLE", ADC_vs_SAMPLE_str, 360, 0, 360, 256, 0, 1024);
173  ADC_vs_SAMPLE -> SetXTitle(ADC_vs_SAMPLE_xaxis_str);
174  ADC_vs_SAMPLE -> SetYTitle("ADC [ADU]");
175 
176  // ADC vs Sample (large)
177  char ADC_vs_SAMPLE_large_str[100];
178  char ADC_vs_SAMPLE_xaxis_large_str[100];
179  sprintf(ADC_vs_SAMPLE_large_str,"ADC Counts vs Large Sample: SECTOR %i",MonitorServerId());
180  sprintf(ADC_vs_SAMPLE_xaxis_large_str,"Sector %i: ADC Time bin [1/20MHz]",MonitorServerId());
181  ADC_vs_SAMPLE_large = new TH2F("ADC_vs_SAMPLE_large", ADC_vs_SAMPLE_large_str, 1080, 0, 1080, 256, 0, 1024);
182  ADC_vs_SAMPLE_large -> SetXTitle(ADC_vs_SAMPLE_xaxis_large_str);
183  ADC_vs_SAMPLE_large -> SetYTitle("ADC [ADU]");
184 
185  // Sample size distribution 1D histogram
186  char sample_size_title_str[100];
187  sprintf(sample_size_title_str,"Distribution of Sample Sizes in Events: SECTOR %i",MonitorServerId());
188  sample_size_hist = new TH1F("sample_size_hist" , sample_size_title_str, 1000, 0.5, 1000.5);
189  sample_size_hist->SetXTitle("sample size");
190  sample_size_hist->SetYTitle("counts");
191 
192  // entries vs FEE*8 + SAMPA Number
193  Check_Sums = new TH1F("Check_Sums" , "Entries vs Fee*8 + SAMPA in Events",208,-0.5, 207.5);
194  Check_Sums->SetXTitle("FEE_NUM*8 + SAMPA_ADRR");
195  Check_Sums->SetYTitle("Entries");
196  Check_Sums->Sumw2(kFALSE); //explicity turn off Sumw2 - we do not want it
197 
198  // checksum error vs FEE*8 + SAMPA Number
199  char checksum_title_str[100];
200  sprintf(checksum_title_str,"Check Sum Error Probability vs Fee*8 + SAMPA in Events: SECTOR %i",MonitorServerId());
201  Check_Sum_Error = new TH1F("Check_Sum_Error" , checksum_title_str,208,-0.5, 207.5);
202  Check_Sum_Error->SetXTitle("FEE_NUM*8 + SAMPA_ADDR");
203  Check_Sum_Error->SetYTitle("Prob. Check. Sum. Err.");
204  Check_Sum_Error->Sumw2(kFALSE); //explicity turn off Sumw2 - we do not want it
205 
206  // Max ADC per waveform dist for each module (R1, R2, R3)
207  char MAXADC_str[100];
208  char YLabel_str[5];
209 
210  sprintf(MAXADC_str,"MAX ADC per Waveform in SLIDING WINDOW: SECTOR %i",MonitorServerId());
211 
212  MAXADC = new TH2F("MAXADC" , MAXADC_str,1025,-0.5, 1024.5,3,-0.5,2.5);
213  MAXADC->SetXTitle("LocalMAX ADC in Waveform [ADU]");
214  MAXADC->SetYTitle("Entries");
215  MAXADC->Sumw2(kFALSE); //explicity turn off Sumw2 - we do not want it
216 
217  for(int i = 0; i < 3; i++ )
218  {
219  sprintf(YLabel_str,"R%i",i+1);
220  MAXADC->GetYaxis()->SetBinLabel(i+1,YLabel_str);
221  MAXADC->GetYaxis()->SetLabelSize(0.12);
222  MAXADC->GetXaxis()->SetLabelSize(0.04);
223  }
224 
225  //________For 1D ADC spectra - Doing this the hard way because I'm not sure if I can have a TH1 array
226  char RAWADC_1D_titlestr[100];
227  char MAXADC_1D_titlestr[100];
228  char SUBADC_1D_titlestr[100];
229 
230  sprintf(RAWADC_1D_titlestr,"RAW ADC for Sector %i R1",MonitorServerId());
231  sprintf(MAXADC_1D_titlestr,"MAX ADC in SLIDING WINDOW for Sector %i R1",MonitorServerId());
232  sprintf(SUBADC_1D_titlestr,"PEDEST_SUB RAW ADC for Sector %i R1",MonitorServerId());
233 
234  RAWADC_1D_R1 = new TH1F("RAWADC_1D_R1",RAWADC_1D_titlestr,1025,-0.5,1024.5);
235  MAXADC_1D_R1 = new TH1F("MAXADC_1D_R1",MAXADC_1D_titlestr,1025,-0.5,1024.5);
236  PEDEST_SUB_1D_R1 = new TH1F("PEDEST_SUB_1D_R1",SUBADC_1D_titlestr,1125,-100.5,1024.5);
237 
238  RAWADC_1D_R1->SetYTitle("Entries");
239  RAWADC_1D_R1->SetXTitle("ADC [ADU]");
240 
241  MAXADC_1D_R1->SetYTitle("Entries");
242  MAXADC_1D_R1->SetXTitle("(MAXADC-pedestal) [ADU]");
243 
244  PEDEST_SUB_1D_R1->SetYTitle("Entries");
245  PEDEST_SUB_1D_R1->SetXTitle("(ADC-pedestal) [ADU]");
246 
247  MAXADC_1D_R1->Sumw2(kFALSE);
248  RAWADC_1D_R1->Sumw2(kFALSE);
249  PEDEST_SUB_1D_R1->Sumw2(kFALSE);
250 
251  MAXADC_1D_R1->SetLineColor(2);
252  RAWADC_1D_R1->SetLineColor(2);
253  PEDEST_SUB_1D_R1->SetLineColor(2);
254 
255  sprintf(RAWADC_1D_titlestr,"RAW ADC for Sector %i R2",MonitorServerId());
256  sprintf(MAXADC_1D_titlestr,"MAX ADC for Sector %i R2",MonitorServerId());
257  sprintf(SUBADC_1D_titlestr,"PEDEST_SUB RAW ADC for Sector %i R2`",MonitorServerId());
258 
259  RAWADC_1D_R2 = new TH1F("RAWADC_1D_R2",RAWADC_1D_titlestr,1025,-0.5,1024.5);
260  MAXADC_1D_R2 = new TH1F("MAXADC_1D_R2",MAXADC_1D_titlestr,1025,-0.5,1024.5);
261  PEDEST_SUB_1D_R2 = new TH1F("PEDEST_SUB_1D_R2",SUBADC_1D_titlestr,1125,-100.5,1024.5);
262 
263  RAWADC_1D_R2->SetYTitle("Entries");
264  RAWADC_1D_R2->SetXTitle("ADC [ADU]");
265 
266  MAXADC_1D_R2->SetYTitle("Entries");
267  MAXADC_1D_R2->SetXTitle("(MAXADC-pedestal) [ADU]");
268 
269  PEDEST_SUB_1D_R2->SetYTitle("Entries");
270  PEDEST_SUB_1D_R2->SetXTitle("(ADC-pedestal) [ADU]");
271 
272  MAXADC_1D_R2->Sumw2(kFALSE);
273  RAWADC_1D_R2->Sumw2(kFALSE);
274  PEDEST_SUB_1D_R2->Sumw2(kFALSE);
275 
276  MAXADC_1D_R2->SetLineColor(3);
277  RAWADC_1D_R2->SetLineColor(3);
278  PEDEST_SUB_1D_R2->SetLineColor(3);
279 
280  sprintf(RAWADC_1D_titlestr,"RAW ADC for Sector %i R3",MonitorServerId());
281  sprintf(MAXADC_1D_titlestr,"MAX ADC for Sector %i R3",MonitorServerId());
282  sprintf(SUBADC_1D_titlestr,"PEDEST_SUB RAW ADC for Sector %i R3",MonitorServerId());
283 
284  RAWADC_1D_R3 = new TH1F("RAWADC_1D_R3",RAWADC_1D_titlestr,1025,-0.5,1024.5);
285  MAXADC_1D_R3 = new TH1F("MAXADC_1D_R3",MAXADC_1D_titlestr,1025,-0.5,1024.5);
286  PEDEST_SUB_1D_R3 = new TH1F("PEDEST_SUB_1D_R3",SUBADC_1D_titlestr,1125,-100.5,1024.5);
287 
288  RAWADC_1D_R3->SetYTitle("Entries");
289  RAWADC_1D_R3->SetXTitle("ADC [ADU]");
290 
291  MAXADC_1D_R3->SetYTitle("Entries");
292  MAXADC_1D_R3->SetXTitle("(MAXADC-pedestal) [ADU]");
293 
294  PEDEST_SUB_1D_R3->SetYTitle("Entries");
295  PEDEST_SUB_1D_R3->SetXTitle("(ADC-pedestal) [ADU]");
296 
297  MAXADC_1D_R3->Sumw2(kFALSE); // ADC vs Sample (small)
298  RAWADC_1D_R3->Sumw2(kFALSE);
299  PEDEST_SUB_1D_R3->Sumw2(kFALSE);
300 
301  MAXADC_1D_R3->SetLineColor(4);
302  RAWADC_1D_R3->SetLineColor(4);
303  PEDEST_SUB_1D_R3->SetLineColor(4);
304 
305 
306  char Layer_ChannelPhi_ADC_weighted_title_str[256];
307  sprintf(Layer_ChannelPhi_ADC_weighted_title_str,"Layer vs Channel Phi");
308  // x-axis is channel phi, y-axis is channel layer, z axis is ADC weithing
309  Layer_ChannelPhi_ADC_weighted = new TH2F("Layer_ChannelPhi_ADC_weighted",Layer_ChannelPhi_ADC_weighted_title_str,4610,-2305.5,2304.5,61,-0.5,59.5);
310  Layer_ChannelPhi_ADC_weighted->SetXTitle("Channel # (#phi bin)");
311  Layer_ChannelPhi_ADC_weighted->SetYTitle("Layer");
312 
314  // register histograms with server otherwise client won't get them
315  se->registerHisto(this, tpchist1); // uses the TH1->GetName() as key
316  se->registerHisto(this, tpchist2);
317  se->registerHisto(this, NorthSideADC);
318  se->registerHisto(this, SouthSideADC);
319  se->registerHisto(this, sample_size_hist);
320  se->registerHisto(this, Check_Sum_Error);
321  se->registerHisto(this, Check_Sums);
322  se->registerHisto(this, ADC_vs_SAMPLE);
324  se->registerHisto(this, MAXADC);
325  se->registerHisto(this, RAWADC_1D_R1);
326  se->registerHisto(this, MAXADC_1D_R1);
327  se->registerHisto(this, PEDEST_SUB_1D_R1);
328  se->registerHisto(this, RAWADC_1D_R2);
329  se->registerHisto(this, MAXADC_1D_R2);
330  se->registerHisto(this, PEDEST_SUB_1D_R2);
331  se->registerHisto(this, RAWADC_1D_R3);
332  se->registerHisto(this, MAXADC_1D_R3);
333  se->registerHisto(this, PEDEST_SUB_1D_R3);
334 
338 
342 
346 
350 
353 
356 
358 
359  Reset();
360  return 0;
361 }
362 
363 int TpcMon::BeginRun(const int /* runno */)
364 {
365  // if you need to read calibrations on a run by run basis
366  // this is the place to do it
367 
368  // we reset the BCO for the new run
369  starting_BCO = -1;
370  rollover_value = 0;
371  current_BCOBIN = 0;
372 
373  return 0;
374 }
375 
376 int TpcMon::process_event(Event *evt/* evt */)
377 {
378 
379  //std::cout << "TpcMon::process_event(Event * evt) Processing Event" << std::endl;
380 
381  if (evt == nullptr)
382  {
383  std::cout << "TpcMon::process_event - Event not found" << std::endl;
384  return -1;
385  }
386 
387  if (evt->getEvtType() >= 8)
388  {
389  std::cout << "TpcMon::process_event - Special Event type >= 8, moving on" << std::endl;
390  return -1;
391  }
392 
393  //reset these each event
394  float North_Side_Arr[36] = {0};
395  float South_Side_Arr[36] = {0};
396 
397  std::vector<int> store_ten;
398  std::vector<int> median_and_stdev_vec;
399 
400 
401  // we check if we have legacy data and start with packet 4000
402  // the range for the TPC is really 4001...4032
403  // we assume we start properly at 4001, but check if not
404 
405  int firstpacket=4001;
406  if (evt->existPacket(4000))
407  {
408  Packet *p = evt->getPacket(4000);
409  if (p->getHitFormat() == IDTPCFEEV3 ) firstpacket = 4000;
410  delete p;
411  }
412  int lastpacket = firstpacket+232;
413 
414 
415  for( int packet = firstpacket; packet < lastpacket; packet++) //packet 4001 or 4002 = Sec 00, packet 4231 or 4232 = Sec 23
416  {
417  Packet* p = evt->getPacket(packet);
418  if (!p)
419  {
420  //std::cout << "TpcMon::process_event - No packet numbered " << packet << " in this event!!" << std::endl;
421  continue;
422  }
423  else
424  {
425  //std::cout << "____________________________________" << std::endl;
426  //std::cout << "Packet # " << packet << std::endl;
427  int nr_of_waveforms = p->iValue(0, "NR_WF");
428  //std::cout << "Hello Waveforms ! - There are " << nr_of_waveforms << " of you !" << std::endl;
429 
430  bool is_channel_stuck = 0;
431 
432  for( int wf = 0; wf < nr_of_waveforms; wf++)
433  {
434 
435  int current_BCO = p->iValue(wf, "BCO") + rollover_value;
436  if (starting_BCO < 0)
437  {
438  starting_BCO = current_BCO;
439  }
440 
441  if (current_BCO < starting_BCO) // we have a rollover
442  {
443  rollover_value += 0x100000;
444  current_BCO = p->iValue(wf, "BCO") + rollover_value;
445  starting_BCO = current_BCO;
446  current_BCOBIN++;
447  }
448 
449 
450  int fee = p->iValue(wf, "FEE");
451  int sampaAddress = p->iValue(wf, "SAMPAADDRESS");
452  int checksumError = p->iValue(wf, "CHECKSUMERROR");
453  int channel = p->iValue(wf, "CHANNEL");
454 
455  Check_Sums->Fill(fee*8 + sampaAddress);
456  if( checksumError == 1){Check_Sum_Error->Fill(fee*8 + sampaAddress);}
457 
458  int nr_Samples = p->iValue(wf, "SAMPLES");
459  sample_size_hist->Fill(nr_Samples);
460 
461 
462  // clockwise FEE mapping
463  //int FEE_map[26]={5, 6, 1, 3, 2, 12, 10, 11, 9, 8, 7, 1, 2, 4, 8, 7, 6, 5, 4, 3, 1, 3, 2, 4, 6, 5};
464  int FEE_R[26]={2, 2, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 1, 2, 2, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3};
465  // counter clockwise FEE mapping (From Takao - DEPRECATED AS OF 08.29)
466  //int FEE_map[26]={3, 2, 5, 3, 4, 0, 2, 1, 3, 4, 5, 7, 6, 2, 0, 1, 0, 1, 4, 5, 11, 9, 10, 8, 6, 7};
467 
468  // FEE mapping from Jin
469  int FEE_map[26]={4, 5, 0, 2, 1, 11, 9, 10, 8, 7, 6, 0, 1, 3, 7, 6, 5, 4, 3, 2, 0, 2, 1, 3, 5, 4};
470 
471 
472  //int pads_per_sector[3] = {96, 128, 192};
473 
474 
476 
477  // setting the mapp of the FEE
478  int feeM = FEE_map[fee];
479  if(FEE_R[fee]==2) feeM += 6;
480  if(FEE_R[fee]==3) feeM += 14;
481 
482  // getting R and Phi coordinates
483  double R = M.getR(feeM, channel);
484  double padphi = 0;
485 
486  if( side(serverid) == 0 ) //NS
487  {
488  padphi = M.getPad(feeM, channel) + (serverid ) * (2304./12.);
489  }
490  else if( side(serverid) == 1 ) //SS
491  {
492  padphi = -M.getPad(feeM, channel) - (serverid-12) * (2304./12) ;
493  }
494 
495  int layer = M.getLayer(feeM, channel) + (serverid);
496  double phi = 0;
497 
498  //double phi = M.getPhi(feeM, channel) + (serverid - 12*side(serverid)) * M_PI / 6 ;
499 
500  if( side(serverid) == 0 ) //NS
501  {
502  phi = M.getPhi(feeM, channel) + (serverid ) * M_PI / 6 ;
503  }
504  else if( side(serverid) == 1 ) //SS
505  {
506  phi = M.getPhi(feeM, channel) + (18 - serverid ) * M_PI / 6 ;
507  }
508 
509  //std::cout<<"Sector = "<< serverid <<" FEE = "<<fee<<" channel = "<<channel<<std::endl;
510 
511  int mid = floor(nr_Samples/2); //get median sample
512 
513  if( nr_Samples > 9)
514  {
515  if( (p->iValue(wf,mid) == p->iValue(wf,mid-1)) && (p->iValue(wf,mid) == p->iValue(wf,mid-2)) && (p->iValue(wf,mid) == p->iValue(wf,mid+1)) && (p->iValue(wf,mid) == p->iValue(wf,mid+2)) )
516  {
517  is_channel_stuck = 1;
518  }
519  for( int si=0;si < nr_Samples; si++ ) //get pedestal and noise before hand
520  {
521  median_and_stdev_vec.push_back(p->iValue(wf,si));
522  }
523  } //Compare 5 values to determine stuck !!
524 
525  std::pair<float, float> result = calculateMedianAndStdDev(median_and_stdev_vec);
526  //std::cout<<"pedestal = "<<result.first<<", RMS = "<<result.second<<", ADC, channel: "<<channel<<", layer: "<<layer<<", phi: "<<phi<<std::endl;
527  float pedestal = result.first; //average/pedestal -- based on MEDIAN OF ALL ENTRIES NOW, NOT MEAN OF FIRST 10 (02/12/24)
528  float noise = result.second; //stdev - BASED ON REASONABLE SIGMA OF ENTRIES THAT ARE +/- 15 ADC WITHIN PEDESTAL
529 
530  int wf_max = 0;
531  int t_max = 0;
532 
533  float pedest_sub_wf_max = 0.;
534 
535  for( int s =0; s < nr_Samples ; s++ )
536  {
537 
538  //int t = s + 2 * (current_BCO - starting_BCO);
539 
540  int adc = p->iValue(wf,s);
541 
542  Layer_ChannelPhi_ADC_weighted->Fill(padphi,layer,adc-pedestal);
543 
544  if( adc > wf_max){ wf_max = adc; t_max = s; pedest_sub_wf_max = adc - pedestal;}
545 
546  if( s >= 10 && s <= 19) // get first 10-19
547  {
548  store_ten.push_back(adc);
549  }
550  else if( s > 19 )
551  {
552 
553  //nine_max = Max_Nine(p->iValue(wf,s-9),p->iValue(wf,s-8),p->iValue(wf,s-7),p->iValue(wf,s-6),p->iValue(wf,s-5),p->iValue(wf,s-4),p->iValue(wf,s-3),p->iValue(wf,s-2),p->iValue(wf,s-1)); //take the previous 9 numbers
554 
555  //VERY IMPORTANT, erase first entry, push_back current
556  store_ten.erase(store_ten.begin());
557  store_ten.push_back(adc);
558 
559  int max_of_previous_10 = *max_element(store_ten.begin(), store_ten.end());
560 
561  if(adc == max_of_previous_10 && (checksumError == 0 && is_channel_stuck == 0)) //if the new value is greater than the previous 9
562  {
563  MAXADC->Fill(adc - pedestal,Module_ID(fee));
564  if(Module_ID(fee)==0){MAXADC_1D_R1->Fill(adc - pedestal);} //Raw 1D for R1
565  else if(Module_ID(fee)==1){MAXADC_1D_R2->Fill(adc - pedestal);} //Raw 1D for R2
566  else if(Module_ID(fee)==2){MAXADC_1D_R3->Fill(adc - pedestal);} //Raw 1D for R3
567  }
568 
569  }
570 
571  if( checksumError == 0 && is_channel_stuck == 0)
572  {
573  ADC_vs_SAMPLE -> Fill(s, adc);
574  ADC_vs_SAMPLE_large -> Fill(s, adc);
575 
576  if(Module_ID(fee)==0){RAWADC_1D_R1->Fill(adc);PEDEST_SUB_1D_R1->Fill(adc-pedestal);} //Raw/pedest_sub 1D for R1
577  else if(Module_ID(fee)==1){RAWADC_1D_R2->Fill(adc);PEDEST_SUB_1D_R2->Fill(adc-pedestal);} //Raw/pedest_sub 1D for R2
578  else if(Module_ID(fee)==2){RAWADC_1D_R3->Fill(adc);PEDEST_SUB_1D_R3->Fill(adc-pedestal);} //Raw/pedest_sub 1D for R3
579  }
580 
581  //increment
582  if(serverid >= 0 && serverid < 12 ){ North_Side_Arr[ Index_from_Module(serverid,fee) ] += adc;}
583  else {South_Side_Arr[ Index_from_Module(serverid,fee)-36 ] += adc;}
584 
585  } //nr samples
586 
587  //for complicated XY stuff ____________________________________________________
588  //20 = 3-5 * sigma - hard-coded
589  // OR 10*noise = 10 sigma
590 
591  float z = 0; //mm
592 
593  if( ((serverid < 12 && (pedest_sub_wf_max) > 5.0*noise)) && layer != 0 )
594  {
595  if(Module_ID(fee)==0){NorthSideADC_clusterXY_R1->Fill(R*cos(phi),R*sin(phi),pedest_sub_wf_max);NorthSideADC_clusterXY_R1_unw->Fill(R*cos(phi),R*sin(phi));} //Raw 1D for R1
596  else if(Module_ID(fee)==1){NorthSideADC_clusterXY_R2->Fill(R*cos(phi),R*sin(phi),pedest_sub_wf_max);NorthSideADC_clusterXY_R2_unw->Fill(R*cos(phi),R*sin(phi));} //Raw 1D for R2
597  else if(Module_ID(fee)==2){NorthSideADC_clusterXY_R3->Fill(R*cos(phi),R*sin(phi),pedest_sub_wf_max);NorthSideADC_clusterXY_R3_unw->Fill(R*cos(phi),R*sin(phi));} //Raw 1D for R3
598 
599  if( t_max >= 10 && t_max <=255 ){z = 1030 - (t_max - 10)*(50 * 0.084);NorthSideADC_clusterZY->Fill(z,R*sin(phi),pedest_sub_wf_max);NorthSideADC_clusterZY_unw->Fill(z,R*sin(phi));}
600  }
601  else if( (serverid >=12 && (pedest_sub_wf_max) > 5.0*noise) && layer != 0)
602  {
603  if(Module_ID(fee)==0){SouthSideADC_clusterXY_R1->Fill(R*cos(phi),R*sin(phi),pedest_sub_wf_max);SouthSideADC_clusterXY_R1_unw->Fill(R*cos(phi),R*sin(phi));} //Raw 1D for R1
604  else if(Module_ID(fee)==1){SouthSideADC_clusterXY_R2->Fill(R*cos(phi),R*sin(phi),pedest_sub_wf_max);SouthSideADC_clusterXY_R2_unw->Fill(R*cos(phi),R*sin(phi));} //Raw 1D for R2
605  else if(Module_ID(fee)==2){SouthSideADC_clusterXY_R3->Fill(R*cos(phi),R*sin(phi),pedest_sub_wf_max);SouthSideADC_clusterXY_R3_unw->Fill(R*cos(phi),R*sin(phi));} //Raw 1D for R3
606 
607  if( t_max >= 10 && t_max <=255 ){z = -1030 + (t_max - 10)*(50 * 0.084);SouthSideADC_clusterZY->Fill(z,R*sin(phi),pedest_sub_wf_max);SouthSideADC_clusterZY_unw->Fill(z,R*sin(phi));}
608  }
609  //________________________________________________________________________________
610 
611  is_channel_stuck = 0; //reset after looping through waveform samples
612 
613  store_ten.clear(); //clear this after every waveform
614 
615  median_and_stdev_vec.clear(); //clear this after every waveform
616 
617 
618  } //nr waveforms
619  delete p;
620  }
621  } //packet loop
622 
623  evtcnt++;
624 
625  // get temporary pointers to histograms
626  // one can do in principle directly se->getHisto("tpchist1")->Fill()
627  // but the search in the histogram Map is somewhat expensive and slows
628  // things down if you make more than one operation on a histogram
629  tpchist1->Fill((float) idummy);
630  tpchist2->Fill((float) idummy, (float) idummy, 1.);
631 
632  //fill the TPC module displays
633  float r, theta;
634 
635  //dummy data
636  //float North_Side_Arr[36] = { 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50 };
637  //float South_Side_Arr[36] = { 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50, 12, 8, 40, 39, 80, 50 };
638 
639  for(int tpciter = 1; tpciter < 73 ; tpciter++){
640 
641  Locate(tpciter, &r, &theta);
642  //std::cout << "r is: "<< r <<" theta is: "<< theta <<"\n";
643  if(tpciter < 37){ //South side
644  NorthSideADC->Fill(theta,r, North_Side_Arr[tpciter-1]); //fill South side with the weight = bin content
645  }
646  else { //North side
647  SouthSideADC->Fill(theta,r,South_Side_Arr[tpciter-37]); //fill North side with the weight = bin content
648  }
649  }
650  //
651 
652  return 0;
653 }
654 
655 int TpcMon::Module_ID(int fee_id) //for simply determining which module you are in (doesn't care about sector)
656 {
657  int mod_id;
658 
659  if( fee_id == 2 || fee_id == 3 || fee_id == 4 || fee_id == 13 || fee_id == 16 || fee_id == 17 ){mod_id = 0;} // R1
660 
661  else if( fee_id == 0 || fee_id == 1 || fee_id == 11 || fee_id == 12 || fee_id == 14 || fee_id == 15 || fee_id == 18 || fee_id == 19 ){mod_id = 1;} // R2
662 
663  else if( fee_id == 5 || fee_id == 6 || fee_id ==7 || fee_id == 8 || fee_id == 9 || fee_id == 10 || fee_id == 20 || fee_id == 21 || fee_id == 22 || fee_id == 23 || fee_id == 24 || fee_id == 25 ){mod_id = 2;} // R3
664 
665  else mod_id = 0;
666 
667  return mod_id;
668 }
669 
670 
671 int TpcMon::Index_from_Module(int sec_id, int fee_id) //for placing in the array (takes into account sector)
672 {
673  int mod_id;
674 
675  if( fee_id == 2 || fee_id == 3 || fee_id == 4 || fee_id == 13 || fee_id == 16 || fee_id == 17 ){mod_id = 3*sec_id + 0;} // R1
676 
677  else if( fee_id == 0 || fee_id == 1 || fee_id == 11 || fee_id == 12 || fee_id == 14 || fee_id == 15 || fee_id == 18 || fee_id == 19 ){mod_id = 3*sec_id + 1;} // R2
678 
679  else if( fee_id == 5 || fee_id == 6 || fee_id ==7 || fee_id == 8 || fee_id == 9 || fee_id == 10 || fee_id == 20 || fee_id == 21 || fee_id == 22 || fee_id == 23 || fee_id == 24 || fee_id == 25 ){mod_id = 3*sec_id + 2;} // R3
680 
681  else mod_id = 0;
682 
683  return mod_id;
684 }
685 
686 void TpcMon::Locate(int id, float *rbin, float *thbin)
687 {
688  float CSIDE_angle_bins[12] = { 0.1*2.*TMath::Pi()/12 , 1.1*2.*TMath::Pi()/12 , 2.1*2.*TMath::Pi()/12 , 3.1*2.*TMath::Pi()/12 , 4.1*2.*TMath::Pi()/12 , 5.1*2.*TMath::Pi()/12 , 6.1*2.*TMath::Pi()/12 , 7.1*2.*TMath::Pi()/12 , 8.1*2.*TMath::Pi()/12 , 9.1*2.*TMath::Pi()/12 , 10.1*2.*TMath::Pi()/12 , 11.1*2.*TMath::Pi()/12 }; //CCW from x = 0 (RHS horizontal)
689 
690  float ASIDE_angle_bins[12] = { 6.1*2.*TMath::Pi()/12 , 5.1*2.*TMath::Pi()/12 , 4.1*2.*TMath::Pi()/12 , 3.1*2.*TMath::Pi()/12 , 2.1*2.*TMath::Pi()/12 , 1.1*2.*TMath::Pi()/12 , 0.1*2.*TMath::Pi()/12 , 11.1*2.*TMath::Pi()/12 , 10.1*2.*TMath::Pi()/12 , 9.1*2.*TMath::Pi()/12 , 8.1*2.*TMath::Pi()/12 , 7.1*2.*TMath::Pi()/12 }; //CCW from x = 0 (RHS horizontal)
691 
692  int modid3 = id % 3;
693 
694  switch(modid3) {
695  case 1:
696  *rbin = 0.4; //R1
697  break;
698  case 2:
699  *rbin = 0.6; //R2
700  break;
701  case 0:
702  *rbin = 0.8; //R3
703  break;
704  }
705 
706  if( id < 37){
707  *thbin = CSIDE_angle_bins[TMath::FloorNint((id-1)/3)];
708  }
709  else if( id >= 37){
710  *thbin = ASIDE_angle_bins[TMath::FloorNint((id-37)/3)];
711  }
712 }
713 
714 int TpcMon::Max_Nine(int one, int two, int three, int four, int five, int six, int seven, int eight, int nine)
715 {
716  int max = 0;
717  int nine_array[9] = {one, two, three, four, five, six, seven, eight, nine};
718 
719  for( int i = 0; i < 9; i++ )
720  {
721  if( nine_array[i] > max ){max = nine_array[i];}
722  }
723 
724  return max;
725 }
726 
727 bool TpcMon::side(int server_id)
728 {
729  bool side_id = 0; // side = 0 for NS, side = 1 for SS
730  if(server_id >= 12){side_id=1;} // side = 1 when serverid 12 or more
731 
732  return side_id;
733 }
734 
735 std::pair<float, float> TpcMon::calculateMedianAndStdDev(const std::vector<int>& values) {
736 
737  // Calculate the median
738  // first, sort
739  std::vector<int> sortedValues = values;
740  std::sort(sortedValues.begin(), sortedValues.end());
741  size_t size = sortedValues.size();
742 
743  float median;
744  if (size % 2 == 0)
745  {
746  median = (sortedValues[size / 2 - 1] + sortedValues[size / 2]) / 2.0;
747  }
748  else
749  {
750  median = sortedValues[size / 2];
751  }
752 
753  std::vector<int> selectedValues;
754 
755  // Select values within the range of median +/- 40
756  for (int value : values) {
757  if (value >= median - 40 && value <= median + 40)
758  {
759  selectedValues.push_back(value);
760  }
761  }
762 
763  //Calculate Mean of selected values
764  float sum = 0.0;
765  for (int value : selectedValues)
766  {
767  sum += value;
768  }
769  float mean = sum / selectedValues.size();
770 
771  // Calculate RMS of selected values
772  float sumSquares = 0.0;
773 
774  // Calculate the standard deviation of selected values only
775  for (int value : selectedValues)
776  {
777  float diff = value - mean;
778  sumSquares += std::pow(diff, 2);
779  }
780  float variance = sumSquares / selectedValues.size();
781  float stdDev = std::sqrt(variance);
782 
783  return std::make_pair(median, stdDev);
784 }
785 
786 
787 
789 {
790  // reset our internal counters
791  evtcnt = 0;
792  idummy = 0;
793  return 0;
794 }
795