for MUSIC by Chloe

This commit is contained in:
Ryan@iMac 2023-02-08 12:00:30 -05:00
parent 4e33fbba28
commit 6e97710f0f
22 changed files with 2158 additions and 247 deletions

BIN
Analysis/EventBuilder_raw Executable file

Binary file not shown.

128
Analysis/TimSyncComp.C Executable file
View File

@ -0,0 +1,128 @@
#include <iostream>
#include <stdlib.h>
#include "TFile.h"
void quicksort( Double_t* arr1, Int_t* arr2, int left, int right)
{
auto i = left;
auto j = right;
auto tmp = arr1[0];
auto pivot = arr1[(int)((left + right)/2)];
// Partition
while (i <= j) {
while (arr1[i] < pivot)
i++;
while (arr1[j] > pivot)
j--;
if (i <= j) {
// swap arr1 elements
tmp = arr1[i];
arr1[i] = arr1[j];
arr1[j] = tmp;
// swap arr2 elements
tmp = arr2[i];
arr2[i] = arr2[j];
arr2[j] = tmp;
i++;
j--;
}
};
// Recursion
if (left < j)
quicksort(arr1, arr2, left, j);
if (i < right)
quicksort(arr1, arr2, i, right);
return;
}
void TimSyncComp()
{
Char_t* f; TChain* MUSICdata = new TChain("Data_R");
f ="/home/bavarians/exp/test0/DAQ/run/RAW/DataR_run.root";
std::cout<<f<<std::endl;
MUSICdata->Add(f);
double run_portion=0.01;
//"""""""""""""""""""""
//TIME synchronization of the digital board
//"""""""""""""""""""""
// Double_t shiftTime[4] ={0.30026482, 0.200206944, 0.100003416, 0.0};//pulser
// Double_t shiftTime[4] ={0.192828788, 0.137373792 , 0.058816296, 0.0};//run28
Double_t shiftTime[4] ={0, 0 ,0., 0.0};
//"""""""""""""""""""""
//MAP
//"""""""""""""""""""""
//Left 0->15
//Right 16->31
//Individual{32=Grid, 33=S0, 34=cathode, 35=S17},
//100=empty
int Map_DAQCha_to_MUSICStrip[4][16]={{34,100, 1, 100, 33, 100, 5, 100, 0, 100, 9, 100, 17, 13, 100, 32},
{2, 100, 16, 100, 21, 100, 20, 100, 8, 100, 24, 100, 27, 28, 100, 14},
{19, 100, 3, 100, 6, 100, 7, 100, 25, 100, 11, 100, 12, 15, 100, 31},
{4, 100, 18, 36, 23, 100, 22, 100, 10, 100, 26, 100, 29, 30, 100, 35}};
//"""""""""""""""""""""
//Data tree structure
//"""""""""""""""""""""
MUSICdata->SetBranchStatus("*", 0);
UShort_t Channel;
ULong64_t Timestamp;
UShort_t Board;
UShort_t Energy;
MUSICdata->SetBranchStatus("Channel", 1);MUSICdata->SetBranchAddress("Channel", &Channel);
MUSICdata->SetBranchStatus("Timestamp", 1);MUSICdata->SetBranchAddress("Timestamp", &Timestamp);
MUSICdata->SetBranchStatus("Board", 1);MUSICdata->SetBranchAddress("Board", &Board);
MUSICdata->SetBranchStatus("Energy", 1);MUSICdata->SetBranchAddress("Energy", &Energy);
double Ibeam = 30000.;
int nStat = MUSICdata->GetEntries();
std::cout<<nStat<<std::endl;
//"""""""""""""""""""""
//time alignment
//"""""""""""""""""""""
TH2F* ChTimeBefore = new TH2F("ChTimeBefore", ";time(ms);channel(S0->LR16)",5000, 0,0+0.5,80,0,80);
Double_t* timestampVec = new Double_t[nStat]; Int_t* entryVec = new Int_t[nStat];
for(int j=0;j<nStat;j++){
MUSICdata->GetEntry(j);
ChTimeBefore->Fill((Timestamp*1e-12)*1000. , Board*16+Channel);
timestampVec[j]= (Timestamp - shiftTime[Board]*1e+12);
entryVec[j]=j;
}
quicksort(timestampVec, entryVec,0,nStat-1);
std::cout<<"sorted "<<std::endl;
int PositiveTime=0;
for(int j=0;j<nStat;j++){
if(timestampVec[j]>=0){
PositiveTime=j;
break;
}
}
//"""""""""""""""""""""
//checking synchronization
//"""""""""""""""""""""
Double_t TimeEv = timestampVec[PositiveTime]*1e-12;
//"""""""""""""""""""""
//Plot definition
//"""""""""""""""""""""
TH2F* ChTimeAfter = new TH2F("ChTimeAfter", ";time(ms);channel(S0->LR16)",5000, 0, 0+0.5,80,0,80);
for(int i=0;i<run_portion*nStat;i++){
MUSICdata->GetEntry(entryVec[i]);
ChTimeAfter->Fill((timestampVec[i]*1e-12)*1e+3, Board*16+Channel);
}
TCanvas* c= new TCanvas("c","c",800,800);c->Divide(1,2);
gStyle->SetPalette(kThermometer);
c->cd(1);ChTimeBefore->Draw("colz");
c->cd(2);ChTimeAfter->Draw("colz");
}

138
Analysis/TimeSync.C Executable file
View File

@ -0,0 +1,138 @@
#include <iostream>
#include <stdlib.h>
#include "TFile.h"
void quicksort( Double_t* arr1, Int_t* arr2, int left, int right)
{
auto i = left;
auto j = right;
auto tmp = arr1[0];
auto pivot = arr1[(int)((left + right)/2)];
// Partition
while (i <= j) {
while (arr1[i] < pivot)
i++;
while (arr1[j] > pivot)
j--;
if (i <= j) {
// swap arr1 elements
tmp = arr1[i];
arr1[i] = arr1[j];
arr1[j] = tmp;
// swap arr2 elements
tmp = arr2[i];
arr2[i] = arr2[j];
arr2[j] = tmp;
i++;
j--;
}
};
// Recursion
if (left < j)
quicksort(arr1, arr2, left, j);
if (i < right)
quicksort(arr1, arr2, i, right);
return;
}
void TimeSync()
{
Char_t* f; TChain* MUSICdata = new TChain("tree");
f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B0.root";
std::cout<<f<<std::endl;
MUSICdata->Add(f);
f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B1.root";
std::cout<<f<<std::endl;
MUSICdata->Add(f);
f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B2.root";
std::cout<<f<<std::endl;
MUSICdata->Add(f);
f ="/fs2data/bavarians/MUSIC_Devel/FSUDAQ/Run_001_B3.root";
std::cout<<f<<std::endl;
MUSICdata->Add(f);
double run_portion=0.01;
//"""""""""""""""""""""
//TIME synchronization of the digital board
//"""""""""""""""""""""
Double_t shiftTime[4] ={0.0, 0.0 , 0.0, 0.0};
//"""""""""""""""""""""
//MAP
//"""""""""""""""""""""
//Left 0->15
//Right 16->31
//Individual{32=Grid, 33=S0, 34=cathode, 35=S17, 40-43 pulser},
//100=empty
int Map_DAQCha_to_MUSICStrip[4][16]={{34,100, 1, 100, 33, 40, 5, 100, 0, 100, 9, 100, 17, 13, 100, 32},
{2, 100, 16, 100, 21, 41, 20, 100, 8, 100, 24, 100, 27, 28, 100, 14},
{19, 100, 3, 100, 6, 42, 7, 100, 25, 100, 11, 100, 12, 15, 100, 31},
{4, 100, 18, 36, 23, 43, 22, 100, 10, 100, 26, 100, 29, 30, 100, 35}};
//"""""""""""""""""""""
//Data tree structure
//"""""""""""""""""""""
MUSICdata->SetBranchStatus("*", 0);
int MAX_MULTI =100;
unsigned short bd[MAX_MULTI] ;
unsigned short ch[MAX_MULTI] ;
unsigned long long e_t[MAX_MULTI] ;
MUSICdata->SetBranchStatus("ch", 1);MUSICdata->SetBranchAddress("ch", &ch);
MUSICdata->SetBranchStatus("bd", 1);MUSICdata->SetBranchAddress("bd", &bd);
MUSICdata->SetBranchStatus("e_t", 1);MUSICdata->SetBranchAddress("e_t", &e_t);
double Ibeam = 30000.;
int nStat = MUSICdata->GetEntries();
std::cout<<nStat<<std::endl;
//"""""""""""""""""""""
//time alignment
//"""""""""""""""""""""
TH2F* ChTimeBefore = new TH2F("ChTimeBefore", ";time(0.1 ms);channel(S0->LR16)",5000, 1000,1000+1,80,0,80);
Double_t* timestampVec = new Double_t[nStat]; Int_t* entryVec = new Int_t[nStat];
for(int j=0;j<nStat;j++){
MUSICdata->GetEntry(j);
ChTimeBefore->Fill((e_t[0]*1e-9)*1e+4 , bd[0]*16+ch[0]);
timestampVec[j]= (e_t[0] - shiftTime[bd[0]]*1e+9);
entryVec[j]=j;
}
quicksort(timestampVec, entryVec,0,nStat-1);
std::cout<<"sorted "<<std::endl;
int PositiveTime=0;
for(int j=0;j<nStat;j++){
if(timestampVec[j]>=0){
PositiveTime=j;
break;
}
}
//"""""""""""""""""""""
//checking synchronization
//"""""""""""""""""""""
Double_t TimeEv = timestampVec[PositiveTime]*1e-9;
//"""""""""""""""""""""
//Plot definition
//"""""""""""""""""""""
TH2F* ChTimeAfter = new TH2F("ChTimeAfter", ";time(0.1 ms);channel(S0->LR16)",5000, 1000, 1000+1,80,0,80);
for(int i=0;i<nStat;i++){
MUSICdata->GetEntry(entryVec[i]);
ChTimeAfter->Fill((timestampVec[i]*1e-9)*1e+4, bd[0]*16+ch[0]);
}
TCanvas* c= new TCanvas("c","c",800,800);c->Divide(1,2);
gStyle->SetPalette(kThermometer);
c->cd(1);ChTimeBefore->Draw("colz");
c->cd(2);ChTimeAfter->Draw("colz");
}

302
Analysis/timeshift.C Normal file
View File

