Commit e51e9398 authored by Kostyleva D.A's avatar Kostyleva D.A

adding drs4 raw and analysis files

parent f9306827
Application for convertation of binary files acquired by DRS4 to ROOT file. Application for convertation of binary files acquired by DRS4 to ROOT file.
1. g++ -o read_binary read_binary.cpp -lm `root-config --cflags --libs`
This compiles read_binary.cpp file and makes object file read_binary.
2. ./read_binary ./data/rawDataDSR4/file_name.dat
With the help of the object file it is possible to convert binary file .dat to file .root (which we call raw /home/dariak/NeuRad_tests/data/rawDataDSR4)
3. read_root.C
This script reads raw file and make another file .root with simple analysis /home/dariak/NeuRad_tests/data/dataDSR4
/*
Name: read_binary.cpp
Created by: Stefan Ritt <stefan.ritt@psi.ch>
Date: July 30th, 2014
Purpose: Example file to read binary data saved by DRSOsc.
Compile and run it with:
gcc -o read_binary read_binary.cpp
./read_binary <filename>
This program assumes that a pulse from a signal generator is split
and fed into channels #1 and #2. It then calculates the time difference
between these two pulses to show the performance of the DRS board
for time measurements.
$Id: read_binary.cpp 22290 2016-04-27 14:51:37Z ritt $
*/
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
//for ROOT
#include "TROOT.h"
#include "TFile.h"
#include "TTree.h"
#include "TH1F.h"
typedef struct {
char tag[3];
char version;
} FHEADER;
typedef struct {
char time_header[4];
} THEADER;
typedef struct {
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; // range center in mV
} EHEADER;
typedef struct {
char tc[2];
unsigned short trigger_cell;
} TCHEADER;
typedef struct {
char c[1];
char cn[3];
} CHEADER;
/*-----------------------------------------------------------------------------*/
int main(int argc, const char * argv[])
{
FHEADER fh;
THEADER th;
BHEADER bh;
EHEADER eh;
TCHEADER tch;
CHEADER ch;
unsigned int scaler;
unsigned short voltage[1024];
double waveform[16][4][1024], time[16][4][1024];
float bin_width[16][4][1024];
int i, j, b, chn, n, chn_index, n_boards;
double t1, t2, t3, t4, dt, dt34;
char filename[256];
int ndt;
double threshold, sumdt, sumdt2;
//for ROOT
TFile* rfile = new TFile("/home/dariak/NeuRad_tests/data/rawDataDSR4/NeuRad_test_08_2.root", "RECREATE");
TTree* rtree = new TTree("rtree", "tree for drs4 analysis");
//rtree->Branch("t1", &t1, "t1/D"); //br for time of threshold crossing signal in 1 ch
// rtree->Branch("t2", &t2, "t2/D"); //br for time of threshold crossing signal in 2 ch
int ncell;
const int ncellMax = 1030;
double amp_ch1[ncellMax], time_ch1[ncellMax]; //variable size array
//------for other channels
// double amp_ch2[ncellMax], time_ch2[ncellMax];
rtree->Branch("ncell", &ncell, "ncell/I");
rtree->Branch("amp_ch1", amp_ch1, "amp_ch1[ncell]/D");
rtree->Branch("time_ch1", time_ch1, "time_ch1[ncell]/D");
//------for other channels
// rtree->Branch("amp_ch2", amp_ch2, "amp_ch2[ncell]/D");
// rtree->Branch("time_ch2", time_ch2, "time_ch2[ncell]/D");
if (argc > 1)
strcpy(filename, argv[1]);
else {
printf("Usage: read_binary <filename>\n");
return 0;
}
// open the binary waveform file
FILE *f = fopen(filename, "r");
if (f == NULL) {
printf("Cannot find file \'%s\'\n", filename);
return 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 0;
}
if (fh.version != '2') {
printf("Found invalid file version \'%c\' in file \'%s\', should be \'2\', aborting.\n", fh.version, filename);
return 0;
}
// read time header
fread(&th, sizeof(th), 1, f);
if (memcmp(th.time_header, "TIME", 4) != 0) {
printf("Invalid time header in file \'%s\', aborting.\n", filename);
return 0;
}
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 data for board #%d\n", bh.board_serial_number);
// read time bin widths
memset(bin_width[b], sizeof(bin_width[0]), 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;
}
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);
/*my printf
printf("bin width %d \n", bin_width[b][i][10]); */
// 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];
/*my printf
printf("bin width %d \n", bin_width[b][i][j+512]); */
}
}
}
n_boards = b;
// initialize statistics
ndt = 0;
sumdt = sumdt2 = 0;
// 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;
if ( !(eh.event_serial_number%100) ) {
printf("Found event #%d\n", eh.event_serial_number);
}
// 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 0;
}
// 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 0;
}
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;
// printf("print channel %d \n",chn_index);
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); //calculation of amplitudes values for each cell
//for ROOT
ncell = i;
if(chn_index == 0) {amp_ch1[i] = waveform[b][chn_index][i];}
// if(chn_index == 1) {amp_ch2[i] = waveform[b][chn_index][i];}
// 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];
}
}
} // end of the channel loop (chn)
// align cell #0 of all channels
t1 = time[b][0][(1024-tch.trigger_cell) % 1024];
//my print;
// printf("t1 %1.6lf \n",time[b][0][(1024-tch.trigger_cell) % 1024]);
for (chn=1 ; chn<4 ; chn++) {
t2 = time[b][chn][(1024-tch.trigger_cell) % 1024];
//adding channels 3 and 4
t3 = time[b][chn][(1024-tch.trigger_cell) % 1024];
t4 = time[b][chn][(1024-tch.trigger_cell) % 1024];
//my prinf
//printf("t2 %f for %d %d %d \n",time[b][chn][(1024-tch.trigger_cell) % 1024], b, chn, i);
dt = t1 - t2;
dt34 = t3 - t4;
for (i=0 ; i<1024 ; i++) {
time[b][chn][i] += dt; //each element of time gets dt correction
//my print;
// printf("time %1.6lf for %d %d %d \n",time[b][chn][i], b, chn, i);
}
}
t1 = t2 = t3 = t4 = 0;
threshold = -0.045; //my threshold, used to be 0.3
//for ROOT
for(i=0 ; i<1024 ; i++) {
time_ch1[i] = time[b][0][i];
// time_ch2[i] = time[b][1][i];
}
// find peak in channel 1 above threshold
for (i=0 ; i<1022 ; i++) {
if (waveform[b][0][i] < threshold && waveform[b][0][i+1] >= threshold) {
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];
//my prinf
//printf("t1 recalc %1.6lf %d \n",t1, i);
break;
}
}
// find peak in channel 2 above threshold
for (i=0 ; i<1022 ; i++) {
if (waveform[b][1][i] < threshold && waveform[b][1][i+1] >= threshold) {
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];
//my prinf
//printf("t2 recalc %1.6lf \n",t2);
break;
}
}
// calculate distance of peaks with statistics
if (t1 > 0 && t2 > 0) {
ndt++;
dt = t2 - t1;
sumdt += dt;
sumdt2 += dt*dt;
}
} //end of the boards loop
rtree->Fill();
} // end of the events loop
// print statistics
printf("dT = %1.3lfns +- %1.1lfps\n", sumdt/ndt, 1000*sqrt(1.0/(ndt-1)*(sumdt2-1.0/ndt*sumdt*sumdt)));
rfile->Write();
rfile->Close();
return 1;
}
void read_root()
{
TFile *f = new TFile("/home/dariak/NeuRad_tests/data/rawDataDSR4/NeuRad_test_07_1.root");
TTree *tr = (TTree*)f->Get("rtree");
tr->SetMakeClass(1);
// TArrayD ampl1;
// TArrayD time1;
// ampl1.Set(ncellMax);
// time1.Set(ncellMax);
const int ncellMax = 1030;
Double_t ampl1[ncellMax];
Double_t time1[ncellMax];
TFile *fw = new TFile("/home/dariak/NeuRad_tests/data/dataDSR4/analysis_07_1.root", "RECREATE");
TTree *tw = new TTree("drs4analysis", "title of drs4 analysis tree");
Double_t minAmplitude1;
tw->Branch("minAmplitude1", &minAmplitude1, "minAmplitude1/D");
/* Double_t ampl1[1024];
Double_t time1[1024];*/
tr->SetBranchAddress("amp_ch1", ampl1);
tr->SetBranchAddress("time_ch1", time1);
const Long64_t nEntries = tr->GetEntries();
cout <<"Number of entries: "<<nEntries<<endl;
//----for pictures
/* TCanvas *c1 = new TCanvas();
c1->Divide(3,4);
for(Int_t i=12; i<24; i++) {
c1->cd(i-11);
tr->GetEntry(i);
TGraph *gr1 = new TGraph(1023, time1, ampl1);
gr1->SetTitle("Signal shape for one event");
gr1->GetXaxis();
gr1->Draw("Al*");
}
tr->GetEntry(428);
TGraph *gr1 = new TGraph(1023, time1, ampl1);
gr1->SetTitle("Signal shape for one event");
gr1->Draw("Al*");*/
//-----
Double_t minAmpl1 = 0.;
for(Int_t i=0; i<tr->GetEntries(); i++) {
tr->GetEntry(i);
minAmpl1 = ampl1[0];
//find minimum by hand
for(Int_t j=0; j<1023; j++) {
//cout<<ampl1[j]<<" "<<j<<endl;
if(ampl1[j] < minAmpl1) {
minAmpl1 = ampl1[j];
}
/*cout<<"Time "<<i<<" "<<j<<" "<<time1[j]<<endl;
//cout<<"Amplitude "<<i<<" "<<j<<" "<<ampl1[j]<<endl;
cout<<endl;*/
}
//fitting 90 percent of rising edge
for(Int_t k=0; k<1023; k++) {
if(ampl1[k] < 0.1*minAmpl1 && ampl1[k] > 0.9*minAmpl1) { //we have negative signals, amplitude between 10 and 90 proc from minimum
/*cout<<"rjgnfre"<<endl;
TGraph *gr2 = new TGraph(1023, time1, ampl1);
gr2->SetTitle("stupido");
gr2->Fit("pol1");
gr2->Draw("Al*");*/
}
}
//getting integral
TGraph *gr3 = new TGraph(1023, time1, ampl1);
//for(Int_t k=120; k<180; k++) {
gr3->Integral(120,180);
cout<<"INtegral "<<gr3->Integral(120,180)<<endl;
//}
minAmplitude1 = minAmpl1;
cout<<"Min amplitude "<<minAmpl1<<" for entry "<<i<<endl;
tw->Fill();
}
fw->cd();
tw->Write();
fw->Close();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment