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