/* Name: read_binary.C Created by: Stefan Ritt Date: July 30th, 2014 Purpose: Example program under ROOT to read a binary data file written by the DRSOsc program. Decode time and voltages from waveforms and display them as a graph. Put values into a ROOT Tree for further analysis. To run it, do: - Crate a file test.dat via the "Save" button in DRSOsc - start ROOT root [0] .L read_binary.C+ root [1] decode("test.dat"); */ #include #include #include "TFile.h" #include "TTree.h" #include "TString.h" #include "TGraph.h" #include "TCanvas.h" #include "Getline.h" typedef struct { char time_header[4]; char bn[2]; unsigned short board_serial_number; } 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; } EHEADER; /*-----------------------------------------------------------------------------*/ void decode(char *filename) { THEADER th; EHEADER eh; char hdr[4]; unsigned short voltage[1024]; double waveform[4][1024], time[4][1024]; float bin_width[4][1024]; char rootfile[256]; int i, j, ch, n, chn_index; double t1, t2, dt; // open the binary waveform file FILE *f = fopen(Form("%s", filename), "r"); if (f == NULL) { printf("Cannot find file \'%s\'\n", filename); return; } //open the root file strcpy(rootfile, filename); if (strchr(rootfile, '.')) *strchr(rootfile, '.') = 0; strcat(rootfile, ".root"); TFile *outfile = new TFile(rootfile, "RECREATE"); // define the rec tree TTree *rec = new TTree("rec","rec"); rec->Branch("t1", time[0] ,"t1[1024]/D"); rec->Branch("t2", time[1] ,"t2[1024]/D"); rec->Branch("t3", time[2] ,"t3[1024]/D"); rec->Branch("t4", time[3] ,"t4[1024]/D"); rec->Branch("w1", waveform[0] ,"w1[1024]/D"); rec->Branch("w2", waveform[1] ,"w2[1024]/D"); rec->Branch("w3", waveform[2] ,"w3[1024]/D"); rec->Branch("w4", waveform[3] ,"w4[1024]/D"); // create canvas TCanvas *c1 = new TCanvas(); // create graph TGraph *g = new TGraph(1024, (double *)time[0], (double *)waveform[0]); // 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); } // 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) 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') { // event header found fseek(f, -4, SEEK_CUR); 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 ; jFill(); // fill graph for (i=0 ; i<1024 ; i++) g->SetPoint(i, time[0][i], waveform[0][i]); // draw graph and wait for user click g->Draw("ACP"); c1->Update(); gPad->WaitPrimitive(); } // print number of events printf("%d events processed, \"%s\" written.\n", n, rootfile); // save and close root file rec->Write(); outfile->Close(); }