aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/displaywindow.ui1
-rw-r--r--src/control.c8
-rw-r--r--src/control.h23
-rw-r--r--src/displaywindow.c275
-rw-r--r--src/displaywindow.h2
-rw-r--r--src/ipr.c61
-rw-r--r--src/main.c42
-rw-r--r--src/reflections.c46
-rw-r--r--src/reflections.h7
-rw-r--r--src/reproject.c55
-rw-r--r--src/reproject.h1
11 files changed, 285 insertions, 236 deletions
diff --git a/data/displaywindow.ui b/data/displaywindow.ui
index e6e8264..b35adc7 100644
--- a/data/displaywindow.ui
+++ b/data/displaywindow.ui
@@ -15,6 +15,7 @@
<menu name="tools" action="ToolsAction">
<menuitem name="dirax" action="DirAxAction" />
<menuitem name="diraxstop" action="StopDirAxAction" />
+ <menuitem name="reproject" action="ReprojectAction" />
</menu>
<menu name="help" action="HelpAction">
diff --git a/src/control.c b/src/control.c
index 80cf7ce..4e49de4 100644
--- a/src/control.c
+++ b/src/control.c
@@ -17,6 +17,12 @@
int control_add_image(ControlContext *ctx, uint16_t *image, int width, int height, double tilt) {
+ if ( ctx->images ) {
+ ctx->images = realloc(ctx->images, (ctx->n_images+1)*sizeof(ImageRecord));
+ } else {
+ ctx->images = malloc(sizeof(ImageRecord));
+ }
+
ctx->images[ctx->n_images].tilt = tilt;
ctx->images[ctx->n_images].omega = ctx->omega;
ctx->images[ctx->n_images].image = image;
@@ -55,6 +61,8 @@ ControlContext *control_ctx_new() {
ctx->have_centres = 0;
ctx->cell = NULL;
ctx->dirax = NULL;
+ ctx->n_images = 0;
+ ctx->images = NULL;
return ctx;
diff --git a/src/control.h b/src/control.h
index 76eb2ff..17a41bd 100644
--- a/src/control.h
+++ b/src/control.h
@@ -20,8 +20,6 @@
#include <inttypes.h>
#include <GL/gl.h>
-#define MAX_IMAGES 256
-
typedef enum ift_enum {
INPUT_NONE,
INPUT_QDRP,
@@ -44,12 +42,6 @@ typedef enum {
PEAKSEARCH_STAT
} PeakSearchMode;
-typedef enum {
- RECONSTRUCTION_MAPPING = 0,
- RECONSTRUCTION_PREDICTION = 1<<0,
- RECONSTRUCTION_DIRAX = 1<<1
-} ReconstructionMode;
-
typedef struct imagerecord_struct {
uint16_t *image;
@@ -81,8 +73,6 @@ typedef struct cctx_struct {
/* Modes */
InputFileType inputfiletype;
- FormulationMode fmode;
- ReconstructionMode rmode;
PeakSearchMode psmode;
unsigned int prealign;
unsigned int savecache;
@@ -94,6 +84,7 @@ typedef struct cctx_struct {
/* Basic parameters, stored here solely so they can be copied
* into the ImageRecord(s) more easily */
+ FormulationMode fmode;
double camera_length;
double omega; /* Degrees */
double resolution;
@@ -111,15 +102,15 @@ typedef struct cctx_struct {
/* The input images */
int n_images;
- ImageRecord images[MAX_IMAGES];
+ ImageRecord *images;
/* Output */
struct reflectionlist_struct *reflectionlist;
struct dw_struct *dw;
- struct basis_struct *cell;
+ struct basis_struct *cell; /* Current estimate of the reciprocal unit cell */
+ struct reflectionlist_struct *cell_lattice; /* Reflections calculated from 'cell' */
/* GTK bits */
- GtkWidget *combo_algorithm;
GtkWidget *combo_peaksearch;
GtkWidget *checkbox_prealign;
GtkWidget *checkbox_savecache;
@@ -142,7 +133,11 @@ typedef struct cctx_struct {
/* DirAx high-level stuff */
int dirax_step;
int dirax_read_cell;
-
+
+ /* Reprojection stuff */
+ int reproject_cur_image;
+ struct imagedisplay_struct *reproject_id;
+
} ControlContext;
extern int control_add_image(ControlContext *ctx, uint16_t *image, int width, int height, double tilt);
diff --git a/src/displaywindow.c b/src/displaywindow.c
index 8899e0b..cfaea27 100644
--- a/src/displaywindow.c
+++ b/src/displaywindow.c
@@ -32,6 +32,7 @@
#include "displaywindow.h"
#include "basis.h"
#include "dirax.h"
+#include "reproject.h"
enum {
DW_ORTHO,
@@ -79,6 +80,10 @@ static void displaywindow_dirax(GtkWidget *widget, DisplayWindow *dw) {
dirax_invoke(dw->ctx);
}
+static void displaywindow_reproject(GtkWidget *widget, DisplayWindow *dw) {
+ reproject_open(dw->ctx);
+}
+
static void displaywindow_dirax_stop(GtkWidget *widget, DisplayWindow *dw) {
dirax_stop(dw->ctx);
}
@@ -179,6 +184,7 @@ static void displaywindow_addmenubar(DisplayWindow *dw) {
{ "ToolsAction", NULL, "_Tools", NULL, NULL, NULL },
{ "DirAxAction", GTK_STOCK_EXECUTE, "Start _DirAx", "<Ctrl>D", NULL, G_CALLBACK(displaywindow_dirax) },
{ "StopDirAxAction", GTK_STOCK_CLOSE, "Stop DirAx", "<Ctrl>D", NULL, G_CALLBACK(displaywindow_dirax_stop) },
+ { "ReprojectAction", NULL, "_Reproject Diffraction Patterns", "<Ctrl>R", NULL, G_CALLBACK(displaywindow_reproject) },
{ "HelpAction", NULL, "_Help", NULL, NULL, NULL },
{ "AboutAction", GTK_STOCK_ABOUT, "_About DTR...", NULL, NULL, G_CALLBACK(displaywindow_about) },
@@ -303,59 +309,56 @@ static gint displaywindow_gl_motion_notify(GtkWidget *widget, GdkEventMotion *ev
} \
}
-#define DRAW_POINTER \
- glBegin(GL_LINES); \
- glVertex3f(50, 0.0, 0.0); \
- glVertex3f(-50, 0.0, 0.0); \
- glEnd(); \
- glBegin(GL_TRIANGLE_FAN); \
- glVertex3f(50.0, 0.0, 0.0); \
- glNormal3f(1.0, 0.0, 0.0); \
- glVertex3f(50.0-5.0, 1.0, 1.0); \
- glNormal3f(-2.5, 1.0, 1.0); \
- glVertex3f(50.0-5.0, -1.0, 1.0); \
- glNormal3f(-2.5, -1.0, 1.0); \
- glVertex3f(50.0-5.0, -1.0, -1.0); \
- glNormal3f(-2.5, -1.0, -1.0); \
- glVertex3f(50.0-5.0, 1.0, -1.0); \
- glNormal3f(-2.5, 1.0, -1.0); \
- glVertex3f(50.0-5.0, 1.0, 1.0); \
- glNormal3f(-2.5, 1.0, 1.0); \
+#define DRAW_POINTER \
+ glBegin(GL_LINES); \
+ glVertex3f(50, 0.0, 0.0); \
+ glVertex3f(-50, 0.0, 0.0); \
+ glEnd(); \
+ glBegin(GL_TRIANGLE_FAN); \
+ glNormal3f(1.0, 0.0, 0.0); \
+ glVertex3f(50.0, 0.0, 0.0); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(50.0-5.0, 1.0, 1.0); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(50.0-5.0, -1.0, 1.0); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(50.0-5.0, -1.0, -1.0); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(50.0-5.0, 1.0, -1.0); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(50.0-5.0, 1.0, 1.0); \
glEnd();
-#define DRAW_SHORT_POINTER \
- glBegin(GL_LINES); \
- glVertex3f(0.0, 0.0, 0.0); \
- glVertex3f(10.0, 0.0, 0.0); \
- glEnd(); \
- glBegin(GL_TRIANGLE_FAN); \
- glVertex3f(10.0, 0.0, 0.0); \
- glNormal3f(1.0, 0.0, 0.0); \
- glVertex3f(10.0-2.0, 0.2, 0.2); \
- glNormal3f(-2.5, 0.2, 0.2); \
- glVertex3f(10.0-2.0, -0.2, 0.2); \
- glNormal3f(-2.5, -0.2, 0.2); \
- glVertex3f(10.0-2.0, -0.2, -0.2); \
- glNormal3f(-2.5, -0.2, -0.2); \
- glVertex3f(10.0-2.0, 0.2, -0.2); \
- glNormal3f(-2.5, 0.2, -0.2); \
- glVertex3f(10.0-2.0, 0.2, 0.2); \
- glNormal3f(-2.5, 0.2, 0.2); \
+#define DRAW_SHORT_POINTER \
+ glBegin(GL_LINES); \
+ glVertex3f(0.0, 0.0, 0.0); \
+ glVertex3f(10.0, 0.0, 0.0); \
+ glEnd(); \
+ glBegin(GL_TRIANGLE_FAN); \
+ glNormal3f(1.0, 0.0, 0.0); \
+ glVertex3f(10.0, 0.0, 0.0); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(10.0-2.0, 0.2, 0.2); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(10.0-2.0, -0.2, 0.2); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(10.0-2.0, -0.2, -0.2); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), -1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(10.0-2.0, 0.2, -0.2); \
+ glNormal3f(-2.5/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1), 1.0/sqrt(2.5*2.5+1+1)); \
+ glVertex3f(10.0-2.0, 0.2, 0.2); \
glEnd();
static void displaywindow_gl_create_list(DisplayWindow *dw) {
GLfloat bblue[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat blue[] = { 0.0, 0.0, 0.5, 1.0 };
- GLfloat blue_spec[] = { 0.0, 0.0, 1.0, 1.0 };
GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
- GLfloat purple[] = { 0.8, 0.0, 1.0, 1.0 };
GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
GLfloat glass[] = { 0.2, 0.0, 0.8, 000.1 };
GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
Reflection *reflection;
- GLUquadricObj *quadric;
int i;
ControlContext *ctx;
GLfloat *vertices;
@@ -366,6 +369,7 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
/* "Measured" reflections */
if ( dw->gl_use_buffers ) {
glGenBuffersARB(1, &dw->gl_ref_vertex_buffer);
+ glGenBuffersARB(1, &dw->gl_marker_normal_buffer);
}
reflection = ctx->reflectionlist->reflections;
i = 0;
@@ -377,11 +381,15 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
i = 0;
reflection = ctx->reflectionlist->reflections;
vertices = malloc(3*dw->gl_ref_num_vertices*sizeof(GLfloat));
+ normals = malloc(3*dw->gl_ref_num_vertices*sizeof(GLfloat));
while ( reflection != NULL ) {
if ( reflection->type == REFLECTION_NORMAL ) {
vertices[3*i + 0] = reflection->x/1e9;
vertices[3*i + 1] = reflection->y/1e9;
vertices[3*i + 2] = reflection->z/1e9;
+ normals[3*i + 0] = reflection->x/1e9;
+ normals[3*i + 1] = reflection->y/1e9;
+ normals[3*i + 2] = reflection->z/1e9;
i++;
}
reflection = reflection->next;
@@ -390,8 +398,12 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_vertex_buffer);
glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_ref_num_vertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
free(vertices);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_normal_buffer);
+ glBufferDataARB(GL_ARRAY_BUFFER, 3*dw->gl_ref_num_vertices*sizeof(GLfloat), normals, GL_STATIC_DRAW);
+ free(normals);
} else {
dw->gl_ref_vertex_array = vertices;
+ dw->gl_ref_normal_array = normals;
}
/* Marker "reflections" */
@@ -460,132 +472,125 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
glBindBufferARB(GL_ARRAY_BUFFER, 0); /* ************* */
} else {
dw->gl_gen_vertex_array = vertices;
+ dw->gl_gen_normal_array = normals;
}
dw->gl_list_id = glGenLists(1);
glNewList(dw->gl_list_id, GL_COMPILE);
/* Bounding cube: 100 nm^-1 side length */
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, purple);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
glBegin(GL_LINE_LOOP);
- glVertex3f(50, 50, 50);
- glVertex3f(-50, 50, 50);
- glVertex3f(-50, -50, 50);
- glVertex3f(50, -50, 50);
+ glNormal3f(50.0, 50.0, 50.0);
+ glVertex3f(50.0, 50.0, 50.0);
+ glNormal3f(-50.0, 50.0, 50.0);
+ glVertex3f(-50.0, 50.0, 50.0);
+ glNormal3f(-50.0, -50.0, 50.0);
+ glVertex3f(-50.0, -50.0, 50.0);
+ glNormal3f(50.0, -50.0, 50.0);
+ glVertex3f(50.0, -50.0, 50.0);
+
glEnd();
glBegin(GL_LINE_LOOP);
- glVertex3f(50, 50, -50);
- glVertex3f(-50, 50, -50);
- glVertex3f(-50, -50, -50);
- glVertex3f(50, -50, -50);
+ glNormal3f(50.0, 50.0, -50.0);
+ glVertex3f(50.0, 50.0, -50.0);
+ glNormal3f(-50.0, 50.0, -50.0);
+ glVertex3f(-50.0, 50.0, -50.0);
+ glNormal3f(-50.0, -50.0, -50.0);
+ glVertex3f(-50.0, -50.0, -50.0);
+ glNormal3f(50.0, -50.0, -50.0);
+ glVertex3f(50.0, -50.0, -50.0);
glEnd();
glBegin(GL_LINES);
- glVertex3f(50, 50, 50);
- glVertex3f(50, 50, -50);
- glVertex3f(-50, 50, 50);
- glVertex3f(-50, 50, -50);
- glVertex3f(-50, -50, 50);
- glVertex3f(-50, -50, -50);
- glVertex3f(50, -50, 50);
- glVertex3f(50, -50, -50);
+ glNormal3f(50.0, 50.0, 50.0);
+ glVertex3f(50.0, 50.0, 50.0);
+ glNormal3f(50.0, 50.0, -50.0);
+ glVertex3f(50.0, 50.0, -50.0);
+ glNormal3f(-50.0, 50.0, 50.0);
+ glVertex3f(-50.0, 50.0, 50.0);
+ glNormal3f(-50.0, 50.0, -50.0);
+ glVertex3f(-50.0, 50.0, -50.0);
+ glNormal3f(-50.0, -50.0, 50.0);
+ glVertex3f(-50.0, -50.0, 50.0);
+ glNormal3f(-50.0, -50.0, -50.0);
+ glVertex3f(-50.0, -50.0, -50.0);
+ glNormal3f(50.0, -50.0, 50.0);
+ glVertex3f(50.0, -50.0, 50.0);
+ glNormal3f(50.0, -50.0, -50.0);
+ glVertex3f(50.0, -50.0, -50.0);
glEnd();
/* x, y, z pointers */
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
DRAW_SHORT_POINTER
-
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
glPushMatrix();
glRotatef(90.0, 0.0, 0.0, 1.0);
DRAW_SHORT_POINTER
glPopMatrix();
-
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, bblue);
glPushMatrix();
glRotatef(-90.0, 0.0, 1.0, 0.0);
DRAW_SHORT_POINTER
glPopMatrix();
- /* Tilt axis */
- glPushMatrix();
- /* Images rotate clockwise by omega to put tilt axis at +x,
- * so rotate tilt axis anticlockwise by omega.
- * Since the rotation is about +z, this is already anticlockwise
- * when looking down z. */
- glRotatef(ctx->images[0].omega, 0.0, 0.0, 1.0);
-// glPolygonOffset(1.0, 1.0);
-// glEnable(GL_POLYGON_OFFSET_LINE);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- DRAW_POINTER
-// glDisable(GL_POLYGON_OFFSET_LINE);
- glPopMatrix();
-
/* Plot the other reflections */
reflection = ctx->reflectionlist->reflections;
- quadric = gluNewQuadric();
while ( reflection != NULL ) {
- if ( reflection->type == REFLECTION_CENTRAL ) {
-
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
- glMaterialfv(GL_FRONT, GL_SPECULAR, blue_spec);
- glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
- glPushMatrix();
- glTranslatef(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- gluSphere(quadric, 0.2, 32, 32);
- glPopMatrix();
-
- }
-
if ( reflection->type == REFLECTION_VECTOR_MARKER_1 ) {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glNormal3f(0.0, 0.0, 0.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
glEnd();
}
if ( reflection->type == REFLECTION_VECTOR_MARKER_2 ) {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glNormal3f(0.0, 0.0, 0.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
glEnd();
}
if ( reflection->type == REFLECTION_VECTOR_MARKER_3 ) {
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
- glEnd();
-
- }
-
- if ( reflection->type == REFLECTION_VECTOR_MARKER_4 ) {
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, purple);
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glBegin(GL_LINES);
- glVertex3f(0.0, 0.0, 0.0);
- glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glNormal3f(0.0, 0.0, 0.0);
+ glVertex3f(0.0, 0.0, 0.0);
+ glNormal3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
+ glVertex3f(reflection->x/1e9, reflection->y/1e9, reflection->z/1e9);
glEnd();
}
@@ -597,9 +602,11 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
/* Draw the reciprocal unit cell if one is available */
if ( ctx->cell ) {
glBegin(GL_LINE_STRIP);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, red);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, red);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, black);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ glNormal3f(1.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(ctx->cell->a.x/1e9, ctx->cell->a.y/1e9, ctx->cell->a.z/1e9);
glVertex3f(ctx->cell->a.x/1e9 + ctx->cell->b.x/1e9,
@@ -642,15 +649,33 @@ static void displaywindow_gl_create_list(DisplayWindow *dw) {
glEnd();
}
- /* Zero plane */
+ /* Tilt axis */
+ if ( ctx->images ) {
+ glPushMatrix();
+ /* Images rotate clockwise by omega to put tilt axis at +x,
+ * so rotate tilt axis anticlockwise by omega.
+ * Since the rotation is about +z, this is already anticlockwise
+ * when looking down z. */
+ glRotatef(ctx->images[0].omega, 0.0, 0.0, 1.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
+ DRAW_POINTER
+ glPopMatrix();
+ }
+
+ /* Zero plane (must be drawn last for transparency to work) */
glBegin(GL_QUADS);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, glass);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
- glVertex3f(50, 50, 0.0);
- glVertex3f(50, -50, 0.0);
- glVertex3f(-50, -50, 0.0);
- glVertex3f(-50, 50, 0.0);
+ glNormal3f(0.0, 0.0, 1.0);
+ glVertex3f(50.0, 50.0, 0.0);
+ glVertex3f(50.0, -50.0, 0.0);
+ glVertex3f(-50.0, -50.0, 0.0);
+ glVertex3f(-50.0, 50.0, 0.0);
glEnd();
glEndList();
@@ -683,15 +708,12 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Di
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- /* NB Camera position is in the ModelView matrix, not the Projection matrix.
- * Therefore, multiply the current ModelView by whatever transformations
- * are required, pushing/popping as appropriate. Don't do glLoadIdentity(). */
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(dw->x_pos, -dw->y_pos, -100.0);
/* If zoomed a long way out, move the model back rather than
* changing the projection matrix. This avoids getting a "fisheye" view */
- if ( dw->distance > 100.0 ) glTranslatef(dw->x_pos, -dw->y_pos, -(dw->distance-100.0));
+ if ( dw->distance > 100.0 ) glTranslatef(0.0, 0.0, -(dw->distance-100.0));
build_rotmatrix(m, dw->view_quat);
glMultMatrixf(&m[0][0]);
@@ -709,15 +731,20 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Di
/* Draw the "measured" reflections */
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, green);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0);
if ( dw->gl_use_buffers ) {
glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_vertex_buffer);
glVertexPointer(3, GL_FLOAT, 0, NULL);
+ glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_ref_normal_buffer);
+ glNormalPointer(GL_FLOAT, 0, NULL);
glDrawArrays(GL_POINTS, 0, dw->gl_ref_num_vertices);
} else {
glVertexPointer(3, GL_FLOAT, 0, dw->gl_ref_vertex_array);
+ glNormalPointer(GL_FLOAT, 0, dw->gl_ref_normal_array);
glDrawArrays(GL_POINTS, 0, dw->gl_ref_num_vertices);
}
glPopClientAttrib();
@@ -726,11 +753,10 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Di
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
- glMaterialfv(GL_FRONT, GL_SPECULAR, blue_spec);
- glMaterialf(GL_FRONT, GL_SHININESS, 50.0);
-// glPolygonOffset(1.0, 1.0);
-// glEnable(GL_POLYGON_OFFSET_FILL);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blue);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, blue_spec);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0);
if ( dw->gl_use_buffers ) {
glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_marker_vertex_buffer);
glVertexPointer(3, GL_FLOAT, 0, NULL);
@@ -742,16 +768,16 @@ static gint displaywindow_gl_expose(GtkWidget *widget, GdkEventExpose *event, Di
glNormalPointer(GL_FLOAT, 0, dw->gl_marker_normal_array);
glDrawArrays(GL_QUADS, 0, dw->gl_marker_num_vertices);
}
-// glDisable(GL_POLYGON_OFFSET_FILL);
glPopClientAttrib();
/* Draw generated reflections */
glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gold);
- glMaterialfv(GL_FRONT, GL_SPECULAR, gold_spec);
- glMaterialf(GL_FRONT, GL_SHININESS, 70.0);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, black);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, gold);
+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, gold_spec);
+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 70.0);
if ( dw->gl_use_buffers ) {
glBindBufferARB(GL_ARRAY_BUFFER, dw->gl_gen_vertex_buffer);
glVertexPointer(3, GL_FLOAT, 0, NULL);
@@ -845,6 +871,7 @@ static void displaywindow_gl_free_resources(DisplayWindow *dw) {
glDeleteBuffersARB(1, &dw->gl_gen_normal_buffer);
} else {
free(dw->gl_ref_vertex_array);
+ free(dw->gl_ref_normal_array);
free(dw->gl_marker_vertex_array);
free(dw->gl_marker_normal_array);
free(dw->gl_gen_vertex_array);
diff --git a/src/displaywindow.h b/src/displaywindow.h
index 6b4fb01..e8ddbf2 100644
--- a/src/displaywindow.h
+++ b/src/displaywindow.h
@@ -44,6 +44,8 @@ typedef struct dw_struct {
int gl_use_buffers; /* 0=use vertex arrays only, otherwise use VBOs */
GLuint gl_ref_vertex_buffer; /* "Measured reflection" stuff */
GLfloat *gl_ref_vertex_array;
+ GLuint gl_ref_normal_buffer;
+ GLfloat *gl_ref_normal_array;
GLsizei gl_ref_num_vertices;
GLuint gl_marker_vertex_buffer; /* Marker "reflection" stuff */
GLuint gl_marker_normal_buffer;
diff --git a/src/ipr.c b/src/ipr.c
index e16d5d8..787106a 100644
--- a/src/ipr.c
+++ b/src/ipr.c
@@ -4,7 +4,6 @@
* Iterative Prediction-Refinement Reconstruction
*
* (c) 2007 Thomas White <taw27@cam.ac.uk>
- * Gordon Ball <gfb21@cam.ac.uk>
*
* dtr - Diffraction Tomography Reconstruction
*
@@ -28,64 +27,6 @@
#include "displaywindow.h"
#include "basis.h"
-/* Generate list of reflections to analyse */
-static ReflectionList *ipr_generate(ControlContext *ctx, Basis *basis) {
-
- ReflectionList *ordered;
- double max_res;
- signed int h, k, l;
- int max_order_a, max_order_b, max_order_c;
-
- /* NB This assumes the diffraction pattern is "vaguely" centered... */
- if ( ctx->inputfiletype != INPUT_CACHE) {
- int max_width, max_height;
- max_width = ctx->images[0].width;
- max_height = ctx->images[0].height;
- if ( ctx->fmode == FORMULATION_PIXELSIZE ) {
- max_res = sqrt(max_width*max_width + max_height*max_height) * ctx->images[0].pixel_size;
- } else {
- max_res = sqrt(max_width*max_width + max_height*max_height) / (ctx->images[0].lambda * ctx->images[0].camera_len);
- }
- max_res = max_res / 2;
- } else {
- max_res = 1e10; //works until I put some more in the reflect.cache header
- }
-
- ordered = reflectionlist_new();
-
- max_order_a = max_res/modulus(basis->a.x, basis->a.y, basis->a.z);
- max_order_b = max_res/modulus(basis->b.x, basis->b.y, basis->b.z);
- max_order_c = max_res/modulus(basis->c.x, basis->c.y, basis->c.z);
- for ( h=-max_order_a; h<=max_order_a; h++ ) {
- for ( k=-max_order_b; k<=max_order_b; k++ ) {
- for ( l=-max_order_c; l<=max_order_c; l++ ) {
-
- double x, y, z;
-
- x = h*basis->a.x + k*basis->b.x + l*basis->c.x;
- y = h*basis->a.y + k*basis->b.y + l*basis->c.y;
- z = h*basis->a.z + k*basis->b.z + l*basis->c.z;
-
- if ( ( x*x + y*y + z*z ) <= max_res*max_res ) {
- Reflection *ref;
- ref = reflection_add(ordered, x, y, z, 1, REFLECTION_GENERATED);
- if ( ref ) { /* Check it's not NULL */
- ref->h = h; ref->k = k; ref->l = l;
- }
- if ( (h!=0) || (k!=0) || (l!=0) ) {
- // reflection_add(ctx->reflectionlist, x, y, z, 1, REFLECTION_GENERATED);
- reflection_add(ordered, x, y, z, 1, REFLECTION_GENERATED);
- }
- }
-
- }
- }
- }
-
- return ordered;
-
-}
-
static gint ipr_clicked(GtkWidget *widget, GdkEventButton *event, ControlContext *ctx) {
ImageReflection *refl;
@@ -121,7 +62,7 @@ int ipr_refine(ControlContext *ctx) {
}
ctx->ipr_basis = basis;
- ctx->ipr_lat = ipr_generate(ctx, basis);
+ ctx->ipr_lat = reflection_list_from_cell(basis);
printf("IP: Performing refinement...\n");
finished = 0;
diff --git a/src/main.c b/src/main.c
index f80da7e..1a93483 100644
--- a/src/main.c
+++ b/src/main.c
@@ -37,22 +37,16 @@
void main_do_reconstruction(ControlContext *ctx) {
- int val = 0;
-
if ( (ctx->inputfiletype != INPUT_CACHE) && (ctx->inputfiletype != INPUT_DRX) ) {
prealign_sum_stack(ctx);
mapping_create(ctx);
}
- if ( (ctx->inputfiletype != INPUT_CACHE) && !val && ctx->reflectionlist && ctx->savecache ) {
+ if ( (ctx->inputfiletype != INPUT_CACHE) && ctx->reflectionlist && ctx->savecache ) {
cache_save(ctx->filename, ctx->reflectionlist);
}
- if ( (ctx->rmode == RECONSTRUCTION_PREDICTION) && (ctx->reflectionlist) ) {
- val = ipr_refine(ctx);
- }
-
- if ( !val && (ctx->reflectionlist) ) {
+ if ( ctx->reflectionlist ) {
ctx->dw = displaywindow_open(ctx);
} else {
fprintf(stderr, "Reconstruction failed.\n");
@@ -67,12 +61,6 @@ static gint main_method_window_response(GtkWidget *method_window, gint response,
int val = 0;
- switch ( gtk_combo_box_get_active(GTK_COMBO_BOX(ctx->combo_algorithm)) ) {
- case 0 : ctx->rmode = RECONSTRUCTION_MAPPING; break;
- case 1 : ctx->rmode = RECONSTRUCTION_PREDICTION; break;
- default: abort();
- }
-
switch ( gtk_combo_box_get_active(GTK_COMBO_BOX(ctx->combo_peaksearch)) ) {
case 0 : ctx->psmode = PEAKSEARCH_THRESHOLD; break;
case 1 : ctx->psmode = PEAKSEARCH_ADAPTIVE_THRESHOLD; break;
@@ -135,7 +123,6 @@ void main_method_dialog_open(ControlContext *ctx) {
GtkWidget *vbox;
GtkWidget *hbox;
GtkWidget *table;
- GtkWidget *method_label;
GtkWidget *peaksearch_label;
method_window = gtk_dialog_new_with_buttons("Reconstruction Parameters", NULL,
@@ -146,21 +133,11 @@ void main_method_dialog_open(ControlContext *ctx) {
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(method_window)->vbox), GTK_WIDGET(hbox), FALSE, FALSE, 7);
gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox), FALSE, FALSE, 10);
- table = gtk_table_new(4, 2, FALSE);
+ table = gtk_table_new(3, 2, FALSE);
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
-
- method_label = gtk_label_new("Reconstruction Algorithm: ");
- gtk_table_attach_defaults(GTK_TABLE(table), method_label, 1, 2, 1, 2);
- gtk_misc_set_alignment(GTK_MISC(method_label), 1, 0.5);
- ctx->combo_algorithm = gtk_combo_box_new_text();
- gtk_combo_box_append_text(GTK_COMBO_BOX(ctx->combo_algorithm), "Feature Detection and Mapping");
- gtk_combo_box_append_text(GTK_COMBO_BOX(ctx->combo_algorithm), "Iterative Prediction and Refinement");
- gtk_combo_box_set_active(GTK_COMBO_BOX(ctx->combo_algorithm), 1);
- gtk_table_attach_defaults(GTK_TABLE(table), ctx->combo_algorithm, 2, 3, 1, 2);
- gtk_table_set_row_spacing(GTK_TABLE(table), 1, 5);
peaksearch_label = gtk_label_new("Peak Search: ");
- gtk_table_attach_defaults(GTK_TABLE(table), peaksearch_label, 1, 2, 2, 3);
+ gtk_table_attach_defaults(GTK_TABLE(table), peaksearch_label, 1, 2, 1, 2);
gtk_misc_set_alignment(GTK_MISC(peaksearch_label), 1, 0.5);
ctx->combo_peaksearch = gtk_combo_box_new_text();
gtk_combo_box_append_text(GTK_COMBO_BOX(ctx->combo_peaksearch), "Simple Thresholding");
@@ -169,13 +146,13 @@ void main_method_dialog_open(ControlContext *ctx) {
gtk_combo_box_append_text(GTK_COMBO_BOX(ctx->combo_peaksearch), "Zaefferer Gradient Search");
gtk_combo_box_append_text(GTK_COMBO_BOX(ctx->combo_peaksearch), "Iterative Statistical Analysis");
gtk_combo_box_set_active(GTK_COMBO_BOX(ctx->combo_peaksearch), 3);
- gtk_table_attach_defaults(GTK_TABLE(table), ctx->combo_peaksearch, 2, 3, 2, 3);
+ gtk_table_attach_defaults(GTK_TABLE(table), ctx->combo_peaksearch, 2, 3, 1, 2);
ctx->checkbox_prealign = gtk_check_button_new_with_label("Pre-align image stack");
- gtk_table_attach_defaults(GTK_TABLE(table), ctx->checkbox_prealign, 1, 3, 3, 4);
+ gtk_table_attach_defaults(GTK_TABLE(table), ctx->checkbox_prealign, 1, 3, 2, 3);
ctx->checkbox_savecache = gtk_check_button_new_with_label("Save 3D mapping cache file");
- gtk_table_attach_defaults(GTK_TABLE(table), ctx->checkbox_savecache, 1, 3, 4, 5);
+ gtk_table_attach_defaults(GTK_TABLE(table), ctx->checkbox_savecache, 1, 3, 3, 4);
if ( ctx->inputfiletype == INPUT_CACHE ) {
gtk_combo_box_append_text(GTK_COMBO_BOX(ctx->combo_peaksearch), "3D coordinates from cache file");
@@ -187,7 +164,7 @@ void main_method_dialog_open(ControlContext *ctx) {
gtk_widget_set_sensitive(GTK_WIDGET(ctx->combo_peaksearch), FALSE);
gtk_combo_box_set_active(GTK_COMBO_BOX(ctx->combo_peaksearch), 5);
}
-
+
gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(table), TRUE, TRUE, 5);
g_signal_connect(G_OBJECT(method_window), "response", G_CALLBACK(main_method_window_response), ctx);
@@ -201,7 +178,6 @@ int main(int argc, char *argv[]) {
char *filename;
ControlContext *ctx;
- InputFileType type;
struct stat stat_buffer;
FILE *fh;
@@ -224,7 +200,6 @@ int main(int argc, char *argv[]) {
filename = argv[1];
ctx = control_ctx_new();
- type = INPUT_NONE;
fh = fopen(filename, "r");
if ( !fh ) {
@@ -251,7 +226,6 @@ int main(int argc, char *argv[]) {
}
ctx->filename = strdup(argv[1]);
- ctx->n_images = 0;
if ( stat(argv[1], &stat_buffer) == -1 ) {
fprintf(stderr, "File '%s' not found\n", argv[1]);
diff --git a/src/reflections.c b/src/reflections.c
index dc3ce2f..0005332 100644
--- a/src/reflections.c
+++ b/src/reflections.c
@@ -351,3 +351,49 @@ ReflectionList *reflectionlist_sort_lfom(ReflectionList *in) {
}
+/* Generate a list of reflections from a unit cell */
+ReflectionList *reflection_list_from_cell(Basis *basis) {
+
+ ReflectionList *ordered;
+ double max_res;
+ signed int h, k, l;
+ int max_order_a, max_order_b, max_order_c;
+
+
+ max_res = 20e9;
+
+ ordered = reflectionlist_new();
+
+ max_order_a = max_res/modulus(basis->a.x, basis->a.y, basis->a.z);
+ max_order_b = max_res/modulus(basis->b.x, basis->b.y, basis->b.z);
+ max_order_c = max_res/modulus(basis->c.x, basis->c.y, basis->c.z);
+ for ( h=-max_order_a; h<=max_order_a; h++ ) {
+ for ( k=-max_order_b; k<=max_order_b; k++ ) {
+ for ( l=-max_order_c; l<=max_order_c; l++ ) {
+
+ double x, y, z;
+
+ x = h*basis->a.x + k*basis->b.x + l*basis->c.x;
+ y = h*basis->a.y + k*basis->b.y + l*basis->c.y;
+ z = h*basis->a.z + k*basis->b.z + l*basis->c.z;
+
+ if ( ( x*x + y*y + z*z ) <= max_res*max_res ) {
+ Reflection *ref;
+ ref = reflection_add(ordered, x, y, z, 1, REFLECTION_GENERATED);
+ if ( ref ) { /* Check it's not NULL */
+ ref->h = h; ref->k = k; ref->l = l;
+ }
+ if ( (h!=0) || (k!=0) || (l!=0) ) {
+ // reflection_add(ctx->reflectionlist, x, y, z, 1, REFLECTION_GENERATED);
+ reflection_add(ordered, x, y, z, 1, REFLECTION_GENERATED);
+ }
+ }
+
+ }
+ }
+ }
+
+ return ordered;
+
+}
+
diff --git a/src/reflections.h b/src/reflections.h
index 11fbdcf..8347574 100644
--- a/src/reflections.h
+++ b/src/reflections.h
@@ -18,13 +18,11 @@
typedef enum {
REFLECTION_NORMAL, /* Measured - expressed as x, y, z position */
- REFLECTION_CENTRAL, /* The central beam */
REFLECTION_GENERATED, /* Generated and intensity-measured - expressed as h, k, l index */
REFLECTION_MARKER,
REFLECTION_VECTOR_MARKER_1,
REFLECTION_VECTOR_MARKER_2,
- REFLECTION_VECTOR_MARKER_3,
- REFLECTION_VECTOR_MARKER_4
+ REFLECTION_VECTOR_MARKER_3
} ReflectionType;
typedef struct reflection_struct {
@@ -75,5 +73,8 @@ extern Reflection *reflectionlist_find_nearest_longer_unknown(ReflectionList *re
extern Reflection *reflectionlist_find_nearest_type(ReflectionList *reflectionlist, double x, double y, double z, ReflectionType type);
extern ReflectionList *reflectionlist_sort_lfom(ReflectionList *in);
+#include "basis.h"
+extern ReflectionList *reflection_list_from_cell(Basis *basis);
+
#endif /* REFLECTION_H */
diff --git a/src/reproject.c b/src/reproject.c
index 38f15ff..60ff104 100644
--- a/src/reproject.c
+++ b/src/reproject.c
@@ -15,6 +15,8 @@
#include "control.h"
#include "reflections.h"
#include "utils.h"
+#include "imagedisplay.h"
+#include "displaywindow.h"
#define MAX_IMAGE_REFLECTIONS 8*1024
@@ -23,7 +25,7 @@ ImageReflection *reproject_get_reflections(ImageRecord image, size_t *n, Reflect
ImageReflection *refl;
Reflection *reflection;
int i;
- double smax = 0.5e8;
+ double smax = 0.1e9;
double tilt, omega;
double nx, ny, nz, nxt, nyt, nzt; /* "normal" vector (and calculation intermediates) */
double kx, ky, kz; /* Electron wavevector ("normal" times 1/lambda */
@@ -188,3 +190,54 @@ ImageReflection *reproject_get_reflections(ImageRecord image, size_t *n, Reflect
}
+static gint reproject_clicked(GtkWidget *widget, GdkEventButton *event, ControlContext *ctx) {
+
+ ImageReflection *refl;
+ size_t n, j;
+
+ ctx->reproject_cur_image++;
+ if ( ctx->reproject_cur_image == ctx->n_images ) ctx->reproject_cur_image = 0;
+
+ imagedisplay_clear_circles(ctx->reproject_id);
+ reflectionlist_clear_markers(ctx->reflectionlist);
+
+ refl = reproject_get_reflections(ctx->images[ctx->reproject_cur_image], &n, ctx->cell_lattice, ctx);
+ for ( j=0; j<n; j++ ) {
+ imagedisplay_mark_circle(ctx->reproject_id, refl[j].x, refl[j].y);
+ }
+
+ imagedisplay_put_data(ctx->reproject_id, ctx->images[ctx->reproject_cur_image]);
+ displaywindow_update(ctx->dw);
+
+ return 0;
+
+}
+
+void reproject_open(ControlContext *ctx) {
+
+ size_t n, j;
+ ImageReflection *refl;
+
+ if ( !ctx->cell ) {
+ printf("RP: No current cell\n");
+ return;
+ }
+
+ if ( !ctx->images ) {
+ printf("RP: No images!\n");
+ return;
+ }
+
+ ctx->cell_lattice = reflection_list_from_cell(ctx->cell);
+ ctx->reproject_cur_image = 0;
+
+ ctx->reproject_id = imagedisplay_open_with_message(ctx->images[ctx->reproject_cur_image], "Current Image", "Click to change image",
+ IMAGEDISPLAY_SHOW_CENTRE | IMAGEDISPLAY_SHOW_TILT_AXIS, G_CALLBACK(reproject_clicked), ctx);
+
+ refl = reproject_get_reflections(ctx->images[ctx->reproject_cur_image], &n, ctx->cell_lattice, ctx);
+ for ( j=0; j<n; j++ ) {
+ imagedisplay_mark_circle(ctx->reproject_id, refl[j].x, refl[j].y);
+ }
+
+}
+
diff --git a/src/reproject.h b/src/reproject.h
index 95a2b77..9ff3579 100644
--- a/src/reproject.h
+++ b/src/reproject.h
@@ -20,6 +20,7 @@
#include "reflections.h"
extern ImageReflection *reproject_get_reflections(ImageRecord image, size_t *n, ReflectionList *reflectionlist, ControlContext *ctx);
+extern void reproject_open(ControlContext *ctx);
#endif /* REPROJECT_H */