/* * 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); }