for MUSIC by Chloe
This commit is contained in:
parent
4e33fbba28
commit
6e97710f0f
BIN
Analysis/EventBuilder_raw
Executable file
BIN
Analysis/EventBuilder_raw
Executable file
Binary file not shown.
128
Analysis/TimSyncComp.C
Executable file
128
Analysis/TimSyncComp.C
Executable 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
138
Analysis/TimeSync.C
Executable 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
302
Analysis/timeshift.C
Normal 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
295
DAQ/Acquisition.cpp
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 = "" );
|
||||
|
|
|
@ -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]);
|
||||
|
@ -69,6 +81,7 @@ int main(int argc, char **argv) {
|
|||
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());
|
||||
|
||||
|
@ -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,40 +166,52 @@ int main(int argc, char **argv) {
|
|||
arrayTrace->BypassStreamer();
|
||||
}
|
||||
|
||||
|
||||
///============= 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());
|
||||
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, 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);
|
||||
|
||||
|
||||
Data * data = new Data();
|
||||
data->DPPType = typeCat[0][0];
|
||||
data->boardSN = idCat[0];
|
||||
data->SetSaveWaveToMemory(true);
|
||||
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;
|
||||
do{
|
||||
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;
|
||||
|
||||
///========== Get 1 aggreration
|
||||
|
||||
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), oldTime);
|
||||
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);
|
||||
fseek(haha, -4, SEEK_CUR);
|
||||
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;
|
||||
|
@ -185,192 +221,228 @@ int main(int argc, char **argv) {
|
|||
if( debug) printf("Board Agg. has %d word = %d bytes\n", aggSize/4, aggSize);
|
||||
|
||||
buffer = new char[aggSize];
|
||||
dump = fread(buffer, aggSize, 1, haha);
|
||||
dump = fread(buffer, aggSize, 1, haha[i]);
|
||||
countBdAgg ++;
|
||||
if( debug) printf("==================== %d Agg\n", countBdAgg);
|
||||
|
||||
data->DecodeBuffer(buffer, aggSize, false, 0);
|
||||
data->ClearBuffer();
|
||||
if( !data->IsNotRollOverFakeAgg ) continue;
|
||||
|
||||
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);
|
||||
data->PrintStat();
|
||||
}
|
||||
|
||||
EventBuilder(data, timeWindow, traceOn, false, debug);
|
||||
}
|
||||
EventBuilder(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;
|
||||
|
||||
}while(!feof(haha) && ftell(haha) < inFileSize);
|
||||
|
||||
fclose(haha);
|
||||
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;
|
||||
long long firstTimeStamp = -1;
|
||||
unsigned long long lastTimeStamp = 0;
|
||||
unsigned long long smallestLastTimeStamp = -1;
|
||||
unsigned int maxNumEvent = 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->NumEvents[chI] == 0 ) continue;
|
||||
|
||||
if( data->Timestamp[chI][0] < firstTimeStamp ) {
|
||||
firstTimeStamp = data->Timestamp[chI][0];
|
||||
if(data[b]->NumEvents[chI] == 0 ) continue;
|
||||
if(data[b]->Timestamp[chI][0] < firstTimeStamp ) {
|
||||
firstTimeStamp = data[b]->Timestamp[chI][0];
|
||||
}
|
||||
unsigned short ev = data->NumEvents[chI]-1;
|
||||
if( data->Timestamp[chI][ev] > lastTimeStamp ) {
|
||||
lastTimeStamp = data->Timestamp[chI][ev];
|
||||
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 ) maxNumEvent = ev + 1;
|
||||
if( data->Timestamp[chI][ev] < smallestLastTimeStamp ){
|
||||
smallestLastTimeStamp = data->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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
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->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( 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;
|
||||
}
|
||||
}
|
||||
if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) && maxNumEvent < MaxNData * 0.6 ) break;
|
||||
}
|
||||
//&& maxNumEvent[b] < MaxNData * 0.6
|
||||
if( !isLastData && ((smallestLastTimeStamp - time1st) < NTimeWinForBuffer * timeWin) ) break;
|
||||
if( ch1st > MaxNChannels ) break;
|
||||
if( b1st < 0 ) 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]];
|
||||
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-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");
|
||||
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-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]);
|
||||
for( int hh = 0; hh < traceLength[multi_evt]; hh++){
|
||||
trace->SetPoint(hh, hh, data[b1st]->Waveform1[ch1st][lastEv[b1st][ch1st]][hh]);
|
||||
}
|
||||
}
|
||||
lastEv[ch1st] ++;
|
||||
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 ++;
|
||||
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->NumEvents[chX] <= lastEv[chX] ) {
|
||||
exhaustedCh ++;
|
||||
singleChannelExhaustedFlag = true;
|
||||
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;
|
||||
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( 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-1] = (unsigned short) data->Waveform1[chX][ev].size();
|
||||
trace = (TGraph *) arrayTrace->ConstructedAt(multi-1, "C");
|
||||
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-1]; hh++){
|
||||
trace->SetPoint(hh, hh, data->Waveform1[chX][ev][hh]);
|
||||
for( int hh = 0; hh < traceLength[multi_evt]; hh++){
|
||||
trace->SetPoint(hh, hh, data[b]->Waveform1[chI][ev][hh]);
|
||||
}
|
||||
}
|
||||
lastEv[chX] = ev + 1;
|
||||
if( lastEv[chX] == data->NumEvents[chX] ) exhaustedCh ++;
|
||||
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, evID);
|
||||
for( int ev = 0; ev < multi; ev++){
|
||||
printf("%3d, ch : %2d, %u, %llu \n", ev, ch[ev], e[ev], e_t[ev]);
|
||||
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 , exhaustedCh %d \n", exhaustedCh);
|
||||
printf("=============== Last Ev , exhaustedBd %d \n", exhaustedBd);
|
||||
for( int chI = 0; chI < MaxNChannels ; chI++){
|
||||
if( lastEv[chI] == 0 ) continue;
|
||||
printf("%2d, %d %d\n", chI, lastEv[chI], data->NumEvents[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 = 0;
|
||||
|
||||
}while( !singleChannelExhaustedFlag || (exhaustedCh < MaxNChannels) );
|
||||
|
||||
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 b=0;b<nFile;b++){
|
||||
for( int chI = 0; chI < MaxNChannels; chI++){
|
||||
if( data->NumEvents[chI] == 0 ) continue;
|
||||
if( data[b]->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];
|
||||
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->NumEvents[chI] - lastEv[chI];
|
||||
data->NumEvents[chI] = (lala >= 0 ? lala: 0);
|
||||
int lala = data[b]->NumEvents[chI] - lastEv[b][chI];
|
||||
data[b]->NumEvents[chI] = (lala >= 0 ? lala: 0);
|
||||
}
|
||||
|
||||
if( verbose > 0 ) {
|
||||
printf("&&&&&&&&&&&&&&&&&&&&&&&&&& end of one event build loop\n");
|
||||
data->PrintData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
446
DAQ/EventBuilder_raw.cpp
Normal 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);
|
||||
}
|
27
DAQ/Makefile
27
DAQ/Makefile
|
@ -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)
|
||||
$(CC) $(COPTS) -o ../Analysis/EventBuilder EventBuilder.cpp $(CAENLIBS) $(ROOTLIBS) -lcurl
|
||||
|
||||
../test_indep : test_indep.cpp RegisterAddress.h macro.h
|
||||
@echo "--------- making test_indep"
|
||||
$(CC) $(COPTS) -o ../test_indep test_indep.cpp $(CAENLIBS)
|
||||
../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
177
DAQ/Plotting.cpp
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
79
DAQ/testStartAtSameTime.cpp
Normal file
79
DAQ/testStartAtSameTime.cpp
Normal 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
17
MUSIC_Topology/Board0.dat
Normal 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
16
MUSIC_Topology/Board1.dat
Normal 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
16
MUSIC_Topology/Board2.dat
Normal 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
16
MUSIC_Topology/Board3.dat
Normal 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
112
README/README.md
Normal 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.
|
50
README/Register_inputs_readme.md
Normal file
50
README/Register_inputs_readme.md
Normal 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)
|
21
README/Topology_MUSIC_read_me.md
Normal file
21
README/Topology_MUSIC_read_me.md
Normal 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
|
Loading…
Reference in New Issue
Block a user