er  dev
ERDRS4Source.cxx
1 /********************************************************************************
2  * Copyright (C) Joint Institute for Nuclear Research *
3  * *
4  * This software is distributed under the terms of the *
5  * GNU Lesser General Public Licence version 3 (LGPL) version 3, *
6  * copied verbatim in the file "LICENSE" *
7  ********************************************************************************/
8 
9 #include "ERDRS4Source.h"
10 
11 #include "ERNeuRadRawEvent.h"
12 
13 #include <iostream>
14 using namespace std;
15 //--------------------------------------------------------------------------------------------------
16 ERDRS4Source::ERDRS4Source():
17 fNChanels(4),
18 fNPoints(1024)
19 {
20 }
21 //--------------------------------------------------------------------------------------------------
22 ERDRS4Source::ERDRS4Source(const ERDRS4Source& source){
23 }
24 //--------------------------------------------------------------------------------------------------
25 ERDRS4Source::~ERDRS4Source(){
26 
27 }
28 //--------------------------------------------------------------------------------------------------
29 Bool_t ERDRS4Source::Init(){
30  std::cerr << "Init" << std::endl;
31  f = fopen(fPath.Data(), "r");
32  if (f == NULL) {
33  printf("Cannot find file \'%s\'\n", fPath.Data());
34  return kFALSE;
35  }
36 
37  //Register new objects in output file
38  fRawEvents = new ERNeuRadRawEvent*[fNChanels];
39  FairRootManager* ioman = FairRootManager::Instance();
40  for (Int_t iChanel = 0; iChanel < fNChanels; iChanel++){
41  fRawEvents[iChanel] = new ERNeuRadRawEvent(fNPoints);
42  TString bName;
43  bName.Form("ch%d.",iChanel+1);
44  ioman->Register(bName, "DSR4", fRawEvents[iChanel], kTRUE);
45  }
46 
47  strcpy(filename, fPath.Data());
48  ReadHeader();
49  return kTRUE;
50 }
51 
52 Int_t ERDRS4Source::ReadHeader()
53 {
54  size_t nReadElements;
55 
56  // read file header
57  nReadElements = fread(&fh, sizeof(fh), 1, f);
58  if (fh.tag[0] != 'D' || fh.tag[1] != 'R' || fh.tag[2] != 'S') {
59  printf("Found invalid file header in file \'%s\', aborting.\n", filename);
60  return 0;
61  }
62 
63  if (fh.version != '2') {
64  printf("Found invalid file version \'%c\' in file \'%s\', should be \'2\', aborting.\n", fh.version, filename);
65  return 0;
66  }
67 
68  // read time header
69  nReadElements = fread(&th, sizeof(th), 1, f);
70  if (memcmp(th.time_header, "TIME", 4) != 0) {
71  printf("Invalid time header in file \'%s\', aborting.\n", filename);
72  return 0;
73  }
74 
75  for (b = 0 ; ; b++) {
76  // read board header
77  nReadElements = fread(&bh, sizeof(bh), 1, f);
78  if (memcmp(bh.bn, "B#", 2) != 0) {
79  // probably event header found
80  fseek(f, -4, SEEK_CUR);
81  break;
82  }
83 
84  printf("Found data for board #%d\n", bh.board_serial_number);
85 
86  // read time bin widths
87  memset(bin_width[b], sizeof(bin_width[0]), 0);
88  for (chn=0 ; chn<5 ; chn++) {
89  nReadElements = fread(&ch, sizeof(ch), 1, f);
90  if (ch.c[0] != 'C') {
91  // event header found
92  fseek(f, -4, SEEK_CUR);
93  break;
94  }
95  i = ch.cn[2] - '0' - 1;
96  printf("Found timing calibration for channel #%d\n", i+1);
97  nReadElements = fread(&bin_width[b][i][0], sizeof(float), 1024, f);
98  /*my printf
99  printf("bin width %d \n", bin_width[b][i][10]); */
100  // fix for 2048 bin mode: double channel
101  if (bin_width[b][i][1023] > 10 || bin_width[b][i][1023] < 0.01) {
102  for (j=0 ; j<512 ; j++)
103  bin_width[b][i][j+512] = bin_width[b][i][j];
104  /*my printf
105  printf("bin width %d \n", bin_width[b][i][j+512]); */
106  }
107  }
108  }
109  n_boards = b;
110 
111  // initialize statistics
112  ndt = 0;
113  sumdt = sumdt2 = 0;
114 }
115 
116 Int_t ERDRS4Source::ReadEvent(UInt_t id)
117 {
118  size_t nReadElements;
119 
120  //reset Events
121  //read event header
122  i = (int)fread(&eh, sizeof(eh), 1, f);
123  if (i < 1)
124  return 1;
125 
126  if ( !(eh.event_serial_number%100) ) {
127  printf("Found event #%d\n", eh.event_serial_number);
128  }
129 
130  // loop over all boards in data file
131  for (b=0 ; b<n_boards ; b++) {
132 
133  // read board header
134  nReadElements = fread(&bh, sizeof(bh), 1, f);
135  if (memcmp(bh.bn, "B#", 2) != 0) {
136  printf("Invalid board header in file \'%s\', aborting.\n", filename);
137  return 0;
138  }
139 
140  // read trigger cell
141  nReadElements = fread(&tch, sizeof(tch), 1, f);
142  if (memcmp(tch.tc, "T#", 2) != 0) {
143  printf("Invalid trigger cell header in file \'%s\', aborting.\n", filename);
144  return 0;
145  }
146 
147  if (n_boards > 1)
148  printf("Found data for board #%d\n", bh.board_serial_number);
149 
150  // reach channel data
151  for (chn=0 ; chn<4 ; chn++) {
152 
153  // read channel header
154  nReadElements = fread(&ch, sizeof(ch), 1, f);
155  if (ch.c[0] != 'C') {
156  // event header found
157  fseek(f, -4, SEEK_CUR);
158  break;
159  }
160  chn_index = ch.cn[2] - '0' - 1;
161  // printf("print channel %d \n",chn_index);
162  nReadElements = fread(&scaler, sizeof(int), 1, f);
163  nReadElements = fread(voltage, sizeof(short), 1024, f);
164 
165  for (i=0 ; i<1024 ; i++) {
166  // convert data to volts
167  waveform[b][chn_index][i] = (voltage[i] / 65536. + eh.range/1000.0 - 0.5); //calculation of amplitudes values for each cell
168 
169  //for ROOT
170  //ncell = i;
171 // if(chn_index == 0) {
172 // event[0]->SetAmp(waveform[b][chn_index][i], i);
173 // }
174  fRawEvents[chn_index]->SetAmp(waveform[b][chn_index][i], i);
175  // if(chn_index == 1) {amp_ch2[i] = waveform[b][chn_index][i];}
176 
177  // calculate time for this cell
178  for (j=0,time[b][chn_index][i]=0 ; j<i ; j++){
179  time[b][chn_index][i] += bin_width[b][chn_index][(j+tch.trigger_cell) % 1024];
180  }
181  }
182  } // end of the channel loop (chn)
183 
184  // align cell #0 of all channels
185  t1 = time[b][0][(1024-tch.trigger_cell) % 1024];
186 // event[0]->SetTime(time[b][chn][i],i);
187  //my print;
188  // printf("t1 %1.6lf \n",time[b][0][(1024-tch.trigger_cell) % 1024]);
189  for (chn=1 ; chn<4 ; chn++) {
190  t2 = time[b][chn][(1024-tch.trigger_cell) % 1024];
191  //adding channels 3 and 4
192  t3 = time[b][chn][(1024-tch.trigger_cell) % 1024];
193  t4 = time[b][chn][(1024-tch.trigger_cell) % 1024];
194  //my prinf
195  //printf("t2 %f for %d %d %d \n",time[b][chn][(1024-tch.trigger_cell) % 1024], b, chn, i);
196  dt = t1 - t2;
197  dt34 = t3 - t4;
198  for (i=0 ; i<1024 ; i++) {
199  time[b][chn][i] += dt; //each element of time gets dt correction
200  //my print;
201  // printf("time %1.6lf for %d %d %d \n",time[b][chn][i], b, chn, i);
202 // event[chn]->SetTime(time[b][chn][i],i);
203  }
204 
205  }
206 
207  t1 = t2 = t3 = t4 = 0;
208  threshold = -0.045; //my threshold, used to be 0.3
209 
210 
211  //for ROOT
212  for(i=0 ; i<1024 ; i++) {
213  for (Int_t chNum = 0; chNum < 4; chNum++) { fRawEvents[chNum]->SetTime(time[b][chNum][i],i); }
214  }
215  //event->Print();
216  // find peak in channel 1 above threshold
217  for (i=0 ; i<1022 ; i++) {
218 
219  if (waveform[b][0][i] < threshold && waveform[b][0][i+1] >= threshold) {
220  t1 = (threshold-waveform[b][0][i])/(waveform[b][0][i+1]-waveform[b][0][i])*(time[b][0][i+1]-time[b][0][i])+time[b][0][i];
221  //my prinf
222  //printf("t1 recalc %1.6lf %d \n",t1, i);
223  break;
224  }
225 
226  }
227 
228  // find peak in channel 2 above threshold
229  for (i=0 ; i<1022 ; i++) {
230  if (waveform[b][1][i] < threshold && waveform[b][1][i+1] >= threshold) {
231  t2 = (threshold-waveform[b][1][i])/(waveform[b][1][i+1]-waveform[b][1][i])*(time[b][1][i+1]-time[b][1][i])+time[b][1][i];
232  //my prinf
233  //printf("t2 recalc %1.6lf \n",t2);
234  break;
235  }
236  }
237 
238  // calculate distance of peaks with statistics
239  if (t1 > 0 && t2 > 0) {
240  ndt++;
241  dt = t2 - t1;
242  sumdt += dt;
243  sumdt2 += dt*dt;
244  }
245  } //end of the boards loop
246  return 0;
247 }
248 
249 void ERDRS4Source::Close(){
250  // print statistics
251  printf("dT = %1.3lfns +- %1.1lfps\n", sumdt/ndt, 1000*sqrt(1.0/(ndt-1)*(sumdt2-1.0/ndt*sumdt*sumdt)));
252 }
253 
254 void ERDRS4Source::Reset(){
255  for (Int_t iChanel = 0; iChanel < fNChanels; iChanel++)
256  {
257  fRawEvents[iChanel]->Reset();
258  }
259 }
class for raw data obtained from measurements or simulations
task for reading raw data from binary files
Definition: ERDRS4Source.h:71