@ -0,0 +1,302 @@
#include <iostream>
#include <TFile.h>
#include <TTree.h>
#include <TTreeReader.h>
#include <TStopwatch.h>
#include <TH1.h>
#include <TH2.h>
#include <TGraph.h>
#include <TRandom3.h>
#include <TCanvas.h>
TCanvas* cGraphs;
TCanvas* cProb;
void computeNSD2(TGraph* ref, TGraph* gr,
Double_t threshDT/*microsec*/,
Double_t OverlapTMin/*sec*/,
Double_t OverlapTMax/*sec*/,
Int_t& npts,
Double_t& NSD2)
{
NSD2 = 0;
npts = 0;
for (Long64_t p=0; p<ref->GetN(); p++) {
Double_t tref, dtref, dt;
ref->GetPoint(p, tref, dtref);
if (tref>=OverlapTMin && tref<=OverlapTMax && dtref>threshDT) {
dt = gr->Eval(tref);
// cout << i << " (" << tref << "," << yref << "," << y << ")" << endl;
NSD2 += pow(dt-dtref,2);
npts++;
}
}
if (NSD2>0) {
NSD2 = sqrt(NSD2);
NSD2 /= npts;
}
else
NSD2 = 1.0;
return;
}
Double_t findshift(TGraph* ref, TGraph* gr,
Double_t OverlapTMin/*sec*/,
Double_t OverlapTMax/*sec*/,
Double_t threshDT/*microsec*/)
{
Double_t shift = 0;
Int_t iterations = 0;
TGraph* grShifted = (TGraph*)gr->Clone("grShifted");
TRandom3 rdm;
Int_t npts = 0;
Double_t NSD2 = 0; // normalized sum of differences squared (NSD2)
Double_t prevNSD2 = 0;
Double_t NSD2min = 1;
Double_t tmin, tmax, aux;
Double_t tini;
TGraph* gInvNSD2 = new TGraph();
ref->GetPoint(0, tini, aux);
// First get a coarse distribution of the 1/NSD2
for (Int_t p=0; p<gr->GetN(); p++) {
npts = 0;
NSD2 = 0;
gr->GetPoint(p, shift, aux);
shift -= tini;
// shift the graph time
for (Long64_t ps=0; ps<gr->GetN(); ps++) {
Double_t tsec, dt;
gr->GetPoint(ps, tsec, dt);
grShifted->SetPoint(ps, tsec-shift, dt);
}
// check that the min/max times are within the overlap limits
grShifted->GetPoint(0, tmin, aux);
grShifted->GetPoint(grShifted->GetN()-1, tmax, aux);
if (tmin<OverlapTMin && tmax>OverlapTMax) {
// compute NSD2 of grShifted with respect to ref
computeNSD2(ref, grShifted, threshDT, OverlapTMin, OverlapTMax, npts, NSD2);
// cout << p << " ";
// cout.precision(10);
// cout << shift;
// cout << " " << npts << " " << NSD2 << endl;
// Fill histogram with inverse NSD2 whose GetRandom() method
// will serve guide the search for a precise time shift.
gInvNSD2->SetPoint(gInvNSD2->GetN(), shift, 1/NSD2);
}
// cout << shift << " " << tmin1 << " " << tmax1 << "\n" << npts << " " << NSD2 << endl;
}
// Retreive time shift with largest 1/NSD2
Double_t bestshift = 0; // return value
Double_t maxInvNSD2 = 0;
Double_t invNSD2 = 0;
for (Int_t i=0; i<gInvNSD2->GetN(); i++) {
gInvNSD2->GetPoint(i, shift, invNSD2);
if (invNSD2>maxInvNSD2) {
bestshift = shift;
maxInvNSD2 = invNSD2;
}
}
cProb = new TCanvas("cPorb","Prob");
gInvNSD2->Draw("al*");
return bestshift;
}
////////////////////////////////////////////////////////////////////////////////
// _______ _ _ _ __ _ //
// |__ __(_) | | (_)/ _| | //
// | | _ _ __ ___ ___ ___| |__ _| |_| |_ //
// | | | | '_ ` _ \ / _ \/ __| '_ \| | _| __| //
// | | | | | | | | | __/\__ \ | | | | | | |_ //
// |_| |_|_| |_| |_|\___||___/_| |_|_|_| \__| //
// //
// Main function of this code.
////////////////////////////////////////////////////////////////////////////////
int timeshift(
UShort_t Board=0, UShort_t Chan=5,
UShort_t minE=400, UShort_t maxE=600,
// UShort_t minE= 1800, UShort_t maxE=2300,
// UShort_t Board=1, UShort_t Chan=4,
// UShort_t minE= 1700, UShort_t maxE=2200,
// UShort_t Board=2, UShort_t Chan=4,
// UShort_t minE= 1500, UShort_t maxE=1900,
UShort_t refBoard=3, UShort_t refChan=5,
UShort_t refMinE= 400, UShort_t refMaxE=600,
Double_t OverlapTMin= 0.3/*sec*/,
Double_t OverlapTMax= 10,/*sec*///
Double_t threshDT= 100/*microsec*/, //80
Int_t MaxEntry=5000000, Int_t FindShift=1)
{
TString infile = "/home/bavarians/exp/test0/DAQ/run/RAW/DataR_run.root";
TFile* myFile = new TFile(infile);
TTree* tree = (TTree*)myFile->Get("Data_R");
tree->Print();
// Simple progress monitor
TStopwatch StpWatch;
Long64_t numEntries = tree->GetEntries();;
long double Frac[6];
int fIndex = 0;
Frac[0] = 0.01;
Frac[1] = 0.25;
Frac[2] = 0.5;
Frac[3] = 0.75;
Frac[4] = 0.9;
Frac[5] = 1.0;
TTreeReader theReader("Data_R", myFile);
TTreeReaderValue<ULong64_t> rvTimestamp(theReader, "Timestamp");
TTreeReaderValue<UShort_t> rvBoard = {theReader, "Board"};
TTreeReaderValue<UShort_t> rvChannel = {theReader, "Channel"};
TTreeReaderValue<UShort_t> rvEnergy = {theReader, "Energy"};
TTreeReaderValue<UInt_t> rvFlags = {theReader, "Flags"};
Long64_t nentries = theReader.GetEntries();
ULong64_t* ts0 = new ULong64_t[nentries]; // reference channel
ULong64_t* ts1 = new ULong64_t[nentries];
cout << "Extracting data from " << infile << " ..." << endl;
Long64_t entry = 0;
Long64_t e0 = 0;
Long64_t e1 = 0;
// Save the timestamps in arrays for selected channels using beam related events (energy cut)
while(theReader.Next() && entry<MaxEntry) {
if (*rvTimestamp/1e12<2*OverlapTMax) {
if (*rvBoard==refBoard && *rvChannel==refChan && *rvEnergy>refMinE && *rvEnergy<refMaxE) {
ts0[e0] = *rvTimestamp;
e0++;
}
else if (*rvBoard==Board && *rvChannel==Chan && *rvEnergy>minE && *rvEnergy<maxE) {
ts1[e1] = *rvTimestamp;
e1++;
}
}
}
cout << "Within the first " << 2*OverlapTMax << " seconds found:\n"
<< e0 << " entries of Board " << refBoard << " Chan " << refChan << "\n"
<< e1 << " entries of Board " << Board << " Chan " << Chan << "\n" << endl;
Double_t tshift = 0.0;// 7.2303 - 6.52073 + 0.00534 + 0.08806 + 0.00012; // run_17
// Make TGraphs for each channel taking only events with deltaT
// greater than a threshold value (in microseconds). This optimizes
// the timeshift search, focusing on the large deltaT peaks which
// are much less frequent and thus easy to spot.
TGraph* Delta0 = new TGraph();
Delta0->SetLineColor(kRed);
TGraph* Delta1 = new TGraph();
Delta1->SetLineColor(kBlue);
Double_t MaxDeltaT = 0;
for (Long64_t i=0; i<e0-1; i++) {
Double_t DTus = (ts0[i+1]-ts0[i])/1e6; // microseconds, hence 1/1e6
if (DTus>threshDT) {
Delta0->SetPoint(Delta0->GetN(), ts0[i]/1e12/*sec*/, DTus);
if (DTus>MaxDeltaT)
MaxDeltaT = DTus;
}
}
for (Long64_t i=0; i<e1-1; i++) {
Double_t DTus = (ts1[i+1]-ts1[i])/1e6; // microseconds, hence 1/1e6
if (DTus>threshDT) {
Delta1->SetPoint(Delta1->GetN(), ts1[i]/1e12-tshift, DTus);
if (DTus>MaxDeltaT)
MaxDeltaT = DTus;
}
}
Double_t tref, yref, y;
Double_t NSD2 = 0; // normalized sum of differences squared (NSD2)
Double_t NSD2min = 1;
Double_t tmin0, tmax0, tmin1, tmax1, tmin2, tmax2;
tmin0 = ts0[0]/1e12;
tmax0 = ts0[e0-1]/1e12;
tmin1 = ts1[0]/1e12;
tmax1 = ts1[e1-1]/1e12;
if (tmin0<=OverlapTMin && tmax0>=OverlapTMax && tmin1<=OverlapTMin && tmax1>=OverlapTMax) {
if (FindShift) {
cout << "executing findshift() ..." << endl;
tshift = findshift(Delta0, Delta1,
OverlapTMin, OverlapTMax, threshDT);
cout.precision(10);
cout << "best timeshift: " << tshift << " sec" << endl;
}
else {
// Just compute the
Int_t npts = 0;
computeNSD2(Delta0, Delta1, threshDT, OverlapTMin, OverlapTMax, npts, NSD2);
cout << tshift << " " << npts << " " << NSD2 << endl;
}
}
else
cout << "Need more entries for channel 0 or 2" << endl;
// Draw the graphs
cGraphs = new TCanvas("cGraphs","graphs");
TH2F* hbk = new TH2F("hbk","",10000,OverlapTMin, OverlapTMax, 20,0,1.2*MaxDeltaT);
hbk->GetXaxis()->SetTitle("Time [s]");
hbk->GetXaxis()->CenterTitle();
hbk->GetYaxis()->SetTitle("#DeltaT [#mus]");
hbk->GetYaxis()->CenterTitle();
TH2F* hba;
if (FindShift) {
cGraphs->Divide(1,2);
hbk->SetTitle("Before");
hba = new TH2F("hba","After",10000,OverlapTMin, OverlapTMax, 20,0,1.2*MaxDeltaT);
hba->GetXaxis()->SetTitle("Time [s]");
hba->GetXaxis()->CenterTitle();
hba->GetYaxis()->SetTitle("#DeltaT [#mus]");
hba->GetYaxis()->CenterTitle();
cGraphs->cd(1);
hbk->Draw();
Delta0->Draw("lp same");
TGraph* Delta1clone = (TGraph*)Delta1->Clone();Delta1clone->Draw("lp same");
cGraphs->cd(2);
hba->Draw();
Delta0->Draw("lp same");
for (Int_t i=0; i<Delta1->GetN(); i++) {
Double_t tsec, DTus;
Delta1->GetPoint(i, tsec, DTus);
Delta1->SetPoint(i, tsec-tshift, DTus);
}
Delta1->Draw("lp same");
}
else {
hbk->Draw();
Delta0->Draw("lp same");
Delta1->Draw("lp same");
}
return 0;
}

295
DAQ/Acquisition.cpp Normal file
View File

