AlcapDAQ  1
res_analysis.cxx
Go to the documentation of this file.
1 #define _FILE_OFFSET_BITS 64
2 
3 /*
4  * slow_extract
5  *
6  * Extracts the slow control data (everything except the primary event ID 1)
7  * from a MIDAS data file.
8  */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 
13 #ifndef __CINT__
14 #include "midas.h"
15 #include "../../compress/mucap_compress.h"
16 #endif
17 
18 #include "TH1.h"
19 #include "TH2.h"
20 #include "TCanvas.h"
21 
22 // #define PRINT_SAMPLES 1
23 
24 TCanvas *c = 0;
25 void process_file(char *input_filename, int addr, int fadc);
26 int process_event(void *pevent, int addr, int fadc);
27 
28 
29 bool get_input_event(FILE * fp, char *pevent, int event_number)
30 {
31  int event_size, size_read;
32  EVENT_HEADER *header;
33 
34  size_read = fread(pevent, 1, sizeof(EVENT_HEADER), fp);
35  if (size_read != sizeof(EVENT_HEADER))
36  return !SUCCESS;
37 
38  header = (EVENT_HEADER *) pevent;
39 
40  if (event_number == 0 && header->trigger_mask != MIDAS_MAGIC) {
41  fprintf(stderr, "Input is not a valid MIDAS file\n");
42  exit(1);
43  }
44 
45  event_size = header->data_size;
46 
47  if ((unsigned int) event_size >= MAX_EVENT_SIZE - sizeof(EVENT_HEADER)) {
48  fprintf(stderr, "Invalid event size %d\n", event_size);
49  exit(1);
50  }
51 
52  size_read = fread(pevent + sizeof(EVENT_HEADER), 1, event_size, fp);
53  if (size_read != event_size)
54  return !SUCCESS;
55 
56  return SUCCESS;
57 }
58 
59 TH2 *hSamples;
65 TH2 *hPed0;
66 
67 void process_file(char *input_filename, int addr, int fadc)
68 {
69  FILE *input_fp;
70  char *input_event;
71  int event_number;
72 
73  hSamples = new TH2D("samples", "Sample profile", 8, -0.5, 7.5, 4096, -0.5, 4095.5);
74  hPed0 = new TH2D("ped0", "Pedestal from first samples", 8, -0.5, 7.5, 4096, -0.5, 4095.5);
75  hChannelNSample = new TH1D("channelNSample", "Number of samples vs. channel", 8, -0.5, 7.5);
76  hChannelNIsland = new TH1D("channelNIsland", "Number of islands vs. channel", 8, -0.5, 7.5);
77  hMinSample = new TH2D("minSample", "Minimum sample in island", 8, -0.5, 7.5, 8192, -0.5, 8191.5);
78  hMaxSample = new TH2D("maxSample", "Maximum sample in island", 8, -0.5, 7.5, 8192, -0.5, 8191.5);
79  hPulseEnergy = new TH2D("pulseEnergy", "Reconstructed energy of pulse", 8, -0.5, 7.5, 4000, 0.5, 12000.5);
80 
81  char host_name[256], exp_name[32];
82  cm_get_environment(host_name, sizeof(host_name), exp_name, sizeof(exp_name));
83  cm_connect_experiment(host_name, exp_name, "show_pulses", NULL);
84  cm_get_experiment_database(&hDB, NULL);
86 
87  /* Open input and output files */
88  input_fp = fopen(input_filename, "rb");
89  if (!input_fp) {
90  fprintf(stderr, "Unable to open %s: ", input_filename);
91  perror("");
92  exit(1);
93  }
94 
95  /* Allocate buffer to hold MIDAS event */
96  input_event = (char *) malloc(MAX_EVENT_SIZE*2);
97 
98  /* Loop over MIDAS events */
99  event_number = 0;
100  while (get_input_event(input_fp, input_event, event_number) == SUCCESS) {
101 
102  EVENT_HEADER *header = (EVENT_HEADER *) input_event;
103 
104  if(header->event_id == 1) {
105  expand_event(header+1, header+1);
106  int stop = process_event(header + 1, addr, fadc);
107  if(stop) break;
108  }
109 
110  event_number++;
111  }
112 
113  fclose(input_fp);
114 }
115 
116 double findPulse(int nsamples, int *samples){
117  int sig_length_counter = 0;
118  double sig_max_height = 0.;
119  int sig_first_index = 0;
120  double sig_integral = 0.;
121  int sig_over_thr = 0;
122 
123  bool hasOvershoot = false;
124  bool hasUndershoot = false;
125  const int kLengthThreshold = 4;
126 
127  // (Serdar) i increased nsamples to 40 (was 16)
128 
129  if(nsamples < 40 ) return 0.;
130 
131  // Let's first find the pedestal
132 
133  // (Serdar) here i check whether selecting the first 5 sample or 10 sample do change anything
134  // on the pedestal determination, see histograms histPeds0first05bins or 10bins for more info
135  // and i find both can be used, so i select first 10 bins to get more info.
136 
137  const int pedSamples = 10;
138  double pedestalOffset = 0;
139  double sumpedestal2 = 0;
140  double pedestalsigma = 0 ;
141 
142  if(pedSamples > nsamples) return 0.;
143 
144  for(int i = 0; i < pedSamples; i++) {
145  pedestalOffset += samples[i];
146  }
147  pedestalOffset /= pedSamples;
148 
149  for(int i = 0; i < pedSamples; i++) {
150  sumpedestal2 += (pedestalOffset-samples[i])*(pedestalOffset-samples[i]);
151  }
152  pedestalsigma= sqrt(sumpedestal2/pedSamples);
153 
154  // printf("Pedestal = %f\n", pedestalOffset);
155  // Pedestal found, let's look for a pulse now
156 
157  // (Serdar) here i calculated the sigma for pedestal calculation, then i will start
158  // searching the pulse if sample is bigger the 4 pedestal sigma,
159 
160  const int kThreshold = 4*pedestalsigma;
161 
162  for(int i = 0; i < nsamples; i++) {
163  double bin_content = -1.*((double)samples[i] - pedestalOffset);
164 
165  double next_bin_content = 0.;
166  if(i<nsamples-1) next_bin_content = -1.*((double)samples[i+1] - pedestalOffset);
167 
168  if(bin_content >= kThreshold || next_bin_content >= kThreshold){
169  sig_length_counter++;
170  sig_over_thr++;
171 
172  if (sig_length_counter == 1){
173  sig_first_index = i;
174  // inspect left shoulder of this pulse
175  int back;
176  for(back=i-1; back>=0; back--){
177  double cont = -1.*((double)samples[back] - pedestalOffset);
178 
179  // (Serdar) here i made 2 changes, first, instead of 1/4 of the kThreshold
180  // i have 3/4, which equals 3 sigma at the left shoulder
181 
182  if(cont > 3*kThreshold/4 && (i-back)<4){
183  // accept it still as part of the left shoulder
184  sig_length_counter++;
185  sig_first_index = back;
186  }
187  else break;
188  }
189  }
190  }
191  else{
192  if (((bin_content < kThreshold) || (i == nsamples - 1)) &&
193  (sig_over_thr >= kLengthThreshold)){
194  // It's the end of the pulse, so let's include part of the right
195  // shoulder
196  int forw; // index for samples right of momentary position
197  for(forw=i+1;forw<nsamples; forw++){
198  double cont = -1.*((double)samples[forw] - pedestalOffset);
199  if(cont > kThreshold/4 && (forw-i)<4){
200  // accept it still as part of the left shoulder
201  sig_length_counter++;
202  }
203  else break; // probably pedestal so let's stop
204  i = forw;
205  }
206 
207  sig_integral = 0.;
208  sig_max_height = 0.;
209 
210  for(int i = sig_first_index; i < sig_first_index+sig_length_counter; i++){
211  double bin_content = -1.*((double)samples[i] - pedestalOffset);
212  sig_integral += bin_content;
213  if (bin_content > sig_max_height){
214  sig_max_height = bin_content;
215  }
216  }
217 
218  // Let's only deal with one pulse at this time!!!
219  break;
220  }
221  }
222  }
223 
224 // printf("Pulse accepted from sample %d to %d with energy %f\n", sig_first_index,
225 // sig_first_index+sig_length_counter, sig_integral);
226 
227  return sig_integral;
228 }
229 
230 int processIsland(int t0, int nsamples, int *samples, int channel)
231 {
232  hChannelNIsland->Fill(channel);
233 
234  if(nsamples < 16) return 0;
235 
236  int minI = -1;
237  int maxI = -1;
238  int minSample = 4097;;
239  int maxSample = -1;
240 
241  double energy = findPulse(nsamples, samples);
242 
243  for(int i = 0; i < nsamples; i++) {
244  hSamples->Fill(channel, samples[i]);
245  hChannelNSample->Fill(channel);
246  if(samples[i] > maxSample) {
247  maxI = i;
248  maxSample = samples[i];
249  }
250  if(samples[i] < minSample) {
251  minI = i;
252  minSample = samples[i];
253  }
254  if(i<10){
255  hPed0->Fill(channel, samples[i]);
256  }
257  }
258 
259  hMinSample->Fill(channel, minSample);
260  hMaxSample->Fill(channel, maxSample);
261  hPulseEnergy->Fill(channel, energy);
262 
263  return 0;
264 }
265 
266 int process_event(void *pevent, int addr, int fadc)
267 {
268  for(int i = 0; i < 8; i++) {
269 
270  if(i != fadc && fadc >= 0) continue;
271 
272  // get the bank
273  char name[80];
274  sprintf(name, "N%c%02x", 'a' + i, addr);
275  unsigned char *raw;
276  int bank_size = bk_locate(pevent, name, &raw);
277  bank_size = bank_size / 10;
278 
279 #ifdef PRINT_SAMPLES
280  printf("-------------------------------------------------------------------------------\n");
281 #endif
282 
283  int islandSamples[8192];
284  int islandNsamples = 0;
285  int islandT0 = -1;
286  bool firstIsland = true;
287 
288  // loop through words to build up "islands"
289  int lastTimestamp = 0;
290  for(int j = 0; j < bank_size; j++) {
291 
292  // data format:
293  //
294  // bits
295  // 78-52 timestamp
296  // 51-48 overflow
297  // 47-36 sampleB0
298  // 35-24 sampleA0
299  // 23-12 sampleB1
300  // 11-0 sampleA1
301  int timestamp = (raw[j*10+0] << 20) |
302  (raw[j*10+1] << 12) |
303  (raw[j*10+2] << 4) |
304  (raw[j*10+3] >> 4);
305  bool overflowB0 = ((raw[j*10+3] & 0x08) != 0);
306  bool overflowA0 = ((raw[j*10+3] & 0x04) != 0);
307  bool overflowB1 = ((raw[j*10+3] & 0x02) != 0);
308  bool overflowA1 = ((raw[j*10+3] & 0x01) != 0);
309  int sampleB0 = (overflowB0 << 12) |
310  (raw[j*10+4] << 4) |
311  (raw[j*10+5] >> 4);
312  int sampleA0 = (overflowA0 << 12) |
313  ((raw[j*10+5] & 0xf) << 8) |
314  (raw[j*10+6]);
315  int sampleB1 = (overflowB1 << 12) |
316  (raw[j*10+7] << 4) |
317  (raw[j*10+8] >> 4);
318  int sampleA1 = (overflowA1 << 12) |
319  ((raw[j*10+8] & 0xf) << 8) |
320  (raw[j*10+9]);
321 
322  if(timestamp < lastTimestamp) {
323  printf("Time ordering error!\n");
324  }
325 
326  if(timestamp != lastTimestamp + 1) {
327  if(!firstIsland) {
328  int stop = processIsland(islandT0*2, islandNsamples, islandSamples, i);
329 #ifdef PRINT_SAMPLES
330  printf("*\n");
331 #endif
332 
333  if(stop) {
334  return 1;
335  }
336  }
337  islandT0 = timestamp;
338  islandNsamples = 0;
339  firstIsland = false;
340  }
341  lastTimestamp = timestamp;
342 
343 #ifdef PRINT_SAMPLES
344  printf("fadc=%d t=%d %d %d %d %d\n", i, timestamp,
345  sampleA1, sampleB1, sampleA0,sampleB0);
346 #endif
347 
348  islandSamples[islandNsamples++] = sampleA1;
349  islandSamples[islandNsamples++] = sampleB1;
350  islandSamples[islandNsamples++] = sampleA0;
351  islandSamples[islandNsamples++] = sampleB0;
352  }
353 
354  if(islandNsamples != 0) {
355  processIsland(islandT0*2, islandNsamples, islandSamples, i);
356 #ifdef PRINT_SAMPLES
357  printf("*\n");
358 #endif
359  }
360  }
361 
362  return 0;
363 }