28 #include <gsl/gsl_errno.h> 29 #include <gsl/gsl_math.h> 30 #include <gsl/gsl_roots.h> 52 float &fx,
float &fy)
const 86 float &
theta,
float &phi)
const 91 float r= sqrt(fx*fx + fy*fy);
102 float detX,
float detY,
float &scaledX,
float &scaledY)
const 109 scaledX= detX/flightLength;
110 scaledY= detY/flightLength;
114 float &realX,
float &realY)
const 120 realX=scaledX*flightLength;
121 realY=scaledY*flightLength;
125 float &fx,
float &fy)
const 129 float r = 2.0*cos(theta);
137 float detX,
float detY,
float &scaledX,
float &scaledY)
const 143 scaledX= 2.0*detX/flightLength;
144 scaledY= 2.0*detY/flightLength;
148 float &realX,
float &realY)
const 154 realX = scaledX*flightLength/2.0;
155 realY = scaledY*flightLength/2.0;
159 float &
theta,
float &phi)
const 166 float r= sqrt(fx*fx + fy*fy);
181 const gsl_root_fsolver_type *T = gsl_root_fsolver_brent;
182 gsl_root_fsolver *s = gsl_root_fsolver_alloc (T);
196 gsl_root_fsolver_set (s, &f, x_lo, x_hi);
201 gsl_root_fsolver_iterate (s);
202 r = gsl_root_fsolver_root (s);
203 x_lo = gsl_root_fsolver_x_lower (s);
204 x_hi = gsl_root_fsolver_x_upper (s);
205 status = gsl_root_test_interval (x_lo, x_hi,
208 }
while (status == GSL_CONTINUE && iter < 20);
211 gsl_root_fsolver_free(s);
213 if(status != GSL_SUCCESS)
236 ASSERT(eta <= M_PI && eta>=0);
239 return atan( sin(eta) / (cos(eta) +
focusDist));
248 const gsl_root_fsolver_type *T = gsl_root_fsolver_brent;
249 gsl_root_fsolver *s = gsl_root_fsolver_alloc (T);
263 gsl_root_fsolver_set (s, &f, x_lo, x_hi);
268 gsl_root_fsolver_iterate (s);
269 r = gsl_root_fsolver_root (s);
270 x_lo = gsl_root_fsolver_x_lower (s);
271 x_hi = gsl_root_fsolver_x_upper (s);
272 status = gsl_root_test_interval (x_lo, x_hi,
275 }
while (status == GSL_CONTINUE && iter < 20);
278 gsl_root_fsolver_free(s);
280 if(status != GSL_SUCCESS)
308 float theta=etaToTheta(eta);
313 bool ModifiedFocusSphericProjection::getProjectionPt(
float theta,
float &f)
const 316 if(theta >=getMaxFOV())
330 if(!getProjectionPt(theta,fRadius) )
334 fx = fRadius*cos(phi);
335 fy = fRadius*sin(phi);
345 radius=sqrt(fx*fx + fy*fy);
350 if(theta > getMaxFOV())
357 float detX,
float detY,
float &scaledX,
float &scaledY)
const 363 scaledX= (1.0+
focusDist)*detX/flightLength;
364 scaledY= (1.0+
focusDist)*detY/flightLength;
368 float &realX,
float &realY)
const 374 realX= scaledX*flightLength/(1.0+
focusDist);
375 realY= scaledY*flightLength/(1.0+
focusDist);
381 bool testAzimuthalProjection();
383 bool testProjection()
385 if(!testAzimuthalProjection())
391 bool testAzimuthalProjection()
403 TEST(
tolEqual(theta,(
float)(45.0f*
M_PI/180.0f),0.1f),
"toAzimuthal failed");
406 theta=45.0f*
M_PI/180.0f;
428 TEST(
tolEqual(theta,(
float)(45.0f*
M_PI/180.0f),0.1f),
"Should form 1-1-sqrt(2) triangle");
431 double roundTripTheta;
433 TEST(
tolEqual(roundTripTheta,0.1, 0.01),
"Round-trip coordinate transform for modified stereographic");
virtual bool toPlanar(float theta, float phi, float &fx, float &fy) const
Convert from spherical coordinates to plane.
virtual void scaleDown(float flightLength, float detX, float detY, float &scaledX, float &scaledY) const
Convert from actual detector postion (eg. mm) and flight path to scaled-down transform.
virtual void scaleUp(float flightLength, float scaledX, float scaledY, float &realX, float &realY) const
Convert from scaled-down radius to actual radius.
double SphericProjectionEqn(double eta, void *p)
ModifiedFocusSphericProjection(float focus)
Create a Spheric projection, with a focal point that is moved behind the sphere.
void setFocus(float focus)
Set the focus position of the sphere. 0= sphere centre, 1=sphere end, >1 is outside sphere...
virtual bool toPlanar(float theta, float phi, float &fx, float &fy) const
Convert from stereographic (NOT SPHERICAL) coordinates to plane.
virtual void scaleUp(float flightLength, float scaledX, float scaledY, float &realX, float &realY) const
Convert from scaled-down to actual dimension.
A 3D point data class storage.
void setISOSpherical(float radius, float theta, float phi)
Assign the vector using spherical coordinates.
virtual bool toAzimuthal(float fx, float fy, float &theta, float &phi) const
Convert from plane coordinates to stereographic (NOT SPHERICAL) coords.
virtual bool toPlanar(float theta, float phi, float &fx, float &fy) const
Convert from stereographic (NOT SPHERICAL) coordinates to plane.
float thetaToEta(float theta) const
Convert azimuthal angle to spherical. See etaToTheta for description.
float thetaToEta(float theta) const
Convert azimuthal angle to spherical. See etaToTheta for description.
float etaToTheta(float eta) const
Convert the spherical angle to an azimuthal angle. See docs/figures for examples. ...
float getMaxFOV() const
Obtain angle spherical angle, eta, (i.e. angle from point of sphere, sphere centre and x axis) of the...
virtual void scaleDown(float flightLength, float detX, float detY, float &scaledX, float &scaledY) const
Convert from actual detector postion (eg. mm) and flight path to scaled-down transform.
float getFOVRadius(float eta) const
Obtain the radius in the XY plane of the sphere-angle (eta) that gives us a given FOV...
virtual bool toAzimuthal(float fx, float fy, float &theta, float &phi) const
Convert from plane coordinates to stereographic (NOT SPHERICAL) coords.
virtual bool toAzimuthal(float fx, float fy, float &theta, float &phi) const
Convert from plane coordinates to spherical coords.
virtual void scaleUp(float flightLength, float scaledX, float scaledY, float &realX, float &realY) const
Convert from scaled-down radius to actual radius.
bool tolEqual(const T &a, const T &b, const T &f)
Test for equality within tolerance f (||a-b|| < f)
virtual void scaleDown(float flightLength, float detX, float detY, float &scaledX, float &scaledY) const
Convert from actual detector postion (eg. mm) and flight path to scaled-down transform.