diff options
-rw-r--r-- | data/displaywindow.ui | 1 | ||||
-rw-r--r-- | src/control.c | 8 | ||||
-rw-r--r-- | src/control.h | 23 | ||||
-rw-r--r-- | src/displaywindow.c | 275 | ||||
-rw-r--r-- | src/displaywindow.h | 2 | ||||
-rw-r--r-- | src/ipr.c | 61 | ||||
-rw-r--r-- | src/main.c | 42 | ||||
-rw-r--r-- | src/reflections.c | 46 | ||||
-rw-r--r-- | src/reflections.h | 7 | ||||
-rw-r--r-- | src/reproject.c | 55 | ||||
-rw-r--r-- | src/reproject.h | 1 |
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; @@ -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; @@ -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 */ |