145 lines
4.8 KiB
C++
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;
|
|
}
|