@ -0,0 +1,295 @@
#include "macro.h"
#include "ClassData.h"
#include "ClassDigitizer.h"
#include "influxdb.h"
#include <condition_variable>
#include <mutex>
#include <sys/time.h> /** struct timeval, select() */
#include <termios.h> /** tcgetattr(), tcsetattr() */
#include <vector>
#include <thread>
#include "TString.h"
#include "TSystem.h"
#include <iostream>
#include <fstream>
#define nDig 4
Digitizer * dig[4];
std::mutex mtx[nDig];
std::condition_variable cv;
bool ready = false;
bool stop_acquisition = false;
timespec ts[nDig];
static struct termios g_old_kbd_mode;
char* path_to_run="/home/bavarians/FSUDAQ_MUSIC/Run/";
char* path_to_DAQ="/home/bavarians/FSUDAQ_MUSIC/";
static void cooked(void){
tcsetattr(0, TCSANOW, &g_old_kbd_mode);
}
static void uncooked(void){
struct termios new_kbd_mode;
/** put keyboard (stdin, actually) in raw, unbuffered mode */
tcgetattr(0, &g_old_kbd_mode);
memcpy(&new_kbd_mode, &g_old_kbd_mode, sizeof(struct termios));
new_kbd_mode.c_lflag &= ~(ICANON | ECHO);
new_kbd_mode.c_cc[VTIME] = 0;
new_kbd_mode.c_cc[VMIN] = 1;
tcsetattr(0, TCSANOW, &new_kbd_mode);
}
static void raw(void){
static char init;
if(init) return;
/** put keyboard (stdin, actually) in raw, unbuffered mode */
uncooked();
/** when we exit, go back to normal, "cooked" mode */
atexit(cooked);
init = 1;
}
int keyboardhit(){
struct timeval timeout;
fd_set read_handles;
int status;
raw();
/** check stdin (fd 0) for activity */
FD_ZERO(&read_handles);
FD_SET(0, &read_handles);
timeout.tv_sec = timeout.tv_usec = 0;
status = select(0 + 1, &read_handles, NULL, NULL, &timeout);
if(status < 0){
printf("select() failed in keyboardhit()\n");
exit(1);
}
return (status);
}
int getch(void){
unsigned char temp;
raw();
/** stdin = fd 0 */
if(read(0, &temp, 1) != 1) return 0;
return temp;
}
void go() {
ready = true;
cv.notify_all();
}
void func(Digitizer * dig, double RunTime, int Rid, int Bid){
std::unique_lock<std::mutex> lck(mtx[Bid]);
while (!ready ){
printf("waiting for unlock %d\n", Bid);
cv.wait(lck);
}
cv.notify_all();
clock_gettime(CLOCK_REALTIME, &ts[Bid]);
printf("----thread %d ready. %ld ns\n", Bid, ts[Bid].tv_nsec);
dig->StartACQ();
if(RunTime>0){
unsigned long time;
unsigned long time0 = get_time();
do{
usleep(5*1000);
dig->ReadData();
dig->GetData()->DecodeBuffer(true,0);
//dig->GetData()->PrintStat();
//dig->GetData()->PrintData();
gSystem->cd(path_to_run);
dig->GetData()->SaveBuffer(Form("Run_%03u_B%01u",Rid, Bid));
time = get_time();
//printf("********************* time : %lu usec\n", time-time0);
}
while((time-time0)*1e-6<=(RunTime));
time = get_time();
//printf("********************* end time : %lu usec\n", time-time0);
dig->StopACQ();
}
if(RunTime<=0){
do{
usleep(5*1000);
dig->ReadData();
unsigned long time1 = get_time();
dig->GetData()->DecodeBuffer(true,0);
unsigned long time2 = get_time();
//dig->GetData()->PrintStat();
//dig->GetData()->PrintData();
gSystem->cd(path_to_run);
dig->GetData()->SaveBuffer(Form("Run_%03u_B%01u",Rid, Bid));
}
while(RunTime<=0 && !stop_acquisition);
dig->StopACQ();
}
printf("thread %d finished.\n", Bid);
}
void boardSetParameters(int BI, Digitizer * dig, double BoardConfigurationval, double DPPAlgoCtrl, double DPPAlgoCtrl_10A0,double DPPAlgoCtrl_10AC, double ShapedTriggerWidthVal, double InputSec[7], double DiscriSec[4], double TrapSec[7]){
//ALL channels
//GENERAL
dig->WriteRegister(Register::DPP::BoardConfiguration, BoardConfigurationval); //Reg=0x8000
dig->WriteRegister(Register::DPP::DPPAlgorithmControl, DPPAlgoCtrl);//Reg=0x1080
dig->WriteRegister(Register::DPP::PHA::DPPAlgorithmControl2_G, DPPAlgoCtrl_10A0); //Reg=0x10A0
dig->WriteRegister(Register::DPP::PHA::DPPAlgorithmControl22_G, DPPAlgoCtrl_10AC); //Reg=0x10AC
//Input Section
dig->WriteRegister(Register::DPP::RecordLength_G, InputSec[1]); //Reg=0x1020
//Syncrhonization Section
//Trigger/Veto/coinc Section
dig->WriteRegister(Register::DPP::PHA::ShapedTriggerWidth, ShapedTriggerWidthVal); //Reg=0x1084
//Miscellaneaous Section
//per channel
for(int i=0;i<16;i++){
//GENERAL
//Input Section
dig->WriteRegister(Register::DPP::PreTrigger, InputSec[2], i);//Reg=0x1038
dig->WriteRegister(Register::DPP::ChannelDCOffset, InputSec[5], i);//Reg=0x1098
dig->WriteRegister(Register::DPP::InputDynamicRange, InputSec[6], i);//Reg=0x1028
//Discriminator Section
dig->WriteRegister(Register::DPP::PHA::TriggerThreshold,DiscriSec[0], i);//Reg=0x106C
dig->WriteRegister(Register::DPP::PHA::TriggerHoldOffWidth, DiscriSec[1], i);//Reg=0x1074
dig->WriteRegister(Register::DPP::PHA::RCCR2SmoothingFactor,DiscriSec[2], i);//Reg=0x1054
dig->WriteRegister(Register::DPP::PHA::InputRiseTime, DiscriSec[3], i);//Reg=0x1058
//Trapezoid Section
dig->WriteRegister(Register::DPP::PHA::TrapezoidRiseTime,TrapSec[0], i);//Reg=0x105C
dig->WriteRegister(Register::DPP::PHA::TrapezoidFlatTop, TrapSec[1], i);//Reg=0x1060
dig->WriteRegister(Register::DPP::PHA::DecayTime, TrapSec[2], i);//Reg=0x1068
dig->WriteRegister(Register::DPP::PHA::PeakingTime,TrapSec[3], i);//Reg=0x1064
dig->WriteRegister(Register::DPP::PHA::PeakHoldOff,TrapSec[5], i);//Reg=0x1078
dig->WriteRegister(Register::DPP::PHA::FineGain,TrapSec[6], i);//Reg=0x10C4
}
}
void boardCommonParameters(Digitizer * dig){
//all channels
dig->WriteRegister(Register::DPP::TriggerValidationMask_G , 0x00000000);//Reg=0x8100
//per channels
for(int i=0;i<16;i++){
dig->WriteRegister(Register::DPP::PHA::RiseTimeValidationWindow, 0x00000000, i);//Reg=0x1070
dig->WriteRegister(Register::DPP::VetoWidth, 0x0000000A, i);//Reg=0x10D4
dig->WriteRegister(Register::DPP::Scratch, 0xAAAAAAAA, i);//Reg=0xEF20
dig->WriteRegister(Register::DPP::InterruptEventNumber, 0x00000000,i);//Reg=0xEF18
dig->WriteRegister(Register::DPP::InterruptStatusID, 0x000000DD,i);//Reg=0xEF14
dig->WriteRegister(Register::DPP::RelocationAddress, 0x00000000,i);//Reg=0xEF10
dig->WriteRegister(Register::DPP::MCSTBaseAddressAndControl , 0x000000AA, i);//Reg=0xEF0C
dig->WriteRegister(Register::DPP::ReadoutControl, 0x00000010, i);//Reg=0xEF00
dig->WriteRegister(Register::DPP::ExtendedVetoDelay, 0x12340014,i);//Reg=0x81C4
dig->WriteRegister(Register::DPP::BufferOccupancyGain , 0x00000000, i);//Reg=0x81B4
dig->WriteRegister(Register::DPP::FrontPanelLVDSIONewFeatures , 0x00001111, i);//Reg=0x81A0
dig->WriteRegister(Register::DPP::RunStartStopDelay , 0x00000000, i);//Reg=0x8170
dig->WriteRegister(Register::DPP::DisableExternalTrigger, 0x00000000,i);//Reg=0x817C
dig->WriteRegister(Register::DPP::FanSpeedControl, 0x00000020, i);//Reg=0x8168
dig->WriteRegister(Register::MemoryBufferAlmostFullLevel, 0x00000000, i);//Reg=0x816C
dig->WriteRegister(Register::DPP::AcquisitionControl, 00000000,i);//Reg=0x8100
dig->WriteRegister(Register::DPP::GlobalTriggerMask, 0x80000000,i);//Reg=0x810C
dig->WriteRegister(Register::DPP::FrontPanelTRGOUTEnableMask, 0x00000000, i);//Reg=0x8110
dig->WriteRegister(Register::DPP::LVDSIOData, 0x0000FFFF, i);//Reg=0x8118
dig->WriteRegister(Register::DPP::FrontPanelIOControl, 0x00008100, i);//Reg=0x811C
dig->WriteRegister(Register::DPP::ChannelEnableMask, 0x0000FFFF, i);//Reg=0x8120
dig->WriteRegister(Register::DPP::VoltageLevelModeConfig, 0x00000000, i);//Reg=0x8138
dig->WriteRegister(Register::DPP::AnalogMonitorMode, 0x00000000, i);//Reg=0x8144
}
}
int main(int argc, char* argv[]){
printf("=====================================\n");
printf("=== FSU DAQ ===\n");
printf("=====================================\n");
if (argc < 2) {
printf("Incorrect number of arguments:\n");
printf("%s [RunTime] [RunId] \n", argv[0]);
printf(" RunTime in sec, default = -1 if unstoppped \n");
return 1;
}
double RunTime = atoi(argv[1]);
int Rid= atoi(argv[2]);
//""""""""""""""""""""""""""""""
//Opening digitizers
//""""""""""""""""""""""""""""""
for(int d=0;d<nDig;d++){
dig[d] = new Digitizer(0, d, false, true);
}
//""""""""""""""""""""""""""""""
//Register value assignment
//""""""""""""""""""""""""""""""
double BoardConfigurationval[4] ={0x014E8905,0x014E0105,0x014E0105,0x014E0105}; //Reg=8000
double DPPAlgoCtrl[4] ={0x0831200E,0x0831200E,0x0831200E,0x0831200E}; //Reg=1080
double DPPAlgoCtrl_10A0[4] ={0x00000000,0x00000000,0x00000000,0x00000000}; //Reg=10A0
double DPPAlgoCtrl_10AC[4] ={0x0010010E,0x0010010E,0x0010010E,0x0010010E}; //Reg=10AC
double ShapedTriggerWidthVal = 6; //Reg=1084 in steps of 16ns
//1==RecordLength input N such length (ns) == N*8*4 , 2==PreTrigger input N such length (ns) == N*4*4
//5==DCoffset DC% = 1 - input/65535, 6==CoarseGain 0=x1 or 1=x4
double InputSec[4][7] ={ {0, 375, 200,0,0,0x00004CCC, 0},
{0, 375, 200,0,0,0x00004CCC, 0},
{0, 375, 200,0,0,0x00004CCC, 0},
{0, 375, 200,0,0,0x00004CCC, 0}};
//0==TriggerThreshold in lsb, 1==TriggerHoldOffWidth in steps of 16ns, 2==FastDiscriSmooth (20=64samp, 63=128samp),
// 3==InputRiseTime in steps of 16ns, 144=9*16 ns
double DiscriSec[4][4]={ {100, 30, 63, 56},
{100, 30, 63, 56},
{100, 30, 63, 56},
{100, 30, 63, 56}};
//0==RiseTime in steps of 16ns, 496=31*16, 1==FlatTop in steps of 16ns, 2=PoleZero in steps of 16ns
//3==PeakingTime in steps of 16ns, 60% of flat top, 5==PeakHoldOff in steps of 16ns, fine gain 1==0x00006C3A
double TrapSec[4][7]={{31, 187, 625,94, 0, 62, 0x00006C3A},
{31, 187, 625,94, 0, 62, 0x00006C3A},
{31, 187, 625,94, 0, 62, 0x00006C3A},
{31, 187, 625,94, 0, 62, 0x00006C3A}};
for( int i = 0; i < nDig; i++){
dig[i]->ProgramPHABoard();
dig[i]->ReadAllSettingsFromBoard();
dig[i]->WriteRegister(Register::DPP::SoftwareClear_W, 1);
dig[i]->WriteRegister(Register::DPP::MaxAggregatePerBlockTransfer, 40);//80 Reg=0xEF1C
dig[i]->WriteRegister(Register::DPP::NumberEventsPerAggregate_G, 511);//1023-->forced in WriteRegisterFromFile Reg=0x1034
printf("========== %d \n", dig[i]->ReadSettingFromFile(Register::DPP::MaxAggregatePerBlockTransfer));
boardSetParameters(i, dig[i], BoardConfigurationval[i],DPPAlgoCtrl[i], DPPAlgoCtrl_10A0[i],DPPAlgoCtrl_10AC[i], ShapedTriggerWidthVal, InputSec[i], DiscriSec[i], TrapSec[i] );
boardCommonParameters(dig[i]);
dig[i]-> SaveAllSettingsAsText(Form("reg_Board%i.txt",i));
dig[i]->GetData()->SetSaveWaveToMemory(false);
}
//""""""""""""""""""""""""""""""
//Parallel digitizer data taking
//""""""""""""""""""""""""""""""
std::thread fdig[nDig];
for (int i = 0; i < nDig; ++i){
fdig[i] = std::thread(func, dig[i],RunTime , Rid, i);
}
printf("%d threads ready to race...\n", nDig);
usleep(1000*1000);
if(RunTime<=0){
printf("Enter to stop ..\n");
if(getchar()){stop_acquisition=true;}
}
go();
for (auto& f : fdig) f.join();
printf("=========== finsihed.\n");
long avg = 0;
for( int i =0; i < nDig ; i++) avg += ts[i].tv_nsec;
avg = avg/nDig;
long min , max;
for( int i =0; i < nDig; i++) {
if( i == 0 ){
min = ts[i].tv_nsec;
max = ts[i].tv_nsec;
continue;
}
if( min > ts[i].tv_nsec) min = ts[i].tv_nsec;
if( max < ts[i].tv_nsec) max = ts[i].tv_nsec;
}
printf(" avg : %ld\n", avg);
printf(" min : %ld, %ld\n", min, avg - min);
printf(" max : %ld, %ld\n", max, max - avg);
printf(" diff : %ld\n", max-min);
for(int i=0;i<nDig;i++){delete dig[i];}
return 0;
}

View File

