XIAEventBuilder/Analyzer.C

463 lines
14 KiB
C++
Raw Normal View History

2021-12-14 10:35:05 -05:00
#define Analyzer_cxx
#include "Analyzer.h"
#include <TH2.h>
#include <TStyle.h>
#include <TH1.h>
#include <TCutG.h>
2021-12-14 10:35:05 -05:00
#include <TCanvas.h>
#include <TMath.h>
#include <vector>
#include <stdio.h>
2021-12-14 10:35:05 -05:00
//############################################ User setting
2022-03-10 13:59:06 -05:00
int rawEnergyRange[2] = {0, 12000}; // in ch
int energyRange[3] = {1, 30, 800}; // keV {resol, min, max}
2021-12-14 10:35:05 -05:00
double BGO_threshold = 0; // in ch
2021-12-14 10:35:05 -05:00
2022-03-10 13:59:06 -05:00
int pidMaxRange[3] = {500, 300, 1800}; //nBin, tail, and peak
TString e_corr = "correction_e.dat";
2022-03-10 13:59:06 -05:00
TString cutFileName1 = "protonCut.root";
//TString cutFileName1 = "alphaCut.root";
//TString cutFileName1 = "LiCut.root";
bool save_ev2 = false;
2021-12-14 10:35:05 -05:00
//############################################ end of user setting
2021-12-14 10:35:05 -05:00
//############################################ histogram declaration
TH2F * heVID;
2021-12-16 19:36:36 -05:00
TH1F * he[NCRYSTAL];
2021-12-14 10:35:05 -05:00
2022-03-10 13:59:06 -05:00
//TH2F * hgg[NCRYSTAL][NCRYSTAL];
2021-12-14 10:35:05 -05:00
TH2F * hcoin;
2022-01-07 13:10:17 -05:00
TH2F * hcrystalBGO;
2022-03-10 13:59:06 -05:00
TH2F * hgg;
2022-01-07 14:46:32 -05:00
TH1F * hTDiff;
2022-03-10 13:59:06 -05:00
TH2F * hPID[NGAGG];
TH2F * hPID_A[NGAGG];
TH2F * hPID_B[NGAGG];
TH2F * hGAGGVID;
///----- after gamma gate
TH2F * hPID_A_g[NGAGG];
2022-01-13 18:23:41 -05:00
///----- after calibration and BGO veto
TH2F * heCalVID;
2021-12-16 19:36:36 -05:00
TH1F * heCal[NCRYSTAL];
2021-12-14 10:52:55 -05:00
TH2F * hcoinBGO;
2022-01-07 13:10:17 -05:00
TH2F * hcrystalBGO_G;
TH1F * hg[NCLOVER];
///----- after particle gate
TH1F * heCal_g[NCRYSTAL];
TH2F * heCalVID_g;
TH1F * hg_g[NCLOVER];
2022-03-10 13:59:06 -05:00
///============= cut
2022-03-10 13:59:06 -05:00
TCutG * cut1;
//############################################ BEGIN
2021-12-14 10:35:05 -05:00
void Analyzer::Begin(TTree * tree){
TString option = GetOption();
totnumEntry = tree->GetEntries();
printf( "=========================================================================== \n");
printf( "========================== Analysis.C/h ================================ \n");
printf( "====== total Entry : %lld \n", totnumEntry);
printf( "=========================================================================== \n");
2021-12-14 10:35:05 -05:00
printf("======================== Histograms declaration\n");
2021-12-16 10:30:38 -05:00
heVID = new TH2F("heVID", "e vs ID; det ID; e [ch]", NCRYSTAL, 0, NCRYSTAL, rawEnergyRange[1] - rawEnergyRange[0], rawEnergyRange[0], rawEnergyRange[1]);
heCalVID = new TH2F("heCalVID", Form("eCal vs ID (BGO veto > %.1f); det ID; Energy [keV]", BGO_threshold), NCRYSTAL, 0, NCRYSTAL, (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2]);
heCalVID_g = new TH2F("heCalVID_g", Form("eCal vs ID (BGO veto > %.1f & particle); det ID; Energy [keV]", BGO_threshold), NCRYSTAL, 0, NCRYSTAL, (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2]);
2021-12-24 16:29:50 -05:00
2022-01-07 14:46:32 -05:00
hTDiff = new TH1F("hTDiff", "data time different within an event; tick [10 ns]", 110, 0, 110);
2022-03-10 13:59:06 -05:00
heVID->SetNdivisions(-410, "X");
heCalVID->SetNdivisions(-410, "X");
2021-12-24 16:29:50 -05:00
2021-12-16 19:36:36 -05:00
for( int i = 0; i < NCRYSTAL; i ++){
he[i] = new TH1F( Form("he%02d", i), Form("e -%02d", i), rawEnergyRange[1] - rawEnergyRange[0], rawEnergyRange[0], rawEnergyRange[1]);
heCal[i] = new TH1F(Form("heCal%02d", i), Form("eCal-%02d (BGO veto > %.1f); Energy [keV]; count / %d keV", i, BGO_threshold, energyRange[0]), (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2]);
heCal_g[i] = new TH1F(Form("heCal_g%02d", i), Form("eCal-%02d (BGO veto > %.1f & particle); Energy [keV]; count / %d keV", i, BGO_threshold, energyRange[0]), (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2]);
2021-12-14 10:35:05 -05:00
}
for( int i = 0; i < NCLOVER; i++){
hg[i] = new TH1F(Form("hg%02d", i), Form("Clover-%02d (added-back)", i), (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2]);
hg_g[i] = new TH1F(Form("hg_g%02d", i), Form("Clover-%02d (added-back) particle", i), (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2]);
}
2022-03-10 13:59:06 -05:00
hgg = new TH2F("hgg", "Gamma - Gamma", (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2], (energyRange[2] - energyRange[1])/energyRange[0], energyRange[1], energyRange[2]);
for( int i = 0; i < NGAGG; i++){
hPID[i] = new TH2F(Form("hPID%02d", i), Form("PID-%2d; tail; peak ", i), pidMaxRange[0], -20, pidMaxRange[1], pidMaxRange[0], -50, pidMaxRange[2]);
hPID_A[i] = new TH2F(Form("hPID_A%02d",i), Form("PID_A detID = %2d; tail; peak ", i) , pidMaxRange[0], -20, pidMaxRange[1], pidMaxRange[0], -50, pidMaxRange[2]);
hPID_B[i] = new TH2F(Form("hPID_B%02d",i), Form("PID_B detID = %2d; tail; peak ", i) , pidMaxRange[0], -20, pidMaxRange[1], pidMaxRange[0], -50, pidMaxRange[2]);
hPID_A_g[i] = new TH2F(Form("hPID_A_g%02d",i), Form("PID_A detID = %2d (gated); tail; peak ", i) , pidMaxRange[0], -20, pidMaxRange[1], pidMaxRange[0], -50, pidMaxRange[2]);
}
2022-01-13 18:23:41 -05:00
2022-03-10 13:59:06 -05:00
hGAGGVID = new TH2F("hGAGGVID", "GAGG V ID", 80, 0, 80, 400, -50, 2000);
2022-01-13 18:23:41 -05:00
2022-03-10 13:59:06 -05:00
/**
2021-12-16 19:36:36 -05:00
for( int i = 0; i < NCRYSTAL; i++){
for( int j = i+1; j < NCRYSTAL; j++){
//hgg[i][j] = new TH2F(Form("hgg%02d%02d", i, j), Form("e%02d vs e%02d; e%02d; e%02d", i, j, i, j),
// (rawEnergyRange[1] - rawEnergyRange[0])/2, rawEnergyRange[0], rawEnergyRange[1],
// (rawEnergyRange[1] - rawEnergyRange[0])/2, rawEnergyRange[0], rawEnergyRange[1]);
2021-12-14 10:35:05 -05:00
}
2022-03-10 13:59:06 -05:00
}*/
2021-12-14 10:35:05 -05:00
2021-12-16 19:36:36 -05:00
hcoin = new TH2F("hcoin", "detector coin.; det ID; det ID", NCRYSTAL, 0, NCRYSTAL, NCRYSTAL, 0 , NCRYSTAL);
2021-12-16 19:36:36 -05:00
hcoinBGO = new TH2F("hcoinBGO", Form("detector coin. (BGO veto > %.1f); det ID; det ID", BGO_threshold), NCRYSTAL, 0, NCRYSTAL, NCRYSTAL, 0 , NCRYSTAL);
hcrystalBGO = new TH2F("hcrystalBGO", Form("crystal vs BGO ; det ID; BGO ID"), NCRYSTAL, 0, NCRYSTAL, NBGO, 0 , NBGO);
2022-01-07 13:10:17 -05:00
hcrystalBGO_G = new TH2F("hcrystalBGO_G", Form("crystal vs BGO (BGO veto); det ID; BGO ID"), NCRYSTAL, 0, NCRYSTAL, NBGO, 0 , NBGO);
2021-12-14 10:35:05 -05:00
printf("======================== Load parameters.\n");
eCorr = LoadCorrectionParameters(e_corr);
2022-03-10 13:59:06 -05:00
if( cutFileName1 != ""){
printf("======================== Load cuts.\n");
2022-03-10 13:59:06 -05:00
TFile * cutFile1 = new TFile(cutFileName1);
cut1 = (TCutG *) cutFile1->Get("CUTG");
printf(" %s is loaded.\n", cut1->GetName());
}
2022-03-10 13:59:06 -05:00
saveEV2 = save_ev2;
2021-12-14 10:35:05 -05:00
}
2022-03-10 13:59:06 -05:00
void Analyzer::PID_calculation(int ID){
}
//############################################ PROCESS
2021-12-14 10:35:05 -05:00
Bool_t Analyzer::Process(Long64_t entry){
ProcessedEntries++;
/*********** Progress Bar ******************************************/
if (ProcessedEntries>totnumEntry*Frac-1) {
TString msg; msg.Form("%llu", totnumEntry/1000);
2021-12-14 10:35:05 -05:00
int len = msg.Sizeof();
printf(" %3.0f%% (%*llu/%llu k) processed in %6.1f sec | expect %6.1f sec\n",
Frac*100, len, ProcessedEntries/1000,totnumEntry/1000,StpWatch.RealTime(), StpWatch.RealTime()/Frac);
2021-12-14 10:35:05 -05:00
StpWatch.Start(kFALSE);
Frac+=0.1;
}
b_energy->GetEntry(entry);
b_time->GetEntry(entry);
b_multi->GetEntry(entry);
b_multiCry->GetEntry(entry);
b_detID->GetEntry(entry);
2022-01-13 18:23:41 -05:00
b_qdc->GetEntry(entry);
2022-03-10 13:59:06 -05:00
b_pileup->GetEntry(entry);
2021-12-14 10:35:05 -05:00
if( multi == 0 ) return kTRUE;
for( int i = 0; i < NCRYSTAL; i++) eCal[i] = TMath::QuietNaN();
for( int i = 0; i < NCLOVER; i++) gamma[i] = 0;
2021-12-14 10:35:05 -05:00
2022-01-07 14:46:32 -05:00
///printf("---------------------------- %d \n", multi);
2022-01-13 18:23:41 -05:00
2022-03-10 13:59:06 -05:00
double bg[NGAGG][2]={0}, peak[NGAGG][2]={0}, tail[NGAGG][2] = {0};
int count[NGAGG] = {0} ;
///=========== make the particle gate
for( int i = 0; i < multi ; i ++){
2022-03-10 13:59:06 -05:00
if( e_t[i] - e_t[0] > 20 ) continue;
if( pileup[i] == 1 ) continue;
if( e[i] < 100 ) continue;
int id = detID[i];
2022-03-10 13:59:06 -05:00
if( id < 200 || id >= 300 ) continue;
id = id - 200;
hGAGGVID->Fill(id, e[i]);
2022-03-10 13:59:06 -05:00
// GAGG_A
if( (0 <= id && id < 50) ) {
bg[id][0] = (qdc[i][0] + qdc[i][1])/60.;
peak[id][0] = qdc[i][3]/20. - bg[id][0];
tail[id][0] = qdc[i][5]/55. - bg[id][0];
hPID_A[id]->Fill( tail[id][0], peak[id][0]);
count[id] ++;
}
2022-03-10 13:59:06 -05:00
// GAGG_B
if( 50 <= id ) {
id = id - 50;
bg[id][1] = (qdc[i][0] + qdc[i][1])/60.;
peak[id][1] = qdc[i][3]/20. - bg[id][1];
tail[id][1] = qdc[i][5]/55. - bg[id][1];
hPID_B[id]->Fill( tail[id][1], peak[id][1]);
count[id]++;
}
}
2022-03-10 13:59:06 -05:00
///#########################################################
///================ coincident gate between proton and gamma
///printf("======================\n");
for ( int i = 0 ; i < NGAGG ; i++){
if( count[i] == 2 ){
double tailAvg = (tail[i][0]+tail[i][1])/2.;
double peakAvg = (peak[i][0]+peak[i][1])/2.;
hPID[i]->Fill( tailAvg, peakAvg);
}
}
2022-03-10 13:59:06 -05:00
///=========== Looping data for the event
for( int i = 0; i < multi ; i ++){
if( pileup[i] == 1 ) continue;
2022-01-07 14:46:32 -05:00
int id = detID[i];
///printf("%d %f %llu\n", id, e[i], e_t[i]);
2021-12-14 10:35:05 -05:00
//======== Fill raw data
2022-01-07 14:46:32 -05:00
if( 0 <= id && id < NCRYSTAL ){ /// gamma data
heVID->Fill( id, e[i]);
he[id]->Fill(e[i]);
for ( int j = i + 1; j < multi; j++){
2022-01-07 14:46:32 -05:00
if( 100 <= detID[j] && detID[j] < 200 ) hcrystalBGO->Fill(id, detID[j]-100); /// crystal - BGO coincident
2022-01-07 14:46:32 -05:00
if( detID[j] < 100 ) hcoin->Fill(id, detID[j]); /// crystal-crystal coincident
}
}
2022-01-07 14:46:32 -05:00
if ( 100 < id && id < 200 ){ /// BGO data
2021-12-14 10:35:05 -05:00
}
2022-01-13 18:23:41 -05:00
if( 200 < id && id < 300){ /// GAGG
2022-03-10 13:59:06 -05:00
continue;
2022-01-13 18:23:41 -05:00
}
2022-03-10 13:59:06 -05:00
//======== TDiff veto
//if( !(e_t[i] - e_t[0] < 20 || e_t[i] - e_t[0] > 35) ) continue;
if( e_t[i] - e_t[0] > 20 ) continue;
2022-01-13 18:23:41 -05:00
2022-01-07 14:46:32 -05:00
if ( i > 0 ) hTDiff->Fill( e_t[i] - e_t[0]);
2022-01-07 14:46:32 -05:00
2021-12-14 10:35:05 -05:00
//======== BGO veto
bool dropflag = false;
2022-01-07 14:46:32 -05:00
if( id < NCRYSTAL && multi > 1) {
for( int j = i + 1; j < multi; j++){
2022-01-07 14:46:32 -05:00
if( detID[j] >= 100 && (detID[j]-100)*4 <= id && id < (detID[j]-100 +1)*4) {
dropflag = true;
break;
}
2021-12-14 10:35:05 -05:00
}
}
2022-03-10 13:59:06 -05:00
if( dropflag ) continue;
2021-12-14 10:35:05 -05:00
2022-01-07 14:46:32 -05:00
if( 0<= id && id < NCRYSTAL ) {
if( e_corr == "" ){
2022-01-07 14:46:32 -05:00
eCal[id] = e[i];
}else{
2022-03-10 13:59:06 -05:00
///========= apply energy correction
2022-01-07 14:46:32 -05:00
int order = (int) eCorr[id].size();
eCal[id] = 0;
for( int k = 0; k < order ; k++){
eCal[id] += eCorr[id][k] * TMath::Power(e[i], k);
}
}
2022-03-10 13:59:06 -05:00
if( id != 30 ) heCalVID->Fill( id, eCal[id]);
2022-01-07 14:46:32 -05:00
heCal[id]->Fill(eCal[id]);
2022-01-07 13:10:17 -05:00
for ( int j = i + 1; j < multi; j++){
2022-01-07 14:46:32 -05:00
if( 100 <= detID[j] && detID[j] < 200 ) hcrystalBGO_G->Fill(id, detID[j]-100); /// crystal - BGO coincident
}
///========== add back and remove cross talk
int cloverID = id /4;
2022-03-10 13:59:06 -05:00
if( eCal[id] > energyRange[1]/4. ) gamma[cloverID] += eCal[id];
2021-12-14 10:52:55 -05:00
}
2022-01-07 14:46:32 -05:00
2021-12-14 10:35:05 -05:00
}
2022-03-10 13:59:06 -05:00
for( int i = 0; i < NCLOVER; i++){
for( int j = 0; j < NCLOVER; j++){
if( gamma[i] > 0 && gamma[j] > 0 && i != j ) hgg->Fill( gamma[i], gamma[j]);
}
}
for( int i = 0 ; i < NCLOVER; i++){
if( gamma[i] > 0 ) {
hg[i]->Fill(gamma[i]);
2022-03-10 13:59:06 -05:00
for( int gi = 0; gi < NGAGG ; gi ++){
if( cut1->IsInside(tail[gi][0], peak[gi][0]) ) {
hg_g[i]->Fill(gamma[i]);
}
}
}
if( abs(gamma[i] - 1052 ) < 8 ){
for( int i = 0; i < NGAGG ; i ++){
hPID_A_g[i]->Fill( tail[i][0], peak[i][0]);
}
}
}
2022-01-13 18:23:41 -05:00
if ( saveEV2) Save2ev2();
2021-12-14 10:35:05 -05:00
return kTRUE;
}
//############################################ TERMINATE
2021-12-14 10:35:05 -05:00
void Analyzer::Terminate(){
2022-03-10 13:59:06 -05:00
if(saveEV2) fclose(outEV2);
printf("============================== finishing.\n");
gROOT->cd();
int canvasXY[2] = {1600 , 800} ;// x, y
int canvasDiv[2] = {4,2};
TCanvas *cCanvas = new TCanvas("cCanvas", "" ,canvasXY[0],canvasXY[1]);
cCanvas->Modified(); cCanvas->Update();
cCanvas->cd(); cCanvas->Divide(canvasDiv[0],canvasDiv[1]);
gStyle->SetOptStat("neiou");
int padID = 0;
//========================= canvas 1
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(0);
heCalVID->Draw("colz");
//========================= canvas 2
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(1);
hGAGGVID->Draw("colz");
//========================= canvas 3
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(0);
hTDiff->Draw();
//========================= canvas 3
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(0);
hg[6]->Draw();
//========================= canvas 5
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(1);
//heCalVID->Draw("colz");
hPID[9]->Draw("colz");
//========================= canvas 6
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(1);
hPID_A[9]->Draw("colz");
cut1->Draw("same");
//========================= canvas 7
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(1);
hPID_B[9]->Draw("colz");
//========================= canvas 8
padID++;
cCanvas->cd(padID);
cCanvas->cd(padID)->SetLogz(1);
//hPID_A_g[9]->Draw("colz");
hg_g[6]->Draw();
/*
//========================= canvas 1
2021-12-14 10:52:55 -05:00
cCanvas->cd(4);
cCanvas->cd(4)->SetLogy(1);
2022-01-13 18:23:41 -05:00
//gROOT->ProcessLine(".x script.C");
//hcrystalBGO_G->Draw("colz");
hg[0]->SetLineColor(2);
hg[0]->Draw();
hg_g[0]->Draw("same");
//hcoinBGO->Draw("colz");
TCanvas *cAux = new TCanvas("cAux", "" ,1000, 0, 800,600);
cAux->cd();
TH1F * h0 = (TH1F *) heCal[0]->Clone("h0");
h0->Add(heCal[1]);
h0->Add(heCal[2]);
h0->Add(heCal[3]);
TH1F * h0_g = (TH1F *) heCal_g[0]->Clone("h0_g");
h0_g->Add(heCal_g[1]);
h0_g->Add(heCal_g[2]);
h0_g->Add(heCal_g[3]);
h0->SetLineColor(kGreen+3);
h0->Draw();
h0_g->Draw("same");
hg[0]->Draw("same");
2022-03-10 13:59:06 -05:00
/**/
2021-12-16 19:36:36 -05:00
printf("=============== loaded AutoFit.C, try showFitMethos()\n");
2021-12-20 17:26:48 -05:00
gROOT->ProcessLine(".L armory/AutoFit.C");
printf("=============== Analyzer Utility\n");
2021-12-20 17:26:48 -05:00
gROOT->ProcessLine(".L armory/Analyzer_Utili.c");
gROOT->ProcessLine("listDraws()");
2021-12-14 10:35:05 -05:00
2021-12-16 19:36:36 -05:00
2021-12-14 10:35:05 -05:00
}