33 reconFOV=initialRadius=shankAngle=0;
40 projectionModel=model;
50 ASSERT(detEfficiency > 0 && detEfficiency <=1);
51 detEfficiency =detEff;
68 ASSERT(shankAngle >=0 && shankAngle <
M_PI/2.0f);
80 const std::vector<float> &detectorY,
81 const std::vector<float> &tof,
82 const std::vector<float> &ionVolume,
83 std::vector<IonHit> &outputPts)
const 86 ASSERT(detectorX.size() == detectorY.size());
87 ASSERT(detectorX.size() == ionVolume.size());
88 outputPts.resize(detectorX.size());
97 if(shankAngle > sqrt(std::numeric_limits<float>::epsilon()))
98 initZoff= initialRadius*(1.0/sin(shankAngle) -1.0) ;
100 initZoff=initialRadius;
103 float etaFOV = projectionModel->
thetaToEta(reconFOV);
106 double distRatio=initialRadius/initZoff;
110 double zOffset=initZoff;
122 if(shankAngle > std::numeric_limits<float>::epsilon())
125 float areaFactor = 1.0f/(2.0f*
M_PI*(1.0-cos(reconFOV)));
127 for(
unsigned int ui=0;ui<detectorX.size() ;ui++)
134 currentR= distRatio*(zOffset);
137 outputPts[ui][2]=zOffset;
140 zOffset +=(ionVolume[ui]/detEfficiency)*areaFactor/(currentR*currentR);
147 float areaSphericalCapInv;
148 areaSphericalCapInv = 1.0/(2.0*
M_PI*initialRadius*initialRadius*(1.0-cos(reconFOV)));
152 for(
unsigned int ui=0;ui<detectorX.size() ;ui++)
155 outputPts[ui][2]=(zOffset-initZoff);
158 zOffset +=(ionVolume[ui]/detEfficiency)*areaSphericalCapInv;
170 #pragma omp parallel for 171 for(
unsigned int ui=0;ui<detectorX.size() ;ui++)
179 projectionModel->
scaleDown(flightPath,detectorX[ui],
180 detectorY[ui],px,py);
192 currentR= distRatio*(outputPts[ui][2]);
193 outputPts[ui][0]=currentR*sin(eta)*cos(phi);
194 outputPts[ui][1]=currentR*sin(eta)*sin(phi);
195 outputPts[ui][2]+=currentR*(1.0f-cos(eta)) - initZoff;
198 outputPts[ui][3]=tof[ui];
218 std::vector<float> dx, dy, tof,ionV;
220 const unsigned int NUM_PTS=100000;
223 ionV.resize(NUM_PTS,0.1);
228 std::random_device r;
229 std::mt19937 mtRnd(r());
230 std::uniform_real_distribution<float> ud(0,1.0f);
233 const float DET_SIZE=40.0f;
234 const float FLIGHT_PATH=42.0f;
235 for(
unsigned int ui=0;ui<NUM_PTS;ui++)
239 dx[ui] = 2.0*(ud(mtRnd)-0.5f);
240 dy[ui] = 2.0*(ud(mtRnd)-0.5f);
241 }
while(dx[ui]*dx[ui] + dy[ui]*dy[ui] > 1.0f);
245 dx[ui]*=DET_SIZE/2.0f;
246 dy[ui]*=DET_SIZE/2.0f;
248 tof[ui]=ud(mtRnd)+0.5;
260 const float TIP_RADIUS=15.0f;
263 recons.
setReconFOV(atan(0.5*DET_SIZE/FLIGHT_PATH));
266 std::vector<IonHit> pts;
270 TEST(errRes,
"Reconstruction should not fail");
271 TEST(pts.size() && (pts.size() <= NUM_PTS),
"One event per reconstruction");
275 TEST(bc.isValid(),
"Valid bounding cube");
279 const double FUDGE=1.5;
281 "Bounding box should not exceed final tip diameter");
284 "Bounding box should not exceed final tip diameter");
void setFlightPath(float detEff)
Set flight path. Units must match detector units (eg mm)
void setReconFOV(float angle)
Set the angle (between 0 and pi radiaans). This is.
virtual float thetaToEta(float theta) const =0
float getSize(unsigned int dim) const
Return the size of the side parallel to the given dimension.
float getVolume() const
Obtain the volume of the cube.
unsigned int savePosFile(const std::vector< Point3D > &points, float mass, const char *name, bool append=false)
Save a vector of Point3Ds into a pos file, using a fixed mass, return nonzero on error.
ReconstructionSphereOnCone()
Default constructor.
virtual bool toAzimuthal(float fx, float fy, float &theta, float &phi) const =0
Convert from plane coordinates to projection coords.
bool reconstruct(const std::vector< float > &detectorX, const std::vector< float > &detectorY, const std::vector< float > &timeOfFlight, const std::vector< float > &ionVolume, std::vector< IonHit > &outputPts) const
Using the current reconstruction model, reconstruct a detector sequence.
Helper class to define a bounding cube.
void setRadiusEvolutionMode(unsigned int evolutionMode)
Set the method of evolution for the shank, as per EVOLUTION_MODE_ enum.
void setInitialRadius(float rInit)
Set the initial tip radius.
void setShankAngle(float angle)
Set initial angle, in radiians.
void setDetectorEfficiency(float detEff)
Set detector efficiency in range (0,1].
void setProjModel(AtomProbe::SphericPlaneProjection *model)
Set a given projection model.
virtual void scaleDown(float flightLength, float detX, float detY, float &scaledX, float &scaledY) const =0
Convert from actual detector postion (eg. mm) and flight path to scaled-down transform.
void setBounds(float xMin, float yMin, float zMin, float xMax, float yMax, float zMax)
Set the bounds by passing in minima and maxima of each dimension.