Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/examples/advanced/doiPET/analysis.cpp

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 //The following code is for anylizing axial sensitivity from coincidence list-mode data
  2 //It takes source position of the event (of those which are detected by the scanner) and analises axial sensitivty.
  3 //by Abdella M. Ahmed, 2020
  4 
  5 #define _USE_MATH_DEFINES
  6 #include <iostream>
  7 #include <cfloat>
  8 #include <cmath>
  9 #include <fstream>
 10 #include <string>
 11 #include <limits>
 12 #include <stdio.h>
 13 #include <random>
 14 #include <string>
 15 
 16 #define UseROOT //ASCII or UseROOT
 17 
 18 #ifdef UseROOT
 19 //for root
 20 #include "TRandom3.h"
 21 #include "TFile.h"
 22 #include "TNtuple.h"
 23 #include "TROOT.h"
 24 #include "TH1.h"
 25 #include "TH2.h"
 26 #include "TTree.h"
 27 #include "TLeaf.h"
 28 #include "TSystem.h"
 29 #endif
 30 
 31 
 32 
 33 
 34 #define AxialLength 216 //(mm), Axial length of the scanner
 35 
 36 //Change this number based of the number of primary particles simulated in the "run.mac" file
 37 #define NumberOfPrimaries 3000000 //Number of particles simulated
 38 
 39 using namespace std;
 40 int main(){
 41 
 42   cout<<"============Axial Sensitivity Analysis =========================="<<endl;
 43 
 44   int eventID0, blockID0, crystalID_axial0, crystalID_tangential0, DOI_ID0; 
 45   double timeStamp0, totalEdep0;
 46     int eventID1, blockID1, crystalID_axial1, crystalID_tangential1, DOI_ID1;
 47   double timeStamp1, totalEdep1;
 48   double  spositionX, spositionY, spositionZ; //source position
 49 
 50   double z_offset = 0.0;//Axial offset position where the plane is located
 51   double planeWidth = 3;// (mm)
 52   int planeNumber;
 53 
 54   float total_sensitivity = 0.0;
 55 
 56   int numberOfSlices = int (AxialLength/planeWidth);
 57   cout<<"Number of axial planes (slices) are: " <<numberOfSlices<<endl;
 58   double Counts_per_plane[numberOfSlices];
 59 
 60   ofstream OutFile("axial_sensitivity.csv");
 61   string filename = "resultCoincidence.data";
 62   string filepath = "";//provide the file path if it is stored in a different location.
 63   ifstream InFile(filepath+filename);
 64 
 65   if (!InFile.is_open())
 66   {
 67     cout << "Unable to open input file to read .... " << endl;
 68     return 1;
 69   }
 70   if (!OutFile.is_open())
 71   {
 72     cout << "Unable to open out file to write ....";
 73     return 1;
 74   }
 75 
 76   OutFile << "PlaneNmber" << "," << "Z(mm)" << "," << "Sensitivity(%)" << endl;
 77 
 78   for (int i_plane = 0; i_plane < numberOfSlices; i_plane++){
 79     Counts_per_plane[i_plane] = 0;
 80   }
 81 #ifdef ASCII
 82     cout<<"\nASCII coincidence list-mode data is being analised..."<<endl;
 83   while (InFile >> eventID0 >> blockID0 >> crystalID_axial0 >> crystalID_tangential0 >> DOI_ID0 >> timeStamp0 >> totalEdep0 >> 
 84                  eventID1 >> blockID1 >> crystalID_axial1 >> crystalID_tangential1 >> DOI_ID1 >> timeStamp1 >> totalEdep1 >> 
 85            spositionX >> spositionY >> spositionZ){
 86     
 87     planeNumber = int(spositionZ/planeWidth + numberOfSlices/2 - 0.5 + 0.5);
 88     Counts_per_plane[planeNumber]++;
 89     total_sensitivity++;
 90   }
 91 #endif
 92   
 93   
 94 #ifdef UseROOT
 95   cout<<"\nROOT coincidence list-mode data is being analised..."<<endl;
 96   TFile *f = new TFile("resultCoincidence.root","READ");
 97   TTree *Singles = (TTree*)gDirectory->Get("Coincidence");
 98 
 99   Singles->SetBranchAddress("eventID0",&eventID0);
100   Singles->SetBranchAddress("blockID0",&blockID0);
101   Singles->SetBranchAddress("crystalID_axial0",&crystalID_axial0);
102   Singles->SetBranchAddress("crystalID_tangential0",&crystalID_tangential0);
103   Singles->SetBranchAddress("DOI_ID0",&DOI_ID0);
104   Singles->SetBranchAddress("timeStamp0",&timeStamp0);
105   Singles->SetBranchAddress("totalEdep0",&totalEdep0);
106 
107   Singles->SetBranchAddress("eventID1",&eventID1);
108   Singles->SetBranchAddress("blockID1",&blockID1);
109   Singles->SetBranchAddress("crystalID_axial1",&crystalID_axial1);
110   Singles->SetBranchAddress("crystalID_tangential1",&crystalID_tangential1);
111   Singles->SetBranchAddress("DOI_ID1",&DOI_ID1);
112   Singles->SetBranchAddress("timeStamp1",&timeStamp1);
113   Singles->SetBranchAddress("totalEdep1",&totalEdep1);
114 
115   Singles->SetBranchAddress("spositionX",&spositionX);
116   Singles->SetBranchAddress("spositionY",&spositionY);
117   Singles->SetBranchAddress("spositionZ",&spositionZ);
118 
119   //
120   int nentries = 0;
121   nentries = Singles->GetEntries();
122   for(int entry=0; entry<nentries; entry++){
123     Singles->GetEntry(entry);      
124     planeNumber = int(spositionZ/planeWidth + numberOfSlices/2 - 0.5 + 0.5);
125     Counts_per_plane[planeNumber]++;
126     total_sensitivity++;
127   }
128 #endif 
129 
130   
131   //Save it into CSV file
132   for (int i_plane = 0; i_plane < numberOfSlices; i_plane++){
133     //Axial mid-position of the plane or slice
134     z_offset = (i_plane - numberOfSlices/2 + 0.5)*planeWidth;
135 
136     OutFile << i_plane << "," << z_offset << "," << (Counts_per_plane[i_plane]/NumberOfPrimaries)*100 << endl;
137   }
138   cout<<"\nSensitivity evaluation has completed."<<endl;
139   cout<<"\nTotal Sensitivity (Number of coinsidence per total number of pair of photons): "<<(total_sensitivity/NumberOfPrimaries)*100 << "%"<<endl;
140   InFile.close();
141   OutFile.close();
142 
143   return 0;
144 }
145