@ -13,7 +13,8 @@
#include "CAENDigitizerType.h"
#include "macro.h"
#define MaxNData 10000 /// 10k events per channels
#define MaxNData 100000 /// N events per channels
#define ch2ns_value 4.0
class Data{
@ -94,7 +95,7 @@ class Data{
//==========================================
inline Data::Data(){
ch2ns = 2.0;
ch2ns = ch2ns_value;
boardSN = 0;
DPPType = V1730_DPP_PHA_CODE;
IsNotRollOverFakeAgg = false;
@ -166,14 +167,14 @@ inline void Data::CopyBuffer(const char * buffer, const unsigned int size){
inline void Data::SaveBuffer(const char * fileName){
char saveFileName[100];
sprintf(saveFileName, "%s_%03d_%03d_%03u.fsu", fileName , boardSN, DPPType, saveFileIndex);
sprintf(saveFileName, "%s_%03u.fsu", fileName, saveFileIndex);
FILE * haha = fopen(saveFileName, "a+");
fseek(haha, 0L, SEEK_END);
unsigned int inFileSize = ftell(haha); /// unsigned int = Max ~ 4 GB
unsigned int inFileSize = ftell(haha); /// unsigned int = Max ~ 1 GB
///printf("file Size = %u Byte\n", inFileSize);
if( inFileSize > (unsigned int)MaxSaveFileSize ) { /// 2 GB
if( inFileSize > (unsigned int)MaxSaveFileSize ) { /// 1 GB
fclose(haha);
saveFileIndex ++;
sprintf(saveFileName, "%s_%03u.fsu", fileName , saveFileIndex);
@ -212,7 +213,7 @@ inline void Data::PrintBuffer() const{
inline void Data::PrintData() const{
printf("============================= Print Data\n");
for( int ch = 0; ch < MaxNChannels ; ch++){
if( NumEvents[ch] == 0 ) continue;
if(NumEvents[ch] == 0 ) continue;
printf("------------ ch : %d, %d \n", ch, NumEvents[ch]);
for( int ev = 0; ev < NumEvents[ch] ; ev++){
printf("%4d, %5u, %15llu, %5u \n", ev, Energy[ch][ev], Timestamp[ch][ev], fineTime[ch][ev]);
@ -277,7 +278,6 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){
nw = nw + 1;
unsigned int bdAggCounter = ReadBuffer(nw, verbose);
if( verbose >= 1 ) printf("Board Agg Counter : %u \n", bdAggCounter & 0x7FFFFF);
nw = nw + 1;
unsigned int bdAggTimeTag = ReadBuffer(nw, verbose);
if( verbose >= 2 ) printf("Agg Counter : %u \n", bdAggTimeTag);
@ -285,7 +285,6 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){
for( int chMask = 0; chMask < MaxNChannels/2 ; chMask ++ ){
if( ((ChannelMask >> chMask) & 0x1 ) == 0 ) continue;
if( verbose >= 2 ) printf("==================== Dual Channel Block, ch Mask : %d, nw : %d\n", chMask *2, nw);
if( DPPType == V1730_DPP_PHA_CODE ) {
if ( DecodePHADualChannelBlock(chMask, fastDecode, verbose) < 0 ) break;
}
@ -298,9 +297,8 @@ inline void Data::DecodeBuffer(bool fastDecode, int verbose){
break;
}
nw++;
///printf("nw : %d ,x 4 = %d, nByte : %d \n", nw, 4*nw, nByte);
//printf("nw : %d ,x 4 = %d, nByte : %d \n", nw, 4*nw, nByte);
}while(4*nw < nByte);
///Calculate trigger rate and first and last Timestamp
for(int ch = 0; ch < MaxNChannels; ch++){
if( NumEventsDecoded[ch] > 0 ) IsNotRollOverFakeAgg = true;

View File

@ -328,8 +328,8 @@ void Digitizer::StartACQ(){
if ( AcqRun ) return;
unsigned int bufferSize = CalByteForBuffer();
if( bufferSize > 80 * 1024 * 1024 ){
printf("============= buffer size bigger than 80 MB");
if( bufferSize > 800 * 1024 * 1024 ){
printf("============= buffer size bigger than 800 MB");
return;
}
@ -341,7 +341,7 @@ void Digitizer::StartACQ(){
return;
}
printf("\e[1m\e[33m======= Acquisition Started for Board %d\e[0m\n", boardID);
printf("\e[1m\e[33m======= Acquisition Started for Board %d - %d \e[0m\n", boardID,portID);
AcqRun = true;
data->ClearTriggerRate();
}
@ -351,7 +351,7 @@ void Digitizer::StopACQ(){
int ret = CAEN_DGTZ_SWStopAcquisition(handle);
ret |= CAEN_DGTZ_ClearData(handle);
if( ret != 0 ) ErrorMsg("something wrong when try to stop ACQ and clear buffer");
printf("\n\e[1m\e[33m====== Acquisition STOPPED for Board %d\e[0m\n", boardID);
printf("\n\e[1m\e[33m====== Acquisition STOPPED for Board %d - %d \e[0m\n", boardID,portID);
AcqRun = false;
data->ClearTriggerRate();
}

View File

@ -91,6 +91,7 @@ class Digitizer{
/// ONLY WriteRegister can have ch = -1, for writting all channels
/// for board setting, ignore ch
void WriteRegister (Reg registerAddress, uint32_t value, int ch = -1, bool isSave2MemAndFile = true);
/// read value from digitizer and memory, and save to memory, and settingFile(if exist),
/// for board setting, ignore ch
uint32_t ReadRegister (Reg registerAddress, unsigned short ch = 0, bool isSave2MemAndFile = true, std::string str = "" );

View File

@ -1,25 +1,38 @@
#include "macro.h"
#include "ClassData.h"
#include <iostream>
#include <fstream>
#include "TROOT.h"
#include "TSystem.h"
#include "TClonesArray.h"
#include "TGraph.h"
#include "TFile.h"
#include "TTree.h"
#include "TSystem.h"
#define MAX_MULTI 100
#define MAX_File 100
#define NTimeWinForBuffer 3
char* path_to_run="/home/bavarians/FSUDAQ_MUSIC/Run/";
char* path_to_DAQ="/home/bavarians/FSUDAQ_MUSIC/";
char* path_to_con="/home/bavarians/FSUDAQ_MUSIC/Conversion/";
char* path_to_top="/home/bavarians/FSUDAQ_MUSIC/MUSIC_Topology/";
TFile * outRootFile = NULL;
TTree * tree = NULL;
unsigned long long evID = 0;
unsigned short multi = 0;
unsigned short bd[MAX_MULTI] = {0}; /// boardID
unsigned short ch[MAX_MULTI] = {0}; /// chID
unsigned short e[MAX_MULTI] = {0}; /// 15 bit
unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit
unsigned short multi_evt=0;
unsigned short multi_hit=0;
unsigned short stp0[MAX_MULTI] = {0}; /// 15 bit
unsigned short stp17[MAX_MULTI] = {0}; /// 15 bit
unsigned short grid[MAX_MULTI] = {0}; /// 15 bit
unsigned short cath[MAX_MULTI] = {0}; /// 15 bit
unsigned short de_l[MAX_MULTI][16] = {{0}}; /// 15 bit
unsigned short de_r[MAX_MULTI][16] = {{0}}; /// 15 bit
unsigned short puls[MAX_MULTI][4] = {{0}}; /// 15 bit
unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit --> to get en sec *2e-9
unsigned short e_f[MAX_MULTI] = {0}; /// fine time 10 bit
/// using TClonesArray to hold the trace in TGraph
@ -30,7 +43,8 @@ TGraph * trace = NULL;
template<typename T> void swap(T * a, T *b );
int partition(int arr[], int kaka[], TString file[], int start, int end);
void quickSort(int arr[], int kaka[], TString file[], int start, int end);
void EventBuilder(Data * data, const unsigned int timeWin, bool traceOn = false, bool isLastData = false, unsigned int verbose = 0);
void extraction_map(int map[4][16]);
void EventBuilder(Data * data[],int nFile, const unsigned int timeWin, bool traceOn = false, bool isLastData = false, unsigned int verbose = 0);
int main(int argc, char **argv) {
@ -40,19 +54,17 @@ int main(int argc, char **argv) {
if (argc <= 3) {
printf("Incorrect number of arguments:\n");
printf("%s [timeWindow] [traceOn/Off] [verbose] [inFile1] [inFile2] .... \n", argv[0]);
printf(" timeWindow : number of tick, 1 tick. default = 100 \n");
printf(" timeWindow : in microsecond, default = 1 \n");
printf(" traceOn/Off : is traces stored \n");
printf(" verbose : > 0 for debug \n");
printf(" Output file name is contructed from inFile1 \n");
return 1;
}
/// File format must be YYY...Y_runXXX_AAA_BBB_CCC.fsu
/// YYY...Y = prefix
/// XXX = runID, 3 digits
/// AAA = board Serial Number, 3 digits
/// BBB = DPPtype, 3 digits
/// CCC = over size index, 3 digits
/// File format must be Run_XXX_BB_YYY.fsu
/// XXX = 3 digits, run number
/// BB = board number, 2 digits
/// YYY = over size index, 3 digits
///============= read input
unsigned int timeWindow = atoi(argv[1]);
@ -68,7 +80,8 @@ int main(int argc, char **argv) {
TString outFileName = inFileName[0];
int pos = outFileName.Index("_");
pos = outFileName.Index("_", pos+1);
outFileName.Remove(pos);
outFileName.Remove(pos);
outFileName += Form("_%03u",atoi(&inFileName[0][inFileName[0].Index("B")+5]));
outFileName += ".root";
printf("-------> Out file name : %s \n", outFileName.Data());
@ -125,16 +138,27 @@ int main(int argc, char **argv) {
}
///============= Set Root Tree
gSystem->cd(path_to_con);
outRootFile = new TFile(outFileName, "recreate");
// gSystem->cd(path_to_DAQ);
tree = new TTree("tree", outFileName);
tree->Branch("evID", &evID, "event_ID/l");
tree->Branch("multi", &multi, "multi/s");
tree->Branch("bd", bd, "bd[multi]/s");
tree->Branch("ch", ch, "ch[multi]/s");
tree->Branch("e", e, "e[multi]/s");
tree->Branch("e_t", e_t, "e_timestamp[multi]/l");
tree->Branch("e_f", e_f, "e_timestamp[multi]/s");
tree->Branch("multi_evt", &multi_evt, "multi_evt/s");
tree->Branch("multi_hit", &multi_hit, "multi_hit/s");
tree->Branch("de_l", de_l, "de_l[multi_evt][16]/s");
tree->Branch("de_r", de_r, "de_r[multi_evt][16]/s");
tree->Branch("stp0", stp0, "stp0[multi_evt]/s");
tree->Branch("stp17", stp17, "stp17[multi_evt]/s");
tree->Branch("grid", grid, "grid[multi_evt]/s");
tree->Branch("cath", cath, "cath[multi_evt]/s");
tree->Branch("puls", puls, "puls[multi_evt][4]/s");
tree->Branch("e_t", e_t, "e_timestamp[multi_evt]/l");
tree->Branch("e_f", e_f, "e_timestamp[multi_evt]/s");
for(int ev=0;ev<MAX_MULTI;ev++){
stp0[ev]=0.;stp17[ev]=0;grid[ev]=0;cath[ev]=0;
for(int b=0;b<nFile;b++){puls[ev][b]=0.;}
for(int c=0;c<MaxNChannels;c++){de_l[ev][c]=0.;de_r[ev][c]=0.;}
}
if( traceOn ) {
arrayTrace = new TClonesArray("TGraph");
tree->Branch("traceLength", traceLength, "traceLength[multi]/s");
@ -142,235 +166,283 @@ int main(int argc, char **argv) {
arrayTrace->BypassStreamer();
}
///============= Open input Files
///============= Open input Files
printf("##############################################\n");
FILE * haha = fopen(fileCat[0][0], "r");
if( haha == NULL ){
printf("#### Cannot open file : %s. Abort.\n", fileCat[0][0].Data());
return -1;
}
fseek(haha, 0L, SEEK_END);
const size_t inFileSize = ftell(haha);
printf("%s | file size : %d Byte = %.2f MB\n", fileCat[0][0].Data(), (int) inFileSize, inFileSize/1024./1024.);
fclose(haha);
gSystem->cd(path_to_run);
Data * data = new Data();
data->DPPType = typeCat[0][0];
data->boardSN = idCat[0];
data->SetSaveWaveToMemory(true);
printf("#### number of files: %i \n", nFile);
FILE * haha[nFile];
size_t inFileSize[nFile];
for( int i = 0; i < nFile; i++){
haha[i]= fopen(fileCat[i][0], "r");
if( haha[i] == NULL ){
printf("#### Cannot open file : %s. Abort.\n", fileCat[i][0].Data());
return -1;
}
fseek(haha[i], 0L, SEEK_END);
inFileSize[i] = ftell(haha[i]);
printf("%s | file size : %d Byte = %.2f MB\n", fileCat[i][0].Data(), (int) inFileSize[i], inFileSize[i]/1024./1024.);
fclose(haha[i]);
}
///============= Main Loop
haha = fopen(inFileName[0], "r");
gSystem->cd(path_to_run);
int countBdAgg = 0;
unsigned long currentTime = 0;
unsigned long oldTime = 0;
char * buffer = NULL;
Data * data[nFile];
for( int i = 0; i < nFile; i++){
haha[i] = fopen(inFileName[i], "r");
data[i] = new Data();
data[i]->DPPType ;
data[i]->boardSN = atoi(&inFileName[i][inFileName[i].Index("B")+1]);
data[i]->SetSaveWaveToMemory(true);
}
int end_of_loop=1;
do{
for( int i = 0; i < nFile; i++){
// haha[i] = fopen(inFileName[i], "r");
///========== Get 1 aggreration for each file
oldTime = get_time();
if( debug) printf("*********************** file pos : %d, %lu\n", (int) ftell(haha[i]), oldTime);
unsigned int word[1]; /// 4 bytes
size_t dump = fread(word, 4, 1, haha[i]);
fseek(haha[i], -4, SEEK_CUR);
///========== Get 1 aggreration
oldTime = get_time();
if( debug) printf("*********************** file pos : %d, %lu\n", (int) ftell(haha), oldTime);
unsigned int word[1]; /// 4 bytes
size_t dump = fread(word, 4, 1, haha);
fseek(haha, -4, SEEK_CUR);
short header = ((word[0] >> 28 ) & 0xF);
if( header != 0xA ) break;
short header = ((word[0] >> 28 ) & 0xF);
if( header != 0xA ) break;
unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte
unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte
if( debug) printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize);
if( debug) printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize);
buffer = new char[aggSize];
dump = fread(buffer, aggSize, 1, haha);
countBdAgg ++;
if( debug) printf("==================== %d Agg\n", countBdAgg);
buffer = new char[aggSize];
dump = fread(buffer, aggSize, 1, haha[i]);
countBdAgg ++;
if( debug) printf("==================== %d Agg\n", countBdAgg);
data[i]->DecodeBuffer(buffer, aggSize,false, 0);//false
if(!data[i]->IsNotRollOverFakeAgg ) continue;
currentTime = get_time();
if( debug) {
printf("~~~~~~~~~~~~~~~~ time used : %lu usec\n", currentTime - oldTime);
}
}
EventBuilder(data, nFile, timeWindow, traceOn, false, debug);
data->DecodeBuffer(buffer, aggSize, false, 0);
data->ClearBuffer();
if( !data->IsNotRollOverFakeAgg ) continue;
currentTime = get_time();
if( debug) {
printf("~~~~~~~~~~~~~~~~ time used : %lu usec\n", currentTime - oldTime);
data->PrintStat();
}
EventBuilder(data, timeWindow, traceOn, false, debug);
if( debug) printf("---------- event built : %llu \n", evID);
//if( countBdAgg > 74) break;
}while(!feof(haha) && ftell(haha) < inFileSize);
fclose(haha);
for( int i = 0; i < nFile; i++){
data[i]->ClearBuffer();
//if( countBdAgg > 74) break;
end_of_loop= end_of_loop*(!feof(haha[i]) && ftell(haha[i]) < inFileSize[i]);
}
}while(end_of_loop==1);
for( int i = 0; i < nFile; i++){ fclose(haha[i]);}
printf("=======@@@@@@@@###############============= end of loop \n");
EventBuilder(data, timeWindow, traceOn, true, debug);
EventBuilder(data, nFile,timeWindow, traceOn, true, debug);
gSystem->cd(path_to_con);
tree->Write();
outRootFile->Close();
printf("========================= finsihed.\n");
printf("total events built = %llu \n", evID);
printf("=======> saved to %s \n", outFileName.Data());
}
void EventBuilder(Data * data, const unsigned int timeWin, bool traceOn, bool isLastData, unsigned int verbose){
void EventBuilder(Data * data[],int nFile, const unsigned int timeWin, bool traceOn, bool isLastData, unsigned int verbose){
if( verbose) {
printf("======================== Event Builder \n");
data->PrintData();
}
///============= Set MUSIC DAQ Topology
int map[4][16];
extraction_map(map);
int temp_index=0;double tempEn;
/// find the last event timestamp;
unsigned long long firstTimeStamp = -1;
unsigned long long lastTimeStamp = 0;
unsigned long long smallestLastTimeStamp = -1;
unsigned int maxNumEvent = 0;
for( int chI = 0; chI < MaxNChannels ; chI ++){
if( data->NumEvents[chI] == 0 ) continue;
if( data->Timestamp[chI][0] < firstTimeStamp ) {
firstTimeStamp = data->Timestamp[chI][0];
}
unsigned short ev = data->NumEvents[chI]-1;
if( data->Timestamp[chI][ev] > lastTimeStamp ) {
lastTimeStamp = data->Timestamp[chI][ev];
}
if( ev + 1 > maxNumEvent ) maxNumEvent = ev + 1;
if( data->Timestamp[chI][ev] < smallestLastTimeStamp ){
smallestLastTimeStamp = data->Timestamp[chI][ev];
}
}
if( maxNumEvent == 0 ) return;
if( verbose) printf("================ time range : %llu - %llu, smallest Last %llu\n", firstTimeStamp, lastTimeStamp, smallestLastTimeStamp );
unsigned short lastEv[MaxNChannels] = {0}; /// store the last event number for each ch
unsigned short exhaustedCh = 0; /// when exhaustedCh == MaxNChannels ==> stop
bool singleChannelExhaustedFlag = false; /// when a single ch has data but exhaused ==> stop
do {
/// find the 1st event
int ch1st = -1;
unsigned long long time1st = -1;
for( int chI = 0; chI < MaxNChannels ; chI ++){
if( data->NumEvents[chI] == 0 ) continue;
if( data->NumEvents[chI] <= lastEv[chI] ) continue;
if( data->Timestamp[chI][lastEv[chI]] < time1st ) {
time1st = data->Timestamp[chI][lastEv[chI]];
ch1st = chI;
}
}
if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) && maxNumEvent < MaxNData * 0.6 ) break;
if( ch1st > MaxNChannels ) break;
multi ++;
bd[multi-1] = data->boardSN;
ch[multi-1] = ch1st;
e[multi-1] = data->Energy[ch1st][lastEv[ch1st]];
e_t[multi-1] = data->Timestamp[ch1st][lastEv[ch1st]];
e_f[multi-1] = data->fineTime[ch1st][lastEv[ch1st]];
if( traceOn ){
arrayTrace->Clear("C");
traceLength[multi-1] = (unsigned short) data->Waveform1[ch1st][lastEv[ch1st]].size();
///if( verbose )printf("------- trace Length : %u \n", traceLength[multi-1]);
trace = (TGraph *) arrayTrace->ConstructedAt(multi-1, "C");
trace->Clear();
for( int hh = 0; hh < traceLength[multi-1]; hh++){
trace->SetPoint(hh, hh, data->Waveform1[ch1st][lastEv[ch1st]][hh]);
///if( verbose )if( hh % 200 == 0 ) printf("%3d | %u \n", hh, data->Waveform1[ch1st][lastEv[ch1st]][hh]);
}
}
lastEv[ch1st] ++;
long long firstTimeStamp = -1;
unsigned long long lastTimeStamp = 0;
long long smallestLastTimeStamp = -1;
unsigned int maxNumEvent[nFile] ;
for( int b = 0; b < nFile ; b++){
maxNumEvent[b] = 0;
for( int chI = 0; chI < MaxNChannels ; chI ++){
if(data[b]->NumEvents[chI] == 0 ) continue;
if(data[b]->Timestamp[chI][0] < firstTimeStamp ) {
firstTimeStamp = data[b]->Timestamp[chI][0];
}
unsigned short ev = data[b]->NumEvents[chI]-1;
if( data[b]->Timestamp[chI][ev] > lastTimeStamp ) {
lastTimeStamp = data[b]->Timestamp[chI][ev];
}
if( ev + 1 > maxNumEvent[b] ) maxNumEvent[b] = ev + 1;
if( data[b]->Timestamp[chI][ev] < smallestLastTimeStamp ){
smallestLastTimeStamp = data[b]->Timestamp[chI][ev];
}
}
if( maxNumEvent[b] == 0 ) return;
}
if( verbose) printf("================ time range : %llu - %llu, smallest Last %llu\n", firstTimeStamp, lastTimeStamp, smallestLastTimeStamp);
unsigned short lastEv[nFile][MaxNChannels] = {0}; /// store the last event number for each ch
unsigned short exhaustedCh[nFile] = {0}; /// when exhaustedCh == MaxNChannels ==> stop
bool singleChannelExhaustedFlag[nFile] = {false}; /// when a single ch has data but exhaused ==> stop
unsigned short exhaustedBd = 0;
bool BoardExhaustedFlag[nFile] = {false};
for( int b = 0; b < nFile ; b++){
singleChannelExhaustedFlag[b]=false;
exhaustedCh[b]=0;
for( int c = 0; c < MaxNChannels; c++){
lastEv[b][c]=0;
}
}
do {
/// find the 1st event
unsigned long long time1st=-1;
int ch1st=-1; int b1st=-1;
for( int b = 0; b < nFile ; b++){
for( int chI = 0; chI < MaxNChannels ; chI ++){
if( data[b]->NumEvents[chI] == 0 ) continue;
if( data[b]->NumEvents[chI] <= lastEv[b][chI] ) continue;
if( data[b]->Timestamp[chI][lastEv[b][chI]] < time1st ) {
time1st= data[b]->Timestamp[chI][lastEv[b][chI]];
ch1st = chI; b1st=b;
}
}
}
//&& maxNumEvent[b] < MaxNData * 0.6
if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) ) break;
if( ch1st > MaxNChannels ) break;
if( b1st < 0 ) break;
temp_index= map[b1st][ch1st];
if(temp_index>=0){
e_t[multi_evt]= data[b1st]->Timestamp[ch1st][lastEv[b1st][ch1st]];
e_f[multi_evt]= data[b1st]->fineTime[ch1st][lastEv[b1st][ch1st]];
tempEn=data[b1st]->Energy[ch1st][lastEv[b1st][ch1st]];
if(temp_index<16){de_l[multi_evt][temp_index] = tempEn;}
if(temp_index<32 && temp_index>15){ de_r[multi_evt][temp_index] = tempEn; }
if(temp_index==500){stp0[multi_evt]= tempEn;}
if(temp_index==501){stp17[multi_evt]= tempEn;}
if(temp_index==502){grid[multi_evt]= tempEn;}
if(temp_index==503){cath[multi_evt]= tempEn;}
if(temp_index==504){puls[multi_evt][b1st]= tempEn;}
multi_hit++;
}
if( traceOn ){
arrayTrace->Clear("C");
traceLength[multi_evt] = (unsigned short) data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]].size();
trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C");
trace->Clear();
for( int hh = 0; hh < traceLength[multi_evt]; hh++){
trace->SetPoint(hh, hh, data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]][hh]);
}
}
lastEv[b1st][ch1st] ++;
/// build the rest of the event
exhaustedCh = 0;
singleChannelExhaustedFlag = false;
for( int chI = ch1st; chI < ch1st + MaxNChannels; chI ++){
unsigned short chX = chI % MaxNChannels;
if( data->NumEvents[chX] == 0 ) {
exhaustedCh ++;
continue;
}
if( data->NumEvents[chX] <= lastEv[chX] ) {
exhaustedCh ++;
singleChannelExhaustedFlag = true;
continue;
}
if( timeWin == 0 ) continue;
for( int ev = lastEv[chX]; ev < data->NumEvents[chX] ; ev++){
if( data->Timestamp[chX][ev] > 0 && (data->Timestamp[chX][ev] - e_t[0] ) < timeWin ) {
multi ++;
bd[multi-1] = data->boardSN;
ch[multi-1] = chX;
e[multi-1] = data->Energy[chX][ev];
e_t[multi-1] = data->Timestamp[chX][ev];
e_f[multi-1] = data->fineTime[chX][ev];
if( traceOn ){
traceLength[multi-1] = (unsigned short) data->Waveform1[chX][ev].size();
trace = (TGraph *) arrayTrace->ConstructedAt(multi-1, "C");
trace->Clear();
for( int hh = 0; hh < traceLength[multi-1]; hh++){
trace->SetPoint(hh, hh, data->Waveform1[chX][ev][hh]);
}
}
lastEv[chX] = ev + 1;
if( lastEv[chX] == data->NumEvents[chX] ) exhaustedCh ++;
}
}
}
if( verbose) {
printf("=============== multi : %d , ev : %llu\n", multi, evID);
for( int ev = 0; ev < multi; ev++){
printf("%3d, ch : %2d, %u, %llu \n", ev, ch[ev], e[ev], e_t[ev]);
}
printf("=============== Last Ev , exhaustedCh %d \n", exhaustedCh);
for( int chI = 0; chI < MaxNChannels ; chI++){
if( lastEv[chI] == 0 ) continue;
printf("%2d, %d %d\n", chI, lastEv[chI], data->NumEvents[chI]);
}
}
/// fill Tree
outRootFile->cd();
tree->Fill();
evID++;
multi = 0;
}while( !singleChannelExhaustedFlag || (exhaustedCh < MaxNChannels) );
/// build the rest of the event
exhaustedBd=0;
for( int b = 0; b < nFile ; b++){
exhaustedCh[b] = 0;
singleChannelExhaustedFlag[b] = false;
//for( int chI = ch1st[b]; chI < ch1st[b] + MaxNChannels; chI ++){
//unsigned short chX = chI % MaxNChannels;
for( int chI = 0; chI < MaxNChannels; chI ++){
if( data[b]->NumEvents[chI] == 0 ) {
exhaustedCh[b] ++;
continue;
}
if(data[b]->NumEvents[chI] <= lastEv[b][chI] ) {
exhaustedCh[b] ++;
singleChannelExhaustedFlag[b] = true;
continue;
}
if(singleChannelExhaustedFlag[b] && exhaustedCh[b] >= MaxNChannels){BoardExhaustedFlag[b]=true;}
if( timeWin == 0 ) continue;
if( BoardExhaustedFlag[b]) continue;
for( int ev = lastEv[b][chI]; ev < data[b]->NumEvents[chI] ; ev++){
if( data[b]->Timestamp[chI][ev] > 0 && ((data[b]->Timestamp[chI][ev] - e_t[0] )*ch2ns_value*1e-9)*1e6 < timeWin ) {
temp_index= map[data[b]->boardSN][chI];
if(temp_index>=0){
tempEn=data[b]->Energy[chI][ev];
if(temp_index<16 && de_l[multi_evt][temp_index]>0){multi_evt ++; de_l[multi_evt][temp_index] = tempEn;}
if(temp_index<16 && de_l[multi_evt][temp_index]==0){de_l[multi_evt][temp_index] = tempEn;}
if(temp_index<32 && temp_index>15 && de_r[multi_evt][temp_index]>0){multi_evt ++;de_r[multi_evt][temp_index] = tempEn;}
if(temp_index<32 && temp_index>15 && de_r[multi_evt][temp_index]==0){de_r[multi_evt][temp_index] = tempEn;}
if(temp_index==500 && stp0[multi_evt]>0){multi_evt ++;stp0[multi_evt]= tempEn;}
if(temp_index==500 && stp0[multi_evt]==0){stp0[multi_evt]= tempEn;}
if(temp_index==501 && stp17[multi_evt]>0){multi_evt ++;stp17[multi_evt]= tempEn;}
if(temp_index==501 && stp17[multi_evt]==0){stp17[multi_evt]= tempEn;}
if(temp_index==502 && grid[multi_evt]>0){multi_evt ++;grid[multi_evt]= tempEn;}
if(temp_index==502 && grid[multi_evt]==0){grid[multi_evt]= tempEn;}
if(temp_index==503 &&cath[multi_evt]>0){multi_evt ++;cath[multi_evt]= tempEn;}
if(temp_index==503 &&cath[multi_evt]==0){cath[multi_evt]= tempEn;}
if(temp_index==504 && puls[multi_evt][b]>0){multi_evt ++;puls[multi_evt][b]= tempEn;}
if(temp_index==504 && puls[multi_evt][b]==0){ puls[multi_evt][b] = tempEn;}
e_t[multi_evt] = data[b]->Timestamp[chI][ev];
e_f[multi_evt] = data[b]->fineTime[chI][ev];
multi_hit++;
}
if( traceOn ){
traceLength[multi_evt] = (unsigned short) data[b]->Waveform1[chI][ev].size();
trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C");
trace->Clear();
for( int hh = 0; hh < traceLength[multi_evt]; hh++){
trace->SetPoint(hh, hh, data[b]->Waveform1[chI][ev][hh]);
}
}
lastEv[b][chI] = ev + 1;
if(lastEv[b][chI] == data[b]->NumEvents[chI] ) exhaustedCh[b] ++;
}
}
}
}
for(int b=0;b<nFile;b++){if(singleChannelExhaustedFlag[b] && exhaustedCh[b] >= MaxNChannels){BoardExhaustedFlag[b]=true;exhaustedBd ++;};}
multi_evt++;
if( verbose) {
printf("=============== multi : %d , ev : %llu\n", multi_evt, evID);
for( int ev = 0; ev < multi_evt; ev++){
printf("%3d, grid time : %u, %llu \n", ev, grid[ev], e_t[ev]);
}
printf("=============== Last Ev , exhaustedBd %d \n", exhaustedBd);
for( int chI = 0; chI < MaxNChannels ; chI++){
for( int b = 0; b < nFile ; b++){
if(lastEv[b][chI] == 0 ) continue;
printf("board %d %2d, %d %d\n", b+1, chI, lastEv[b][chI], data[b]->NumEvents[chI]);
}
}
}
/// fill Tree
outRootFile->cd();
tree->Fill();
evID++;
for(int ev=0;ev<multi_evt;ev++){
stp0[ev]=0.;stp17[ev]=0;grid[ev]=0;cath[ev]=0;
for(int b=0;b<nFile;b++){puls[ev][b]=0.;}
for(int c=0;c<MaxNChannels;c++){de_l[ev][c]=0.;de_r[ev][c]=0.;}
}
multi_evt=0; multi_hit=0;
}while(exhaustedBd < nFile && exhaustedBd<MaxNBoards);
///========== clear built data
/// move the last data to the top,
for( int chI = 0; chI < MaxNChannels; chI++){
if( data->NumEvents[chI] == 0 ) continue;
int count = 0;
for( int ev = lastEv[chI] ; ev < data->NumEvents[chI] ; ev++){
data->Energy[chI][count] = data->Energy[chI][ev];
data->Timestamp[chI][count] = data->Timestamp[chI][ev];
data->fineTime[chI][count] = data->fineTime[chI][ev];
count++;
}
int lala = data->NumEvents[chI] - lastEv[chI];
data->NumEvents[chI] = (lala >= 0 ? lala: 0);
}
if( verbose > 0 ) {
printf("&&&&&&&&&&&&&&&&&&&&&&&&&& end of one event build loop\n");
data->PrintData();
}
for(int b=0;b<nFile;b++){
for( int chI = 0; chI < MaxNChannels; chI++){
if( data[b]->NumEvents[chI] == 0 ) continue;
int count = 0;
for( int ev = lastEv[b][chI] ; ev < data[b]->NumEvents[chI] ; ev++){
data[b]->Energy[chI][count] = data[b]->Energy[chI][ev];
data[b]->Timestamp[chI][count] = data[b]->Timestamp[chI][ev];
data[b]->fineTime[chI][count] = data[b]->fineTime[chI][ev];
count++;
}
int lala = data[b]->NumEvents[chI] - lastEv[b][chI];
data[b]->NumEvents[chI] = (lala >= 0 ? lala: 0);
}
}
}
template<typename T> void swap(T * a, T *b ){
@ -378,7 +450,6 @@ template<typename T> void swap(T * a, T *b ){
*b = *a;
*a = temp;
}
int partition(int arr[], int kaka[], TString file[], int start, int end){
int pivot = arr[start];
int count = 0;
@ -406,8 +477,26 @@ int partition(int arr[], int kaka[], TString file[], int start, int end){
}
return pivotIndex;
}
void extraction_map(int map[4][16]) {
std::ifstream in;
char* file; int nlines =0;
Double_t DAQmap[4][16];
gSystem->cd(path_to_top);
for(int b=0;b<4;b++){
in.open(Form("Board%i.dat",b));
nlines =0 ;
while (1) {
in >> DAQmap[b][nlines] >> map[b][nlines] ; // MeV/a.u.
if (!in.good()) break;
nlines++;
}
in.close();
}
gSystem->cd(path_to_run);
//return 1;
}
void quickSort(int arr[], int kaka[], TString file[], int start, int end){
/// base case
if (start >= end) return;
/// partitioning the array

446
DAQ/EventBuilder_raw.cpp Normal file
View File

@ -0,0 +1,446 @@
#include "macro.h"
#include "ClassData.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TClonesArray.h"
#include "TGraph.h"
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TSystem.h"
#define MAX_MULTI 100
#define MAX_File 100
#define NTimeWinForBuffer 3
char* path_to_run="/home/bavarians/FSUDAQ_MUSIC/Run/";
char* path_to_DAQ="/home/bavarians/FSUDAQ_MUSIC/";
char* path_to_con="/home/bavarians/FSUDAQ_MUSIC/Conversion/Raw/";
TFile * outRootFile = NULL;
TTree * tree = NULL;
unsigned long long evID = 0;
unsigned short multi_evt=0;
unsigned short bd[MAX_MULTI] = {0}; /// boardPort
unsigned short ch[MAX_MULTI] = {0}; /// chID
unsigned short e[MAX_MULTI] = {0}; /// 15 bit
unsigned long long e_t[MAX_MULTI] = {0}; /// timestamp 47 bit --> to get en sec *4e-9
unsigned short e_f[MAX_MULTI] = {0}; /// fine time 10 bit
/// using TClonesArray to hold the trace in TGraph
TClonesArray * arrayTrace = NULL;
unsigned short traceLength[MAX_MULTI] = {0};
TGraph * trace = NULL;
template<typename T> void swap(T * a, T *b );
int partition(int arr[], int kaka[], TString file[], int start, int end);
void quickSort(int arr[], int kaka[], TString file[], int start, int end);
void EventBuilder_raw(Data * data[],int nFile, const unsigned int timeWin, bool traceOn = false, bool isLastData = false, unsigned int verbose = 0);
int main(int argc, char **argv) {
printf("=====================================\n");
printf("=== *.fsu Events Builder ===\n");
printf("=====================================\n");
if (argc <= 3) {
printf("Incorrect number of arguments:\n");
printf("%s [timeWindow] [traceOn/Off] [verbose] [inFile1] [inFile2] .... \n", argv[0]);
printf(" timeWindow : in microsecond, default = 1 \n");
printf(" traceOn/Off : is traces stored \n");
printf(" verbose : > 0 for debug \n");
printf(" Output file name is contructed from inFile1 \n");
return 1;
}
/// File format must be Run_XXX_BB_YYY.fsu
/// XXX = 3 digits, run number
/// BB = board number, 2 digits
/// YYY = over size index, 3 digits
///============= read input
unsigned int timeWindow = atoi(argv[1]);
bool traceOn = atoi(argv[2]);
unsigned int debug = atoi(argv[3]);
int nFile = argc - 4;
TString inFileName[nFile];
for( int i = 0 ; i < nFile ; i++){
inFileName[i] = argv[i+4];
}
/// Form outFileName;
TString outFileName = inFileName[0];
int pos = outFileName.Index("_");
pos = outFileName.Index("_", pos+1);
outFileName.Remove(pos);
outFileName += Form("_%03u",atoi(&inFileName[0][inFileName[0].Index("B")+5]));
outFileName += ".root";
printf("-------> Out file name : %s \n", outFileName.Data());
printf(" Number of Files : %d \n", nFile);
for( int i = 0; i < nFile; i++) printf("%2d | %s \n", i, inFileName[i].Data());
printf("=====================================\n");
printf(" Time Window = %u \n", timeWindow);
printf("=====================================\n");
///============= sorting file by the serial number & order
int ID[nFile]; /// serial+ order*1000;
int type[nFile];
for( int i = 0; i < nFile; i++){
int snPos = inFileName[i].Index("_");
snPos = inFileName[i].Index("_", snPos+1);
int sn = atoi(&inFileName[i][snPos+1]);
type[i] = atoi(&inFileName[i][snPos+5]);
int order = atoi(&inFileName[i][snPos+9]);
ID[i] = sn + order * 1000;
}
quickSort(&(ID[0]), &(type[0]), &(inFileName[0]), 0, nFile-1);
for( int i = 0 ; i < nFile; i++){
printf("%d | %6d | %3d | %s \n", i, ID[i], type[i], inFileName[i].Data());
}
///=============== Separate files
std::vector<int> idCat;
std::vector<std::vector<int>> typeCat;
std::vector<std::vector<TString>> fileCat;
for( int i = 0; i < nFile; i++){
if( ID[i] / 1000 == 0 ) {
std::vector<TString> temp = {inFileName[i]};
std::vector<int> temp2 = {type[i]};
fileCat.push_back(temp);
typeCat.push_back(temp2);
idCat.push_back(ID[i]%1000);
}else{
for( int p = 0; p < (int) idCat.size(); p++){
if( (ID[i] % 1000) == idCat[p] ) {
fileCat[p].push_back(inFileName[i]);
typeCat[p].push_back(type[i]);
}
}
}
}
printf("=====================================\n");
for( int i = 0; i < (int) idCat.size(); i++){
printf("............ %d \n", idCat[i]);
for( int j = 0; j< (int) fileCat[i].size(); j++){
printf("%s | %d\n", fileCat[i][j].Data(), typeCat[i][j]);
}
}
///============= Set Root Tree
gSystem->cd(path_to_con);
outRootFile = new TFile(outFileName, "recreate");
// gSystem->cd(path_to_DAQ);
tree = new TTree("tree", outFileName);
tree->Branch("evID", &evID, "event_ID/l");
tree->Branch("multi_evt", &multi_evt, "multi_evt/s");
tree->Branch("bd", bd, "bd[multi_evt]/s");
tree->Branch("ch", ch, "ch[multi_evt]/s");
tree->Branch("e", e, "e[multi_evt]/s");
tree->Branch("e_t", e_t, "e_timestamp[multi_evt]/l");
tree->Branch("e_f", e_f, "e_timestamp[multi_evt]/s");
if( traceOn ) {
arrayTrace = new TClonesArray("TGraph");
tree->Branch("traceLength", traceLength, "traceLength[multi_evt]/s");
tree->Branch("trace", arrayTrace, 2560000);
arrayTrace->BypassStreamer();
}
///============= Open input Files
printf("##############################################\n");
gSystem->cd(path_to_run);
printf("#### number of files: %i \n", nFile);
FILE * haha[nFile];
size_t inFileSize[nFile];
for( int i = 0; i < nFile; i++){
haha[i]= fopen(fileCat[i][0], "r");
if( haha[i] == NULL ){
printf("#### Cannot open file : %s. Abort.\n", fileCat[i][0].Data());
return -1;
}
fseek(haha[i], 0L, SEEK_END);
inFileSize[i] = ftell(haha[i]);
printf("%s | file size : %d Byte = %.2f MB\n", fileCat[i][0].Data(), (int) inFileSize[i], inFileSize[i]/1024./1024.);
fclose(haha[i]);
}
///============= Main Loop
gSystem->cd(path_to_run);
int countBdAgg = 0;
unsigned long currentTime = 0;
unsigned long oldTime = 0;
char * buffer = NULL;
Data * data[nFile];
for( int i = 0; i < nFile; i++){
haha[i] = fopen(inFileName[i], "r");
data[i] = new Data();
data[i]->DPPType ;//typeCat[0][0];
// data->boardSN = atoi(&inFileName[0][inFileName[0].Index("_")+1]); //idCat[0];
data[i]->boardSN = atoi(&inFileName[i][inFileName[i].Index("B")+1]); //idCat[0];
data[i]->SetSaveWaveToMemory(true);
// fclose(haha[i]);
}
int end_of_loop=1;
do{
for( int i = 0; i < nFile; i++){
///========== Get 1 aggreration for each file
oldTime = get_time();
if( debug) printf("*********************** file pos : %d, %lu\n", (int) ftell(haha[i]), oldTime);
unsigned int word[1]; /// 4 bytes
size_t dump = fread(word, 4, 1, haha[i]);
fseek(haha[i], -4, SEEK_CUR);
short header = ((word[0] >> 28 ) & 0xF);
if( header != 0xA ) break;
unsigned int aggSize = (word[0] & 0x0FFFFFFF) * 4; ///byte
if( debug) printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize);
buffer = new char[aggSize];
dump = fread(buffer, aggSize, 1, haha[i]);
countBdAgg ++;
if( debug) printf("==================== %d Agg\n", countBdAgg);
data[i]->DecodeBuffer(buffer, aggSize,false, 0);//false
if(!data[i]->IsNotRollOverFakeAgg ) continue;
currentTime = get_time();
if( debug) {
printf("~~~~~~~~~~~~~~~~ time used : %lu usec\n", currentTime - oldTime);
}
}
EventBuilder_raw(data, nFile, timeWindow, traceOn, false, debug);
if( debug) printf("---------- event built : %llu \n", evID);
for( int i = 0; i < nFile; i++){
data[i]->ClearBuffer();
//if( countBdAgg > 74) break;
end_of_loop= end_of_loop*(!feof(haha[i]) && ftell(haha[i]) < inFileSize[i]);
}
}while(end_of_loop==1);
for( int i = 0; i < nFile; i++){ fclose(haha[i]);}
printf("=======@@@@@@@@###############============= end of loop \n");
EventBuilder_raw(data, nFile,timeWindow, traceOn, true, debug);
gSystem->cd(path_to_con);
tree->Write();
outRootFile->Close();
printf("========================= finsihed.\n");
printf("total events built = %llu \n", evID);
printf("=======> saved to %s \n", outFileName.Data());
}
void EventBuilder_raw(Data * data[], int nFile, const unsigned int timeWin, bool traceOn, bool isLastData, unsigned int verbose){
if( verbose) {
printf("======================== Event Builder \n");
}
/// find the last event timestamp;
long long firstTimeStamp = -1;
unsigned long long lastTimeStamp = 0;
long long smallestLastTimeStamp = -1;
unsigned int maxNumEvent[nFile] ;
for( int b = 0; b < nFile ; b++){
maxNumEvent[b] = 0;
for( int chI = 0; chI < MaxNChannels ; chI ++){
if(data[b]->NumEvents[chI] == 0 ) continue;
if(data[b]->Timestamp[chI][0] < firstTimeStamp ) {
firstTimeStamp = data[b]->Timestamp[chI][0];
}
unsigned short ev = data[b]->NumEvents[chI]-1;
if( data[b]->Timestamp[chI][ev] > lastTimeStamp ) {
lastTimeStamp = data[b]->Timestamp[chI][ev];
}
if( ev + 1 > maxNumEvent[b] ) maxNumEvent[b] = ev + 1;
if( data[b]->Timestamp[chI][ev] < smallestLastTimeStamp ){
smallestLastTimeStamp = data[b]->Timestamp[chI][ev];
}
}
if( maxNumEvent[b] == 0 ) return;
}
if( verbose) printf("================ time range : %llu - %llu, smallest Last %llu\n", firstTimeStamp, lastTimeStamp, smallestLastTimeStamp);
unsigned short lastEv[nFile][MaxNChannels] = {0}; /// store the last event number for each ch
unsigned short exhaustedCh[nFile] = {0}; /// when exhaustedCh == MaxNChannels ==> stop
bool singleChannelExhaustedFlag[nFile] = {false}; /// when a single ch has data but exhaused ==> stop
unsigned short exhaustedBd = 0;
bool BoardExhaustedFlag[nFile] = {false};
for( int b = 0; b < nFile ; b++){
singleChannelExhaustedFlag[b]=false;
exhaustedCh[b]=0;
for( int c = 0; c < MaxNChannels; c++){
lastEv[b][c]=0;
}
}
do {
/// find the 1st event
unsigned long long time1st=-1;
int ch1st=-1; int b1st=-1;
for( int b = 0; b < nFile ; b++){
for( int chI = 0; chI < MaxNChannels ; chI ++){
if( data[b]->NumEvents[chI] == 0 ) continue;
if( data[b]->NumEvents[chI] <= lastEv[b][chI] ) continue;
if( data[b]->Timestamp[chI][lastEv[b][chI]] < time1st ) {
time1st= data[b]->Timestamp[chI][lastEv[b][chI]];
ch1st = chI; b1st=b;
}
}
}
//&& maxNumEvent[b] < MaxNData * 0.6
if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) ) break;
if( ch1st > MaxNChannels ) break;
if( b1st < 0 ) break;
bd[multi_evt]= data[b1st]->boardSN;
ch[multi_evt]= ch1st;
e[multi_evt]= data[b1st]->Energy[ch1st][lastEv[b1st][ch1st]];
e_t[multi_evt]= data[b1st]->Timestamp[ch1st][lastEv[b1st][ch1st]];
e_f[multi_evt]= data[b1st]->fineTime[ch1st][lastEv[b1st][ch1st]];
if( traceOn ){
arrayTrace->Clear("C");
traceLength[multi_evt] = (unsigned short) data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]].size();
trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C");
trace->Clear();
for( int hh = 0; hh < traceLength[multi_evt]; hh++){
trace->SetPoint(hh, hh, data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]][hh]);
}
}
multi_evt ++;
lastEv[b1st][ch1st] ++;
/// build the rest of the event
exhaustedBd=0;
for( int b = 0; b < nFile ; b++){
exhaustedCh[b] = 0;
singleChannelExhaustedFlag[b] = false;
//for( int chI = ch1st[b]; chI < ch1st[b] + MaxNChannels; chI ++){
//unsigned short chX = chI % MaxNChannels;
for( int chI = 0; chI < MaxNChannels; chI ++){
if( data[b]->NumEvents[chI] == 0 ) {
exhaustedCh[b] ++;
continue;
}
if(data[b]->NumEvents[chI] <= lastEv[b][chI] ) {
exhaustedCh[b] ++;
singleChannelExhaustedFlag[b] = true;
continue;
}
if(singleChannelExhaustedFlag[b] && exhaustedCh[b] >= MaxNChannels){BoardExhaustedFlag[b]=true;}
if( timeWin == 0 ) continue;
if( BoardExhaustedFlag[b]) continue;
for( int ev = lastEv[b][chI]; ev < data[b]->NumEvents[chI] ; ev++){
if( data[b]->Timestamp[chI][ev] > 0 && ((data[b]->Timestamp[chI][ev] - e_t[0] )*ch2ns_value*1e-9)*1e6 <= timeWin ) {
bd[multi_evt] = data[b]->boardSN;
ch[multi_evt] = chI;
e[multi_evt] = data[b]->Energy[chI][ev];
e_t[multi_evt] = data[b]->Timestamp[chI][ev];
e_f[multi_evt] = data[b]->fineTime[chI][ev];
if( traceOn ){
traceLength[multi_evt] = (unsigned short) data[b]->Waveform1[chI][ev].size();
trace = (TGraph *) arrayTrace->ConstructedAt(multi_evt, "C");
trace->Clear();
for( int hh = 0; hh < traceLength[multi_evt]; hh++){
trace->SetPoint(hh, hh, data[b]->Waveform1[chI][ev][hh]);
}
}
lastEv[b][chI] = ev + 1;
multi_evt ++;
if(lastEv[b][chI] == data[b]->NumEvents[chI] ) exhaustedCh[b] ++;
}
}
}
}
for(int b=0;b<nFile;b++){if(singleChannelExhaustedFlag[b] && exhaustedCh[b] >= MaxNChannels){BoardExhaustedFlag[b]=true;exhaustedBd ++;};}
if( verbose) {
printf("=============== multi : %d , ev : %llu\n", multi_evt, evID);
for( int ev = 0; ev < multi_evt; ev++){
printf("%3d, bd, ch : %2d, %2d, %u, %llu \n", ev, bd[ev], ch[ev], e[ev], e_t[ev]);
}
printf("=============== Last Ev , exhaustedBd %d \n", exhaustedBd);
for( int chI = 0; chI < MaxNChannels ; chI++){
for( int b = 0; b < nFile ; b++){
if(lastEv[b][chI] == 0 ) continue;
printf("board %d %2d, %d %d\n", b+1, chI, lastEv[b][chI], data[b]->NumEvents[chI]);
}
}
}
/// fill Tree
outRootFile->cd();
tree->Fill();
evID++;
multi_evt=0;
}while(exhaustedBd < nFile && exhaustedBd<MaxNBoards);
//!singleChannelExhaustedFlag || (exhaustedCh < MaxNChannels) );
///========== clear built data
/// move the last data to the top,
for(int b=0;b<nFile;b++){
for( int chI = 0; chI < MaxNChannels; chI++){
if( data[b]->NumEvents[chI] == 0 ) continue;
int count = 0;
for( int ev = lastEv[b][chI] ; ev < data[b]->NumEvents[chI] ; ev++){
data[b]->Energy[chI][count] = data[b]->Energy[chI][ev];
data[b]->Timestamp[chI][count] = data[b]->Timestamp[chI][ev];
data[b]->fineTime[chI][count] = data[b]->fineTime[chI][ev];
count++;
}
int lala = data[b]->NumEvents[chI] - lastEv[b][chI];
data[b]->NumEvents[chI] = (lala >= 0 ? lala: 0);
}
}
}
template<typename T> void swap(T * a, T *b ){
T temp = * b;
*b = *a;
*a = temp;
}
int partition(int arr[], int kaka[], TString file[], int start, int end){
int pivot = arr[start];
int count = 0;
for (int i = start + 1; i <= end; i++) {
if (arr[i] <= pivot) count++;
}
/// Giving pivot element its correct position
int pivotIndex = start + count;
swap(&arr[pivotIndex], &arr[start]);
swap(&file[pivotIndex], &file[start]);
swap(&kaka[pivotIndex], &kaka[start]);
/// Sorting left and right parts of the pivot element
int i = start, j = end;
while (i < pivotIndex && j > pivotIndex) {
while (arr[i] <= pivot) {i++;}
while (arr[j] > pivot) {j--;}
if (i < pivotIndex && j > pivotIndex) {
int ip = i++;
int jm = j--;
swap( &arr[ip], &arr[jm]);
swap(&file[ip], &file[jm]);
swap(&kaka[ip], &kaka[jm]);
}
}
return pivotIndex;
}
void quickSort(int arr[], int kaka[], TString file[], int start, int end){
/// base case
if (start >= end) return;
/// partitioning the array
int p = partition(arr, kaka, file, start, end);
/// Sorting the left part
quickSort(arr, kaka, file, start, p - 1);
/// Sorting the right part
quickSort(arr, kaka, file, p + 1, end);
}

View File

@ -15,25 +15,31 @@ OBJS = influxdb.o startStopDialog.o programSetting.o triggerSummary.o registerSe
#########################################################################
all : ../test ../FSUDAQ ../test_indep ../Analysis/EventBuilder
all : ../Acquisition ../Analysis ../FSUDAQ /EventBuilder ../Analysis/EventBuilder_raw ../Plotting
##../testStartAtSameTime
clean :
/bin/rm -f $(OBJS) test FSUDAQ test_indep EventBuilder FSUDAQDict.cxx *.pcm
/bin/rm -f $(OBJS) Acquisition FSUDAQ EventBuilder EventBuilder_raw Plotting FSUDAQDict.cxx *.pcm
##testStartAtSameTime
ClassDigitizer.o : ClassDigitizer.cpp ClassDigitizer.h RegisterAddress.h macro.h ClassData.h
$(CC) $(COPTS) -c ClassDigitizer.cpp
../test : test.cpp ClassDigitizer.o influxdb.o
@echo "--------- making test"
$(CC) $(COPTS) -o ../test test.cpp ClassDigitizer.o influxdb.o $(CAENLIBS) $(ROOTLIBS) -lcurl
../Acquisition : Acquisition.cpp ClassDigitizer.o influxdb.o
@echo "--------- making Acquisition"
$(CC) $(COPTS) -o ../Acquisition Acquisition.cpp ClassDigitizer.o influxdb.o $(CAENLIBS) $(ROOTLIBS) -lcurl
../Analysis/EventBuilder : EventBuilder.cpp ClassData.h
@echo "--------- making EventBuilder"
$(CC) $(COPTS) -o ../Analysis/EventBuilder EventBuilder.cpp $(ROOTLIBS)
../test_indep : test_indep.cpp RegisterAddress.h macro.h
@echo "--------- making test_indep"
$(CC) $(COPTS) -o ../test_indep test_indep.cpp $(CAENLIBS)
$(CC) $(COPTS) -o ../Analysis/EventBuilder EventBuilder.cpp $(CAENLIBS) $(ROOTLIBS) -lcurl
../Analysis/EventBuilder_raw : EventBuilder_raw.cpp ClassData.h
@echo "--------- making EventBuilder_raw"
$(CC) $(COPTS) -o ../Analysis/EventBuilder_raw EventBuilder_raw.cpp $(CAENLIBS) $(ROOTLIBS) -lcurl
../Plotting : Plotting.cpp ClassData.h
@echo "--------- making Plotting"
$(CC) $(COPTS) -o ../Plotting Plotting.cpp $(CAENLIBS) $(ROOTLIBS) -lcurl
../FSUDAQ : FSUDAQDict.cxx $(OBJS) ClassData.h
@echo "----------- creating FSUDAQ"
@ -85,4 +91,7 @@ startStopDialog.o: startStopDialog.h startStopDialog.cpp
#BoxScore : src/BoxScore.c Class/ClassDigitizer.h Class/FileIO.h Class/GenericPlane.h Class/HelioTarget.h Class/IsoDetect.h Class/HelioArray.h Class/MCPClass.h
# g++ -std=c++17 -pthread src/BoxScore.c -o BoxScore $(DEPLIBS) $(ROOTLIBS)
#../testStartAtSameTime : testStartAtSameTime.cpp ClassDigitizer.o influxdb.o
# @echo "--------- making testStartAtSameTime"
# $(CC) $(COPTS) -o ../testStartAtSameTime testStartAtSameTime.cpp ClassDigitizer.o influxdb.o $(CAENLIBS) $(ROOTLIBS) -lcurl

177
DAQ/Plotting.cpp Normal file
View File

@ -0,0 +1,177 @@
#include "macro.h"
#include "ClassData.h"
#include "TH1.h"
#include "TH2.h"
#include "TStyle.h"
#include "TCanvas.h"
#include "TFile.h"
#include "TChain.h"
#include "TSystem.h"
#include "TTree.h"
#include <iostream>
#include "TApplication.h"
char* path_to_con="/home/bavarians/FSUDAQ_MUSIC/Conversion/";
TH1I * heleft[MaxNChannels];
TH1I * heright[MaxNChannels];
TH1I * MultiEVT;
TH1I * MultiHIT;
TH2F* MapFull ;
TH2F* MapLeft;
TH2F* MapRight;
TH2F* S0A1l;
TH2F* S0grid;
TH2F* S0cath;
TH2F* A1A2;
TH2F* gridcath;
TH2F* MapTime;
//IF SILICON DETECTOR
/*TH1F* E_histo ;
TH1F* dE_histo;
TH2F* dEE;
TH2F* si_de_time ;
TH2F* si_e_time;*/
TCanvas* csegLeft;
TCanvas* csegRight;
TCanvas* c;
TCanvas* cmult;
TCanvas* cmap;
TCanvas* cantime;
#define MAX_MULTI 100
unsigned long long evID ;
unsigned short multi_evt;
unsigned short multi_hit;
unsigned short stp0[MAX_MULTI]; /// 15 bit
unsigned short stp17[MAX_MULTI]; /// 15 bit
unsigned short grid[MAX_MULTI]; /// 15 bit
unsigned short cath[MAX_MULTI] ; /// 15 bit
unsigned short de_l[MAX_MULTI][16] ; /// 15 bit
unsigned short de_r[MAX_MULTI][16] ; /// 15 bit
unsigned short puls[MAX_MULTI][4]; /// 15 bit
unsigned long long e_t[MAX_MULTI]; /// timestamp 47 bit --> to get en sec *2e-9
unsigned short e_f[MAX_MULTI]; /// fine time 10 bit
int main(int argc, char* argv[]){
printf("=====================================\n");
printf("=== Data Visualization ===\n");
printf("=====================================\n");
if (argc < 2) {
printf("Incorrect number of arguments:\n");
printf("%s [RunId] \n", argv[0]);
printf("%s [Number of subfiles] \n", argv[1]);
return 1;
}
if (argc > 1) {
TApplication theApp("App",&argc, argv);
int Rid= atoi(argv[1]);
int Nfiles = atoi(argv[2]);
//"""""""""""""""""""""
//Accesing run
//"""""""""""""""""""""
gSystem->cd(path_to_con);
//FILE * haha[Nfiles]; TString inFileName;
char* inFileName;
TChain* MusicTree = new TChain("tree");
for(int f=0;f<Nfiles;f++){
if(f<10){inFileName= Form("Run_00%i_00%i.root", Rid, f);}
if(f>9 && f<100){inFileName= Form("Run_00%i_0%i.root", Rid, f);}
if(f>99 && f<1000){inFileName= Form("Run_00%i_%i.root", Rid, f);}
printf("input file %s \n", inFileName);
//haha[f] = fopen(inFileName, "r");
MusicTree->Add(inFileName);
}
MusicTree->SetBranchAddress("evID", &evID);
MusicTree->SetBranchAddress("multi_evt",&multi_evt); MusicTree->SetBranchAddress("multi_hit", &multi_hit);
MusicTree->SetBranchAddress("de_l", de_l); MusicTree->SetBranchAddress("de_r", de_r);
MusicTree->SetBranchAddress("stp0", stp0); MusicTree->SetBranchAddress("stp17", stp17);
MusicTree->SetBranchAddress("grid", grid); MusicTree->SetBranchAddress("cath" ,cath);
MusicTree->SetBranchAddress("puls", puls);
MusicTree->SetBranchAddress("e_t",e_t); MusicTree->SetBranchAddress("e_f", e_f);
int nStat = MusicTree->GetEntries();
printf("number of Tree entries %i \n", nStat);
//"""""""""""""""""""""
//Plot definition
//"""""""""""""""""""""
csegLeft= new TCanvas("csegLeft","csegLeft",1600,1600);csegLeft->Divide(4,4);
csegRight= new TCanvas("csegRight","csegRight",1600,1600);csegRight->Divide(4,4);
c= new TCanvas("c","c",1600,1600);c->Divide(2,2);
cmult= new TCanvas("cmult","cmult",1600,1600);cmult->Divide(2,2);
cmap= new TCanvas("cmap","cmap",900,1600);cmap->Divide(1,3);
cantime= new TCanvas("cantime","cantime",400,400);
cantime->cd();
double Er[2]={0., 16000}; double Timer[2]={0., 5000};
double bin_raw=2; double bin_raw_time=0.1;
int Nbins = int((Er[1]-Er[0])/bin_raw);
int NbinsTime = int((Timer[1]-Timer[0])/ bin_raw_time);
S0A1l = new TH2F("S0A1l",";#DeltaE_{0} (a.u.); #DeltaE_{1} left (a.u.)",Nbins, Er[0], Er[1], Nbins, Er[0], Er[1]);
S0cath = new TH2F("S0cath",";cathode (a.u.);#DeltaE_{0} (a.u.)",Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]);
S0grid= new TH2F("S0grid",";grid (a.u.);#DeltaE_{0} (a.u.)", Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]);
A1A2 = new TH2F("A1A2",";#DeltaE_{1} (a.u.);#DeltaE_{2} (a.u.)",Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]);
gridcath= new TH2F("gridcath",";grid (a.u.);cathode (a.u.)", Nbins, Er[0], Er[1],Nbins, Er[0], Er[1]);
MapLeft= new TH2F("MapLeft","Left;Strip;#DeltaE (a.u.)", 18,0,18,Nbins, Er[0], Er[1]);
MapRight = new TH2F("MapRight","Right;Strip;#DeltaE (a.u.)", 18,0,18,Nbins, Er[0], Er[1]);
MapFull = new TH2F("MapFull","Long segments;Strip;#DeltaE (a.u.)", 18,0,17,Nbins, Er[0], Er[1]);
MapTime = new TH2F("MapTime",";Time event (ms); grid = 0 & Pulser = 5+Board*5", NbinsTime,Timer[0],Timer[1],25,0,25);
MultiEVT = new TH1I("MultiEVT",";Event multiplicity", 10, 0, 10);
MultiHIT= new TH1I("MultiHIT",";DAQ Channel Hit multiplicity", 100, 0, 100);
for(int c=0;c<MaxNChannels;c++){
heleft[c]= new TH1I(Form("heleft%0d",c), Form("Left Strip %0d;#DeltaE (a.u.)",c+1), Nbins, Er[0], Er[1]);
heright[c]= new TH1I(Form("heright%0d",c), Form("Right Strip %0d;#DeltaE (a.u.)",c+1), Nbins, Er[0], Er[1]);
}
MusicTree->Draw("multi_evt>>MultiEVT");
MusicTree->Draw("multi_hit>>MultiHIT");
for(int i = 0;i<nStat;i++){
MusicTree->GetEntry(i);
if(multi_evt*multi_hit>0){
for(int ev=0;ev<multi_evt;ev++){
S0grid->Fill(grid[ev],stp0[ev]); S0cath->Fill(cath[ev],stp0[ev]);
gridcath->Fill(grid[ev],cath[ev]);
MapRight->Fill(0.,stp0[ev]); MapLeft->Fill(0.,stp0[ev]);
MapRight->Fill(17,stp17[ev]); MapLeft->Fill(17,stp17[ev]);
A1A2->Fill(de_l[ev][0],de_r[ev][1]); S0A1l->Fill(stp0[ev], de_l[ev][0]);
for( int c = 0; c <MaxNChannels; c++){
heleft[c]->Fill(de_l[ev][c]); heright[c]->Fill(de_r[ev][c]);
MapRight->Fill(c+1,de_r[ev][c]); MapLeft->Fill(c+1,de_l[ev][c]);
if(c%2==0){MapFull->Fill(c+1, de_l[ev][c]);}
if(c%2==1){MapFull->Fill(c+1, de_r[ev][c]);}
}
if(e_t[ev]*ch2ns_value*1e-9<Timer[1]*0.001){
if(grid[ev]>0){MapTime->Fill(e_t[ev]*ch2ns_value*1e-6,0);}
for(int b = 0; b <MaxNBoards;b++){
if( puls[ev][b]>0){MapTime->Fill(e_t[ev]*ch2ns_value*1e-6,5+b*5);}
}
}
}
}
}
printf("Enter Ctrl+C to stop ...");
//"""""""""""""""""""""
//Plotting
//"""""""""""""""""""""
gStyle->SetPalette(kThermometer);
c->cd(1);S0grid->Draw("colz");S0grid->GetXaxis()->CenterTitle();S0grid->GetYaxis()->CenterTitle();
c->cd(2);S0cath->Draw("colz");S0cath->GetXaxis()->CenterTitle();S0cath->GetYaxis()->CenterTitle();
c->cd(3); S0A1l->Draw("colz"); S0A1l->GetXaxis()->CenterTitle(); S0A1l->GetYaxis()->CenterTitle();
c->cd(4);A1A2->Draw("colz");A1A2->GetXaxis()->CenterTitle();A1A2->GetYaxis()->CenterTitle();
cmult->cd(1);gridcath->Draw("colz");gridcath->GetXaxis()->CenterTitle();gridcath->GetYaxis()->CenterTitle();
cantime->cd();MapTime->Draw("colz");MapTime->GetXaxis()->CenterTitle();MapTime->GetYaxis()->CenterTitle();
cmap->cd(1);MapLeft->Draw("colz");MapLeft->GetXaxis()->CenterTitle();MapLeft->GetYaxis()->CenterTitle();
cmap->cd(2);MapRight->Draw("colz");MapRight->GetXaxis()->CenterTitle();MapRight->GetYaxis()->CenterTitle();
cmap->cd(3);MapFull->Draw("colz");MapFull->GetXaxis()->CenterTitle();MapFull->GetYaxis()->CenterTitle();
for( int i = 0; i <MaxNChannels; i++){
csegLeft->cd(i+1); heleft[i]->Draw("h");heleft[i]->GetXaxis()->CenterTitle();
csegRight->cd(i+1); heright[i]->Draw("h");heright[i]->GetXaxis()->CenterTitle();
}
cmult->cd(3);MultiEVT->Draw("h");MultiEVT->GetXaxis()->CenterTitle();
cmult->cd(4);MultiHIT->Draw("h");MultiHIT->GetXaxis()->CenterTitle();
theApp.Run();
return 1;
}
}

