1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
/*
* argand.c
*
* "Argand plane tracking"
*
* (c) 2006-2007 Thomas White <taw27@cam.ac.uk>
*
* synth2d - Two-Dimensional Crystallographic Fourier Synthesis
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gtk/gtk.h>
#include <png.h>
#include <math.h>
#include <stdlib.h>
#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; y<height; y++ ) {
for ( x=0; x<width; x++ ) {
data[y + height*x][0] = 0;
data[y + height*x][1] = 0;
}
}
for ( i=0; i<reflections->n_reflections; i++ ) {
double am = reflections->refs[i].amplitude;
if ( am > max ) max = am;
}
mag = (width/2) / max;
for ( i=0; i<reflections->n_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);
}
|