aboutsummaryrefslogtreecommitdiff
path: root/libcrystfel/src/geometry.c
diff options
context:
space:
mode:
Diffstat (limited to 'libcrystfel/src/geometry.c')
-rw-r--r--libcrystfel/src/geometry.c110
1 files changed, 90 insertions, 20 deletions
diff --git a/libcrystfel/src/geometry.c b/libcrystfel/src/geometry.c
index 60fab488..704baa51 100644
--- a/libcrystfel/src/geometry.c
+++ b/libcrystfel/src/geometry.c
@@ -3,11 +3,11 @@
*
* Geometry of diffraction
*
- * Copyright © 2012 Deutsches Elektronen-Synchrotron DESY,
+ * Copyright © 2013 Deutsches Elektronen-Synchrotron DESY,
* a research centre of the Helmholtz Association.
*
* Authors:
- * 2010-2012 Thomas White <taw@physics.org>
+ * 2010-2013 Thomas White <taw@physics.org>
*
* This file is part of CrystFEL.
*
@@ -33,6 +33,7 @@
#include <stdlib.h>
#include <assert.h>
+#include <fenv.h>
#include "utils.h"
#include "cell.h"
@@ -43,6 +44,7 @@
#include "reflist.h"
#include "reflist-utils.h"
#include "symmetry.h"
+#include "geometry.h"
static signed int locate_peak(double x, double y, double z, double k,
@@ -117,7 +119,7 @@ static double partiality(double rlow, double rhigh, double r)
}
-static Reflection *check_reflection(struct image *image,
+static Reflection *check_reflection(struct image *image, Crystal *cryst,
signed int h, signed int k, signed int l,
double xl, double yl, double zl)
{
@@ -131,6 +133,9 @@ static Reflection *check_reflection(struct image *image,
double klow, khigh; /* Wavenumber */
Reflection *refl;
double cet, cez;
+ double pr;
+
+ pr = crystal_get_profile_radius(cryst);
/* "low" gives the largest Ewald sphere (wavelength short => k large)
* "high" gives the smallest Ewald sphere (wavelength long => k small)
@@ -152,8 +157,8 @@ static Reflection *check_reflection(struct image *image,
rlow = klow - distance(cet, cez, tl, zl); /* Loss of precision */
if ( (signbit(rlow) == signbit(rhigh))
- && (fabs(rlow) > image->profile_radius)
- && (fabs(rhigh) > image->profile_radius) ) return NULL;
+ && (fabs(rlow) > pr)
+ && (fabs(rhigh) > pr) ) return NULL;
/* If the "lower" Ewald sphere is a long way away, use the
* position at which the Ewald sphere would just touch the
@@ -164,26 +169,26 @@ static Reflection *check_reflection(struct image *image,
* et al. (1979).
*/
clamp_low = 0; clamp_high = 0;
- if ( rlow < -image->profile_radius ) {
- rlow = -image->profile_radius;
+ if ( rlow < -pr ) {
+ rlow = -pr;
clamp_low = -1;
}
- if ( rlow > +image->profile_radius ) {
- rlow = +image->profile_radius;
+ if ( rlow > +pr ) {
+ rlow = +pr;
clamp_low = +1;
}
- if ( rhigh < -image->profile_radius ) {
- rhigh = -image->profile_radius;
+ if ( rhigh < -pr ) {
+ rhigh = -pr;
clamp_high = -1;
}
- if ( rhigh > +image->profile_radius ) {
- rhigh = +image->profile_radius;
+ if ( rhigh > +pr ) {
+ rhigh = +pr;
clamp_high = +1;
}
assert(clamp_low >= clamp_high);
/* Calculate partiality */
- part = partiality(rlow, rhigh, image->profile_radius);
+ part = partiality(rlow, rhigh, pr);
/* Locate peak on detector. */
p = locate_peak(xl, yl, zl, 1.0/image->lambda, image->det, &xda, &yda);
@@ -205,7 +210,7 @@ static Reflection *check_reflection(struct image *image,
}
-RefList *find_intersections(struct image *image, UnitCell *cell)
+RefList *find_intersections(struct image *image, Crystal *cryst)
{
double ax, ay, az;
double bx, by, bz;
@@ -217,6 +222,10 @@ RefList *find_intersections(struct image *image, UnitCell *cell)
int hmax, kmax, lmax;
double mres;
signed int h, k, l;
+ UnitCell *cell;
+
+ cell = crystal_get_cell(cryst);
+ if ( cell == NULL ) return NULL;
reflections = reflist_new();
@@ -262,7 +271,7 @@ RefList *find_intersections(struct image *image, UnitCell *cell)
yl = h*asy + k*bsy + l*csy;
zl = h*asz + k*bsz + l*csz;
- refl = check_reflection(image, h, k, l, xl, yl, zl);
+ refl = check_reflection(image, cryst, h, k, l, xl, yl, zl);
if ( refl != NULL ) {
add_refl_to_list(refl, reflections);
@@ -276,8 +285,68 @@ RefList *find_intersections(struct image *image, UnitCell *cell)
}
+RefList *select_intersections(struct image *image, Crystal *cryst)
+{
+ double ax, ay, az;
+ double bx, by, bz;
+ double cx, cy, cz;
+ const double min_dist = 0.25;
+ RefList *list;
+ int i;
+
+ /* Round towards nearest */
+ fesetround(1);
+
+ /* Cell basis vectors for this image */
+ cell_get_cartesian(crystal_get_cell(cryst), &ax, &ay, &az,
+ &bx, &by, &bz, &cx, &cy, &cz);
+
+ list = reflist_new();
+ if ( list == NULL ) return NULL;
+
+ /* Loop over peaks, checking proximity to nearest reflection */
+ for ( i=0; i<image_feature_count(image->features); i++ ) {
+
+ struct imagefeature *f;
+ struct rvec q;
+ double h, k, l, hd, kd, ld;
+ double dsq;
+
+ f = image_get_feature(image->features, i);
+ if ( f == NULL ) continue;
+
+ /* Reciprocal space position of found peak */
+ q = get_q(image, f->fs, f->ss, NULL, 1.0/image->lambda);
+
+ /* Decimal and fractional Miller indices of nearest
+ * reciprocal lattice point */
+ hd = q.u * ax + q.v * ay + q.w * az;
+ kd = q.u * bx + q.v * by + q.w * bz;
+ ld = q.u * cx + q.v * cy + q.w * cz;
+ h = lrint(hd);
+ k = lrint(kd);
+ l = lrint(ld);
+
+ /* Check distance */
+ dsq = pow(h-hd, 2.0) + pow(k-kd, 2.0) + pow(l-ld, 2.0);
+
+ if ( sqrt(dsq) < min_dist ) {
+
+ Reflection *refl;
+
+ refl = add_refl(list, h, k, l);
+ set_detector_pos(refl, sqrt(dsq), f->fs, f->ss);
+
+ }
+
+ }
+
+ return list;
+}
+
+
/* Calculate partialities and apply them to the image's reflections */
-void update_partialities(struct image *image)
+void update_partialities(Crystal *cryst)
{
Reflection *refl;
RefListIterator *iter;
@@ -285,14 +354,15 @@ void update_partialities(struct image *image)
double asx, asy, asz;
double bsx, bsy, bsz;
double csx, csy, csz;
+ struct image *image = crystal_get_image(cryst);
- cell_get_reciprocal(image->indexed_cell, &asx, &asy, &asz,
+ cell_get_reciprocal(crystal_get_cell(cryst), &asx, &asy, &asz,
&bsx, &bsy, &bsz, &csx, &csy, &csz);
/* Scratch list to give check_reflection() something to add to */
predicted = reflist_new();
- for ( refl = first_refl(image->reflections, &iter);
+ for ( refl = first_refl(crystal_get_reflections(cryst), &iter);
refl != NULL;
refl = next_refl(refl, iter) )
{
@@ -309,7 +379,7 @@ void update_partialities(struct image *image)
yl = h*asy + k*bsy + l*csy;
zl = h*asz + k*bsz + l*csz;
- vals = check_reflection(image, h, k, l, xl, yl, zl);
+ vals = check_reflection(image, cryst, h, k, l, xl, yl, zl);
if ( vals == NULL ) {
set_redundancy(refl, 0);