View File

@ -264,7 +264,8 @@ namespace Register {
const Reg TriggerHoldOffWidth ("TriggerHoldOffWidth" , 0x1074); /// R/W OK
const Reg PeakHoldOff ("PeakHoldOff" , 0x1078); /// R/W OK
const Reg ShapedTriggerWidth ("ShapedTriggerWidth" , 0x1084); /// R/W not sure
const Reg DPPAlgorithmControl2_G ("DPPAlgorithmControl2_G" , 0x10A0, 0, 1); /// R/W OK
const Reg DPPAlgorithmControl2_G ("DPPAlgorithmControl2_G" , 0x10A0, 0); /// R/W OK
const Reg DPPAlgorithmControl22_G ("DPPAlgorithmControl22_G" , 0x10AC); /// R/W OK
const Reg FineGain ("FineGain" , 0x10C4); /// R/W OK
}

View File

@ -2,10 +2,10 @@
#define MACRO_H
#define MaxNPorts 4
#define MaxNBoards 22
#define MaxNBoards 4
#define MaxNChannels 16
#define MaxRecordLength 0x3fff * 8
#define MaxSaveFileSize 1024 * 1024 * 1024 * 2
#define MaxSaveFileSize 1024 * 1024 * 1024 * 1.0
#define SETTINGSIZE 2048

