aboutsummaryrefslogtreecommitdiff
path: root/src/geometry.c
diff options
context:
space:
mode:
authorThomas White <taw@physics.org>2010-11-22 11:19:23 +0100
committerThomas White <taw@physics.org>2012-02-22 15:27:06 +0100
commit20d05388833bd9f3b6819d82f983eea424663407 (patch)
treebb5ffe085ea697e4363d03003febeed517ec383b /src/geometry.c
parent10c4b9c1c596c6196e5ca478fca7f1fa27f2da0c (diff)
Fix post refinement maths and take clamping status into account
Diffstat (limited to 'src/geometry.c')
-rw-r--r--src/geometry.c52
1 files changed, 30 insertions, 22 deletions
diff --git a/src/geometry.c b/src/geometry.c
index 0ef1f1c3..664817e0 100644
--- a/src/geometry.c
+++ b/src/geometry.c
@@ -103,26 +103,17 @@ static double excitation_error(double xl, double yl, double zl,
static double partiality(double r1, double r2, double r)
{
double q1, q2;
- double p, p1, p2;
+ double p1, p2;
/* Calculate degrees of penetration */
q1 = (r1 + r)/(2.0*r);
q2 = (r2 + r)/(2.0*r);
- /* Clamp */
- if ( q1 > 1.0 ) q1 = 1.0;
- if ( q1 < 0.0 ) q1 = 0.0;
- if ( q2 > 1.0 ) q2 = 1.0;
- if ( q2 < 0.0 ) q2 = 0.0;
-
/* Convert to partiality */
p1 = 3.0*pow(q1,2.0) - 2.0*pow(q1,3.0);
p2 = 3.0*pow(q2,2.0) - 2.0*pow(q2,3.0);
- /* Input values may have been backwards */
- p = fabs(p2 - p1);
-
- return p;
+ return p2 - p1;
}
@@ -143,8 +134,6 @@ struct cpeak *find_intersections(struct image *image, UnitCell *cell,
double klow, kcen, khigh; /* Wavenumber */
/* Bounding sphere for the shape transform approximation */
const double profile_cutoff = 0.02e9; /* 0.02 nm^-1 */
- /* Actual radius of the profile */
- const double profile_radius = 0.005e9;
cpeaks = malloc(sizeof(struct cpeak)*MAX_CPEAKS);
if ( cpeaks == NULL ) {
@@ -178,6 +167,8 @@ struct cpeak *find_intersections(struct image *image, UnitCell *cell,
double xda, yda; /* Position on detector */
int close, inside;
double part; /* Partiality */
+ int clamp_low = 0;
+ int clamp_high = 0;
/* Ignore central beam */
if ( (h==0) && (k==0) && (l==0) ) continue;
@@ -216,21 +207,36 @@ struct cpeak *find_intersections(struct image *image, UnitCell *cell,
/* If the "lower" Ewald sphere is a long way away, use the
* position at which the Ewald sphere would just touch the
* reflection. */
- if ( rlow > profile_cutoff ) rlow = profile_cutoff;
- if ( rlow < -profile_cutoff ) rlow = -profile_cutoff;
+ if ( rlow < -profile_cutoff ) {
+ rlow = -profile_cutoff;
+ clamp_low = -1;
+ }
+ if ( rlow > +profile_cutoff ) {
+ rlow = +profile_cutoff;
+ clamp_low = +1;
+ }
+ /* Likewise the "higher" Ewald sphere */
+ if ( rhigh < -profile_cutoff ) {
+ rhigh = -profile_cutoff;
+ clamp_high = -1;
+ }
+ if ( rhigh > +profile_cutoff ) {
+ rhigh = +profile_cutoff;
+ clamp_high = +1;
+ }
+ /* The six possible combinations of clamp_{low,high} (including
+ * zero) correspond to the six situations in Table 3 of Rossmann
+ * et al. (1979). */
- /* As above, other side. */
- if ( rhigh > profile_cutoff ) rhigh = profile_cutoff;
- if ( rhigh < -profile_cutoff ) rhigh = -profile_cutoff;
+ /* Calculate partiality and reject if too small */
+ part = partiality(rlow, rhigh, image->profile_radius);
+ if ( part < 0.1 ) continue;
/* Locate peak on detector. */
p = locate_peak(xl, yl, zl, kcen, image->det, &xda, &yda);
if ( p == -1 ) continue;
- part = partiality(rlow, rhigh, profile_radius);
-
- if ( part < 0.1 ) continue;
-
+ /* Add peak to list */
cpeaks[np].h = h;
cpeaks[np].k = k;
cpeaks[np].l = l;
@@ -239,6 +245,8 @@ struct cpeak *find_intersections(struct image *image, UnitCell *cell,
cpeaks[np].r1 = rlow;
cpeaks[np].r2 = rhigh;
cpeaks[np].p = part;
+ cpeaks[np].clamp1 = clamp_low;
+ cpeaks[np].clamp2 = clamp_high;
np++;
if ( output ) {