519 lines
14 KiB
C
519 lines
14 KiB
C
#define peachCake_cxx
|
|
|
|
#include "peachCake.h"
|
|
#include <TMath.h>
|
|
#include <TCanvas.h>
|
|
#include <TStyle.h>
|
|
#include <TCutG.h>
|
|
|
|
#include "./armory/AnalysisLibrary.h"
|
|
|
|
//============== User settings
|
|
|
|
int tofRange[3] = {500, -280, -210};
|
|
int dERange[3] = {500, 0, 5500};
|
|
|
|
|
|
//============== histograms
|
|
|
|
TH2F * hCloverID;
|
|
TH2F * hPID;
|
|
TH1F * hZ;
|
|
TH2F * hPID0; // raw
|
|
TH2F * hPID2; // z vs A/Q
|
|
|
|
TH1F * hTOF;
|
|
TH1F * hdE;
|
|
|
|
TH2F * hImplantIons;
|
|
TH2F * hImplantBeta; //high gain
|
|
|
|
TH2F * hImplantX;
|
|
TH2F * hImplantY;
|
|
|
|
TH2F * hImplantDyIons;
|
|
TH2F * hImplantDyBeta;
|
|
|
|
TH1F * hDecay;
|
|
TH1F * hDecay_veto;
|
|
|
|
TH1F * hFlag;
|
|
TH1F * hvetoFlag;
|
|
|
|
///TH1F * hZ3;
|
|
///TH1F * hZ6;
|
|
///TH1F * hZ10;
|
|
///TH1F * hZ14;
|
|
|
|
//============ parameters
|
|
//TString cutFileName="PIDCuts.root";
|
|
//TFile * cutFile;
|
|
//TCutG * cut = NULL;
|
|
//TObjArray * cutList;
|
|
//int numCut = 0;
|
|
|
|
std::vector<std::vector<double>> eCorr;
|
|
|
|
double TOFCorrection(double x){
|
|
///========= for run 250
|
|
double par[6] = {10.9179,
|
|
0.00416034,
|
|
-233.306,
|
|
3607.16,
|
|
1538.37,
|
|
0.000430609};
|
|
return par[0] * exp( - par[1] * x ) + par[2] - par[5] * (par[3] - x) * exp( - pow( (par[3]-x)/par[4],2) );
|
|
}
|
|
|
|
|
|
void peachCake::Begin(TTree * /*tree*/){
|
|
|
|
TString option = GetOption();
|
|
|
|
hCloverID = createTH2F("hCloverID", "Clover; ID; energy [keV]", 52, 0, 52, 400, 0, 2000);
|
|
|
|
hPID0 = createTH2F("hPID0", "PID raw; ns; msx100", tofRange[0], tofRange[1], tofRange[2], dERange[0], dERange[1], dERange[2]);
|
|
hPID = createTH2F("hPID", "PID slew corrected; ns; msx100", tofRange[0], tofRange[1], tofRange[2], dERange[0], dERange[1], dERange[2]);
|
|
hPID2 = createTH2F("hPID2", "PID; A/Q; Z", tofRange[0], 2.0, 4.2, dERange[0], 0, 16.5);
|
|
|
|
hTOF = createTH1F("hTOF", "TOF", tofRange[0], tofRange[1], tofRange[2]);
|
|
hdE = createTH1F("hdE", "dE", dERange[0], dERange[1], dERange[2]);
|
|
|
|
hZ = createTH1F("hZ", "Z; Z; count", 500, 0, 16);
|
|
|
|
hImplantIons = createTH2F("hImplantIons", "Implant low gain; x ; y", 400, 0, 1, 400, 0, 1);
|
|
hImplantBeta = createTH2F("hImplantBeta", "Implant high gain; x ; y", 400, 0, 1, 400, 0, 1);
|
|
|
|
hImplantX = createTH2F("hImplantX", "Implant X; low ; high", 400, 0, 1, 400, 0, 1);
|
|
hImplantY = createTH2F("hImplantY", "Implant Y; low ; high", 400, 0, 1, 400, 0, 1);
|
|
|
|
hImplantDyIons = createTH2F("hImplantDyIonslow", "Implant low; sum_a; dy", 400, 0, 16000, 400, 0, 16000);
|
|
hImplantDyBeta = createTH2F("hImplantDyBetahigh", "Implant high; sum_a; dy", 400, 0, 80000, 400, 0, 80000);
|
|
|
|
hDecay = createTH1F("hDecay", "Decay (beta.time - ion.time) ; [ticks]; counts", 100, 0, 2000);
|
|
hDecay_veto = createTH1F("hDecay_veto", "Decay (beta.time - ion.time) [veto]; [ticks]; counts", 100, 0, 2000);
|
|
|
|
hFlag = createTH1F("hFlag", "Flag ( 1 = beam, 2 = Ions, 4 = Beta)", 8, 0, 8);
|
|
hvetoFlag = createTH1F("hvetoFlag", "vetoFlag ( 1 = front, 4 = rear)", 8, 0, 8);
|
|
|
|
///hZ3 = createTH1F("hZ3", "Z=3; A ; count ", 200, 6, 12);
|
|
///hZ6 = createTH1F("hZ6", "Z=6; A ; count ", 200, 14, 21);
|
|
///hZ10 = createTH1F("hZ10", "Z=10; A ; count ", 200, 25, 33);
|
|
///hZ14 = createTH1F("hZ14", "Z=14; A ; count ", 200, 38, 44);
|
|
|
|
eCorr = LoadCorrectionParameters("correction_e.dat");
|
|
|
|
if( pidCorrFileName != "" ){
|
|
pidCorr = LoadCorrectionParameters(pidCorrFileName, 1);
|
|
}
|
|
|
|
printf("============ start \n");
|
|
|
|
}
|
|
|
|
|
|
Bool_t peachCake::Process(Long64_t entry){
|
|
|
|
nProcessed++;
|
|
|
|
b_multi->GetEntry(entry);
|
|
b_detID->GetEntry(entry);
|
|
b_e->GetEntry(entry);
|
|
b_e_t->GetEntry(entry);
|
|
b_cfd->GetEntry(entry);
|
|
b_runID->GetEntry(entry);
|
|
|
|
//========= initialization
|
|
dE = TMath::QuietNaN();
|
|
TOF = TMath::QuietNaN();
|
|
Z = TMath::QuietNaN();
|
|
AoQ = TMath::QuietNaN();
|
|
Long64_t startTimeL = 0;
|
|
Long64_t startTimeR = 0;
|
|
|
|
double cfdL = TMath::QuietNaN();
|
|
double cfdR = TMath::QuietNaN();
|
|
double cdB2 = TMath::QuietNaN();
|
|
|
|
Long64_t stopTime = 0;
|
|
Long64_t startTime40 = 0;
|
|
double cfd40 = TMath::QuietNaN();
|
|
|
|
double a_L[5] = {TMath::QuietNaN()}; ///0 = dy, 1-4 = anode
|
|
double a_H[5] = {TMath::QuietNaN()};
|
|
|
|
veto_f = TMath::QuietNaN();
|
|
veto_r = TMath::QuietNaN();
|
|
|
|
veto_f_time = 0;
|
|
veto_r_time = 0;
|
|
|
|
crossEnergy = 0; /// for analog signal, cross T2
|
|
crossTime = 0;
|
|
|
|
for( int i = 0; i < 4 ; i++) {
|
|
dyIonsTime[i] = 0;
|
|
dyBetaTime[i] = 0;
|
|
dyIonsEnergy[i] = 0;
|
|
dyBetaEnergy[i] = 0;
|
|
}
|
|
|
|
int multiDyBeta = 0;
|
|
int multiDyIons = 0;
|
|
|
|
flag = 0;
|
|
vetoFlag = 0;
|
|
|
|
//============ format canvas title
|
|
if( entry == 0 ){
|
|
if( runID/100 == lastRunID + 1 ) {
|
|
int len = canvasTitle.Sizeof();
|
|
if( contFlag == false) {
|
|
canvasTitle.Remove(len-3);
|
|
canvasTitle += " - ";
|
|
}
|
|
if( contFlag == true) canvasTitle.Remove(len-6);
|
|
contFlag = true;
|
|
}
|
|
if( runID/100 > lastRunID + 1 ) contFlag = false;
|
|
if( runID/100 > lastRunID ){
|
|
canvasTitle += Form("%03d, ", runID/100 );
|
|
lastRunID = runID/100;
|
|
}
|
|
}
|
|
|
|
//======= Fill detectors
|
|
for( int i = 0; i < multi; i++){
|
|
//----- clover
|
|
///if( 0 <= detID[i] && detID[i] < 100 ){
|
|
/// if( e[i] > 0 ) {
|
|
/// int id = detID[i];
|
|
/// double eCal = 0;
|
|
/// for( int k = 0; k < int(eCorr[id].size()); k++){
|
|
/// eCal += eCorr[id][k] * TMath::Power(e[i], k);
|
|
/// }
|
|
/// hCloverID->Fill(detID[i], eCal);
|
|
/// }
|
|
///}
|
|
//----- dy Ions (low-gain)
|
|
if( detID[i] == 200 ) {
|
|
if ( multiDyBeta < 4 ){
|
|
dyIonsTime[multiDyBeta] = e_t[i];
|
|
dyIonsEnergy[multiDyBeta] = e[i];
|
|
multiDyIons ++;
|
|
}
|
|
}
|
|
if( 201 <= detID[i] && detID[i] < 250){
|
|
a_L[detID[i] - 200] = e[i];
|
|
}
|
|
//----- dy Beta (high-gain)
|
|
if( detID[i] == 250 ) {
|
|
if ( multiDyIons < 4 ){
|
|
dyBetaTime[multiDyIons] = e_t[i];
|
|
dyBetaEnergy[multiDyIons] = e[i];
|
|
multiDyBeta ++;
|
|
}
|
|
}
|
|
if( 251 <= detID[i] && detID[i] < 260){
|
|
a_H[detID[i] - 250] = e[i];
|
|
}
|
|
//----- veto_front
|
|
if( detID[i] == 290 ) {
|
|
veto_f = e[i];
|
|
veto_f_time = e_t[i];
|
|
if( veto_f > 0 && (vetoFlag & 1) == 0) vetoFlag += 1;
|
|
}
|
|
//----- veto_rear
|
|
if( detID[i] == 291 ) {
|
|
veto_r = e[i];
|
|
veto_r_time = e_t[i];
|
|
if( veto_r > 0 && (vetoFlag & 2) == 0) vetoFlag += 2;
|
|
}
|
|
//----- image scint L
|
|
if( detID[i] == 300 ) {
|
|
if( e[i] > 1000 ) {
|
|
startTimeL = e_t[i];
|
|
cfdL = cfd[i]/16384.;
|
|
}
|
|
}
|
|
//----- image scint R
|
|
if( detID[i] == 301 ) {
|
|
startTimeR = e_t[i];
|
|
cfdR = cfd[i]/16384.;
|
|
}
|
|
//----- cross T2 analog
|
|
if( detID[i] == 306 ) {
|
|
if( (vetoFlag & 4) == 0) vetoFlag += 4;
|
|
crossEnergy = e[i];
|
|
crossTime = e_t[i];
|
|
}
|
|
//----- cross B2 logic
|
|
if( detID[i] == 307 ) {
|
|
stopTime = e_t[i];
|
|
cdB2 = cfd[i]/16384.;
|
|
if( (vetoFlag & 4) == 0) vetoFlag += 4;
|
|
}
|
|
//----- MSX40
|
|
///if( detID[i] == 308 ) dE = e[i];
|
|
//----- MSX100
|
|
if( detID[i] == 309 ) dE = e[i];
|
|
//----- MSX40 logic
|
|
if( detID[i] == 310 ) {
|
|
startTime40 = e_t[i];
|
|
cfd40 = cfd[i]/16384.;
|
|
}
|
|
}
|
|
|
|
//================================== PID
|
|
Long64_t startTime = startTimeL;
|
|
double startCFD = cfdL;
|
|
|
|
if( startTime > 0 && stopTime > 0 && dE > 0 ){
|
|
if( stopTime > startTime ){
|
|
TOF = double(stopTime - startTime) - startCFD + cdB2;
|
|
}else{
|
|
TOF = -double(startTime - stopTime) - startCFD + cdB2 ;
|
|
}
|
|
TOF = TOF * 8; /// to ns
|
|
|
|
///============== PID correction
|
|
if( pidCorrFileName != "" ){
|
|
for( int k = 0; k < (int) pidCorr.size() ; k++){
|
|
if( int(pidCorr[k][0]) != runID/100 ) continue;
|
|
TOF = pidCorr[k][1] + pidCorr[k][2] * TOF;
|
|
dE = pidCorr[k][3] + pidCorr[k][4] * dE + pidCorr[k][5] * dE * dE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// TOF correction, A/Q = 3 to have a fixed TOF.
|
|
if( dE > 160./44.*(TOF + 260) +180 ) {
|
|
hPID0->Fill(TOF, dE);
|
|
hTOF->Fill(TOF);
|
|
hdE->Fill(dE);
|
|
}
|
|
|
|
///--------- slew correction
|
|
double newTOF = TOF - TOFCorrection(dE) - 234;
|
|
hPID->Fill(newTOF, dE);
|
|
|
|
flag += 1;
|
|
|
|
///======== Z vs A/Q
|
|
double c = 299.792458; /// mm/ns
|
|
double FL = 56423 ; /// mm
|
|
double Brho = 9.04; /// T.mm
|
|
double ma = 931.5;
|
|
double beta0 = Brho * c / TMath::Sqrt( 9*ma*ma + Brho*Brho*c*c); // for AoQ = 3
|
|
double tofOffset = 504.69; /// ns
|
|
|
|
double beta = FL/c/(newTOF+tofOffset);
|
|
double gamma = 1./TMath::Sqrt(1.-beta*beta);
|
|
|
|
Z = sqrt((dE + 11.9473) / 23.097) * TMath::Power(beta / beta0, 1.3) ;
|
|
AoQ = c * Brho / gamma/ beta / ma;
|
|
|
|
Z = 0.0153343 + 1.00339 * Z;
|
|
|
|
hPID2->Fill(AoQ, Z);
|
|
hZ->Fill(Z);
|
|
|
|
///if( 3.5 > Z && Z > 2.5 ) hZ3->Fill( AoQ * 3);
|
|
///if( 6.5 > Z && Z > 5.5 ) hZ6->Fill( AoQ * 6);
|
|
///if( 10.5 > Z && Z > 9.5 ) hZ10->Fill( AoQ * 10);
|
|
///if( 14.5 > Z && Z > 13.5 ) hZ14->Fill( AoQ * 14);
|
|
|
|
}
|
|
|
|
//================================== Implant
|
|
double sumA_L = 0;
|
|
double sumA_H = 0;
|
|
for( int i = 1; i <= 4 ; i++){
|
|
if( a_L[i] > 0 ) sumA_L += a_L[i];
|
|
if( a_H[i] > 0 ) sumA_H += a_H[i];
|
|
}
|
|
|
|
xIons = (a_L[3]+a_L[2])/sumA_L;
|
|
yIons = (a_L[1]+a_L[2])/sumA_L;
|
|
xBeta = (a_H[3]+a_H[2])/sumA_H;
|
|
yBeta = (a_H[1]+a_H[2])/sumA_H;
|
|
|
|
if( 0 < xIons && xIons < 1 && 0 < yIons && yIons < 1 ) flag += 2;
|
|
if( 0 < xBeta && xBeta < 1 && 0 < yBeta && yBeta < 1 ) flag += 4;
|
|
|
|
if( (flag & 1) == 0 ) { ///has beam
|
|
hImplantIons->Fill(xIons, yIons);
|
|
hImplantBeta->Fill(xBeta, yBeta);
|
|
hImplantDyIons->Fill(sumA_L, dyIonsEnergy[0]);
|
|
hImplantDyBeta->Fill(sumA_H, dyBetaEnergy[0]);
|
|
|
|
hImplantX->Fill(xIons, xBeta);
|
|
hImplantY->Fill(yIons, yBeta);
|
|
}
|
|
|
|
if( !TMath::IsNaN(veto_f) && !TMath::IsNaN(veto_r) && crossTime == 0 ){
|
|
///hImplantIons->Fill(xIons, yIons);
|
|
///hImplantBeta->Fill(xBeta, yBeta);
|
|
///hImplantDyIons->Fill(sumA_L, dyIonsEnergy[0]);
|
|
///hImplantDyBeta->Fill(sumA_H, dyBetaEnergy[0]);
|
|
///
|
|
///hImplantX->Fill(xIons, xBeta);
|
|
///hImplantY->Fill(yIons, yBeta);
|
|
}
|
|
|
|
|
|
hFlag->Fill(flag);
|
|
hvetoFlag->Fill(vetoFlag);
|
|
|
|
|
|
//============================== debug
|
|
if ( false ) {
|
|
|
|
printf("################# %lld, multi:%d\n", entry, multi);
|
|
|
|
printf("----- beam Line \n");
|
|
printf(" MSX100 eneergy : %f \n", dE);
|
|
printf(" startTime : %llu, CFD : %f \n", startTime, startCFD);
|
|
printf(" stopTime : %llu, CFD : %f \n", stopTime, cdB2);
|
|
printf(" TOF : %f ns \n", TOF);
|
|
|
|
printf("----- Ions, low gain \n");
|
|
for( int i = 1; i <= 4; i++ )printf("a%d : %f\n", i, a_L[i]);
|
|
printf("sum A : %f \n", sumA_L);
|
|
printf("x : %f , y : %f \n", xIons, yIons);
|
|
for ( int i = 0; i < 4; i++ )printf("dy : %u, %llu \n", dyIonsEnergy[i], dyIonsTime[i]);
|
|
|
|
printf("----- Beta, high gain \n");
|
|
for( int i = 1; i <= 4; i++ )printf("a%d : %f\n", i, a_H[i]);
|
|
printf("sum A : %f \n", sumA_H);
|
|
printf("x : %f , y : %f \n", xBeta, yBeta);
|
|
for ( int i = 0; i < 4; i++ )printf("dy : %u, %llu \n", dyBetaEnergy[i], dyBetaTime[i]);
|
|
|
|
printf("----- Veto \n");
|
|
printf(" cross Time : %llu \n", crossTime);
|
|
printf(" cross energy : %d \n", crossEnergy);
|
|
printf("veto_f energy : %f \n", veto_f);
|
|
printf( "veto_f Time : %llu \n", veto_f_time);
|
|
printf("veto_r energy : %f \n", veto_r);
|
|
printf( "veto_r Time : %llu \n", veto_r_time);
|
|
|
|
printf("============ flag : %d, vetoFlag : %d\n", flag, vetoFlag);
|
|
|
|
}
|
|
|
|
|
|
//============================= Progress
|
|
clock.Stop("timer");
|
|
Double_t time = clock.GetRealTime("timer");
|
|
clock.Start("timer");
|
|
|
|
if ( !shown ) {
|
|
if (fmod(time, 10) < 1 ){
|
|
printf( "%12llu[%2d%%]|%3.0f min %5.2f sec | expect:%5.2f min \n",
|
|
nProcessed,
|
|
TMath::Nint((nProcessed+1)*100./totnumEntry),
|
|
TMath::Floor(time/60.), time - TMath::Floor(time/60.)*60.,
|
|
totnumEntry*time/(nProcessed+1.)/60.);
|
|
shown = 1;}
|
|
}else{
|
|
if (fmod(time, 10) > 9 ){
|
|
shown = 0;
|
|
}
|
|
}
|
|
|
|
//============================= Rejection
|
|
if ( flag == 0 ) return kTRUE;
|
|
if ( Z < 0 ) return kTRUE;
|
|
|
|
//============================= Save Tree
|
|
if( saveNewTree ){
|
|
saveFile->cd();
|
|
newTree->Fill();
|
|
}
|
|
|
|
return kTRUE;
|
|
}
|
|
|
|
|
|
void peachCake::Terminate(){
|
|
|
|
printf("\n=============================================\n");
|
|
|
|
if( saveNewTree ){
|
|
saveFile->cd();
|
|
newTree->Write();
|
|
saveFile->Close();
|
|
}
|
|
|
|
if( plotHists ){
|
|
|
|
gStyle->SetOptStat(111111);
|
|
int div[2] = {4, 2} ; ///x, y
|
|
int len = canvasTitle.Sizeof();
|
|
canvasTitle.Remove(len - 3);
|
|
printf("|%s|\n", canvasTitle.Data());
|
|
TCanvas * c1 = new TCanvas("c1", canvasTitle, 700 * div[0], 700 * div[1]);
|
|
c1->Divide(div[0], div[1]);
|
|
int padID=0;
|
|
|
|
///padID ++;
|
|
///c1->cd(padID); //c1->cd(padID)->SetLogz();
|
|
///hPID0->Draw("colz");
|
|
|
|
///padID ++;
|
|
///c1->cd(padID); //c1->cd(padID)->SetLogz();
|
|
///hPID->Draw("colz");
|
|
|
|
padID ++;
|
|
c1->cd(padID); c1->cd(padID)->SetLogz();
|
|
hPID2->Draw("colz");
|
|
|
|
//padID ++;
|
|
//c1->cd(padID); c1->cd(padID)->SetGrid(); c1->cd(padID)->SetLogz();
|
|
//hCloverID->Draw("colz"); hCloverID->SetNdivisions(-13);
|
|
|
|
|
|
padID ++;
|
|
c1->cd(padID); c1->cd(padID)->SetLogz();
|
|
hImplantIons->Draw("colz");
|
|
|
|
padID ++;
|
|
c1->cd(padID); c1->cd(padID)->SetLogz(); hImplantBeta->Draw("colz");
|
|
|
|
//padID ++;
|
|
//c1->cd(padID); c1->cd(padID)->SetLogz(); hImplantBeta_veto->Draw("colz");
|
|
|
|
padID ++;
|
|
c1->cd(padID); c1->cd(padID)->SetLogz(); hImplantDyIons->Draw("colz");
|
|
|
|
padID ++;
|
|
c1->cd(padID); c1->cd(padID)->SetLogz(); hImplantDyBeta->Draw("colz");
|
|
|
|
padID ++;
|
|
c1->cd(padID); c1->cd(padID)->SetLogz(); hImplantX->Draw("colz");
|
|
|
|
padID ++;
|
|
c1->cd(padID); c1->cd(padID)->SetLogz(); hImplantY->Draw("colz");
|
|
|
|
padID ++;
|
|
c1->cd(padID); hFlag->Draw("");
|
|
hvetoFlag->SetLineColor(2); hvetoFlag->Draw("same");
|
|
|
|
}
|
|
|
|
//================ Save historgram
|
|
if( fHistRootName != "" ){
|
|
TFile * fHist = new TFile(fHistRootName, "recreate");
|
|
fHist->cd();
|
|
|
|
hTOF->Write();
|
|
hdE->Write();
|
|
hPID0->Write();
|
|
|
|
fHist->Close();
|
|
|
|
printf("---- Save PID histogram as %s \n", fHistRootName.Data());
|
|
}
|
|
|
|
}
|