From 189da15810deabd739d7c11c6e95fea55739fe60 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Sat, 1 Aug 2020 15:13:49 +0200 Subject: Initial import from archive --- src/geometry.c | 324 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 src/geometry.c (limited to 'src/geometry.c') diff --git a/src/geometry.c b/src/geometry.c new file mode 100644 index 0000000..7a2d621 --- /dev/null +++ b/src/geometry.c @@ -0,0 +1,324 @@ +/* + * geometry.c + * + * Geometrical (Lorentz) Corrections + * + * (c) 2006 Thomas White + * Synth2D - two-dimensional Fourier synthesis + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#include "main.h" + +#include "displaywindow.h" +#include "data.h" + +typedef struct { + + GtkWidget *wn_entry; /* Electon wavenumber */ + GtkWidget *cr_entry; /* Laue Circle radius */ + GtkWidget *wn_label; + GtkWidget *cr_label; + GtkWidget *wn_nm_label; + GtkWidget *cr_nm_label; + GeometryCorrectionType correction_type; + +} GeometryCorrectionWindow; + +static int geometry_window_open = 0; + +/* Apply "Lorentz" factor to reflections */ +void geometry_correct(ReflectionList *reflections, GeometryCorrectionType correction_type, double wavenumber, double R) { + + unsigned int i; + double a = data_a(); + double b = data_b(); + double c = data_c(); + + for ( i=1; in_reflections; i++ ) { + + double corr = 1; + double g, g_xy, g_z; + signed int h = reflections->refs[i].h; + signed int k = reflections->refs[i].k; + signed int l = reflections->refs[i].l; + + /* Calculate g, g_xy and g_z */ + g = sqrt(((h*h)/(a*a)) + ((k*k)/(b*b)) + ((l*l)/(c*c))); + g_xy = sqrt(((h*h)/(a*a)) + ((k*k)/(b*b))); + g_z = l/c; + + switch ( correction_type ) { + + case GEOMETRY_CORRECTION_TYPE_VINCENT_MIDGLEY : { + + /* Vincent-Midgley */ + /* eqn (9) from Ultramicroscopy vol 53 1994 p271-282 */ + double corr1, corr2, corr3; + + corr1 = g/(2*R); + corr2 = pow(corr1, 2); + corr3 = 1 - corr2; + corr = sqrt(corr3); + + break; + + } + + case GEOMETRY_CORRECTION_TYPE_GJONNES : { + + /* Gjonnes (without divergence) */ + /* eqn (9) from Ultramicroscopy 69 1997 p1-11 */ + double corr1, corr2, corr3, corr4; + + corr1 = 2*R*g_xy; corr1 = pow(corr1, 2); + corr2 = pow(g,2) - (2*wavenumber*g_z); corr2 = pow(corr2, 2); + corr3 = corr1 - corr2; + corr4 = 2*wavenumber; + corr = sqrt(corr3) / (2 * corr4); + + break; + + } + + case GEOMETRY_CORRECTION_TYPE_GJONNES_DIVERGENCE : { + + /* Gjønnes (with divergence) */ + /* eqn (37) from Ultramicroscopy 69 1997 p1-11 */ + double corr1, corr2, corr3, corr3b, corr4, corr4a, corr4b; + + corr1 = pow(R, 3) / pow(wavenumber, 2); + corr2 = pow((g_xy / g), 2); + corr3b = (pow(g, 2) - 2*wavenumber*g_z) / (2*R*g_xy); + corr3 = 1 - pow(corr3b, 2); + corr4a = pow(((pow(g, 2) - (2*wavenumber*g_z))/wavenumber), 2); + corr4a = 1 - (corr4a / 2); + corr4b = (wavenumber*g_z)/pow(g, 2); + corr4b = 1 - (corr4b * 2); + corr4 = corr4a / corr4b; + corr = corr1 * corr2 * corr3 * corr4; + + //printf("corr1=%f, corr2=%f, corr3b=%f, corr3=%f, corr4a=%f, corr4b=%f, corr4=%f\n", + // corr1, corr2, corr3b, corr3, corr4a, corr4b, corr4); + + break; + + } + + } + + printf("%f %f\n", g, corr); + + if ( corr < 0 ) corr = 0; + + /* Square root here because we are working with amplitudes not intensities */ + reflections->refs[i].amplitude = sqrt(corr) * reflections->refs[i].amplitude; + assert( reflections->refs[i].amplitude >= 0 ); + + } + + displaywindow_switchview(); + +} + +static gint geometry_window_response(GtkWidget *geometry_window, gint response, GeometryCorrectionWindow *gcw) { + + if ( response == GTK_RESPONSE_OK ) { + + const char *str; + float wavenumber_f, circleradius_f; + double wavenumber, circleradius; + + str = gtk_entry_get_text(GTK_ENTRY(gcw->wn_entry)); + sscanf(str, "%f", &wavenumber_f); wavenumber = wavenumber_f; + + str = gtk_entry_get_text(GTK_ENTRY(gcw->cr_entry)); + sscanf(str, "%f", &circleradius_f); circleradius = circleradius_f; + + main_geometry_correct(gcw->correction_type, wavenumber, circleradius); + + } + + geometry_window_open = 0; + gtk_widget_destroy(geometry_window); + free(gcw); + + return 0; + +} + +static gint geometry_select_vm(GtkWidget *widget, GeometryCorrectionWindow *gcw) { + + gcw->correction_type = GEOMETRY_CORRECTION_TYPE_VINCENT_MIDGLEY; + + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_entry), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_label), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_nm_label), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_entry), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_label), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_nm_label), TRUE); + + return 0; + +} + +static gint geometry_select_gn(GtkWidget *widget, GeometryCorrectionWindow *gcw) { + + gcw->correction_type = GEOMETRY_CORRECTION_TYPE_GJONNES; + + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_entry), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_label), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_nm_label), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_entry), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_label), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_nm_label), TRUE); + + return 0; + +} + +static gint geometry_select_gd(GtkWidget *widget, GeometryCorrectionWindow *gcw) { + + gcw->correction_type = GEOMETRY_CORRECTION_TYPE_GJONNES_DIVERGENCE; + + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_entry), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_label), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->wn_nm_label), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_entry), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_label), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(gcw->cr_nm_label), TRUE); + + return 0; + +} + +/* Wavelength of an electron (in m) given accelerating potential (in V) */ +static double lambda(double V) { + + double m = 9.110E-31; + double h = 6.625E-34; + double e = 1.60E-19; + double c = 2.998E8; + + return h / sqrt(2*m*e*V*(1+((e*V) / (2*m*c*c)))); + +} + +static void geometry_set_defaults(GeometryCorrectionWindow *gcw) { + + double wn; + char string[32]; + int i; + double r; + ReflectionList *reflections; + + wn = 1/(lambda(300000)*1e9); /* Answer in nm^-1 */ + snprintf(string, 31, "%f", wn); + gtk_entry_set_text(GTK_ENTRY(gcw->wn_entry), string); + + reflections = main_reflist(); + r = 0; + double a = data_a(); + double b = data_b(); + for ( i=1; in_reflections; i++ ) { + + double g; + signed int h = reflections->refs[i].h; + signed int k = reflections->refs[i].k; + + g = sqrt(((h*h)/(a*a)) + ((k*k)/(b*b))); + + if ( g > r ) r = g; + + } + + snprintf(string, 31, "%f", r); + gtk_entry_set_text(GTK_ENTRY(gcw->cr_entry), string); + +} + +void geometry_dialog_open() { + + GtkWidget *geometry_window; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *table; + GtkWidget *geometry_type_vm; + GtkWidget *geometry_type_gn; + GtkWidget *geometry_type_gd; + GeometryCorrectionWindow *gcw; + + if ( geometry_window_open ) { + return; + } + geometry_window_open = 1; + + gcw = malloc(sizeof(GeometryCorrectionWindow)); + + geometry_window = gtk_dialog_new_with_buttons("Geometrical Correction", GTK_WINDOW(displaywindow_gtkwindow()), + GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CLOSE, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); + + vbox = gtk_vbox_new(FALSE, 0); + hbox = gtk_hbox_new(TRUE, 0); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(geometry_window)->vbox), GTK_WIDGET(hbox), FALSE, FALSE, 7); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(vbox), FALSE, FALSE, 5); + + table = gtk_table_new(5, 3, FALSE); + gtk_table_set_row_spacings(GTK_TABLE(table), 5); + gtk_table_set_col_spacings(GTK_TABLE(table), 5); + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(table), FALSE, FALSE, 0); + + geometry_type_vm = gtk_radio_button_new_with_label(NULL, "Vincent-Midgley"); + geometry_type_gn = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(geometry_type_vm), + "Gjønnes (without divergence)"); + geometry_type_gd = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(geometry_type_vm), + "Gjønnes (with divergence)"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(geometry_type_gd), TRUE); + gcw->correction_type = GEOMETRY_CORRECTION_TYPE_GJONNES_DIVERGENCE; + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(geometry_type_vm), 1, 4, 1, 2); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(geometry_type_gn), 1, 4, 2, 3); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(geometry_type_gd), 1, 4, 3, 4); + + gcw->wn_label = gtk_label_new("Electron Wavenumber:"); + gtk_misc_set_alignment(GTK_MISC(gcw->wn_label), 1, 0.5); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(gcw->wn_label), 1, 2, 4, 5); + gcw->wn_nm_label = gtk_label_new("nm^-1"); + gtk_label_set_markup(GTK_LABEL(gcw->wn_nm_label), "nm-1"); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(gcw->wn_nm_label), 3, 4, 4, 5); + + gcw->wn_entry = gtk_entry_new(); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(gcw->wn_entry), 2, 3, 4, 5); + + gcw->cr_label = gtk_label_new("Laue Circle Radius:"); + gtk_misc_set_alignment(GTK_MISC(gcw->cr_label), 1, 0.5); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(gcw->cr_label), 1, 2, 5, 6); + gcw->cr_nm_label = gtk_label_new("nm^-1"); + gtk_label_set_markup(GTK_LABEL(gcw->cr_nm_label), "nm-1"); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(gcw->cr_nm_label), 3, 4, 5, 6); + + gcw->cr_entry = gtk_entry_new(); + gtk_table_attach_defaults(GTK_TABLE(table), GTK_WIDGET(gcw->cr_entry), 2, 3, 5, 6); + + geometry_set_defaults(gcw); + + g_signal_connect(G_OBJECT(geometry_type_vm), "clicked", G_CALLBACK(geometry_select_vm), gcw); + g_signal_connect(G_OBJECT(geometry_type_gn), "clicked", G_CALLBACK(geometry_select_gn), gcw); + g_signal_connect(G_OBJECT(geometry_type_gd), "clicked", G_CALLBACK(geometry_select_gd), gcw); + + g_signal_connect(G_OBJECT(geometry_window), "response", G_CALLBACK(geometry_window_response), gcw); + + gtk_widget_show_all(geometry_window); + + gtk_widget_grab_focus(GTK_WIDGET(gcw->wn_entry)); + +} -- cgit v1.2.3