View File

@ -0,0 +1,79 @@
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable
#include <sys/time.h> // time in nano-sec
#include <unistd.h> // usleep
#define nTh 5
std::mutex mtx[nTh];
std::condition_variable cv;
bool ready = false;
timespec ts[nTh];
void print_id(int id) {
std::unique_lock<std::mutex> lck(mtx[id]);
while (!ready ){
printf("waiting for unlock %d\n", id);
cv.wait(lck);
}
cv.notify_all();
clock_gettime(CLOCK_REALTIME, &ts[id]);
printf("----thread %d ready. %ld ns\n", id, ts[id].tv_nsec);
usleep(2000*2000);
printf("thread %d finished.\n", id);
}
void go() {
ready = true;
cv.notify_all();
}
int main(){
std::thread threads[nTh];
for (int i = 0; i < nTh; ++i){
threads[i] = std::thread(print_id, i);
}
printf("%d threads ready to race...\n", nTh);
usleep(1000*1000);
go(); // go!
for (auto& th : threads) th.join();
printf("=========== finsihed.\n");
long avg = 0;
for( int i =0; i < nTh ; i++) avg += ts[i].tv_nsec;
avg = avg/nTh;
long min , max;
for( int i =0; i < nTh; i++) {
if( i == 0 ){
min = ts[i].tv_nsec;
max = ts[i].tv_nsec;
continue;
}
if( min > ts[i].tv_nsec) min = ts[i].tv_nsec;
if( max < ts[i].tv_nsec) max = ts[i].tv_nsec;
}
printf(" avg : %ld\n", avg);
printf(" min : %ld, %ld\n", min, avg - min);
printf(" max : %ld, %ld\n", max, max - avg);
printf(" diff : %ld\n", max-min);
return 0;
}

