Import Geant4 11.2.0 source tree
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
//******************************************************************************************
|
||||
// BinToStd_GammaAtCreation.C
|
||||
// Root command file
|
||||
// Type: root BinToStd_GammaAtCreation.C
|
||||
//
|
||||
// Read the output file GammaAtCreation.dat that is generated by Geant4
|
||||
// tomography simulation It read all the gamma at creation information, and
|
||||
// rewrite the events in a binary file PixeEvent_std_AtCreation.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//*******************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
|
||||
// double DegreeToRadian(double degree) { return (PI * degree / 180.); }
|
||||
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
void BinToStd_GammaAtCreation()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector = 135.; // angle of detector relative to the incident
|
||||
// direction of the primary protons //
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex
|
||||
// angle of the right circular cone in radian
|
||||
double theta = 70 * TMath::DegToRad(); // in radian
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
FILE* input = fopen("../build/GammaAtCreation.dat", "rb");
|
||||
FILE* out = fopen("../build/PixeEvent_std_AtCreation.DAT", "wb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input GammaAtCreation.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
PixeEvent pixeEvent;
|
||||
Point centerOfDetector;
|
||||
Point gammaMomentum;
|
||||
long long count = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
|
||||
// while(!feof(input)) //if not the end, read
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
// if(runID==5) continue;
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//(begin)*****************************************************************
|
||||
// the following codes are used only when in the simulation
|
||||
// the index of projection, slice and pixel is not
|
||||
// correctly configured
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
//(end)******************************************************************
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf(
|
||||
"---------RunID=%d:\nProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,"
|
||||
"nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> gammaAtCreation(nbParticle);
|
||||
fread(&gammaAtCreation[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means
|
||||
// the angle between source direction and detector, which should be constant
|
||||
// when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtCreation[i].energy_keV >= 40.95 || gammaAtCreation[i].energy_keV <= 0.9)
|
||||
continue; // gamma selection
|
||||
|
||||
gammaMomentum.m_x = gammaAtCreation[i].mx;
|
||||
gammaMomentum.m_y = gammaAtCreation[i].my;
|
||||
gammaMomentum.m_z = gammaAtCreation[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtCreation[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&pixeEvent, 7, 1, out);
|
||||
count++;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
// printf("momentum: (%f, %f, %f), energy: %f keV %d 10eV\n",
|
||||
// gammaAtCreation[i].mx, gammaAtCreation[i].my, gammaAtCreation[i].mz,
|
||||
// gammaAtCreation[i].energy_keV, pixeEvent.energy_10eV);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(
|
||||
"---------------Number of PixeEvent in total: "
|
||||
"%lld------------------------\n",
|
||||
count);
|
||||
fclose(input);
|
||||
fclose(out);
|
||||
|
||||
// Recheck the output file in case
|
||||
// FILE* input2 = fopen("PixeEvent_std_AtCreation.DAT","rb");
|
||||
// PixeEvent p;
|
||||
// while(fread(&p, 7, 1, input2))
|
||||
// {
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,
|
||||
// Energy_10eV=%d\n", p.projectionIndex, p.sliceIndex, p.pixelIndex,
|
||||
// p.energy_10eV);
|
||||
|
||||
// }
|
||||
// fclose(input2);
|
||||
}
|
||||
@@ -0,0 +1,196 @@
|
||||
//***********************************************************************************************************
|
||||
// BinToStd_GammaAtExit.C
|
||||
// Root command file
|
||||
// Type: root BinToStd_GammaAtExit.C
|
||||
//
|
||||
// Read the output file ProtonAtExit.dat that is generated by Geant4 tomography
|
||||
// simulation It read all the gamma at exit information, and rewrite the events
|
||||
// in a binary file PixeEvent_std_AtExit.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
void BinToStd_GammaAtExit()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector = 135.; // angle of detector relative to the incident
|
||||
// direction of the primary protons //
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex
|
||||
// angle of the right circular cone in radian
|
||||
double theta = 70 * TMath::DegToRad(); // in radian
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
FILE* input = fopen("../build/GammaAtExit.dat", "rb");
|
||||
FILE* out = fopen("../build/PixeEvent_std_AtExit.DAT", "wb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input GammaAtExit.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
PixeEvent pixeEvent;
|
||||
Point centerOfDetector;
|
||||
Point gammaMomentum;
|
||||
long long count = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
|
||||
// while(!feof(input)) //if not the end, read
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
// the following codes are used only when in the simulation
|
||||
// ************(begin) the index of projection, slice and pixel is not
|
||||
// correctly configured
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
//************************************************************************(end)
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf(
|
||||
"---------RunID=%d:\nProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,"
|
||||
"nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> gammaAtExit(nbParticle);
|
||||
fread(&gammaAtExit[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means
|
||||
// the angle between source direction and detector, which should be constant
|
||||
// when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtExit[i].energy_keV >= 40.95 || gammaAtExit[i].energy_keV <= 0.9) continue;
|
||||
|
||||
gammaMomentum.m_x = gammaAtExit[i].mx;
|
||||
gammaMomentum.m_y = gammaAtExit[i].my;
|
||||
gammaMomentum.m_z = gammaAtExit[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtExit[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&pixeEvent, 7, 1, out);
|
||||
count++;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
// printf("momentum: (%f, %f, %f), energy: %f keV %d 10eV\n",
|
||||
// gammaAtExit[i].mx, gammaAtExit[i].my, gammaAtExit[i].mz,
|
||||
// gammaAtExit[i].energy_keV, pixeEvent.energy_10eV);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
}
|
||||
}
|
||||
}
|
||||
printf(
|
||||
"\n---------------Number of PixeEvent in total: "
|
||||
"%lld------------------------\n",
|
||||
count);
|
||||
fclose(input);
|
||||
fclose(out);
|
||||
|
||||
// Recheck the output file in case
|
||||
// FILE* input2;
|
||||
// input2 = fopen("PixeEvent_std_AtExit.DAT","rb");
|
||||
// PixeEvent p;
|
||||
// while(fread(&p, 7, 1, input2))
|
||||
// {
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,
|
||||
// Energy_10eV=%d\n", p.projectionIndex, p.sliceIndex, p.pixelIndex,
|
||||
// p.energy_10eV);
|
||||
|
||||
// }
|
||||
// fclose(input2);
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
//***********************************************************************************************************
|
||||
// BinToStd_ProtonAtExit.C
|
||||
// Root command file
|
||||
// Type: root BinToStd_ProtonAtExit.C
|
||||
//
|
||||
// Read the output file ProtonAtExit.dat that is generated by Geant4 tomography simulation
|
||||
// It reads proton at exit information, and rewrite the events in a binary file StimEvent_std.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct StimEvent
|
||||
{
|
||||
uint16_t energy_keV; // different from Pixe Event, it is in keV
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
void BinToStd_ProtonAtExit()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
// angle of detector relative to the incident direction of the primary protons at first projection
|
||||
// for proton, it is fixed to 0 degree, namely opposite to the source
|
||||
double angleOfDetector = 0.;
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex angle of the right
|
||||
// circular cone in radian
|
||||
double theta = 10.2 * TMath::DegToRad(); // in radian
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
FILE* input = fopen("../build/ProtonAtExit.dat", "rb");
|
||||
FILE* out = fopen("../build/StimEvent_std.DAT", "wb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input ProtonAtExit.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
StimEvent stimEvent;
|
||||
Point centerOfDetector;
|
||||
Point protonMomentum;
|
||||
long long count = 0;
|
||||
int runID = -1;
|
||||
|
||||
// while(!feof(input)) //if not the end, read
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//(begin)***************************************************************
|
||||
// the following codes are used only when in the simulation
|
||||
// the index of projection, slice and pixel is not
|
||||
// correctly configured
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
//(end)******************************************************************
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("---------RunID=%d: ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> protonAtExit(nbParticle);
|
||||
fread(&protonAtExit[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// proton selection: energy should be lower than 4095 keV
|
||||
if (protonAtExit[i].energy_keV >= 4095) continue; // proton selection
|
||||
|
||||
protonMomentum.m_x = protonAtExit[i].mx;
|
||||
protonMomentum.m_y = protonAtExit[i].my;
|
||||
protonMomentum.m_z = protonAtExit[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, protonMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
stimEvent.energy_keV = floor(protonAtExit[i].energy_keV + 0.5);
|
||||
stimEvent.projectionIndex = runInfo.projectionIndex;
|
||||
stimEvent.sliceIndex = runInfo.sliceIndex;
|
||||
stimEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&stimEvent, 7, 1, out);
|
||||
count++;
|
||||
// printf("energy=%f keV\n",protonAtExit[i].energy_keV);
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of StimEvent in total: %lld------------------------\n", count);
|
||||
fclose(input);
|
||||
fclose(out);
|
||||
|
||||
// FILE* input2;
|
||||
// input2 = fopen("StimEvent_std.DAT","rb");
|
||||
// StimEvent p;
|
||||
// double eventId = -1;
|
||||
// while(fread(&p, 7, 1, input2))
|
||||
// {
|
||||
|
||||
// if(p.projectionIndex == 8 &&p.sliceIndex ==64 && p.pixelIndex==64)
|
||||
// {
|
||||
// eventId++;
|
||||
// printf("StimEvent_%.0f ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_keV=%d keV\n",
|
||||
// eventId, p.projectionIndex, p.sliceIndex, p.pixelIndex, p.energy_keV);
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
// fclose(input2);
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
//***********************************************************************************************************
|
||||
// BinToStd_gamma_position.C
|
||||
// Root command file
|
||||
// Type: root BinToStd_gamma_position.C
|
||||
//
|
||||
// Read the X-ray output file that is generated by Geant4 tomography
|
||||
// simulation. It reads gamma information, either at creation, or at exit, and rewrite the events
|
||||
// in a binary file PixeEvent_std.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
bool IsEqual(double a, double b, double eps, double releps)
|
||||
{
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fabs(a - b) <= releps * fabs(b)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fabs(a - b) < eps) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
double eps = 1e-20; // absolut difference
|
||||
double releps = 1e-10; // relative difference
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else {
|
||||
// printf(" acos: %f, radius: %f\n", r, theta);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDetected_position(Point poi1, Point poi2, double r)
|
||||
{
|
||||
double a = sqrt((poi1.m_x - poi2.m_x) * (poi1.m_x - poi2.m_x)
|
||||
+ (poi1.m_y - poi2.m_y) * (poi1.m_y - poi2.m_y)
|
||||
+ (poi1.m_z - poi2.m_z) * (poi1.m_z - poi2.m_z));
|
||||
|
||||
// if(a <= r) return true;
|
||||
if (a > r)
|
||||
return false;
|
||||
|
||||
else {
|
||||
// printf(" distance of two points: %f, radius: %f\n", a, r);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void BinToStd_gamma_position()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 1;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 1;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector = 135.; // angle of detector relative to the incident
|
||||
|
||||
double distanceObjectDetector = 22000.; // um
|
||||
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex
|
||||
// angle of the right circular cone in radian
|
||||
double theta = 14.726 * TMath::DegToRad(); // in radian
|
||||
double radiusOfDetector = distanceObjectDetector * tan(theta);
|
||||
bool usePosition = true;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
FILE* input = fopen("../build/GammaAtExit.dat", "rb");
|
||||
FILE* out = fopen("../build/PixeEvent_std_AtExit.DAT", "wb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
PixeEvent pixeEvent;
|
||||
Point centerOfDetector;
|
||||
Point gammaMomentum;
|
||||
Point gammaPosition;
|
||||
Point intersectionPoint;
|
||||
long long count = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
|
||||
// while(!feof(input)) //if not the end, read
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//(begin)****************************************************************
|
||||
// the following codes are used only when in the simulation
|
||||
// the index of projection, slice and pixel is not
|
||||
// correctly configured
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
|
||||
//(end)******************************************************************
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf(
|
||||
"---------RunID=%d:\nProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,"
|
||||
"nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> gammaAtExit(nbParticle);
|
||||
fread(&gammaAtExit[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means
|
||||
// the angle between source direction and detector, which should be constant
|
||||
// when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtExit[i].energy_keV >= 40.95 || gammaAtExit[i].energy_keV <= 0.9) continue;
|
||||
|
||||
gammaMomentum.m_x = gammaAtExit[i].mx;
|
||||
gammaMomentum.m_y = gammaAtExit[i].my;
|
||||
gammaMomentum.m_z = gammaAtExit[i].mz;
|
||||
|
||||
if (!usePosition) {
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta)) continue;
|
||||
}
|
||||
else {
|
||||
double c =
|
||||
distanceObjectDetector * (gammaMomentum.m_x * cos(ra) + gammaMomentum.m_y * sin(ra));
|
||||
if (IsEqual(0, c, eps, releps)) continue; // parallel
|
||||
|
||||
gammaPosition.m_x = gammaAtExit[i].x;
|
||||
gammaPosition.m_y = gammaAtExit[i].y;
|
||||
gammaPosition.m_z = gammaAtExit[i].z;
|
||||
|
||||
double t = (distanceObjectDetector * distanceObjectDetector
|
||||
- gammaPosition.m_x * distanceObjectDetector * cos(ra)
|
||||
- gammaPosition.m_y * distanceObjectDetector * sin(ra))
|
||||
/ c;
|
||||
|
||||
intersectionPoint.m_x = gammaPosition.m_x + gammaMomentum.m_x * t;
|
||||
intersectionPoint.m_y = gammaPosition.m_y + gammaMomentum.m_y * t;
|
||||
intersectionPoint.m_z = gammaPosition.m_z + gammaMomentum.m_z * t;
|
||||
|
||||
if (!IsDetected_position(centerOfDetector, intersectionPoint, radiusOfDetector)) continue;
|
||||
|
||||
// printf(" t = %f, intersection point: (%f, %f, %f) centor of detector: (%f, %f, %f)
|
||||
// 111=%f, 222=%f \n", t, intersectionPoint.m_x,intersectionPoint.m_y,intersectionPoint.m_z,
|
||||
// centerOfDetector.m_x,centerOfDetector.m_y,centerOfDetector.m_z,
|
||||
// (distanceObjectDetector*distanceObjectDetector-gammaPosition.m_x*distanceObjectDetector*cos(ra)
|
||||
// -gammaPosition.m_y*distanceObjectDetector*sin(ra)), c);
|
||||
|
||||
// printf(" distanceObjectDetector = %f, gammaPosition.m_x=%f,
|
||||
// distanceObjectDetector*cos(ra)=%f, gammaPosition.m_y=%f,
|
||||
// distanceObjectDetector*sin(ra)=%f\n", distanceObjectDetector, gammaPosition.m_x,
|
||||
// distanceObjectDetector*cos(ra),
|
||||
// gammaPosition.m_y,
|
||||
// distanceObjectDetector*sin(ra));
|
||||
|
||||
double tt = (intersectionPoint.m_x - gammaPosition.m_x) * gammaMomentum.m_x
|
||||
+ (intersectionPoint.m_y - gammaPosition.m_y) * gammaMomentum.m_y
|
||||
+ (intersectionPoint.m_z - gammaPosition.m_z) * gammaMomentum.m_z;
|
||||
if (tt < 0) continue;
|
||||
}
|
||||
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtExit[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&pixeEvent, 7, 1, out);
|
||||
count++;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!usePosition) {
|
||||
printf(
|
||||
"---------id = %d, RunID=%d ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, momentum: "
|
||||
"(%f, %f, %f), energy: %f keV\n",
|
||||
i, runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex,
|
||||
gammaAtExit[i].mx, gammaAtExit[i].my, gammaAtExit[i].mz, gammaAtExit[i].energy_keV);
|
||||
}
|
||||
else {
|
||||
// printf("---------id = %d, RunID=%d ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,
|
||||
// momentum: (%f, %f, %f), energy: %f keV, position: (%f, %f, %f)\n", i, runID,
|
||||
// runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, gammaAtExit[i].mx,
|
||||
// gammaAtExit[i].my, gammaAtExit[i].mz, gammaAtExit[i].energy_keV, gammaAtExit[i].x,
|
||||
// gammaAtExit[i].y, gammaAtExit[i].z);
|
||||
|
||||
printf(
|
||||
"---------id = %d, RunID=%d ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, momentum: "
|
||||
"(%f, %f, %f), energy: %f keV\n",
|
||||
i, runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex,
|
||||
gammaAtExit[i].mx, gammaAtExit[i].my, gammaAtExit[i].mz, gammaAtExit[i].energy_keV);
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
}
|
||||
}
|
||||
printf(
|
||||
"\n---------------Number of PixeEvent in total: "
|
||||
"%lld------------------------\n",
|
||||
count);
|
||||
fclose(input);
|
||||
fclose(out);
|
||||
|
||||
// Recheck the output file in case
|
||||
// FILE* input2;
|
||||
// input2 = fopen("PixeEvent_std_AtExit.DAT","rb");
|
||||
// PixeEvent p;
|
||||
// while(fread(&p, 7, 1, input2))
|
||||
// {
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,
|
||||
// Energy_10eV=%d\n", p.projectionIndex, p.sliceIndex, p.pixelIndex,
|
||||
// p.energy_10eV);
|
||||
|
||||
// }
|
||||
// fclose(input2);
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
//***********************************************************************************************************
|
||||
// BinToStd_proton_position.C
|
||||
// Root command file
|
||||
// Type: root BinToStd_proton_position.C
|
||||
//
|
||||
// Read the X-ray output file that is generated by Geant4 tomography
|
||||
// simulation. It reads gamma information, either at creation, or at exit, and rewrite the events
|
||||
// in a binary file StimEvent_std.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
bool IsEqual(double a, double b, double eps, double releps)
|
||||
{
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fabs(a - b) <= releps * fabs(b)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fabs(a - b) < eps) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
double eps = 1e-20; // absolut difference
|
||||
double releps = 1e-10; // relative difference
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct StimEvent
|
||||
{
|
||||
uint16_t energy_keV; // different from Pixe Event, it is in keV
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else {
|
||||
// printf(" acos: %f, radius: %f\n", r, theta);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDetected_position(Point poi1, Point poi2, double r)
|
||||
{
|
||||
double a = sqrt((poi1.m_x - poi2.m_x) * (poi1.m_x - poi2.m_x)
|
||||
+ (poi1.m_y - poi2.m_y) * (poi1.m_y - poi2.m_y)
|
||||
+ (poi1.m_z - poi2.m_z) * (poi1.m_z - poi2.m_z));
|
||||
|
||||
// if(a <= r) return true;
|
||||
if (a > r)
|
||||
return false;
|
||||
|
||||
else {
|
||||
// printf(" distance of two points: %f, radius: %f\n", a, r);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void BinToStd_proton_position()
|
||||
{
|
||||
// printf("%f %f %f\n", acos(1), acos(-1), acos(0));
|
||||
// return;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 1;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 1;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector = 0.; // angle of detector relative to the incident
|
||||
|
||||
double distanceObjectDetector = 22000.; // um
|
||||
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex
|
||||
// angle of the right circular cone in radian
|
||||
double theta = 10.2 * TMath::DegToRad(); // in radian
|
||||
double radiusOfDetector = distanceObjectDetector * tan(theta);
|
||||
bool usePosition = true;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
FILE* input = fopen("../build/ProtonAtExit.dat", "rb");
|
||||
FILE* out = fopen("../build/StimEvent_std", "wb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
StimEvent stimEvent;
|
||||
Point centerOfDetector;
|
||||
Point protonMomentum;
|
||||
Point protonPosition;
|
||||
Point intersectionPoint;
|
||||
long long count = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
|
||||
// while(!feof(input)) //if not the end, read
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//(begin)****************************************************************
|
||||
// the following codes are used only when in the simulation
|
||||
// the index of projection, slice and pixel is not
|
||||
// correctly configured
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
|
||||
//(end)*******************************************************************
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf(
|
||||
"---------RunID=%d:\nProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,"
|
||||
"nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> protonAtExit(nbParticle);
|
||||
fread(&protonAtExit[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means
|
||||
// the angle between source direction and detector, which should be constant
|
||||
// when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// proton selection: energy should be lower than 4095 keV
|
||||
if (protonAtExit[i].energy_keV >= 4095) continue;
|
||||
|
||||
protonMomentum.m_x = protonAtExit[i].mx;
|
||||
protonMomentum.m_y = protonAtExit[i].my;
|
||||
protonMomentum.m_z = protonAtExit[i].mz;
|
||||
|
||||
if (!usePosition) {
|
||||
if (!IsDetected(centerOfDetector, protonMomentum, theta)) continue;
|
||||
}
|
||||
else {
|
||||
double c =
|
||||
distanceObjectDetector * (protonMomentum.m_x * cos(ra) + protonMomentum.m_y * sin(ra));
|
||||
if (IsEqual(0, c, eps, releps)) continue; // parallel
|
||||
|
||||
protonPosition.m_x = protonAtExit[i].x;
|
||||
protonPosition.m_y = protonAtExit[i].y;
|
||||
protonPosition.m_z = protonAtExit[i].z;
|
||||
|
||||
double t = (distanceObjectDetector * distanceObjectDetector
|
||||
- protonPosition.m_x * distanceObjectDetector * cos(ra)
|
||||
- protonPosition.m_y * distanceObjectDetector * sin(ra))
|
||||
/ c;
|
||||
|
||||
intersectionPoint.m_x = protonPosition.m_x + protonMomentum.m_x * t;
|
||||
intersectionPoint.m_y = protonPosition.m_y + protonMomentum.m_y * t;
|
||||
intersectionPoint.m_z = protonPosition.m_z + protonMomentum.m_z * t;
|
||||
|
||||
if (!IsDetected_position(centerOfDetector, intersectionPoint, radiusOfDetector)) continue;
|
||||
|
||||
// printf(" t = %f, intersection point: (%f, %f, %f) centor of detector: (%f, %f, %f)
|
||||
// 111=%f, 222=%f \n", t, intersectionPoint.m_x,intersectionPoint.m_y,intersectionPoint.m_z,
|
||||
// centerOfDetector.m_x,centerOfDetector.m_y,centerOfDetector.m_z,
|
||||
// (distanceObjectDetector*distanceObjectDetector-protonPosition.m_x*distanceObjectDetector*cos(ra)
|
||||
// -protonPosition.m_y*distanceObjectDetector*sin(ra)), c);
|
||||
|
||||
// printf(" distanceObjectDetector = %f, protonPosition.m_x=%f,
|
||||
// distanceObjectDetector*cos(ra)=%f, protonPosition.m_y=%f,
|
||||
// distanceObjectDetector*sin(ra)=%f\n", distanceObjectDetector, protonPosition.m_x,
|
||||
// distanceObjectDetector*cos(ra),
|
||||
// protonPosition.m_y,
|
||||
// distanceObjectDetector*sin(ra));
|
||||
|
||||
double tt = (intersectionPoint.m_x - protonPosition.m_x) * protonMomentum.m_x
|
||||
+ (intersectionPoint.m_y - protonPosition.m_y) * protonMomentum.m_y
|
||||
+ (intersectionPoint.m_z - protonPosition.m_z) * protonMomentum.m_z;
|
||||
if (tt < 0) continue;
|
||||
}
|
||||
|
||||
stimEvent.energy_10eV = floor(100 * protonAtExit[i].energy_keV + 0.5);
|
||||
stimEvent.projectionIndex = runInfo.projectionIndex;
|
||||
stimEvent.sliceIndex = runInfo.sliceIndex;
|
||||
stimEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&stimEvent, 7, 1, out);
|
||||
count++;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information
|
||||
//(begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!usePosition) {
|
||||
printf(
|
||||
"---------id = %d, RunID=%d ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, momentum: "
|
||||
"(%f, %f, %f), energy: %f keV\n",
|
||||
i, runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex,
|
||||
protonAtExit[i].mx, protonAtExit[i].my, protonAtExit[i].mz, protonAtExit[i].energy_keV);
|
||||
}
|
||||
else {
|
||||
// printf("---------id = %d, RunID=%d ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d,
|
||||
// momentum: (%f, %f, %f), energy: %f keV, position: (%f, %f, %f)\n", i, runID,
|
||||
// runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, protonAtExit[i].mx,
|
||||
// protonAtExit[i].my, protonAtExit[i].mz, protonAtExit[i].energy_keV, protonAtExit[i].x,
|
||||
// protonAtExit[i].y, protonAtExit[i].z);
|
||||
|
||||
printf(
|
||||
"---------id = %d, RunID=%d ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, momentum: "
|
||||
"(%f, %f, %f), energy: %f keV\n",
|
||||
i, runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex,
|
||||
protonAtExit[i].mx, protonAtExit[i].my, protonAtExit[i].mz, protonAtExit[i].energy_keV);
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
}
|
||||
}
|
||||
printf(
|
||||
"\n---------------Number of StimEvent in total: "
|
||||
"%lld------------------------\n",
|
||||
count);
|
||||
fclose(input);
|
||||
fclose(out);
|
||||
|
||||
// FILE* input2;
|
||||
// input2 = fopen("StimEvent_std.DAT","rb");
|
||||
// StimEvent p;
|
||||
// double eventId = -1;
|
||||
// while(fread(&p, 7, 1, input2))
|
||||
// {
|
||||
|
||||
// if(p.projectionIndex == 8 &&p.sliceIndex ==64 && p.pixelIndex==64)
|
||||
// {
|
||||
// eventId++;
|
||||
// printf("StimEvent_%.0f ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_keV=%d keV\n",
|
||||
// eventId, p.projectionIndex, p.sliceIndex, p.pixelIndex, p.energy_keV);
|
||||
|
||||
// }
|
||||
|
||||
// }
|
||||
// fclose(input2);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
//***********************************************************************************************************
|
||||
// Check_PixeEventFile.C
|
||||
// Root command file
|
||||
// Use it by typing in the command line of Root terminal: root Check_PixeEventFile.C
|
||||
//
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
#define PI 3.14159265f
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
double DegreeToRadian(double degree)
|
||||
{
|
||||
return (PI * degree / 180.);
|
||||
}
|
||||
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void Check_PixeEventFile()
|
||||
{
|
||||
FILE* input2 =
|
||||
fopen("../build/PixeEvent_std_AtExit_Detector135_Aperture70_50Projections.DAT", "rb");
|
||||
PixeEvent ppp;
|
||||
int proj = -1;
|
||||
while (fread(&ppp, 7, 1, input2)) {
|
||||
if (ppp.projectionIndex != proj) {
|
||||
printf("__ProjectionIndex=%d\n", ppp.projectionIndex);
|
||||
proj = ppp.projectionIndex;
|
||||
}
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// ppp.projectionIndex, ppp.sliceIndex, ppp.pixelIndex, ppp.energy_10eV);
|
||||
}
|
||||
fclose(input2);
|
||||
}
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
//***********************************************************************************************************
|
||||
// Concatenate_BinToStd_GammaAtCreation.C
|
||||
// Root command file
|
||||
// Type: root Concatenate_BinToStd_GammaAtCreation.C
|
||||
//
|
||||
// It is used in case of interruption
|
||||
// Read 2 output files GammaAtCreation_1.dat and GammaAtCreation_2.dat that are generated by Geant4
|
||||
// tomography simulation. It reads all the gamma at creation information, and rewrite the events in
|
||||
// a binary file PixeEvent_std_AtCreation.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
void Concatenate_BinToStd_GammaAtCreation()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector =
|
||||
135.; // angle of detector relative to the incident direction of the primary protons //
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex angle of the right
|
||||
// circular cone in radian
|
||||
double theta = 70 * TMath::DegToRad(); // in radian
|
||||
|
||||
int P_interrupt = 6; // Projection of interruption
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
// assuming there is one interruption
|
||||
FILE* input1 = fopen("../build/GammaAtCreation_1.dat", "rb");
|
||||
FILE* input2 = fopen("../build/GammaAtCreation_2.dat", "rb");
|
||||
FILE* out = fopen("../build/PixeEvent_std_AtCreation.DAT", "wb");
|
||||
|
||||
if (input1 == NULL) {
|
||||
printf("error for opening the input GammaAtCreation_1.dat file\n");
|
||||
return;
|
||||
}
|
||||
if (input2 == NULL) {
|
||||
printf("error for opening the input GammaAtCreation_2.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
PixeEvent pixeEvent;
|
||||
Point centerOfDetector;
|
||||
Point gammaMomentum;
|
||||
long long count1 = 0;
|
||||
long long count2 = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
|
||||
// ************************************************************(begin)
|
||||
// **********************READ FIRST FILE***********************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input1)) {
|
||||
runID++;
|
||||
|
||||
//(begin)***************************************************************
|
||||
// the following codes are used only when in the simulation
|
||||
// the index of projection, slice and pixel is not
|
||||
// correctly configured
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
//(end)******************************************************************
|
||||
|
||||
if (runInfo.projectionIndex == P_interrupt) {
|
||||
runID--;
|
||||
break;
|
||||
}
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
std::vector<ParticleInfo> gammaAtCreation(nbParticle);
|
||||
fread(&gammaAtCreation[0], sizeof(ParticleInfo), nbParticle, input1);
|
||||
|
||||
// if(runInfo.sliceIndex!=1) continue;
|
||||
// if(runInfo.sliceIndex!=31&&runInfo.sliceIndex!=32) continue;
|
||||
// if(runInfo.sliceIndex!=31) continue;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("-1--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtCreation[i].energy_keV >= 40.95 || gammaAtCreation[i].energy_keV <= 0.9)
|
||||
continue; // gamma selection
|
||||
|
||||
gammaMomentum.m_x = gammaAtCreation[i].mx;
|
||||
gammaMomentum.m_y = gammaAtCreation[i].my;
|
||||
gammaMomentum.m_z = gammaAtCreation[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtCreation[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&pixeEvent, 7, 1, out);
|
||||
count1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of PixeEvent in the first file: %lld------------------------\n",
|
||||
count1);
|
||||
fclose(input1);
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ FIRST FILE (end)*****************
|
||||
// ************************************************************
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ SECOND FILE (begin)**************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input2)) {
|
||||
runID++;
|
||||
|
||||
//(begin)***************************************************************
|
||||
// the following codes are used only when in the simulation
|
||||
// the index of projection, slice and pixel is not
|
||||
// correctly configured
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
//(end)******************************************************************
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("-2--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> gammaAtCreation(nbParticle);
|
||||
fread(&gammaAtCreation[0], sizeof(ParticleInfo), nbParticle, input2);
|
||||
|
||||
// if(runInfo.sliceIndex!=1) continue;
|
||||
// if(runInfo.sliceIndex!=31) continue;
|
||||
// if(runInfo.sliceIndex!=31&&runInfo.sliceIndex!=32) continue;
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtCreation[i].energy_keV >= 40.95 || gammaAtCreation[i].energy_keV <= 0.9)
|
||||
continue; // gamma selection
|
||||
|
||||
gammaMomentum.m_x = gammaAtCreation[i].mx;
|
||||
gammaMomentum.m_y = gammaAtCreation[i].my;
|
||||
gammaMomentum.m_z = gammaAtCreation[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtCreation[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&pixeEvent, 7, 1, out);
|
||||
count2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of PixeEvent in in the second file: %lld------------------------\n",
|
||||
count2);
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ SECOND FILE (end)****************
|
||||
// ************************************************************
|
||||
|
||||
printf("---------------Number of PixeEvent in total: %lld------------------------\n",
|
||||
count1 + count2);
|
||||
fclose(input2);
|
||||
fclose(out);
|
||||
|
||||
// Recheck the output file in case
|
||||
// FILE* input2 = fopen("PixeEvent_std_AtCreation.DAT","rb");
|
||||
// PixeEvent p;
|
||||
// while(fread(&p, 7, 1, input2))
|
||||
// {
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// p.projectionIndex, p.sliceIndex, p.pixelIndex, p.energy_10eV);
|
||||
|
||||
// }
|
||||
// fclose(input2);
|
||||
}
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
//***********************************************************************************************************
|
||||
// Concatenate_BinToStd_GammaAtCreation_fabricate.C
|
||||
// Root command file
|
||||
// Use it by typing in the command line of Root terminal: root
|
||||
// Concatenate_BinToStd_GammaAtCreation_fabricate.C
|
||||
//
|
||||
//
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
#define PI 3.14159265f
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
double DegreeToRadian(double degree)
|
||||
{
|
||||
return (PI * degree / 180.);
|
||||
}
|
||||
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void Concatenate_BinToStd_GammaAtCreation_fabricate()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 100;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 128;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector =
|
||||
135.; // angle of detector relative to the incident direction of the primary protons //
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex angle of the right
|
||||
// circular cone in radian double theta = 14.726*TMath::DegToRad(); // in radian
|
||||
double theta = 70 * TMath::DegToRad(); // in radian
|
||||
// double theta = 70*TMath::DegToRad(); // in radian
|
||||
// double theta = DegreeToRadian(70);
|
||||
|
||||
int P_interrupt = 1; // Projection of interruption
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
// assuming there is one interruption
|
||||
FILE* input1 = fopen("../RT7_GDP_1Projs_1Slice_128Pixels_2000000_4MeV/GammaAtCreation.dat", "rb");
|
||||
FILE* out =
|
||||
fopen("../RT7_GDP_1Projs_1Slice_128Pixels_2000000_4MeV/PixeEvent_std_AtCreation.DAT", "wb");
|
||||
// FILE* temp;
|
||||
// temp =fopen("temp.DAT","wb");
|
||||
|
||||
if (input1 == NULL) {
|
||||
printf("error for opening the input GammaAtCreation.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
PixeEvent pixeEvent;
|
||||
Point centerOfDetector;
|
||||
Point gammaMomentum;
|
||||
long long count1 = 0;
|
||||
long long count2 = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
std::vector<PixeEvent> eventVec;
|
||||
|
||||
// ************************************************************(begin)
|
||||
// **********************READ FIRST FILE***********************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input1)) {
|
||||
runID++;
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
if (runInfo.projectionIndex == P_interrupt) {
|
||||
runID--;
|
||||
break;
|
||||
}
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
std::vector<ParticleInfo> gammaAtCreation(nbParticle);
|
||||
fread(&gammaAtCreation[0], sizeof(ParticleInfo), nbParticle, input1);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
// printf("-1--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle =
|
||||
// %d\n",runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra =
|
||||
DegreeToRadian(angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtCreation[i].energy_keV >= 40.95 || gammaAtCreation[i].energy_keV <= 0.9)
|
||||
continue; // gamma selection
|
||||
|
||||
gammaMomentum.m_x = gammaAtCreation[i].mx;
|
||||
gammaMomentum.m_y = gammaAtCreation[i].my;
|
||||
gammaMomentum.m_z = gammaAtCreation[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtCreation[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
|
||||
eventVec.push_back(pixeEvent);
|
||||
// fwrite(&pixeEvent, 7, 1, temp);
|
||||
// fwrite(&pixeEvent, 7, 1, out);
|
||||
count1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of PixeEvent in the first file: %lld------------------------\n",
|
||||
count1);
|
||||
fclose(input1);
|
||||
// fclose(temp);
|
||||
|
||||
// ************************************************************(end)
|
||||
// **********************READ FIRST FILE***********************
|
||||
// ************************************************************
|
||||
|
||||
PixeEvent pp;
|
||||
PixeEvent p;
|
||||
|
||||
for (int i = 0; i < nbProjection; ++i) {
|
||||
int size = eventVec.size();
|
||||
for (int j = 0; j < size; ++j) {
|
||||
p = eventVec[j];
|
||||
pp.energy_10eV = p.energy_10eV;
|
||||
pp.projectionIndex = p.projectionIndex + i;
|
||||
pp.sliceIndex = p.sliceIndex; // index of slices should be reset, starting from 0
|
||||
pp.pixelIndex = p.pixelIndex;
|
||||
pp.pixelIndex = p.pixelIndex;
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// pp.projectionIndex, pp.sliceIndex, pp.pixelIndex, pp.energy_10eV);
|
||||
fwrite(&pp, 7, 1, out);
|
||||
}
|
||||
}
|
||||
|
||||
// fclose(temp);
|
||||
fclose(out);
|
||||
|
||||
// Recheck the output file in case
|
||||
FILE* input2 =
|
||||
fopen("../RT7_GDP_1Projs_1Slice_128Pixels_2000000_4MeV/PixeEvent_std_AtCreation.DAT", "rb");
|
||||
PixeEvent ppp;
|
||||
int proj = -1;
|
||||
while (fread(&ppp, 7, 1, input2)) {
|
||||
if (ppp.projectionIndex != proj) {
|
||||
printf("__ProjectionIndex=%d\n", ppp.projectionIndex);
|
||||
proj = ppp.projectionIndex;
|
||||
}
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// ppp.projectionIndex, ppp.sliceIndex, ppp.pixelIndex, ppp.energy_10eV);
|
||||
}
|
||||
fclose(input2);
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
//***********************************************************************************************************
|
||||
// Concatenate_BinToStd_GammaAtExit.C
|
||||
// Root command file
|
||||
// Type: root Concatenate_BinToStd_GammaAtExit.C
|
||||
//
|
||||
// It is used in case of one interruption
|
||||
// Read 2 output files GammaAtExit_1.dat and GammaAtExit_2.dat that are generated by Geant4
|
||||
// tomography simulation It reads gamma at exit information, and rewrite the events in a binary file
|
||||
// PixeEvent_std_AtExit.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
void Concatenate_BinToStd_GammaAtExit()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector =
|
||||
135.; // angle of detector relative to the incident direction of the primary protons //
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex angle of the right
|
||||
// circular cone in radian
|
||||
double theta = 70 * TMath::DegToRad(); // in radian
|
||||
|
||||
int P_interrupt = 6; // Projection of interruption
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
// assuming there is one interruption
|
||||
FILE* input1 = fopen("../build/GammaAtExit_1.dat", "rb");
|
||||
FILE* input2 = fopen("../build/GammaAtExit_2.dat", "rb");
|
||||
FILE* out = fopen("../build/PixeEvent_std_AtExit.DAT", "wb");
|
||||
|
||||
if (input1 == NULL) {
|
||||
printf("error for opening the input GammaAtExit_1.dat file\n");
|
||||
return;
|
||||
}
|
||||
if (input2 == NULL) {
|
||||
printf("error for opening the input GammaAtExit_2.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
PixeEvent pixeEvent;
|
||||
Point centerOfDetector;
|
||||
Point gammaMomentum;
|
||||
long long count1 = 0;
|
||||
long long count2 = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ FIRST FILE (begin)***************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input1)) {
|
||||
runID++;
|
||||
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
|
||||
if (runInfo.projectionIndex == P_interrupt) {
|
||||
runID--;
|
||||
break;
|
||||
}
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("-1--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
|
||||
std::vector<ParticleInfo> gammaAtExit(nbParticle);
|
||||
fread(&gammaAtExit[0], sizeof(ParticleInfo), nbParticle, input1);
|
||||
|
||||
// if(runInfo.sliceIndex!=1) continue;
|
||||
// if(runInfo.sliceIndex!=31&&runInfo.sliceIndex!=32) continue;
|
||||
// if(runInfo.sliceIndex!=31) continue;
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtExit[i].energy_keV >= 40.95 || gammaAtExit[i].energy_keV <= 0.9)
|
||||
continue; // gamma selection
|
||||
|
||||
gammaMomentum.m_x = gammaAtExit[i].mx;
|
||||
gammaMomentum.m_y = gammaAtExit[i].my;
|
||||
gammaMomentum.m_z = gammaAtExit[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtExit[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&pixeEvent, 7, 1, out);
|
||||
count1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of PixeEvent in the first file: %lld------------------------\n",
|
||||
count1);
|
||||
fclose(input1);
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ FIRST FILE (end)*****************
|
||||
// ************************************************************
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ SECOND FILE (begin)**************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input2)) {
|
||||
runID++;
|
||||
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("-2--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> gammaAtExit(nbParticle);
|
||||
fread(&gammaAtExit[0], sizeof(ParticleInfo), nbParticle, input2);
|
||||
|
||||
// if(runInfo.sliceIndex!=1) continue;
|
||||
// if(runInfo.sliceIndex!=31&&runInfo.sliceIndex!=32) continue;
|
||||
// if(runInfo.sliceIndex!=31) continue;
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtExit[i].energy_keV >= 40.95 || gammaAtExit[i].energy_keV <= 0.9)
|
||||
continue; // gamma selection
|
||||
|
||||
gammaMomentum.m_x = gammaAtExit[i].mx;
|
||||
gammaMomentum.m_y = gammaAtExit[i].my;
|
||||
gammaMomentum.m_z = gammaAtExit[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtExit[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&pixeEvent, 7, 1, out);
|
||||
count2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of PixeEvent in in the second file: %lld------------------------\n",
|
||||
count2);
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ SECOND FILE (end)****************
|
||||
// ************************************************************
|
||||
|
||||
printf("---------------Number of PixeEvent in total: %lld------------------------\n",
|
||||
count1 + count2);
|
||||
fclose(input2);
|
||||
fclose(out);
|
||||
|
||||
// Recheck the output file in case
|
||||
// FILE* input2 = fopen("PixeEvent_std_AtExit.DAT","rb");
|
||||
// PixeEvent p;
|
||||
// while(fread(&p, 7, 1, input2))
|
||||
// {
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// p.projectionIndex, p.sliceIndex, p.pixelIndex, p.energy_10eV);
|
||||
|
||||
// }
|
||||
// fclose(input2);
|
||||
}
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
//***********************************************************************************************************
|
||||
// Concatenate_BinToStd_GammaAtExit_fabricate.C
|
||||
// Root command file
|
||||
// Use it by typing in the command line of Root terminal: root
|
||||
// Concatenate_BinToStd_GammaAtExit_fabricate.C
|
||||
//
|
||||
//
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
#define PI 3.14159265f
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
double DegreeToRadian(double degree)
|
||||
{
|
||||
return (PI * degree / 180.);
|
||||
}
|
||||
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void Concatenate_BinToStd_GammaAtExit_fabricate()
|
||||
{
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 100;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 128;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
double angleOfDetector =
|
||||
135.; // angle of detector relative to the incident direction of the primary protons //
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex angle of the right
|
||||
// circular cone in radian double theta = 14.726*TMath::DegToRad(); // in radian
|
||||
double theta = 70 * TMath::DegToRad(); // in radian
|
||||
// double theta = 70*TMath::DegToRad(); // in radian
|
||||
// double theta = DegreeToRadian(70);
|
||||
|
||||
int P_interrupt = 1; // Projection of interruption
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
// assuming there is one interruption
|
||||
FILE* input1 = fopen("../RT7_GDP_1Projs_1Slice_128Pixels_2000000_4MeV/GammaAtExit.dat", "rb");
|
||||
FILE* out =
|
||||
fopen("../RT7_GDP_1Projs_1Slice_128Pixels_2000000_4MeV/PixeEvent_std_AtExit.DAT", "wb");
|
||||
// FILE* temp;
|
||||
// temp =fopen("temp.DAT","wb");
|
||||
|
||||
if (input1 == NULL) {
|
||||
printf("error for opening the input GammaAtExit.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
PixeEvent pixeEvent;
|
||||
Point centerOfDetector;
|
||||
Point gammaMomentum;
|
||||
long long count1 = 0;
|
||||
long long count2 = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
std::vector<PixeEvent> eventVec;
|
||||
|
||||
// ************************************************************(begin)
|
||||
// **********************READ FIRST FILE***********************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input1)) {
|
||||
runID++;
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
if (runInfo.projectionIndex == P_interrupt) {
|
||||
runID--;
|
||||
break;
|
||||
}
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
std::vector<ParticleInfo> gammaAtExit(nbParticle);
|
||||
fread(&gammaAtExit[0], sizeof(ParticleInfo), nbParticle, input1);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("-1--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra =
|
||||
DegreeToRadian(angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// gamma selection: energy should be lower than 4095*10eV = 49.45 keV
|
||||
if (gammaAtExit[i].energy_keV >= 40.95 || gammaAtExit[i].energy_keV <= 0.9)
|
||||
continue; // gamma selection
|
||||
|
||||
gammaMomentum.m_x = gammaAtExit[i].mx;
|
||||
gammaMomentum.m_y = gammaAtExit[i].my;
|
||||
gammaMomentum.m_z = gammaAtExit[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, gammaMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
pixeEvent.energy_10eV = floor(100 * gammaAtExit[i].energy_keV + 0.5);
|
||||
pixeEvent.projectionIndex = runInfo.projectionIndex;
|
||||
pixeEvent.sliceIndex = runInfo.sliceIndex;
|
||||
pixeEvent.pixelIndex = runInfo.pixelIndex;
|
||||
|
||||
eventVec.push_back(pixeEvent);
|
||||
count1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of PixeEvent in the first file: %lld------------------------\n",
|
||||
count1);
|
||||
fclose(input1);
|
||||
// fclose(temp);
|
||||
|
||||
// ************************************************************(end)
|
||||
// **********************READ FIRST FILE***********************
|
||||
// ************************************************************
|
||||
|
||||
// ************************************************************(begin)
|
||||
// **********************READ SECOND FILE**********************
|
||||
// ************************************************************
|
||||
// temp =fopen("temp.DAT","rb");
|
||||
|
||||
PixeEvent pp;
|
||||
PixeEvent p;
|
||||
|
||||
for (int i = 0; i < nbProjection; ++i) {
|
||||
int size = eventVec.size();
|
||||
for (int j = 0; j < size; ++j) {
|
||||
p = eventVec[j];
|
||||
pp.energy_10eV = p.energy_10eV;
|
||||
pp.projectionIndex = p.projectionIndex + i;
|
||||
pp.sliceIndex = p.sliceIndex; // index of slices should be reset, starting from 0
|
||||
pp.pixelIndex = p.pixelIndex;
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// pp.projectionIndex, pp.sliceIndex, pp.pixelIndex, pp.energy_10eV);
|
||||
fwrite(&pp, 7, 1, out);
|
||||
}
|
||||
}
|
||||
|
||||
// ************************************************************(end)
|
||||
// **********************READ SECOND FILE**********************
|
||||
// ************************************************************
|
||||
|
||||
// fclose(temp);
|
||||
fclose(out);
|
||||
|
||||
// Recheck the output file in case
|
||||
FILE* input2 =
|
||||
fopen("../RT7_GDP_1Projs_1Slice_128Pixels_2000000_4MeV/PixeEvent_std_AtExit.DAT", "rb");
|
||||
PixeEvent ppp;
|
||||
int proj = -1;
|
||||
while (fread(&ppp, 7, 1, input2)) {
|
||||
if (ppp.projectionIndex != proj) {
|
||||
printf("__ProjectionIndex=%d\n", ppp.projectionIndex);
|
||||
proj = ppp.projectionIndex;
|
||||
}
|
||||
// if(proj<20) printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// ppp.projectionIndex, ppp.sliceIndex, ppp.pixelIndex, ppp.energy_10eV);
|
||||
}
|
||||
fclose(input2);
|
||||
}
|
||||
@@ -0,0 +1,276 @@
|
||||
//***********************************************************************************************************
|
||||
// Concatenate_BinToStd_ProtonAtExit.C
|
||||
// Root command file
|
||||
// Type: root Concatenate_BinToStd_ProtonAtExit.C
|
||||
//
|
||||
// It is used in case of interruption
|
||||
// Read 2 output files ProtonAtExit_1.dat and ProtonAtExit_2.dat that are generated by Geant4
|
||||
// tomography simulation It reads protons at exit information, and rewrite the events in a binary
|
||||
// file StimEvent_std.DAT
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct StimEvent
|
||||
{
|
||||
uint16_t energy_keV; // different from Pixe Event, it is in keV
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
struct Point
|
||||
{
|
||||
double m_x;
|
||||
double m_y;
|
||||
double m_z;
|
||||
};
|
||||
bool IsDetected(Point poi1, Point poi2, double theta)
|
||||
{
|
||||
double a = (poi1.m_x * poi2.m_x + poi1.m_y * poi2.m_y + poi1.m_z * poi2.m_z)
|
||||
/ sqrt(poi1.m_x * poi1.m_x + poi1.m_y * poi1.m_y + poi1.m_z * poi1.m_z)
|
||||
/ sqrt(poi2.m_x * poi2.m_x + poi2.m_y * poi2.m_y + poi2.m_z * poi2.m_z);
|
||||
if (a > 1.0) a = 1;
|
||||
if (a < -1.0) a = -1;
|
||||
double r = acos(a);
|
||||
if (r > theta)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void Recheck()
|
||||
{
|
||||
// Recheck the output file in case
|
||||
FILE* input3 = fopen("../build/StimEvent_std_Detector0_Aperture10.2.DAT", "rb");
|
||||
StimEvent p;
|
||||
double eventId = -1;
|
||||
while (fread(&p, 7, 1, input3)) {
|
||||
if (p.projectionIndex == 8 && p.sliceIndex == 64 && p.pixelIndex == 10) {
|
||||
eventId++;
|
||||
printf("StimEvent_%.0f ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_keV=%d keV\n",
|
||||
eventId, p.projectionIndex, p.sliceIndex, p.pixelIndex, p.energy_keV);
|
||||
}
|
||||
}
|
||||
fclose(input3);
|
||||
}
|
||||
void Concatenate_BinToStd_ProtonAtExit()
|
||||
{
|
||||
// Recheck();
|
||||
// return;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 128;
|
||||
const int nbPixel = 20;
|
||||
double totalAngleSpan = 180.; // in degree
|
||||
|
||||
// angle of detector relative to the incident direction of the primary protons at first projection
|
||||
// for proton, it is fixed to 0 degree, namely opposite to the source
|
||||
double angleOfDetector = 0.;
|
||||
double distanceObjectDetector = 22.; // 22 mm
|
||||
double radiusOfDetector = 5.; // 5 mm
|
||||
// double theta = atan(radiusOfDetector/distanceObjectDetector); //half apex angle of the right
|
||||
// circular cone in radian
|
||||
double theta = 10.2 * TMath::DegToRad(); // in radian
|
||||
|
||||
int P_interrupt = 2; // Projection of interruption
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
// assuming there is one interruption
|
||||
FILE* input1 = fopen("../build/ProtonAtExit_1.dat", "rb");
|
||||
FILE* input2 = fopen("../build/ProtonAtExit_2.dat", "rb");
|
||||
FILE* out = fopen("../build/StimEvent_std.DAT", "wb");
|
||||
|
||||
if (input1 == NULL) {
|
||||
printf("error for opening the input ProtonAtExit_1.dat file\n");
|
||||
return;
|
||||
}
|
||||
if (input2 == NULL) {
|
||||
printf("error for opening the input ProtonAtExit_2.dat file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
StimEvent stimEvent;
|
||||
Point centerOfDetector;
|
||||
Point protonMomentum;
|
||||
|
||||
long long count1 = 0;
|
||||
long long count2 = 0;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
|
||||
// ************************************************************(begin)
|
||||
// **********************READ FIRST FILE***********************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input1)) {
|
||||
runID++;
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
if (runInfo.projectionIndex == P_interrupt) {
|
||||
runID--;
|
||||
break;
|
||||
}
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("-1--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> protonAtExit(nbParticle);
|
||||
fread(&protonAtExit[0], sizeof(ParticleInfo), nbParticle, input1);
|
||||
|
||||
// if(runInfo.sliceIndex!=1) continue;
|
||||
// if(runInfo.sliceIndex!=31&&runInfo.sliceIndex!=32) continue;
|
||||
// if(runInfo.sliceIndex!=31) continue;
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// proton selection: energy should be lower than 4095 keV
|
||||
if (protonAtExit[i].energy_keV >= 4095) continue; // proton selection
|
||||
|
||||
protonMomentum.m_x = protonAtExit[i].mx;
|
||||
protonMomentum.m_y = protonAtExit[i].my;
|
||||
protonMomentum.m_z = protonAtExit[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, protonMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
stimEvent.energy_keV = floor(protonAtExit[i].energy_keV + 0.5);
|
||||
stimEvent.projectionIndex = runInfo.projectionIndex;
|
||||
stimEvent.sliceIndex = runInfo.sliceIndex;
|
||||
stimEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&stimEvent, 7, 1, out);
|
||||
count1++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of StimEvent in the first file: %lld------------------------\n",
|
||||
count1);
|
||||
fclose(input1);
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ FIRST FILE (end)*****************
|
||||
// ************************************************************
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ SECOND FILE (begin)**************
|
||||
// ************************************************************
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input2)) {
|
||||
runID++;
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (begin)********************
|
||||
//***********************************************************************
|
||||
|
||||
printf("-2--runId %d, ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runID, runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Print information (end)**********************
|
||||
//***********************************************************************
|
||||
|
||||
if (!nbParticle) continue;
|
||||
|
||||
std::vector<ParticleInfo> protonAtExit(nbParticle);
|
||||
fread(&protonAtExit[0], sizeof(ParticleInfo), nbParticle, input2);
|
||||
|
||||
// if(runInfo.sliceIndex!=1) continue;
|
||||
// if(runInfo.sliceIndex!=31) continue;
|
||||
// if(runInfo.sliceIndex!=31&&runInfo.sliceIndex!=32) continue;
|
||||
|
||||
// angleOfDetector+totalAngleSpan/nbProjection*runInfo.projectionIndex means the angle between
|
||||
// source direction and detector, which should be constant when source is rotating
|
||||
double ra = TMath::DegToRad()
|
||||
* (angleOfDetector + totalAngleSpan / nbProjection * runInfo.projectionIndex);
|
||||
centerOfDetector.m_x = distanceObjectDetector * cos(ra);
|
||||
centerOfDetector.m_y = distanceObjectDetector * sin(ra);
|
||||
centerOfDetector.m_z = 0;
|
||||
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// proton selection: energy should be lower than 4095 keV
|
||||
if (protonAtExit[i].energy_keV >= 4095) continue; // proton selection
|
||||
|
||||
protonMomentum.m_x = protonAtExit[i].mx;
|
||||
protonMomentum.m_y = protonAtExit[i].my;
|
||||
protonMomentum.m_z = protonAtExit[i].mz;
|
||||
|
||||
if (!IsDetected(centerOfDetector, protonMomentum, theta))
|
||||
continue;
|
||||
else {
|
||||
stimEvent.energy_keV = floor(protonAtExit[i].energy_keV + 0.5);
|
||||
stimEvent.projectionIndex = runInfo.projectionIndex;
|
||||
stimEvent.sliceIndex = runInfo.sliceIndex;
|
||||
stimEvent.pixelIndex = runInfo.pixelIndex;
|
||||
fwrite(&stimEvent, 7, 1, out);
|
||||
count2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("---------------Number of StimEvent in in the second file: %lld------------------------\n",
|
||||
count2);
|
||||
|
||||
// ************************************************************
|
||||
// **********************READ SECOND FILE (end)****************
|
||||
// ************************************************************
|
||||
|
||||
printf("---------------Number of StimEvent in total: %lld------------------------\n",
|
||||
count1 + count2);
|
||||
fclose(input2);
|
||||
fclose(out);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
//***********************************************************************************************************
|
||||
// Extract_Slice.C
|
||||
// Root command file
|
||||
// Use it by typing in the command line of Root terminal: root Extract_Slice.C
|
||||
//
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
#define PI 3.14159265f
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
|
||||
// to extract a certain slice or slices
|
||||
|
||||
void Extract_Projection()
|
||||
{
|
||||
// FILE *in =fopen("PixeEvent_std_AtCreation.DAT","rb");
|
||||
FILE* in = fopen("../build/PixeEvent_std_AtExit_Detector135_Aperture70.DAT", "rb");
|
||||
|
||||
// FILE* out = fopen("PixeEvent_std_AtCreation_50Projections.DAT","wb");
|
||||
FILE* out = fopen("../build/PixeEvent_std_AtExit_Detector135_Aperture70_50Projections.DAT", "wb");
|
||||
|
||||
if (in == NULL) {
|
||||
printf("error for opening the intput file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PixeEvent p;
|
||||
PixeEvent pp;
|
||||
vector<int> valid_projections;
|
||||
for (int i = 0; i < 50; ++i) {
|
||||
int p = 2 * i;
|
||||
valid_projections.push_back(p);
|
||||
}
|
||||
|
||||
while (fread(&p, 7, 1, in)) {
|
||||
int key = p.projectionIndex;
|
||||
|
||||
if (std::find(valid_projections.begin(), valid_projections.end(), key)
|
||||
!= valid_projections.end()) {
|
||||
pp.energy_10eV = p.energy_10eV;
|
||||
pp.projectionIndex = p.projectionIndex / 2;
|
||||
pp.sliceIndex = p.sliceIndex; // index of slices should be reset, starting from 0
|
||||
pp.pixelIndex = p.pixelIndex;
|
||||
pp.pixelIndex = p.pixelIndex;
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// pp.projectionIndex, pp.sliceIndex, pp.pixelIndex, pp.energy_10eV);
|
||||
fwrite(&pp, 7, 1, out);
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//***********************************************************************************************************
|
||||
// Extract_Slice.C
|
||||
// Root command file
|
||||
// Use it by typing in the command line of Root terminal: root Extract_Slice.C
|
||||
//
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
#define PI 3.14159265f
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
|
||||
// to extract a certain slice or slices
|
||||
|
||||
void Extract_Slice()
|
||||
{
|
||||
int start_slice = 0; // start_slice: the first slice you would like to select
|
||||
int end_slice = 0; // end_slice: the last slice you would like to select
|
||||
|
||||
FILE* in = fopen("../build/PixeEvent_std_AtCreation.DAT", "rb");
|
||||
// FILE *in =fopen("PixeEvent_std_AtExit.DAT.DAT","rb");
|
||||
|
||||
FILE* out = fopen("../build/PixeEvent_std_AtCreation_slice.DAT", "wb");
|
||||
// FILE* out = fopen("PixeEvent_std_AtExit_slice.DAT","wb");
|
||||
|
||||
if (in == NULL) {
|
||||
printf("error for opening the intput file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
PixeEvent p;
|
||||
PixeEvent pp;
|
||||
|
||||
while (fread(&p, 7, 1, in)) {
|
||||
if (p.sliceIndex >= start_slice && p.sliceIndex <= end_slice) {
|
||||
pp.energy_10eV = p.energy_10eV;
|
||||
pp.projectionIndex = p.projectionIndex;
|
||||
pp.sliceIndex =
|
||||
p.sliceIndex - start_slice; // index of slices should be reset, starting from 0
|
||||
pp.pixelIndex = p.pixelIndex;
|
||||
pp.pixelIndex = p.pixelIndex;
|
||||
// printf("__ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, Energy_10eV=%d\n",
|
||||
// pp.projectionIndex, pp.sliceIndex, pp.pixelIndex, pp.energy_10eV);
|
||||
fwrite(&pp, 7, 1, out);
|
||||
}
|
||||
}
|
||||
fclose(in);
|
||||
fclose(out);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//***********************************************************************************************************
|
||||
// LocateInterruption_GammaAtExit.C
|
||||
// Root command file
|
||||
// Type: root LocateInterruption_GammaAtExit.C
|
||||
//
|
||||
// It is used by reading GammaAtExit.dat file to locate at which projection the interruption happens
|
||||
//
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
|
||||
// struct ParticleInfo
|
||||
// {
|
||||
// float energy_keV;
|
||||
// float mx;
|
||||
// float my;
|
||||
// float mz;
|
||||
// float x;
|
||||
// float y;
|
||||
// float z;
|
||||
// };
|
||||
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
void LocateInterruption_GammaAtExit()
|
||||
{
|
||||
FILE* input = fopen("../build/GammaAtExit_1.dat", "rb");
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
int projection = 0; // the projection when interruption occurs
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
int runID = -1;
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
std::vector<ParticleInfo> gammaAtExit(nbParticle);
|
||||
fread(&gammaAtExit[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
printf("---------ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
projection = runInfo.projectionIndex;
|
||||
}
|
||||
|
||||
printf("-----------------------It is interrupted at ProjectionIndex = %d--------------------\n",
|
||||
projection);
|
||||
fclose(input);
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//***********************************************************************************************************
|
||||
// LocateInterruption_ProtonAtExit.C
|
||||
// Root command file
|
||||
// Type: root LocateInterruption_ProtonAtExit.C
|
||||
//
|
||||
// It is used by reading ProtonAtExit.dat file to locate at which projection the interruption is
|
||||
//
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
|
||||
// struct ParticleInfo
|
||||
// {
|
||||
// float energy_keV;
|
||||
// float mx;
|
||||
// float my;
|
||||
// float mz;
|
||||
// float x;
|
||||
// float y;
|
||||
// float z;
|
||||
// };
|
||||
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
void LocateInterruption_ProtonAtExit()
|
||||
{
|
||||
FILE* input = fopen("../build/ProtonAtExit_1.dat", "rb");
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
RunInfo runInfo;
|
||||
int projection = 0; // the projection when interruption occurs
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 128;
|
||||
const int nbPixel = 20;
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Detection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
int runID = -1;
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
std::vector<ParticleInfo> protonAtExit(nbParticle);
|
||||
fread(&protonAtExit[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
printf("---------ProjectionIndex=%d, SliceIndex=%d, PixelIndex=%d, nbParticle = %d\n",
|
||||
runInfo.projectionIndex, runInfo.sliceIndex, runInfo.pixelIndex, nbParticle);
|
||||
|
||||
projection = runInfo.projectionIndex;
|
||||
}
|
||||
|
||||
printf("-----------------------It is interrupted at ProjectionIndex = %d--------------------\n",
|
||||
projection);
|
||||
fclose(input);
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
//***********************************************************************************************************
|
||||
// Spectrum_gamma.C
|
||||
// Root command file
|
||||
// Type: root Spectrum_gamma.C
|
||||
//
|
||||
// It visualizes the spectrum of X-rays and plots a histogram by reading
|
||||
// simulation result GammaAtCreation.dat or GammaAtExit.dat
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
|
||||
// struct ParticleInfo
|
||||
//{
|
||||
// float energy_keV;
|
||||
// float mx;
|
||||
// float my;
|
||||
// float mz;
|
||||
// float x;
|
||||
// float y;
|
||||
// float z;
|
||||
//};
|
||||
|
||||
void Plot(vector<double>& energies, int bin, double eMin, double eMax)
|
||||
{
|
||||
auto mycanvas = new TCanvas("canvas", "canvas", 800, 50, 600, 600);
|
||||
gPad->SetLeftMargin(0.15);
|
||||
|
||||
// unit is in keV
|
||||
auto hist = new TH1D("hist (keV)", "Spectrum of photons", bin, eMin, eMax);
|
||||
|
||||
for (int i = 0; i < energies.size(); ++i) {
|
||||
hist->Fill(energies[i]);
|
||||
}
|
||||
|
||||
hist->Draw();
|
||||
hist->GetXaxis()->SetTitle("Energy (keV)");
|
||||
hist->GetYaxis()->SetTitle("Counts");
|
||||
hist->GetXaxis()->CenterTitle();
|
||||
hist->GetYaxis()->CenterTitle();
|
||||
|
||||
mycanvas->Print("spectrum_gamma.png");
|
||||
}
|
||||
|
||||
void Spectrum_gamma()
|
||||
{
|
||||
FILE* input = fopen("../build/GammaAtExit.dat", "rb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
|
||||
int projection_index_begin = 0; // starter of the projection selected
|
||||
int projection_index_end = 0; // end of the projection selected
|
||||
|
||||
int slice_index_begin = 0; // starter of the slice selected
|
||||
int slice_index_end = 0; // end of the slice selected
|
||||
|
||||
//********************Parameters for spectrum***************************
|
||||
int bin = 100;
|
||||
double eMin = 0; // keV
|
||||
double eMax = 0; // keV
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
RunInfo runInfo;
|
||||
vector<double> energies;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
// while(!feof(input)) //if not the end, read
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
// ***********the following codes are used
|
||||
// if**************************************(begin)
|
||||
// ***********the index of projection, slice and pixel is not correctly
|
||||
// configured in the simulation
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
//************************************************************************(end)
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> particles(nbParticle);
|
||||
fread(&particles[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
if (runInfo.projectionIndex >= projection_index_begin
|
||||
&& runInfo.projectionIndex <= projection_index_end)
|
||||
{
|
||||
if (runInfo.sliceIndex >= slice_index_begin && runInfo.sliceIndex <= slice_index_end) {
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
// printf("--%d, %.9e\n", i, particles[i].energy_keV);
|
||||
|
||||
energies.push_back(particles[i].energy_keV);
|
||||
if (particles[i].energy_keV > eMax) eMax = particles[i].energy_keV;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
Plot(energies, bin, eMin, eMax + 10);
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
//***********************************************************************************************************
|
||||
// Spectrum_proton.C
|
||||
// Root command file
|
||||
// Type: root Spectrum_proton.C
|
||||
//
|
||||
// It visualizes the spectrum of protons and plots a histogram by reading
|
||||
// simulation result ProtonAtExit.dat
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
// Define a structure to read and write each event in the required binary format
|
||||
struct RunInfo
|
||||
{
|
||||
// uint_16t
|
||||
uint8_t projectionIndex; // 1 byte
|
||||
uint16_t sliceIndex; //
|
||||
uint16_t pixelIndex;
|
||||
uint32_t nbParticle; // 4 bytes int
|
||||
};
|
||||
|
||||
struct ParticleInfo
|
||||
{
|
||||
float energy_keV;
|
||||
float mx;
|
||||
float my;
|
||||
float mz;
|
||||
};
|
||||
|
||||
void Plot(vector<double>& energies, int bin, double eMin, double eMax)
|
||||
{
|
||||
auto mycanvas = new TCanvas("canvas", "canvas", 800, 50, 600, 600);
|
||||
gPad->SetLeftMargin(0.15);
|
||||
|
||||
// unit is in keV
|
||||
auto hist = new TH1D("hist (keV)", "Spectrum of protons", bin, eMin, eMax);
|
||||
|
||||
for (int i = 0; i < energies.size(); ++i) {
|
||||
hist->Fill(energies[i]);
|
||||
}
|
||||
|
||||
hist->Draw();
|
||||
hist->GetXaxis()->SetTitle("Energy (keV)");
|
||||
hist->GetYaxis()->SetTitle("Counts");
|
||||
hist->GetXaxis()->CenterTitle();
|
||||
hist->GetYaxis()->CenterTitle();
|
||||
|
||||
mycanvas->Print("spectrum_proton.png");
|
||||
}
|
||||
|
||||
void Spectrum_proton()
|
||||
{
|
||||
FILE* input = fopen("../build/ProtonAtExit.dat", "rb");
|
||||
if (input == NULL) {
|
||||
printf("error for opening the input file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 128;
|
||||
const int nbPixel = 20;
|
||||
|
||||
int projection_index_begin = 0; // starter of the projection selected
|
||||
int projection_index_end = 0; // end of the projection selected
|
||||
|
||||
int slice_index_begin = 64; // starter of the slice selected
|
||||
int slice_index_end = 64; // end of the slice selected
|
||||
|
||||
//********************Parameters for spectrum***************************
|
||||
int bin = 100;
|
||||
double eMin = 0; // keV
|
||||
double eMax = 0; // keV
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
RunInfo runInfo;
|
||||
vector<double> energies;
|
||||
int runID = -1; // index of simulations, namely runID, starting from 0
|
||||
// while(!feof(input)) //if not the end, read
|
||||
while (fread(&runInfo, sizeof(RunInfo), 1, input)) {
|
||||
runID++;
|
||||
int nbParticle = runInfo.nbParticle;
|
||||
|
||||
// ***********the following codes are used
|
||||
// if**************************************(begin)
|
||||
// ***********the index of projection, slice and pixel is not correctly
|
||||
// configured in the simulation
|
||||
runInfo.projectionIndex = runID / (nbSlice * nbPixel);
|
||||
int remain = runID % (nbSlice * nbPixel);
|
||||
runInfo.sliceIndex = remain / nbPixel;
|
||||
runInfo.pixelIndex = remain % nbPixel;
|
||||
//******************************************************************************************(end)
|
||||
|
||||
if (!nbParticle) continue;
|
||||
std::vector<ParticleInfo> proton(nbParticle);
|
||||
fread(&proton[0], sizeof(ParticleInfo), nbParticle, input);
|
||||
|
||||
if (runInfo.projectionIndex >= projection_index_begin
|
||||
&& runInfo.projectionIndex <= projection_index_end)
|
||||
{
|
||||
if (runInfo.sliceIndex >= slice_index_begin && runInfo.sliceIndex <= slice_index_end) {
|
||||
for (int i = 0; i < nbParticle; ++i) {
|
||||
energies.push_back(proton[i].energy_keV);
|
||||
if (proton[i].energy_keV > eMax) eMax = proton[i].energy_keV;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
Plot(energies, bin, eMin, eMax + 10);
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
//***********************************************************************************************************
|
||||
// TomoSpectrum.C
|
||||
// Root command file
|
||||
// Type: root TomoSpectrum.C
|
||||
//
|
||||
// It visualizes the spectrum of X-rays and plots a graph by reading PixeEvent data.
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
|
||||
void Plot(int nbChannels, vector<int>& X, vector<int>& Y)
|
||||
{
|
||||
gROOT->Reset();
|
||||
|
||||
auto mycanvas = new TCanvas("canvas", "canvas", 800, 50, 600, 600);
|
||||
mycanvas->ToggleEventStatus();
|
||||
|
||||
gPad->SetLeftMargin(0.15);
|
||||
|
||||
auto graph = new TGraph(nbChannels, X.data(), Y.data());
|
||||
graph->SetLineColor(8);
|
||||
|
||||
graph->Draw("AL");
|
||||
|
||||
graph->SetLineColor(8);
|
||||
graph->SetTitle("TOMO Energy Spectrum");
|
||||
graph->GetXaxis()->SetTitle("ADC channels");
|
||||
graph->GetYaxis()->SetTitle("Nb events");
|
||||
graph->GetXaxis()->CenterTitle();
|
||||
graph->GetYaxis()->CenterTitle();
|
||||
|
||||
mycanvas->Print("TomoSpectrum.png");
|
||||
}
|
||||
|
||||
void TomoSpectrum()
|
||||
{
|
||||
FILE* input = fopen("../build/PixeEvent_std_AtExit_Detector135_Aperture70.DAT", "rb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("----------error for opening the input file--------------\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
|
||||
int projection_index_begin = 0; // starter of the projection selected
|
||||
int projection_index_end = 0; // end of the projection selected
|
||||
|
||||
int slice_index_begin = 0; // starter of the slice selected
|
||||
int slice_index_end = 0; // end of the slice selected
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
int nbChannels = 4096;
|
||||
vector<int> X(nbChannels); // save channels 1-4096, index X: 0-4095
|
||||
vector<int> Y(nbChannels); // save event counts for channel 1-4096, index Y: 0-4095
|
||||
PixeEvent p;
|
||||
|
||||
while (fread(&p, 7, 1, input)) {
|
||||
if (p.projectionIndex >= projection_index_begin && p.projectionIndex <= projection_index_end) {
|
||||
if (p.sliceIndex >= slice_index_begin && p.sliceIndex <= slice_index_end) {
|
||||
// printf("%d %d %d\n",p.projectionIndex, p.sliceIndex, p.energy_10eV);
|
||||
Y[p.energy_10eV - 1] = Y[p.energy_10eV - 1] + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(input);
|
||||
for (int i = 0; i < nbChannels; ++i) {
|
||||
X[i] = 1 + i;
|
||||
}
|
||||
|
||||
FILE* out = fopen("Spectrum.txt", "wb");
|
||||
for (int i = 0; i < nbChannels; ++i) {
|
||||
fprintf(out, "%d\t%d\n", X[i], Y[i]);
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
Plot(nbChannels, X, Y);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
//***********************************************************************************************************
|
||||
// TomoSpectrum_HIST.C
|
||||
// Root command file
|
||||
// Type: root TomoSpectrum_HIST.C
|
||||
//
|
||||
// It visualizes the spectrum of X-rays and plots a histogram by reading PixeEvent data
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
struct PixeEvent
|
||||
{
|
||||
uint16_t energy_10eV;
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
|
||||
void Plot(vector<double>& energies, int bin, double eMin, double eMax)
|
||||
{
|
||||
gROOT->Reset();
|
||||
|
||||
auto mycanvas = new TCanvas("canvas", "canvas", 800, 50, 600, 600);
|
||||
mycanvas->ToggleEventStatus();
|
||||
|
||||
gPad->SetLeftMargin(0.15);
|
||||
|
||||
auto hist = new TH1D("HIST", "Spectrum", bin, eMin, eMax);
|
||||
|
||||
for (int i = 0; i < energies.size(); ++i) {
|
||||
hist->Fill(energies[i]);
|
||||
}
|
||||
|
||||
hist->Draw();
|
||||
hist->SetTitle("TOMO Energy Spectrum");
|
||||
hist->GetXaxis()->SetTitle("ADC channels");
|
||||
hist->GetYaxis()->SetTitle("Nb events");
|
||||
|
||||
hist->GetXaxis()->CenterTitle();
|
||||
hist->GetYaxis()->CenterTitle();
|
||||
|
||||
// hist->GetYaxis()->SetTitleOffset(2);
|
||||
|
||||
mycanvas->Print("TomoSpectrum_hist.png");
|
||||
}
|
||||
|
||||
void TomoSpectrum_HIST()
|
||||
{
|
||||
FILE* input = fopen("../build/PixeEvent_std_AtExit_Detector135_Aperture70.DAT", "rb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("----------error for opening the input file--------------\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 1;
|
||||
const int nbPixel = 20;
|
||||
|
||||
int projection_index_begin = 0; // starter of the projection selected
|
||||
int projection_index_end = 0; // end of the projection selected
|
||||
|
||||
int slice_index_begin = 0; // starter of the slice selected
|
||||
int slice_index_end = 0; // end of the slice selected
|
||||
|
||||
//********************Parameters for spectrum***************************
|
||||
int nbChannels = 4096;
|
||||
double eMin = 0; // initialization
|
||||
double eMax = 0; //
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
vector<double> energies;
|
||||
PixeEvent p;
|
||||
while (fread(&p, 7, 1, input)) {
|
||||
if (p.projectionIndex >= projection_index_begin && p.projectionIndex <= projection_index_end) {
|
||||
if (p.sliceIndex >= slice_index_begin && p.sliceIndex <= slice_index_end) {
|
||||
energies.push_back(p.energy_10eV);
|
||||
if (p.energy_10eV > eMax) eMax = p.energy_10eV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
|
||||
long int size = energies.size();
|
||||
vector<int> X(nbChannels); // save channels 1-4096
|
||||
vector<int> Y(nbChannels);
|
||||
for (long int i = 0; i < size; ++i) {
|
||||
int energy = energies[i];
|
||||
Y[energy - 1] = Y[energy - 1] + 1;
|
||||
}
|
||||
for (int i = 0; i < nbChannels; ++i) {
|
||||
X[i] = 1 + i;
|
||||
}
|
||||
|
||||
FILE* out = fopen("Spectrum_hist.txt", "wb");
|
||||
|
||||
for (int i = 0; i < nbChannels; ++i) {
|
||||
fprintf(out, "%d\t%d\n", X[i], Y[i]);
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
|
||||
Plot(energies, nbChannels, 0, nbChannels);
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
//***********************************************************************************************************
|
||||
// TomoSpectrum_HIST_proton.C
|
||||
// Root command file
|
||||
// Type: root TomoSpectrum_HIST_proton.C
|
||||
//
|
||||
// It visualizes the spectrum of protons and plots a histogram by reading StimEvent data
|
||||
//
|
||||
// More information is available in UserGuide
|
||||
// Created by Z.LI LP2i Bordeaux 2022
|
||||
//***********************************************************************************************************
|
||||
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vector>
|
||||
// using namespace std;
|
||||
|
||||
struct StimEvent
|
||||
{
|
||||
uint16_t energy_keV; // different from Pixe Event, it is in keV
|
||||
uint16_t pixelIndex;
|
||||
uint16_t sliceIndex;
|
||||
uint8_t projectionIndex;
|
||||
};
|
||||
|
||||
void Plot(vector<double>& energies, int bin, double eMin, double eMax)
|
||||
{
|
||||
gROOT->Reset();
|
||||
|
||||
auto mycanvas = new TCanvas("canvas", "canvas", 800, 50, 600, 600);
|
||||
mycanvas->ToggleEventStatus();
|
||||
|
||||
gPad->SetLeftMargin(0.15);
|
||||
|
||||
auto hist = new TH1D("HIST", "Spectrum", bin, eMin, eMax);
|
||||
|
||||
for (int i = 0; i < energies.size(); ++i) {
|
||||
hist->Fill(energies[i]);
|
||||
}
|
||||
|
||||
hist->Draw();
|
||||
hist->SetTitle("TOMO Energy Spectrum");
|
||||
hist->GetXaxis()->SetTitle("ADC channels");
|
||||
hist->GetYaxis()->SetTitle("Nb events");
|
||||
|
||||
hist->GetXaxis()->CenterTitle();
|
||||
hist->GetYaxis()->CenterTitle();
|
||||
|
||||
// hist->GetYaxis()->SetTitleOffset(2);
|
||||
|
||||
mycanvas->Print("TomoSpectrum_hist_proton.png");
|
||||
}
|
||||
|
||||
void TomoSpectrum_HIST_proton()
|
||||
{
|
||||
FILE* input = fopen("../build/StimEvent_std_Detector0_Aperture10.2.DAT", "rb");
|
||||
|
||||
if (input == NULL) {
|
||||
printf("----------error for opening the input file--------------\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (begin)*****************
|
||||
//***********************************************************************
|
||||
const int nbProjection = 10;
|
||||
const int nbSlice = 128;
|
||||
const int nbPixel = 20;
|
||||
|
||||
int projection_index_begin = 0; // starter of the projection selected
|
||||
int projection_index_end = 0; // end of the projection selected
|
||||
|
||||
int slice_index_begin = 64; // starter of the slice selected
|
||||
int slice_index_end = 64; // end of the slice selected
|
||||
|
||||
//********************Parameters for spectrum***************************
|
||||
int nbChannels = 4096;
|
||||
double eMin = 0; // initialization
|
||||
double eMax = 0; //
|
||||
|
||||
//***********************************************************************
|
||||
//**************************Selection parameters (end)*******************
|
||||
//***********************************************************************
|
||||
|
||||
vector<double> energies;
|
||||
StimEvent s;
|
||||
while (fread(&s, 7, 1, input)) {
|
||||
if (s.projectionIndex >= projection_index_begin && s.projectionIndex <= projection_index_end) {
|
||||
if (s.sliceIndex >= slice_index_begin && s.sliceIndex <= slice_index_end) {
|
||||
energies.push_back(s.energy_keV);
|
||||
if (s.energy_keV > eMax) eMax = s.energy_keV;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(input);
|
||||
|
||||
if (eMax > 4096) printf("---error in data----\n");
|
||||
long int size = energies.size();
|
||||
vector<int> X(nbChannels); // save channels 1-4096
|
||||
vector<int> Y(nbChannels);
|
||||
|
||||
for (long int i = 0; i < size; ++i) {
|
||||
int energy = energies[i];
|
||||
Y[energy - 1] = Y[energy - 1] + 1;
|
||||
}
|
||||
for (int i = 0; i < nbChannels; ++i) {
|
||||
X[i] = 1 + i;
|
||||
}
|
||||
|
||||
FILE* out = fopen("Spectrum_hist_proton.txt", "wb");
|
||||
|
||||
for (int i = 0; i < nbChannels; ++i) {
|
||||
fprintf(out, "%d\t%d\n", X[i], Y[i]);
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
|
||||
Plot(energies, nbChannels, 0, nbChannels);
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
import sys
|
||||
import struct
|
||||
import math
|
||||
import numpy as np
|
||||
|
||||
# lists for super resolution (vol_work) and regular resolution (vol_result)
|
||||
vol_work = []
|
||||
vol_result = []
|
||||
|
||||
############################################################################
|
||||
# size image 128x128 -> 500 microm -> resol x,y : 3.90625 microm #
|
||||
# nb slices 128 -> 500 microm -> resol z : 3.90625 microm #
|
||||
############################################################################
|
||||
|
||||
sizex = 128
|
||||
sizey = 128
|
||||
sizez = 128
|
||||
resolx = 3.90625
|
||||
resoly = 3.90625
|
||||
resolz = 3.90625
|
||||
superres = 8 # factor of super resolution
|
||||
|
||||
# sphere 1 (radius) - outer sphere
|
||||
r1 = 196
|
||||
|
||||
# sphere 2 (radius) - inner sphere
|
||||
r2 = 171
|
||||
|
||||
# density values for sphere 1 and sphere 2
|
||||
type = 2 # type for constructing a STIM or PIXE phantom
|
||||
# type = 1, STIM phantom, density value for STIM in 0.01 g/cm3
|
||||
# type =2, PIXE phantom, density value for PIXE in 0.000001 g/cm3, namely microgram/cm3
|
||||
value1 = 0
|
||||
value2 = 0
|
||||
|
||||
if type == 1:
|
||||
value1 = 108
|
||||
value2 = 0
|
||||
elif type == 2:
|
||||
value1 = 54000
|
||||
value2 = 0
|
||||
|
||||
# center of two spheres
|
||||
x0 = 0.0
|
||||
y0 = 0.0
|
||||
z0 = -1.953125
|
||||
|
||||
# size in super resolution by voxel
|
||||
super_sizex = sizex * superres
|
||||
super_sizey = sizey * superres
|
||||
super_sizez = sizez * superres
|
||||
center_shift = sizex / 2 # translation of half scan
|
||||
|
||||
|
||||
def make_sphere_center(r, x, y, z, value):
|
||||
rsample = (r / resolx) * superres # radius in super resolution by voxel
|
||||
xsample = (x / resolx) * superres
|
||||
ysample = (y / resoly) * superres
|
||||
zsample = (z / resolz) * superres
|
||||
center_shift_sample = center_shift * superres # translation of the center for x (i) and y (j) axis
|
||||
|
||||
print(rsample, xsample, ysample, zsample)
|
||||
number = 0
|
||||
|
||||
for k in range(0, super_sizez):
|
||||
for j in range(0, super_sizey):
|
||||
for i in range(0, super_sizex):
|
||||
ii = i + 0.5
|
||||
jj = j + 0.5
|
||||
kk = k + 0.5
|
||||
res = pow((ii - xsample - center_shift_sample), 2) / (rsample * rsample) + \
|
||||
pow((jj - ysample - center_shift_sample), 2) / (rsample * rsample) + \
|
||||
pow((kk - zsample - center_shift_sample), 2) / (rsample * rsample) # z-axis correction done
|
||||
# if the point (ii, jj, kk) is in the sphere, we attribute the voxel (i,j, k) value
|
||||
if (res <= 1.0):
|
||||
vol_work[i + j * super_sizex + k * super_sizex * super_sizey] = value
|
||||
number += 1
|
||||
|
||||
print(number)
|
||||
|
||||
|
||||
# initialisation for two tables vol_result (128*128*128), vol_work (128*superres)*(128*superres)*(128*superres)
|
||||
def initialize():
|
||||
for k in range(0, sizez):
|
||||
for j in range(0, sizey):
|
||||
for i in range(0, sizex):
|
||||
vol_result.append(0.0)
|
||||
for k in range(0, super_sizez):
|
||||
for j in range(0, super_sizey):
|
||||
for i in range(0, super_sizex):
|
||||
vol_work.append(0.0)
|
||||
|
||||
|
||||
# Calculate the vol_result based on vol_work
|
||||
def undersample():
|
||||
x = 0
|
||||
y = 0
|
||||
z = 0
|
||||
for k in range(0, super_sizez, superres):
|
||||
for j in range(0, super_sizey, superres):
|
||||
for i in range(0, super_sizex, superres):
|
||||
# print ("***",i,j,k)
|
||||
total = 0
|
||||
for kk in range(0, superres):
|
||||
for jj in range(0, superres):
|
||||
for ii in range(0, superres):
|
||||
total = total + vol_work[
|
||||
i + ii + (j + jj) * super_sizex + (k + kk) * (super_sizex * super_sizey)]
|
||||
vol_result[x + y * sizex + z * (sizex * sizey)] = total / (superres * superres * superres)
|
||||
# print ("###",vol_result[x+y*sizex+z*(sizex*sizey)])
|
||||
x += 1
|
||||
y += 1
|
||||
x = 0
|
||||
z += 1
|
||||
y = 0
|
||||
|
||||
|
||||
# save the total volume of super resolution
|
||||
def save_whole_work(file):
|
||||
fd = open(file, "wb")
|
||||
for i in range(0, len(vol_work)):
|
||||
fd.write(struct.pack("f", vol_work[i]))
|
||||
fd.close()
|
||||
|
||||
|
||||
# save one slice in super resolution vol_work
|
||||
# 0<=slice<super_sizez (128*8=1024)
|
||||
def save_workslice(file, slice):
|
||||
fd = open(file, "wb")
|
||||
for j in range(0, super_sizey):
|
||||
for i in range(0, super_sizex):
|
||||
fd.write(struct.pack("f", vol_work[i + j * super_sizex + slice * super_sizex * super_sizey]))
|
||||
fd.close()
|
||||
|
||||
|
||||
# save the total result volume
|
||||
def save_whole_result(file):
|
||||
fd = open(file, "wb")
|
||||
for i in range(0, len(vol_result)):
|
||||
fd.write(struct.pack("f", vol_result[i]))
|
||||
fd.close()
|
||||
|
||||
|
||||
# save one slie in regular resolution vol_result
|
||||
# 0<=slice<128
|
||||
def save_slice(file, slice):
|
||||
fd = open(file, "wb")
|
||||
for j in range(0, sizey):
|
||||
for i in range(0, sizex):
|
||||
fd.write(struct.pack("f", vol_result[i + j * sizex + slice * sizex * sizey]))
|
||||
|
||||
fd.close()
|
||||
|
||||
|
||||
print("------intialisation------")
|
||||
initialize()
|
||||
print("------end intialisation------")
|
||||
|
||||
print("------begin sphere 1------")
|
||||
make_sphere_center(r1, x0, y0, z0, value1)
|
||||
print("------end sphere 1------")
|
||||
|
||||
print("------begin sphere 2------")
|
||||
make_sphere_center(r2, x0, y0, z0, value2)
|
||||
print("------end sphere 2------")
|
||||
|
||||
print("------begin undersample------")
|
||||
undersample()
|
||||
print("------end undersample------")
|
||||
|
||||
print("The length of vol_work: ", len(vol_work))
|
||||
print("The length of vol_result: ", len(vol_result))
|
||||
|
||||
# print ("------begin save slice 63 ------")
|
||||
# save_slice("./slice_63.dat",63)
|
||||
# print ("------end save slice 63 ------")
|
||||
|
||||
save_whole_result("./vol_result.dat")
|
||||
save_whole_work("./vol_work.dat")
|
||||
print("------end save work------")
|
||||
@@ -0,0 +1,265 @@
|
||||
import sys
|
||||
import struct
|
||||
import math
|
||||
|
||||
# tables for super resolution (vol_work) and regular resolution (vol_result)
|
||||
vol_work = []
|
||||
vol_result = []
|
||||
|
||||
############################################################################
|
||||
# size image 128x128 -> 76.464 microm -> resol x,y : 0,597375 microm #
|
||||
# nb slices 128 -> 201,217 microm -> resol z : 1,57200781 microm #
|
||||
# slice of interest : 11 -> 18,07 microm #
|
||||
############################################################################
|
||||
|
||||
sizex = 128
|
||||
sizey = 128
|
||||
sizez = 128
|
||||
double_sizez = 256 # for computation only
|
||||
resolx = 0.597375
|
||||
resoly = 0.597375
|
||||
resolz = 1.57200781
|
||||
superres = 8
|
||||
|
||||
slice = 11
|
||||
|
||||
# ellipsoide 1 (semi-axes, center, rotation z, value) - skin
|
||||
a1 = 20.61
|
||||
b1 = 21.42
|
||||
c1 = 187.82
|
||||
x1 = 0.0
|
||||
y1 = 0.0
|
||||
z1 = 0.0
|
||||
rz1 = 0.0
|
||||
value1 = 49.73
|
||||
|
||||
# ellipsoide 2 (semi-axes, center, rotation z, value) - body
|
||||
a2 = 18.61
|
||||
b2 = 19.01
|
||||
c2 = 186.64
|
||||
x2 = -0.39
|
||||
y2 = 0.0
|
||||
z2 = 0.0
|
||||
rz2 = 0.0
|
||||
value2 = 40.85
|
||||
|
||||
# ellipsoide 3 (semi-axes, center, rotation z, value) - core 1
|
||||
a3 = 1.95
|
||||
b3 = 3.23
|
||||
c3 = 4.32
|
||||
x3 = 1.97
|
||||
y3 = -7.09
|
||||
z3 = 18.07
|
||||
rz3 = 0.0
|
||||
value3 = 66.26
|
||||
|
||||
# ellipsoide 4 (semi-axes, center, rotation z, value) - core 2
|
||||
a4 = 2.08
|
||||
b4 = 2.46
|
||||
c4 = 4.32
|
||||
x4 = 8.27
|
||||
y4 = -3.15
|
||||
z4 = 18.07
|
||||
rz4 = 0.0
|
||||
value4 = 60.23
|
||||
|
||||
# ellipsoide 5 (semi-axes, center, rotation z, value) - intestine
|
||||
a5 = 3.67
|
||||
b5 = 16.48
|
||||
c5 = 28.68
|
||||
x5 = 1.25
|
||||
y5 = 0.61
|
||||
z5 = 0
|
||||
rz5 = -58.99
|
||||
value5 = 54.06
|
||||
|
||||
# ellipsoide 6 ((emi-axes, center, rotation z, value) - region titane
|
||||
a6 = 1.62
|
||||
b6 = 1.95
|
||||
c6 = 1.62
|
||||
x6 = 6.25
|
||||
y6 = 3.61
|
||||
z6 = 18.07
|
||||
rz6 = 0.0
|
||||
value6 = 75.14
|
||||
|
||||
# size in super resolution by voxel
|
||||
super_sizex = sizex * superres
|
||||
super_sizey = sizey * superres
|
||||
super_sizez = double_sizez * superres # we will save only half of the z
|
||||
center_shift = sizex / 2 # for x and y axis
|
||||
center_shift_z = double_sizez / 2
|
||||
|
||||
|
||||
def make_ellipse_center(a, b, c, x, y, z, rz, value):
|
||||
asample = (a / resolx) * superres
|
||||
bsample = (b / resoly) * superres
|
||||
csample = (c / resolz) * superres
|
||||
# if (rz != 0.0):
|
||||
rzsample = math.radians(rz) # angle in radians
|
||||
xsample = (x / resolx) * superres
|
||||
ysample = (y / resoly) * superres
|
||||
zsample = (z / resolz) * superres
|
||||
center_shift_sample = center_shift * superres # translation of center for x and y axis
|
||||
center_shift_z_sample = center_shift_z * superres # translation of center for z axis
|
||||
|
||||
print(asample, bsample, csample, xsample, ysample, zsample)
|
||||
number = 0 ## debug
|
||||
|
||||
# a loop in axes of voxels
|
||||
for k in range(0, super_sizez):
|
||||
for j in range(0, super_sizey):
|
||||
for i in range(0, super_sizex):
|
||||
ii = i + 0.5
|
||||
jj = j + 0.5
|
||||
kk = k + 0.5
|
||||
res = pow(((ii - xsample - center_shift_sample) * math.cos(rzsample) + (
|
||||
jj - ysample - center_shift_sample) * math.sin(rzsample)), 2) / (asample * asample) + \
|
||||
pow(((ii - xsample - center_shift_sample) * math.sin(rzsample) - (
|
||||
jj - ysample - center_shift_sample) * math.cos(rzsample)), 2) / (bsample * bsample) + \
|
||||
((kk - zsample - center_shift_z_sample) * (kk - zsample - center_shift_z_sample)) / (
|
||||
csample * csample) # z-axis correction done
|
||||
# print(res)
|
||||
# if the voxel belongs to the ellipsoide, set the value
|
||||
if (res <= 1.0):
|
||||
vol_work[i + j * super_sizex + k * super_sizex * super_sizey] = value
|
||||
number += 1
|
||||
|
||||
print(number)
|
||||
|
||||
|
||||
# initialisation
|
||||
def initialize():
|
||||
for k in range(0, double_sizez):
|
||||
for j in range(0, sizey):
|
||||
for i in range(0, sizex):
|
||||
vol_result.append(0.0)
|
||||
for k in range(0, super_sizez):
|
||||
for j in range(0, super_sizey):
|
||||
for i in range(0, super_sizex):
|
||||
vol_work.append(0.0)
|
||||
|
||||
|
||||
# Calculate the vol_result based on vol_work
|
||||
def undersample():
|
||||
x = 0
|
||||
y = 0
|
||||
z = 0
|
||||
for k in range(0, super_sizez, superres):
|
||||
for j in range(0, super_sizey, superres):
|
||||
for i in range(0, super_sizex, superres):
|
||||
# on se place sur v1 et on recupere les valeurs de densite des 8 voxels du voisinage qui vont correspondre a 1 voxel de l'image finale
|
||||
# v1 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey)]
|
||||
# v2 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey) + 1]
|
||||
# v3 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey) + super_sizex]
|
||||
# v4 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey) + super_sizex + 1]
|
||||
# v5 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey) + super_sizex*super_sizey]
|
||||
# v6 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey) + 1 + super_sizex*super_sizey]
|
||||
# v7 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey) + super_sizex + super_sizex*super_sizey]
|
||||
# v8 = vol_work[i+j*super_sizex+k*(super_sizex*super_sizey) + super_sizex + 1 + super_sizex*super_sizey]
|
||||
# vol_result[x+y*sizex+z*(sizex*sizey)] = (v1+v2+v3+v4+v5+v6+v7+v8)/8.0
|
||||
# print ("***",i,j,k)
|
||||
total = 0
|
||||
for kk in range(0, superres):
|
||||
for jj in range(0, superres):
|
||||
for ii in range(0, superres):
|
||||
total = total + vol_work[
|
||||
i + ii + (j + jj) * super_sizex + (k + kk) * (super_sizex * super_sizey)]
|
||||
vol_result[x + y * sizex + z * (sizex * sizey)] = total / (superres * superres * superres)
|
||||
# print ("###",vol_result[x+y*sizex+z*(sizex*sizey)])
|
||||
x += 1
|
||||
y += 1
|
||||
x = 0
|
||||
z += 1
|
||||
y = 0
|
||||
|
||||
|
||||
# Save the total volume (including the negative parts of the ellipsoids)
|
||||
def save_whole_work(file):
|
||||
fd = open(file, "wb")
|
||||
for i in range(0, len(vol_work)):
|
||||
fd.write(struct.pack("f", vol_work[i]))
|
||||
|
||||
|
||||
# Save half the volume (including only the positive parts of the ellipsoids)
|
||||
def save_half_work(file):
|
||||
fd = open(file, "wb")
|
||||
for i in range(int(len(vol_work) / 2), len(vol_work)):
|
||||
fd.write(struct.pack("f", vol_work[i]))
|
||||
|
||||
|
||||
# save one slice in super resolution vol_work
|
||||
# 0<=slice<super_sizez
|
||||
def save_workslice(file, slice):
|
||||
fd = open(file, "wb")
|
||||
for j in range(0, super_sizey):
|
||||
for i in range(0, super_sizex):
|
||||
fd.write(struct.pack("f", vol_work[i + j * super_sizex + slice * super_sizex * super_sizey]))
|
||||
|
||||
|
||||
# Save the total result volume (including the negative parts of the ellipsoids)
|
||||
def save_whole_result(file):
|
||||
fd = open(file, "wb")
|
||||
for i in range(0, len(vol_result)):
|
||||
fd.write(struct.pack("f", vol_result[i]))
|
||||
|
||||
|
||||
# Save half of the result volume (including only the positive parts of the ellipsoids)
|
||||
def save_half_result(file):
|
||||
fd = open(file, "wb")
|
||||
for i in range(int(len(vol_result) / 2), len(vol_result)):
|
||||
fd.write(struct.pack("f", vol_result[i]))
|
||||
|
||||
|
||||
# save one slie in regular resolution vol_result
|
||||
# 0<=slice<128
|
||||
def save_slice(file, slice):
|
||||
fd = open(file, "wb")
|
||||
for j in range(0, sizey):
|
||||
for i in range(0, sizex):
|
||||
fd.write(struct.pack("f", vol_result[i + j * sizex + slice * sizex * sizey]))
|
||||
|
||||
|
||||
print("------intialisation------")
|
||||
initialize()
|
||||
print("------end intialisation------")
|
||||
|
||||
print("------begin ellipse 1------------")
|
||||
make_ellipse_center(a1, b1, c1, x1, y1, z1, rz1, value1)
|
||||
print("------end ellipse 1--------------")
|
||||
|
||||
print("------begin ellipse 2------------")
|
||||
make_ellipse_center(a2, b2, c2, x2, y2, z2, rz2, value2)
|
||||
print("------end ellipse 2--------------")
|
||||
|
||||
print("------begin ellipse 3------------")
|
||||
make_ellipse_center(a3, b3, c3, x3, y3, z3, rz3, value3)
|
||||
print("------end ellipse 3--------------")
|
||||
|
||||
print("------begin ellipse 4------------")
|
||||
make_ellipse_center(a4, b4, c4, x4, y4, z4, rz4, value4)
|
||||
print("------end ellipse 4--------------")
|
||||
|
||||
print("------begin ellipse 5------------")
|
||||
make_ellipse_center(a5, b5, c5, x5, y5, z5, rz5, value5)
|
||||
print("------end ellipse 5--------------")
|
||||
|
||||
print("------begin ellipse 6------------")
|
||||
make_ellipse_center(a6, b6, c6, x6, y6, z6, rz6, value6)
|
||||
print("------end ellipse 6--------------")
|
||||
|
||||
print("------begin undersample------")
|
||||
undersample()
|
||||
print("------end undersample------")
|
||||
|
||||
print("The length of vol_work: ", len(vol_work))
|
||||
print("The length of vol_result: ", len(vol_result))
|
||||
|
||||
# print ("------begin save slice 139 ------")
|
||||
save_slice("./slice_139.dat", 139)
|
||||
# print ("------end save slice 139 ------")
|
||||
|
||||
|
||||
save_half_result("./vol_result.dat")
|
||||
# save_whole_work("./vol_work.dat")
|
||||
print("------end save work------")
|
||||
Reference in New Issue
Block a user