/* * argand.c * * "Argand plane tracking" * * (c) 2006-2007 Thomas White * * synth2d - Two-Dimensional Crystallographic Fourier Synthesis * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include "reflist.h" #include "displaywindow.h" GtkWidget *argand_pixmap_widget = NULL; GdkPixbuf *argand_pixbuf = NULL; GtkWidget *argand_window = NULL; static fftw_complex *argand_draw(ReflectionList *reflections, unsigned int width, unsigned int height) { unsigned int x, y, i; double mag = 6; double max = 0; fftw_complex *data; data = malloc(height*width*sizeof(fftw_complex)); for ( y=0; yn_reflections; i++ ) { double am = reflections->refs[i].amplitude; if ( am > max ) max = am; } mag = (width/2) / max; for ( i=0; in_reflections; i++ ) { unsigned int xd, yd; double real, imag; double am = reflections->refs[i].amplitude; double ph = reflections->refs[i].phase_known; real = am * cos(ph); imag = am * sin(ph); xd = (width-1-((width/2)+(real*mag))); yd = (height-1-((height/2)+(imag*mag))); data[yd + height*xd][0] = 1; data[yd + height*xd][1] = 0; } data[(height/2) + height*(width/2)][0]=-1; data[(height/2-1) + height*(width/2)][0]=-1; data[(height/2+1) + height*(width/2)][0]=-1; data[(height/2-2) + height*(width/2)][0]=-1; data[(height/2+2) + height*(width/2)][0]=-1; data[(height/2) + height*(width/2+1)][0]=-1; data[(height/2) + height*(width/2-1)][0]=-1; data[(height/2) + height*(width/2+2)][0]=-1; data[(height/2) + height*(width/2-2)][0]=-1; return data; } void argand_update(ReflectionList *reflections) { fftw_complex *data; if ( argand_window == NULL ) return; if ( argand_pixbuf ) gdk_pixbuf_unref(argand_pixbuf); if ( argand_pixmap_widget ) gtk_widget_destroy(argand_pixmap_widget); data = argand_draw(reflections, 321, 321); argand_pixbuf = displaywindow_render_pixbuf(data, 1, 321, 321, M_PI_2, 1, 1); argand_pixmap_widget = gtk_image_new_from_pixbuf(argand_pixbuf); gtk_container_add(GTK_CONTAINER(argand_window), argand_pixmap_widget); gtk_widget_show(argand_pixmap_widget); free(data); } static void argand_close() { argand_window = NULL; argand_pixbuf = NULL; argand_pixmap_widget = NULL; } void argand_open(ReflectionList *reflections) { if ( argand_window ) return; argand_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(argand_window), "Argand Plane"); g_signal_connect(GTK_OBJECT(argand_window), "destroy", G_CALLBACK(argand_close), NULL); gtk_widget_show_all(argand_window); argand_update(reflections); }