17
MUSIC_Topology/Board0.dat Normal file
View File

@ -0,0 +1,17 @@
0 503
1 -1
2 1
3 -1
4 500
5 504
6 5
7 -1
8 0
9 -1
10 9
11 -1
12 17
13 13
14 -1
15 502

16
MUSIC_Topology/Board1.dat Normal file
View File

@ -0,0 +1,16 @@
0 2
1 -1
2 16
3 -1
4 21
5 504
6 20
7 -1
8 8
9 -1
10 24
11 -1
12 27
13 28
14 -1
15 14

16
MUSIC_Topology/Board2.dat Normal file
View File

@ -0,0 +1,16 @@
0 19
1 -1
2 3
3 -1
4 6
5 504
6 7
7 -1
8 25
9 -1
10 11
11 -1
12 12
13 15
14 -1
15 10

16
MUSIC_Topology/Board3.dat Normal file
View File

@ -0,0 +1,16 @@
0 4
1 -1
2 18
3 -1
4 23
5 504
6 22
7 -1
8 29
9 -1
10 26
11 -1
12 31
13 30
14 -1
15 501

112
README/README.md Normal file
View File

@ -0,0 +1,112 @@
## Introduction (First Version)
The FSUDAQ_MUSIC is an ONGOING online and offline aquisition for CAEN x725 digitizers with DPP-PHA firmware for MUSIC set-up at ATLAS/Argonne National Laboratory.
It is based on CERN_ROOT/C++. The x730 digitizer and the DPP-PSD firmware are also possible.
Additional inforamtion in https://fsunuc.physics.fsu.edu/wiki/index.php/CAEN_digitizer#FSU_DAQ
## Required Library
1. CAENComm 1.4+
2. CAENVMELib 2.5+
3. CAENDigitizer 2.12+
4. CAEN A3818 Driver 1.61+ (for optical link)
5. CERN ROOT 6
6. libcurl4-nss-dev (for the libcurl, used in InfluxDB class)
7. InfluxDB 1.8 (recommanded for trigger rate, optional for database)
## Folder Structure
FSUDAQ_MUSIC \
├── Analysis \
├── Conversion \
| └── Raw \
├── DAQ \
├── MUSIC_Topology\
├── README \
└── Run \
The parent folder FSUDAQ_MUSIC should be placed on the Home directory.
Information available in README/ folder.
All source codes are in DAQ/ folder.
The key codes are
1. ClassData.h
2. RegisterAddress.h
3. ClassDigitizer.h/cpp
4. Acquisition.cpp
5. EventBuilder.cpp EventBuilder_raw.cpp
6. Plotting.cpp
4. The Acquisition.cpp is the main code for online acquisition. It controls, readouts digitizers and stores the data in Run/ folder.
5. The EventBuilder_raw.cpp and EventBuilder.cpp are the codes for online /offline event building with the raw DAQ topology and the MUSIC setup toplogy, respectively.
Saved raw run .fsu files (in Run/) are converted in TTree .root run files in Conversion/Raw/ and Conversion/ for EventBuilder_raw.cpp and EventBuilder.cpp, respectively.
Compiled scripts are stored in Analysis/ folder.
6. The Plotting.cpp is a code for online or offline data visualization from the converted .root run files in Conversion/, requiring the MUSIC setup toplogy.
The MUSIC setup toplogy is defined in MUSIC_Topology/.
--> see description in README/Topology_MUSIC_read_me.md
## To Compile (--> according to DAQ/Makefile)
> cd DAQ/; make ../Acquisition;cd ../;
> cd DAQ/; make ../Analysis/EventBuilder_raw;cd ../;
> cd DAQ/; make ../Analysis/EventBuilder;cd ../;
> cd DAQ/; make ../Plotting;cd ../;
Executables produced for each code.
########
# Usages
########
## Acquisition
--> Input = [Run Time in second, 0 for infinite one] [Run number]
Number of available digitizers defined at start
--> nDig
Data taking done in parallel with the function:
--> func(Digitizer * dig, double RunTime, int Rid, int Bid)
All digitizers start at close time (~dT tens of microseconds)
Assignement of registers value done through 2 functions
--> boardSetParameters //Parameters usually tuned at the start of a MUSIC experiment with the help of CoMPASS software
--> boardCommonParameters //Standard parameters for MUSIC setup
Details on how to assign the registers values are given in
--> README/Register_inputs_readme.md
Raw data are stored in Run/, with the path defined at start
--> path_to_run
A file per board and files size limit is 1 GB (defined with MaxSaveFileSize in DAQ/macro.h )
--> Run_00#_B#_###.fsu
## EventBuilder_raw and EventBuilder
--> Input = [Time window in microsecond] [Trace ==0, off] [verbose 0/1] [list of raw run .fsu filenames ...]
Building of events in readable format, i.e. oot TTree 'tree' (see defined tree structures).
Raw conversion stores within the time window the lists of energy/time/board/channel. The number of DAQ channel hits corresponds to
-->multi_evt
Final conversion stores within the time window the physical events with MUSIC inputs (energies of left/right segments, grid, cathode, strip0, strip17,..., and times, pulsers...).
The number of events within the time window is
-->multi_evt
The number of MUSIC signals hits for each event (e.g. std value is 16+4(+4puls)) is
-->multi_hit
MUSIC setup toplogy path is defined at start
--> path_to_top
Converted root files are stored in Conversion/, with the path defined at start
--> path_to_con
## Plotting
--> Input = [Run number] [number of run_subfiles]
Standard MUSIC histograms for PID, beam trajectory and segment maps (2x16), event built multiplicities and time structure (if pulser input per board).
Additional (like Silicon PID..) histograms to be defined at the start of the script.

