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/contourise.c | 441 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 441 insertions(+) create mode 100644 src/contourise.c (limited to 'src/contourise.c') diff --git a/src/contourise.c b/src/contourise.c new file mode 100644 index 0000000..56e10b8 --- /dev/null +++ b/src/contourise.c @@ -0,0 +1,441 @@ +/* + * contourise.c + * + * Draw contour maps + * + * (c) 2006-2009 Thomas White + * + * synth2d - Two-Dimensional Crystallographic Fourier Synthesis + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "displaywindow.h" +#include "model.h" +#include "data.h" +#include "renderer.h" + +typedef struct { + GtkWidget *rad_mod; + GtkWidget *rad_mod_sign; + GtkWidget *rad_real; + GtkWidget *rad_imag; + GtkWidget *n_contours; + int nx; + int ny; +} ContourDialog; + +typedef enum { + VALUES_NONE, + VALUES_MODULUS, + VALUES_MODULUS_SIGN, + VALUES_REAL, + VALUES_IMAGINARY +} ContourValues; + +static GtkWidget *contourise_dialog = NULL; + +static void griwrite(FILE *gri, const char *string) +{ + fwrite(string, strlen(string), 1, gri); +} + +static void contourise_map(fftw_complex *out, unsigned int width, + unsigned int height, ContourValues vals, + int nx, int ny, int ncont) +{ + FILE *gri; + char tmp[1024]; + double maxval; + int model_marks; + int xn, yn; + pid_t pid; + int status; + size_t width_n, height_n; + double gamma; + double aspect; + int landscape; /* 1=landscape, 0=portrait */ + int fit_x; /* 1=fit the x-axis to the page, 0=fit the y-axis */ + ComplexArray cxar; + double xsize, ysize, scale; + + gamma = data_gamma(); + + if ( ( displaywindow_mode() == DWV_MODEL ) + || ( displaywindow_mode() == DWV_DIFFERENCE ) + || ( displaywindow_mode() == DWV_EXITWAVE ) + || ( displaywindow_mode() == DWV_REFSYN ) ) { + model_marks = 1; + } else { + model_marks = 0; + } + + width_n = renderer_width(width, height, gamma, nx, ny); + height_n = renderer_height(width, height, gamma, nx, ny); + + maxval = displaywindow_max(); + + gri = popen("gri -b -no_startup_message", "w"); + if ( !gri ) { + fprintf(stderr, "Couldn't invoke gri. Please check your PATH."); + return; + } + + /* Initialise */ + griwrite(gri, "set postscript filename synth2d.ps\n"); + griwrite(gri, "set page size A4\n"); + snprintf(tmp, 1023, "set x grid 0 1 /%i\n", width_n); + griwrite(gri, tmp); + snprintf(tmp, 1023, "set y grid 0 1 /%i\n", height_n); + griwrite(gri, tmp); + + /* Figure out the size */ + aspect = (double)height_n/width_n; + if ( width_n > height_n ) { + landscape = 1; + if ( aspect < (19.0/27.7) ) { + fit_x = 1; + } else { + fit_x = 0; + } + } else { + landscape = 0; + if ( aspect < (27.7/19.0) ) { + fit_x = 1; + } else { + fit_x = 0; + } + } + if ( landscape ) { + if ( fit_x ) { + xsize = 27.7; + ysize = 27.7*aspect; + scale = 27.7/width_n; + } else { + xsize = 19.0/aspect; + ysize = 19.0; + scale = 19.0/height_n; + } + } else { + if ( fit_x ) { + xsize = 19.0; + ysize = 19.0*aspect; + scale = 19.0/width_n; + } else { + xsize = 27.7/aspect; + ysize = 27.7; + scale = 27.7/height_n; + } + } + printf("CO: aspect=%f => selected ", aspect); + if ( landscape ) { + printf("landscape, "); + griwrite(gri, "set page landscape\n"); + } else { + printf("portrait, "); + griwrite(gri, "set page portrait\n"); + } + if ( fit_x ) { + printf("fitting x, "); + } else { + printf("fitting y, "); + } + snprintf(tmp, 1023, "set x size %f\n", xsize); + griwrite(gri, tmp); + snprintf(tmp, 1023, "set y size %f\n", ysize); + griwrite(gri, tmp); + printf("width=%f height=%f\n", xsize, ysize); + + griwrite(gri, "set x margin 1\n"); /* cm */ + griwrite(gri, "set y margin 1\n"); /* cm */ + griwrite(gri, "set axes style none\n"); + griwrite(gri, "set line width 3.0\n"); + if ( landscape ) { + if ( fit_x ) { + snprintf(tmp, 1023, "draw box 1 1 %f %f cm\n", + 1.0+27.7, 1.0+27.7*aspect); + griwrite(gri, tmp); + } else { + snprintf(tmp, 1023, "draw box 1 1 %f %f cm\n", + 1.0+19.0/aspect, 1.0+19.0); + griwrite(gri, tmp); + } + } else { + if ( fit_x ) { + snprintf(tmp, 1023, "draw box 1 1 %f %f cm\n", + 1.0+19.0, 1.0+19.0*aspect); + griwrite(gri, tmp); + } else { + snprintf(tmp, 1023, "draw box 1 1 %f %f cm\n", + 1.0+27.7/aspect, 1.0+27.7); + griwrite(gri, tmp); + } + } + + /* Read the data and plot contours */ + griwrite(gri, "read grid data\n"); + + /* Give it the data to read... */ + cxar = renderer_draw(out, width, height, gamma, nx, ny); + for ( yn=height_n-1; yn>=0; yn-- ) { + + int first = 1; + + for ( xn=0; xnn_atoms; i++ ) { + + double p, q; + int xc, yc; + + p = model->atoms[i].x; + q = model->atoms[i].y; + + for ( xc=0; xcrad_mod)) ) + vals = VALUES_MODULUS; + if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + cd->rad_mod_sign)) ) + vals = VALUES_MODULUS_SIGN; + if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + cd->rad_real)) ) + vals = VALUES_REAL; + if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( + cd->rad_imag)) ) + vals = VALUES_IMAGINARY; + if ( vals == VALUES_NONE ) error = 1; + + ncont_s = gtk_entry_get_text(GTK_ENTRY(cd->n_contours)); + if ( sscanf(ncont_s, "%i", &ncont) != 1 ) { + error_report("Invalid number of contours"); + error = 1; + } else { + if ( ncont < 1 ) { + error_report("Invalid number of contours"); + error = 1; + } + } + + if ( error == 0 ) { + contourise_map(displaywindow_outarray(), + data_width(), data_height(), + vals, + cd->nx, cd->ny, ncont); + } + + } + + if ( error == 0 ) { + gtk_widget_destroy(window); + contourise_dialog = NULL; + free(cd); + } + + return 0; +} + +void contourise_dialog_open(int nx, int ny) +{ + ContourDialog *cd; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *text; + GtkWidget *ncont_hbox; + + if ( contourise_dialog ) { + return; + } + + contourise_dialog = gtk_dialog_new_with_buttons("Contour Map", + GTK_WINDOW(displaywindow_gtkwindow()), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); + cd = malloc(sizeof(ContourDialog)); + if ( !cd ) return; + cd->nx = nx; /* Number of unit cells */ + cd->ny = ny; /* Store these for later */ + + /* Structure */ + vbox = gtk_vbox_new(FALSE, 0); + hbox = gtk_hbox_new(TRUE, 0); + gtk_box_pack_start(GTK_BOX(GTK_DIALOG(contourise_dialog)->vbox), + GTK_WIDGET(hbox), TRUE, TRUE, 7); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5); + + text = gtk_label_new(""); + gtk_label_set_markup(GTK_LABEL(text), + "" + "What do you want to plot?"); + gtk_label_set_line_wrap(GTK_LABEL(text), TRUE); + gtk_box_pack_start(GTK_BOX(vbox), text, FALSE, FALSE, 5); + + cd->rad_mod_sign = gtk_radio_button_new_with_label(NULL, + "Modulus with sign: √[Re(V)² + Im(V)²] × sign[Re(V)]"); + gtk_box_pack_start(GTK_BOX(vbox), cd->rad_mod_sign, FALSE, FALSE, 2); + cd->rad_mod = gtk_radio_button_new_with_label_from_widget( + GTK_RADIO_BUTTON(cd->rad_mod_sign), + "Modulus alone: √[Re(V)² + Im(V)²]"); + gtk_box_pack_start(GTK_BOX(vbox), cd->rad_mod, FALSE, FALSE, 2); + cd->rad_real = gtk_radio_button_new_with_label_from_widget( + GTK_RADIO_BUTTON(cd->rad_mod_sign), + "Real part: Re(V)"); + gtk_box_pack_start(GTK_BOX(vbox), cd->rad_real, FALSE, FALSE, 2); + cd->rad_imag = gtk_radio_button_new_with_label_from_widget( + GTK_RADIO_BUTTON(cd->rad_mod_sign), + "Imaginary part: Im(V)"); + gtk_box_pack_start(GTK_BOX(vbox), cd->rad_imag, FALSE, FALSE, 2); + + text = gtk_label_new("Number of contours:"); + gtk_misc_set_alignment(GTK_MISC(text), 1.0, 0.5); + ncont_hbox = gtk_hbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(ncont_hbox), text, FALSE, TRUE, 2); + gtk_box_pack_end(GTK_BOX(vbox), ncont_hbox, FALSE, FALSE, 2); + cd->n_contours = gtk_entry_new(); + gtk_entry_set_width_chars(GTK_ENTRY(cd->n_contours), 4); + gtk_box_pack_start(GTK_BOX(ncont_hbox), cd->n_contours, FALSE, TRUE, 2); + gtk_entry_set_text(GTK_ENTRY(cd->n_contours), "20"); + + g_signal_connect(G_OBJECT(contourise_dialog), "response", + G_CALLBACK(contourise_dialog_close), cd); + gtk_widget_show_all(contourise_dialog); +} -- cgit v1.2.3