Files
geant4/examples/advanced/doiPET/analysis.cpp
T
2021-12-10 16:15:15 +00:00

145 lines
4.8 KiB
C++

//The following code is for anylizing axial sensitivity from coincidence list-mode data
//It takes source position of the event (of those which are detected by the scanner) and analises axial sensitivty.
//by Abdella M. Ahmed, 2020
#define _USE_MATH_DEFINES
#include <iostream>
#include <cfloat>
#include <cmath>
#include <fstream>
#include <string>
#include <limits>
#include <stdio.h>
#include <random>
#include <string>
#define UseROOT //ASCII or UseROOT
#ifdef UseROOT
//for root
#include "TRandom3.h"
#include "TFile.h"
#include "TNtuple.h"
#include "TROOT.h"
#include "TH1.h"
#include "TH2.h"
#include "TTree.h"
#include "TLeaf.h"
#include "TSystem.h"
#endif
#define AxialLength 216 //(mm), Axial length of the scanner
//Change this number based of the number of primary particles simulated in the "run.mac" file
#define NumberOfPrimaries 3000000 //Number of particles simulated
using namespace std;
int main(){
cout<<"============Axial Sensitivity Analysis =========================="<<endl;
int eventID0, blockID0, crystalID_axial0, crystalID_tangential0, DOI_ID0;
double timeStamp0, totalEdep0;
int eventID1, blockID1, crystalID_axial1, crystalID_tangential1, DOI_ID1;
double timeStamp1, totalEdep1;
double spositionX, spositionY, spositionZ; //source position
double z_offset = 0.0;//Axial offset position where the plane is located
double planeWidth = 3;// (mm)
int planeNumber;
float total_sensitivity = 0.0;
int numberOfSlices = int (AxialLength/planeWidth);
cout<<"Number of axial planes (slices) are: " <<numberOfSlices<<endl;
double Counts_per_plane[numberOfSlices];
ofstream OutFile("axial_sensitivity.csv");
string filename = "resultCoincidence.data";
string filepath = "";//provide the file path if it is stored in a different location.
ifstream InFile(filepath+filename);
if (!InFile.is_open())
{
cout << "Unable to open input file to read .... " << endl;
return 1;
}
if (!OutFile.is_open())
{
cout << "Unable to open out file to write ....";
return 1;
}
OutFile << "PlaneNmber" << "," << "Z(mm)" << "," << "Sensitivity(%)" << endl;
for (int i_plane = 0; i_plane < numberOfSlices; i_plane++){
Counts_per_plane[i_plane] = 0;
}
#ifdef ASCII
cout<<"\nASCII coincidence list-mode data is being analised..."<<endl;
while (InFile >> eventID0 >> blockID0 >> crystalID_axial0 >> crystalID_tangential0 >> DOI_ID0 >> timeStamp0 >> totalEdep0 >>
eventID1 >> blockID1 >> crystalID_axial1 >> crystalID_tangential1 >> DOI_ID1 >> timeStamp1 >> totalEdep1 >>
spositionX >> spositionY >> spositionZ){
planeNumber = int(spositionZ/planeWidth + numberOfSlices/2 - 0.5 + 0.5);
Counts_per_plane[planeNumber]++;
total_sensitivity++;
}
#endif
#ifdef UseROOT
cout<<"\nROOT coincidence list-mode data is being analised..."<<endl;
TFile *f = new TFile("resultCoincidence.root","READ");
TTree *Singles = (TTree*)gDirectory->Get("Coincidence");
Singles->SetBranchAddress("eventID0",&eventID0);
Singles->SetBranchAddress("blockID0",&blockID0);
Singles->SetBranchAddress("crystalID_axial0",&crystalID_axial0);
Singles->SetBranchAddress("crystalID_tangential0",&crystalID_tangential0);
Singles->SetBranchAddress("DOI_ID0",&DOI_ID0);
Singles->SetBranchAddress("timeStamp0",&timeStamp0);
Singles->SetBranchAddress("totalEdep0",&totalEdep0);
Singles->SetBranchAddress("eventID1",&eventID1);
Singles->SetBranchAddress("blockID1",&blockID1);
Singles->SetBranchAddress("crystalID_axial1",&crystalID_axial1);
Singles->SetBranchAddress("crystalID_tangential1",&crystalID_tangential1);
Singles->SetBranchAddress("DOI_ID1",&DOI_ID1);
Singles->SetBranchAddress("timeStamp1",&timeStamp1);
Singles->SetBranchAddress("totalEdep1",&totalEdep1);
Singles->SetBranchAddress("spositionX",&spositionX);
Singles->SetBranchAddress("spositionY",&spositionY);
Singles->SetBranchAddress("spositionZ",&spositionZ);
//
int nentries = 0;
nentries = Singles->GetEntries();
for(int entry=0; entry<nentries; entry++){
Singles->GetEntry(entry);
planeNumber = int(spositionZ/planeWidth + numberOfSlices/2 - 0.5 + 0.5);
Counts_per_plane[planeNumber]++;
total_sensitivity++;
}
#endif
//Save it into CSV file
for (int i_plane = 0; i_plane < numberOfSlices; i_plane++){
//Axial mid-position of the plane or slice
z_offset = (i_plane - numberOfSlices/2 + 0.5)*planeWidth;
OutFile << i_plane << "," << z_offset << "," << (Counts_per_plane[i_plane]/NumberOfPrimaries)*100 << endl;
}
cout<<"\nSensitivity evaluation has completed."<<endl;
cout<<"\nTotal Sensitivity (Number of coinsidence per total number of pair of photons): "<<(total_sensitivity/NumberOfPrimaries)*100 << "%"<<endl;
InFile.close();
OutFile.close();
return 0;
}