View File

@ -0,0 +1,50 @@
## Introduction
Assignement of registers value done in DAQ/Acquisition.cpp,
parameters are usually tuned at the start of a MUSIC experiment with the help of CoMPASS software.
Assigned registers saved in
--> reg_Board%i.txt
## Usage
Digitizer class function
--> dig->WriteRegister(Register::#DPP::#PHA::#name, #value_in_hexadecimal, #channel_index)
To access registers values, looked in CoMPASS software (or if saved in reg_Board%i.txt) with register address "Reg" defined by
--> 0x####
Aggregate registers
--> MaxAggregatePerBlockTransfer //Reg=0xEF1C
--> NumberEventsPerAggregate_G //Reg=0x1034
Standard registers defined and assigned in
--> boardCommonParameters(Digitizer * dig)
Specific registers per MUSIC experiment defined and assigned in
--> boardSetParameters(...)
where inputs defined in main function
--> double BoardConfigurationval //Reg=0x8000
--> double DPPAlgoCtrl //Reg=0x1080
--> double DPPAlgoCtrl_10A0 //Reg=0x10A0
--> double DPPAlgoCtrl_10AC //Reg=0x10AC
--> double ShapedTriggerWidthVal //Reg=0x1084 in steps of 16ns, 96=6*16
--> double InputSec[7] // Corresponding to CoMPASS Inputs Section
0. Not used
1. //Reg=0x1020 RecordLength input N such length (ns) == N*8*4
2. //Reg=0x1038 PreTrigger in steps of 16ns, input N such length (ns) == N*4*4
3. Not used
4. Not used
5. //Reg=0x1098 DCoffset DC% = 1 - input/65535 (ChannelDCOffset)
6. //Reg=0x1028 CoarseGain 0=x1 or 1=x4 (InputDynamicRange)
--> double DiscriSec[4] // Corresponding to CoMPASS Discriminator Section
0. //Reg=0x106C TriggerThreshold in lsb
1. //Reg=0x1074 TriggerHoldOffWidth in steps of 16ns
2. //Reg=0x1054 FastDiscriSmooth, e.g. 20=64samp, 63=128samp, (RCCR2SmoothingFactor)
3. //Reg=0x1058 InputRiseTime in steps of 16ns
--> double TrapSec[7] // Corresponding to CoMPASS Trapezoid Section
0. //Reg=0x105C RiseTime in steps of 16ns
1. //Reg=0x1060 FlatTop in steps of 16ns
2. //Reg=0x1068 PoleZero in steps of 16ns (DecayTime)
3. //Reg=0x1064 PeakingTime in steps of 16ns
4. Not used
5. //Reg=0x1078 PeakHoldOff in steps of 16ns
6. //Reg=0x10C4 fine gain, eg 1==0x00006C3A (FineGain)

View File

@ -0,0 +1,21 @@
## Introduction
The topology of the DAQ w.r.t detection inputs (MUSIC signals, pulser, additional Silicon signals...) is given in a file per board
--> Board#.dat
Files and associated topology information are extracted and used by DAQ/EventBuilder.cpp to build back events from DAQ channels to physics signals.
Used function in DAQ/EventBuilder.cpp
--> extraction_map(int map[4][16])
## Path to files
FSUDAQ_MUSIC/MUSIC_Topology/Board#.dat
## File Structure --> 2 columns
DAQ channel (0->15) | MUSIC Segment
## Correspondance MUSIC Segment to physics inputs
500 == Strip 0
501 == Strip 17
502 == Grid
503 == Cathode
504 == Pulse
0->15 == left side
16->31 == right side