Made read_binary.C work with current data format

This commit is contained in:
2019-05-27 17:15:08 +02:00
parent 8f8c01897a
commit 725294e96a
6 changed files with 200 additions and 94 deletions
+161 -84
View File
@@ -29,39 +29,58 @@
#include "Getline.h"
typedef struct {
char time_header[4];
char bn[2];
unsigned short board_serial_number;
char tag[3];
char version;
} FHEADER;
typedef struct {
char time_header[4];
} THEADER;
typedef struct {
char event_header[4];
unsigned int event_serial_number;
unsigned short year;
unsigned short month;
unsigned short day;
unsigned short hour;
unsigned short minute;
unsigned short second;
unsigned short millisecond;
unsigned short reserved1;
char bs[2];
unsigned short board_serial_number;
char tc[2];
unsigned short trigger_cell;
char bn[2];
unsigned short board_serial_number;
} BHEADER;
typedef struct {
char event_header[4];
unsigned int event_serial_number;
unsigned short year;
unsigned short month;
unsigned short day;
unsigned short hour;
unsigned short minute;
unsigned short second;
unsigned short millisecond;
unsigned short range;
} EHEADER;
typedef struct {
char tc[2];
unsigned short trigger_cell;
} TCHEADER;
typedef struct {
char c[1];
char cn[3];
} CHEADER;
/*-----------------------------------------------------------------------------*/
void decode(char *filename) {
THEADER th;
EHEADER eh;
char hdr[4];
void decode(const char *filename) {
FHEADER fh;
THEADER th;
BHEADER bh;
EHEADER eh;
TCHEADER tch;
CHEADER ch;
unsigned int scaler;
unsigned short voltage[1024];
double waveform[4][1024], time[4][1024];
float bin_width[4][1024];
double waveform[16][4][1024], time[16][4][1024];
float bin_width[16][4][1024];
char rootfile[256];
int i, j, ch, n, chn_index;
int i, j, b, chn, n, chn_index, n_boards;
double t1, t2, dt;
// open the binary waveform file
@@ -73,8 +92,11 @@ void decode(char *filename) {
//open the root file
strcpy(rootfile, filename);
if (strchr(rootfile, '.'))
*strchr(rootfile, '.') = 0;
for (i=0 ; i<strlen(rootfile) ; i++)
if (rootfile[i] == '.') {
rootfile[i] = 0;
break;
}
strcat(rootfile, ".root");
TFile *outfile = new TFile(rootfile, "RECREATE");
@@ -95,76 +117,131 @@ void decode(char *filename) {
// create graph
TGraph *g = new TGraph(1024, (double *)time[0], (double *)waveform[0]);
// read file header
fread(&fh, sizeof(fh), 1, f);
if (fh.tag[0] != 'D' || fh.tag[1] != 'R' || fh.tag[2] != 'S') {
printf("Found invalid file header in file \'%s\', aborting.\n", filename);
return;
}
if (fh.version != '2') {
printf("Found invalid file version \'%c\' in file \'%s\', should be \'2\', aborting.\n", fh.version, filename);
return;
}
// read time header
fread(&th, sizeof(th), 1, f);
printf("Found data for board #%d\n", th.board_serial_number);
// read time bin widths
memset(bin_width, sizeof(bin_width), 0);
for (ch=0 ; ch<5 ; ch++) {
fread(hdr, sizeof(hdr), 1, f);
if (hdr[0] != 'C') {
// event header found
fseek(f, -4, SEEK_CUR);
break;
}
i = hdr[3] - '0' - 1;
printf("Found timing calibration for channel #%d\n", i+1);
fread(&bin_width[i][0], sizeof(float), 1024, f);
if (memcmp(th.time_header, "TIME", 4) != 0) {
printf("Invalid time header in file \'%s\', aborting.\n", filename);
return;
}
// loop over all events in data file
for (n=0 ; n<5 ; n++) {
// read event header
i = fread(&eh, sizeof(eh), 1, f);
if (i < 1)
for (b = 0 ; ; b++) {
// read board header
fread(&bh, sizeof(bh), 1, f);
if (memcmp(bh.bn, "B#", 2) != 0) {
// probably event header found
fseek(f, -4, SEEK_CUR);
break;
printf("Found event #%d\n", eh.event_serial_number);
// reach channel data
for (ch=0 ; ch<5 ; ch++) {
i = fread(hdr, sizeof(hdr), 1, f);
if (i < 1)
break;
if (hdr[0] != 'C') {
}
printf("Found data for board #%d\n", bh.board_serial_number);
// read time bin widths
memset(bin_width[b], 0, sizeof(bin_width[0]));
for (chn=0 ; chn<5 ; chn++) {
fread(&ch, sizeof(ch), 1, f);
if (ch.c[0] != 'C') {
// event header found
fseek(f, -4, SEEK_CUR);
break;
break;
}
chn_index = hdr[3] - '0' - 1;
fread(voltage, sizeof(short), 1024, f);
for (i=0 ; i<1024 ; i++) {
// convert data to volts
waveform[chn_index][i] = (voltage[i] / 65536. - 0.5);
// calculate time for this cell
for (j=0,time[chn_index][i]=0 ; j<i ; j++)
time[chn_index][i] += bin_width[chn_index][(j+eh.trigger_cell) % 1024];
i = ch.cn[2] - '0' - 1;
printf("Found timing calibration for channel #%d\n", i+1);
fread(&bin_width[b][i][0], sizeof(float), 1024, f);
// fix for 2048 bin mode: double channel
if (bin_width[b][i][1023] > 10 || bin_width[b][i][1023] < 0.01) {
for (j=0 ; j<512 ; j++)
bin_width[b][i][j+512] = bin_width[b][i][j];
}
}
// align cell #0 of all channels
t1 = time[0][(1024-eh.trigger_cell) % 1024];
for (ch=1 ; ch<4 ; ch++) {
t2 = time[ch][(1024-eh.trigger_cell) % 1024];
dt = t1 - t2;
for (i=0 ; i<1024 ; i++)
time[ch][i] += dt;
}
}
n_boards = b;
// fill root tree
rec->Fill();
// loop over all events in the data file
for (n=0 ; ; n++) {
// read event header
i = (int)fread(&eh, sizeof(eh), 1, f);
if (i < 1)
break;
// fill graph
for (i=0 ; i<1024 ; i++)
g->SetPoint(i, time[0][i], waveform[0][i]);
printf("Found event #%d %d %d\n", eh.event_serial_number, eh.second, eh.millisecond);
// draw graph and wait for user click
g->Draw("ACP");
c1->Update();
gPad->WaitPrimitive();
// loop over all boards in data file
for (b=0 ; b<n_boards ; b++) {
// read board header
fread(&bh, sizeof(bh), 1, f);
if (memcmp(bh.bn, "B#", 2) != 0) {
printf("Invalid board header in file \'%s\', aborting.\n", filename);
return;
}
// read trigger cell
fread(&tch, sizeof(tch), 1, f);
if (memcmp(tch.tc, "T#", 2) != 0) {
printf("Invalid trigger cell header in file \'%s\', aborting.\n", filename);
return;
}
if (n_boards > 1)
printf("Found data for board #%d\n", bh.board_serial_number);
// reach channel data
for (chn=0 ; chn<4 ; chn++) {
// read channel header
fread(&ch, sizeof(ch), 1, f);
if (ch.c[0] != 'C') {
// event header found
fseek(f, -4, SEEK_CUR);
break;
}
chn_index = ch.cn[2] - '0' - 1;
fread(&scaler, sizeof(int), 1, f);
fread(voltage, sizeof(short), 1024, f);
for (i=0 ; i<1024 ; i++) {
// convert data to volts
waveform[b][chn_index][i] = (voltage[i] / 65536. + eh.range/1000.0 - 0.5);
// calculate time for this cell
for (j=0,time[b][chn_index][i]=0 ; j<i ; j++)
time[b][chn_index][i] += bin_width[b][chn_index][(j+tch.trigger_cell) % 1024];
}
}
// align cell #0 of all channels
t1 = time[b][0][(1024-tch.trigger_cell) % 1024];
for (chn=1 ; chn<4 ; chn++) {
t2 = time[b][chn][(1024-tch.trigger_cell) % 1024];
dt = t1 - t2;
for (i=0 ; i<1024 ; i++)
time[b][chn][i] += dt;
}
// fill root tree
rec->Fill();
// fill graph
for (i=0 ; i<1024 ; i++)
g->SetPoint(i, time[b][0][i], waveform[b][0][i]);
// draw graph and wait for user click
g->Draw("ACP");
c1->Update();
gPad->WaitPrimitive();
}
}
// print number of events