From 6ec178c76a4298680f497b3a043ec1198d3a66b2 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 16 Mar 2020 10:56:56 +0100 Subject: Split off GUI peak search stuff to separate file --- CMakeLists.txt | 3 +- src/crystfel_gui.c | 380 +-------------------------------------------------- src/crystfel_gui.h | 85 ++++++++++++ src/gui_peaksearch.c | 369 +++++++++++++++++++++++++++++++++++++++++++++++++ src/gui_peaksearch.h | 41 ++++++ 5 files changed, 500 insertions(+), 378 deletions(-) create mode 100644 src/crystfel_gui.h create mode 100644 src/gui_peaksearch.c create mode 100644 src/gui_peaksearch.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2311b565..124d8bf6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -371,7 +371,8 @@ list(APPEND CRYSTFEL_EXECUTABLES cell_tool) if (GTK_FOUND) - set(CRYSTFEL_GUI_SOURCES src/crystfel_gui.c src/crystfelimageview.c) + set(CRYSTFEL_GUI_SOURCES src/crystfel_gui.c src/crystfelimageview.c + src/gui_peaksearch.c) add_executable(crystfel ${CRYSTFEL_GUI_SOURCES}) target_include_directories(crystfel PRIVATE ${COMMON_INCLUDES} ${GTK_INCLUDE_DIRS}) diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c index 5c3b00c3..cd4ba58d 100644 --- a/src/crystfel_gui.c +++ b/src/crystfel_gui.c @@ -43,6 +43,9 @@ #include #include "crystfelimageview.h" +#include "crystfelimageview.h" +#include "crystfel_gui.h" +#include "gui_peaksearch.h" static void show_help(const char *s) @@ -58,59 +61,6 @@ static void show_help(const char *s) } -struct peak_params { - enum peak_search_method method; - float threshold; /* zaef, pf8 */ - float min_sq_gradient; /* zaef */ - float min_snr; /* zaef, pf8 */ - int min_pix_count; /* pf8 */ - int max_pix_count; /* pf8 */ - int local_bg_radius; /* pf8 */ - int min_res; /* pf8 */ - int max_res; /* pf8 */ - float min_snr_biggest_pix; /* pf9 */ - float min_snr_peak_pix; /* pf9 */ - float min_sig; /* pf9 */ - float min_peak_over_neighbour; /* pf9 */ - float pk_inn; - float pk_mid; - float pk_out; - int half_pixel_shift; /* cxi, hdf5 */ -}; - -struct crystfelproject { - - GtkWidget *window; - GtkUIManager *ui; - GtkActionGroup *action_group; - - GtkWidget *imageview; - GtkWidget *icons; /* Drawing area for task icons */ - GtkWidget *report; /* Text view at the bottom for messages */ - GtkWidget *image_info; - - int cur_frame; - - char *geom_filename; - - int n_frames; - int max_frames; - char **filenames; - char **events; - - int show_peaks; - struct peak_params peak_search_params; - - GtkWidget *file_chooser; /* Data location in "Find data" window */ - GtkWidget *geom_chooser; /* Data location in "Find data" window */ - GtkWidget *type_combo; /* Search pattern in "Find data" window */ - - GtkWidget *peak_vbox; /* Box for peak search parameter widgets */ - GtkWidget *peak_params; /* Peak search parameter widgets */ - struct peak_params original_params; -}; - - static gboolean destroy_sig(GtkWidget *da, struct crystfelproject *proj) { gtk_main_quit(); @@ -128,59 +78,6 @@ static void add_ui_sig(GtkUIManager *ui, GtkWidget *widget, } -static void update_peaks(struct crystfelproject *proj) -{ - struct image *image; - - if ( proj->n_frames == 0 ) return; - - if ( proj->show_peaks ) { - - image = crystfel_image_view_get_image_struct(CRYSTFEL_IMAGE_VIEW(proj->imageview)); - if ( image == NULL ) return; - - switch ( proj->peak_search_params.method ) { - - case PEAK_ZAEF: - search_peaks(image, - proj->peak_search_params.threshold, - proj->peak_search_params.min_sq_gradient, - proj->peak_search_params.min_snr, - proj->peak_search_params.pk_inn, - proj->peak_search_params.pk_mid, - proj->peak_search_params.pk_out, - 1); - break; - - case PEAK_PEAKFINDER8: - STATUS("NB peakfinder8 doesn't get use new API\n"); - search_peaks_peakfinder8(image, 2048, - proj->peak_search_params.threshold, - proj->peak_search_params.min_snr, - proj->peak_search_params.min_pix_count, - proj->peak_search_params.max_pix_count, - proj->peak_search_params.local_bg_radius, - proj->peak_search_params.min_res, - proj->peak_search_params.max_res, - 1); - break; - - default: - ERROR("This peak detection method not implemented!\n"); - break; - - } - - crystfel_image_view_set_peaks(CRYSTFEL_IMAGE_VIEW(proj->imageview), - image->features, 0); - - } else { - crystfel_image_view_set_peaks(CRYSTFEL_IMAGE_VIEW(proj->imageview), - NULL, 0); - } -} - - static void update_imageview(struct crystfelproject *proj) { char tmp[1024]; @@ -382,276 +279,6 @@ static void finddata_response_sig(GtkWidget *dialog, gint resp, } -static int get_val(GtkWidget *entry, float *v) -{ - const char *text; - float val; - text = gtk_entry_get_text(GTK_ENTRY(entry)); - if (sscanf(text, "%f", &val) != 1) { - ERROR("Invalid value\n"); - return 1; - } - *v = val; - return 0; -} - - -static void peaksearch_threshold_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.threshold = val; - update_peaks(proj); -} - - -static void peaksearch_sqgradient_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.min_sq_gradient = val; - update_peaks(proj); -} - - -static void peaksearch_snr_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.min_snr = val; - update_peaks(proj); -} - - -static void peaksearch_min_pix_count_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.min_pix_count = val; - update_peaks(proj); -} - - -static void peaksearch_max_pix_count_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.max_pix_count = val; - update_peaks(proj); -} - - -static void peaksearch_local_bg_radius_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.local_bg_radius = val; - update_peaks(proj); -} - - -static void peaksearch_min_res_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.min_res = val; - update_peaks(proj); -} - - -static void peaksearch_max_res_sig(GtkWidget *entry, - struct crystfelproject *proj) -{ - float val; - if ( get_val(entry, &val) ) return; - proj->peak_search_params.max_res = val; - update_peaks(proj); -} - - -static void add_param(GtkWidget *params_box, const char *labeltext, - float initial_val, GCallback act_cb, - struct crystfelproject *proj) -{ - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *entry; - char tmp[64]; - - hbox = gtk_hbox_new(FALSE, 0.0); - gtk_box_pack_start(GTK_BOX(params_box), - GTK_WIDGET(hbox), FALSE, FALSE, 8.0); - label = gtk_label_new(labeltext); - gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), - FALSE, FALSE, 2.0); - entry = gtk_entry_new(); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry), - TRUE, TRUE, 2.0); - snprintf(tmp, 63, "%.2f", initial_val); - gtk_entry_set_text(GTK_ENTRY(entry), tmp); - g_signal_connect(G_OBJECT(entry), "activate", - G_CALLBACK(act_cb), proj); -} - - -static void peaksearch_algo_changed(GtkWidget *combo, - struct crystfelproject *proj) -{ - const char *algo_id; - - if ( proj->peak_params != NULL ) { - gtk_container_remove(GTK_CONTAINER(proj->peak_vbox), - proj->peak_params); - proj->peak_params = NULL; - } - - proj->peak_params = gtk_vbox_new(FALSE, 0.0); - gtk_box_pack_start(GTK_BOX(proj->peak_vbox), - GTK_WIDGET(proj->peak_params), - FALSE, FALSE, 8.0); - - algo_id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(combo)); - - if ( strcmp(algo_id, "zaef") == 0 ) { - - proj->peak_search_params.method = PEAK_ZAEF; - - add_param(proj->peak_params, "Threshold:", - proj->peak_search_params.threshold, - G_CALLBACK(peaksearch_threshold_sig), proj); - add_param(proj->peak_params, "Minimum squared gradient:", - proj->peak_search_params.min_sq_gradient, - G_CALLBACK(peaksearch_sqgradient_sig), proj); - add_param(proj->peak_params, "Minimum signal/noise ratio:", - proj->peak_search_params.min_snr, - G_CALLBACK(peaksearch_snr_sig), proj); - - } else if ( strcmp(algo_id, "peakfinder8") == 0 ) { - - proj->peak_search_params.method = PEAK_PEAKFINDER8; - - add_param(proj->peak_params, "Threshold:", - proj->peak_search_params.threshold, - G_CALLBACK(peaksearch_threshold_sig), proj); - add_param(proj->peak_params, "Minimum signal/noise ratio:", - proj->peak_search_params.min_snr, - G_CALLBACK(peaksearch_snr_sig), proj); - add_param(proj->peak_params, "Minimum number of pixels:", - proj->peak_search_params.min_pix_count, - G_CALLBACK(peaksearch_min_pix_count_sig), proj); - add_param(proj->peak_params, "Maximum number of pixels:", - proj->peak_search_params.max_pix_count, - G_CALLBACK(peaksearch_max_pix_count_sig), proj); - add_param(proj->peak_params, "Local background radius:", - proj->peak_search_params.local_bg_radius, - G_CALLBACK(peaksearch_local_bg_radius_sig), proj); - add_param(proj->peak_params, "Minimum resolution (pixels):", - proj->peak_search_params.min_res, - G_CALLBACK(peaksearch_min_res_sig), proj); - add_param(proj->peak_params, "Maximum resolution (pixels):", - proj->peak_search_params.max_res, - G_CALLBACK(peaksearch_max_res_sig), proj); - - } /* else no parameters! */ - - /* FIXME: Radii */ - - gtk_widget_show_all(proj->peak_vbox); - update_peaks(proj); -} - - -static void peaksearch_response_sig(GtkWidget *dialog, gint resp, - struct crystfelproject *proj) -{ - - if ( (resp == GTK_RESPONSE_DELETE_EVENT) - || (resp == GTK_RESPONSE_CANCEL) ) - { - proj->peak_search_params = proj->original_params; - update_peaks(proj); - } - - gtk_widget_destroy(dialog); - proj->peak_vbox = NULL; - proj->peak_params = NULL; -} - - -static gint peaksearch_sig(GtkWidget *widget, struct crystfelproject *proj) -{ - GtkWidget *dialog; - GtkWidget *content_area; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *combo; - GtkWidget *w; - - if ( proj->peak_params != NULL ) return FALSE; - - proj->show_peaks = 1; - - w = gtk_ui_manager_get_widget(proj->ui, "/ui/mainwindow/view/peaks"); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w), 1); - - /* Take a copy of the original parameters, for reverting */ - proj->original_params = proj->peak_search_params; - - dialog = gtk_dialog_new_with_buttons("Peak search", - GTK_WINDOW(proj->window), - GTK_DIALOG_DESTROY_WITH_PARENT, - "Discard changes", GTK_RESPONSE_CANCEL, - "Confirm", GTK_RESPONSE_ACCEPT, - NULL); - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(peaksearch_response_sig), proj); - - vbox = gtk_vbox_new(FALSE, 0.0); - content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - gtk_container_add(GTK_CONTAINER(content_area), vbox); - gtk_container_set_border_width(GTK_CONTAINER(content_area), 8); - proj->peak_vbox = vbox; - - hbox = gtk_hbox_new(FALSE, 0.0); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 8.0); - label = gtk_label_new("Peak search algorithm"); - gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), FALSE, FALSE, 2.0); - combo = gtk_combo_box_text_new(); - gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(combo), TRUE, TRUE, 2.0); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "zaef", - "Zaefferer gradient search (zaef)"); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "cxi", - "Get list from CXI file"); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "hdf5", - "Get list from HDF5 file"); - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "peakfinder8", - "Radial background estimation (peakfinder8)"); - #ifdef HAVE_FDIP - gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "peakfinder9", - "Local background estimation (peakfinder9)"); - #endif - g_signal_connect(G_OBJECT(combo), "changed", - G_CALLBACK(peaksearch_algo_changed), proj); - gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); - proj->type_combo = combo; - - gtk_widget_show_all(dialog); - - return FALSE; -} - - static gint finddata_sig(GtkWidget *widget, struct crystfelproject *proj) { GtkWidget *dialog; @@ -809,7 +436,6 @@ static gint show_peaks_sig(GtkWidget *w, struct crystfelproject *proj) } - static void add_menu_bar(struct crystfelproject *proj, GtkWidget *vbox) { GError *error = NULL; diff --git a/src/crystfel_gui.h b/src/crystfel_gui.h new file mode 100644 index 00000000..7706a34a --- /dev/null +++ b/src/crystfel_gui.h @@ -0,0 +1,85 @@ +/* + * crystfel_gui.h + * + * CrystFEL's main graphical user interface + * + * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2020 Thomas White + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see . + * + */ + +#ifndef CRYSTFEL_GUI_H +#define CRYSTFEL_GUI_H + +struct peak_params { + enum peak_search_method method; + float threshold; /* zaef, pf8 */ + float min_sq_gradient; /* zaef */ + float min_snr; /* zaef, pf8 */ + int min_pix_count; /* pf8 */ + int max_pix_count; /* pf8 */ + int local_bg_radius; /* pf8 */ + int min_res; /* pf8 */ + int max_res; /* pf8 */ + float min_snr_biggest_pix; /* pf9 */ + float min_snr_peak_pix; /* pf9 */ + float min_sig; /* pf9 */ + float min_peak_over_neighbour; /* pf9 */ + float pk_inn; + float pk_mid; + float pk_out; + int half_pixel_shift; /* cxi, hdf5 */ +}; + + +struct crystfelproject { + + GtkWidget *window; + GtkUIManager *ui; + GtkActionGroup *action_group; + + GtkWidget *imageview; + GtkWidget *icons; /* Drawing area for task icons */ + GtkWidget *report; /* Text view at the bottom for messages */ + GtkWidget *image_info; + + int cur_frame; + + char *geom_filename; + + int n_frames; + int max_frames; + char **filenames; + char **events; + + int show_peaks; + struct peak_params peak_search_params; + + GtkWidget *file_chooser; /* Data location in "Find data" window */ + GtkWidget *geom_chooser; /* Data location in "Find data" window */ + GtkWidget *type_combo; /* Search pattern in "Find data" window */ + + GtkWidget *peak_vbox; /* Box for peak search parameter widgets */ + GtkWidget *peak_params; /* Peak search parameter widgets */ + struct peak_params original_params; +}; + +#endif diff --git a/src/gui_peaksearch.c b/src/gui_peaksearch.c new file mode 100644 index 00000000..149aacc8 --- /dev/null +++ b/src/gui_peaksearch.c @@ -0,0 +1,369 @@ +/* + * gui_peaksearch.c + * + * Peak search parts of GUI + * + * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2020 Thomas White + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see . + * + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "crystfel_gui.h" +#include "crystfelimageview.h" + + +void update_peaks(struct crystfelproject *proj) +{ + struct image *image; + + if ( proj->n_frames == 0 ) return; + + if ( proj->show_peaks ) { + + image = crystfel_image_view_get_image_struct(CRYSTFEL_IMAGE_VIEW(proj->imageview)); + if ( image == NULL ) return; + + switch ( proj->peak_search_params.method ) { + + case PEAK_ZAEF: + search_peaks(image, + proj->peak_search_params.threshold, + proj->peak_search_params.min_sq_gradient, + proj->peak_search_params.min_snr, + proj->peak_search_params.pk_inn, + proj->peak_search_params.pk_mid, + proj->peak_search_params.pk_out, + 1); + break; + + case PEAK_PEAKFINDER8: + STATUS("NB peakfinder8 doesn't yet use new API\n"); + search_peaks_peakfinder8(image, 2048, + proj->peak_search_params.threshold, + proj->peak_search_params.min_snr, + proj->peak_search_params.min_pix_count, + proj->peak_search_params.max_pix_count, + proj->peak_search_params.local_bg_radius, + proj->peak_search_params.min_res, + proj->peak_search_params.max_res, + 1); + break; + + default: + ERROR("This peak detection method not implemented!\n"); + break; + + } + + crystfel_image_view_set_peaks(CRYSTFEL_IMAGE_VIEW(proj->imageview), + image->features, 0); + + } else { + crystfel_image_view_set_peaks(CRYSTFEL_IMAGE_VIEW(proj->imageview), + NULL, 0); + } +} + + +static int get_val(GtkWidget *entry, float *v) +{ + const char *text; + float val; + text = gtk_entry_get_text(GTK_ENTRY(entry)); + if (sscanf(text, "%f", &val) != 1) { + ERROR("Invalid value\n"); + return 1; + } + *v = val; + return 0; +} + + +static void peaksearch_threshold_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.threshold = val; + update_peaks(proj); +} + + +static void peaksearch_sqgradient_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.min_sq_gradient = val; + update_peaks(proj); +} + + +static void peaksearch_snr_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.min_snr = val; + update_peaks(proj); +} + + +static void peaksearch_min_pix_count_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.min_pix_count = val; + update_peaks(proj); +} + + +static void peaksearch_max_pix_count_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.max_pix_count = val; + update_peaks(proj); +} + + +static void peaksearch_local_bg_radius_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.local_bg_radius = val; + update_peaks(proj); +} + + +static void peaksearch_min_res_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.min_res = val; + update_peaks(proj); +} + + +static void peaksearch_max_res_sig(GtkWidget *entry, + struct crystfelproject *proj) +{ + float val; + if ( get_val(entry, &val) ) return; + proj->peak_search_params.max_res = val; + update_peaks(proj); +} + + +static void add_param(GtkWidget *params_box, const char *labeltext, + float initial_val, GCallback act_cb, + struct crystfelproject *proj) +{ + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *entry; + char tmp[64]; + + hbox = gtk_hbox_new(FALSE, 0.0); + gtk_box_pack_start(GTK_BOX(params_box), + GTK_WIDGET(hbox), FALSE, FALSE, 8.0); + label = gtk_label_new(labeltext); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), + FALSE, FALSE, 2.0); + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(entry), + TRUE, TRUE, 2.0); + snprintf(tmp, 63, "%.2f", initial_val); + gtk_entry_set_text(GTK_ENTRY(entry), tmp); + g_signal_connect(G_OBJECT(entry), "activate", + G_CALLBACK(act_cb), proj); +} + + +static void peaksearch_algo_changed(GtkWidget *combo, + struct crystfelproject *proj) +{ + const char *algo_id; + + if ( proj->peak_params != NULL ) { + gtk_container_remove(GTK_CONTAINER(proj->peak_vbox), + proj->peak_params); + proj->peak_params = NULL; + } + + proj->peak_params = gtk_vbox_new(FALSE, 0.0); + gtk_box_pack_start(GTK_BOX(proj->peak_vbox), + GTK_WIDGET(proj->peak_params), + FALSE, FALSE, 8.0); + + algo_id = gtk_combo_box_get_active_id(GTK_COMBO_BOX(combo)); + + if ( strcmp(algo_id, "zaef") == 0 ) { + + proj->peak_search_params.method = PEAK_ZAEF; + + add_param(proj->peak_params, "Threshold:", + proj->peak_search_params.threshold, + G_CALLBACK(peaksearch_threshold_sig), proj); + add_param(proj->peak_params, "Minimum squared gradient:", + proj->peak_search_params.min_sq_gradient, + G_CALLBACK(peaksearch_sqgradient_sig), proj); + add_param(proj->peak_params, "Minimum signal/noise ratio:", + proj->peak_search_params.min_snr, + G_CALLBACK(peaksearch_snr_sig), proj); + + } else if ( strcmp(algo_id, "peakfinder8") == 0 ) { + + proj->peak_search_params.method = PEAK_PEAKFINDER8; + + add_param(proj->peak_params, "Threshold:", + proj->peak_search_params.threshold, + G_CALLBACK(peaksearch_threshold_sig), proj); + add_param(proj->peak_params, "Minimum signal/noise ratio:", + proj->peak_search_params.min_snr, + G_CALLBACK(peaksearch_snr_sig), proj); + add_param(proj->peak_params, "Minimum number of pixels:", + proj->peak_search_params.min_pix_count, + G_CALLBACK(peaksearch_min_pix_count_sig), proj); + add_param(proj->peak_params, "Maximum number of pixels:", + proj->peak_search_params.max_pix_count, + G_CALLBACK(peaksearch_max_pix_count_sig), proj); + add_param(proj->peak_params, "Local background radius:", + proj->peak_search_params.local_bg_radius, + G_CALLBACK(peaksearch_local_bg_radius_sig), proj); + add_param(proj->peak_params, "Minimum resolution (pixels):", + proj->peak_search_params.min_res, + G_CALLBACK(peaksearch_min_res_sig), proj); + add_param(proj->peak_params, "Maximum resolution (pixels):", + proj->peak_search_params.max_res, + G_CALLBACK(peaksearch_max_res_sig), proj); + + } /* else no parameters! */ + + /* FIXME: Radii */ + + gtk_widget_show_all(proj->peak_vbox); + update_peaks(proj); +} + + +static void peaksearch_response_sig(GtkWidget *dialog, gint resp, + struct crystfelproject *proj) +{ + + if ( (resp == GTK_RESPONSE_DELETE_EVENT) + || (resp == GTK_RESPONSE_CANCEL) ) + { + proj->peak_search_params = proj->original_params; + update_peaks(proj); + } + + gtk_widget_destroy(dialog); + proj->peak_vbox = NULL; + proj->peak_params = NULL; +} + + +gint peaksearch_sig(GtkWidget *widget, struct crystfelproject *proj) +{ + GtkWidget *dialog; + GtkWidget *content_area; + GtkWidget *vbox; + GtkWidget *hbox; + GtkWidget *label; + GtkWidget *combo; + GtkWidget *w; + + if ( proj->peak_params != NULL ) return FALSE; + + proj->show_peaks = 1; + + w = gtk_ui_manager_get_widget(proj->ui, "/ui/mainwindow/view/peaks"); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w), 1); + + /* Take a copy of the original parameters, for reverting */ + proj->original_params = proj->peak_search_params; + + dialog = gtk_dialog_new_with_buttons("Peak search", + GTK_WINDOW(proj->window), + GTK_DIALOG_DESTROY_WITH_PARENT, + "Discard changes", GTK_RESPONSE_CANCEL, + "Confirm", GTK_RESPONSE_ACCEPT, + NULL); + + g_signal_connect(G_OBJECT(dialog), "response", + G_CALLBACK(peaksearch_response_sig), proj); + + vbox = gtk_vbox_new(FALSE, 0.0); + content_area = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + gtk_container_add(GTK_CONTAINER(content_area), vbox); + gtk_container_set_border_width(GTK_CONTAINER(content_area), 8); + proj->peak_vbox = vbox; + + hbox = gtk_hbox_new(FALSE, 0.0); + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(hbox), FALSE, FALSE, 8.0); + label = gtk_label_new("Peak search algorithm"); + gtk_misc_set_alignment(GTK_MISC(label), 1.0, 0.5); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(label), FALSE, FALSE, 2.0); + combo = gtk_combo_box_text_new(); + gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(combo), TRUE, TRUE, 2.0); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "zaef", + "Zaefferer gradient search (zaef)"); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "cxi", + "Get list from CXI file"); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "hdf5", + "Get list from HDF5 file"); + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "peakfinder8", + "Radial background estimation (peakfinder8)"); + #ifdef HAVE_FDIP + gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(combo), "peakfinder9", + "Local background estimation (peakfinder9)"); + #endif + g_signal_connect(G_OBJECT(combo), "changed", + G_CALLBACK(peaksearch_algo_changed), proj); + gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); + proj->type_combo = combo; + + gtk_widget_show_all(dialog); + + return FALSE; +} diff --git a/src/gui_peaksearch.h b/src/gui_peaksearch.h new file mode 100644 index 00000000..5124acdb --- /dev/null +++ b/src/gui_peaksearch.h @@ -0,0 +1,41 @@ +/* + * gui_peaksearch.h + * + * Peak search parts of GUI + * + * Copyright © 2020 Deutsches Elektronen-Synchrotron DESY, + * a research centre of the Helmholtz Association. + * + * Authors: + * 2020 Thomas White + * + * This file is part of CrystFEL. + * + * CrystFEL is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * CrystFEL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with CrystFEL. If not, see . + * + */ + +#ifndef GUI_PEAKSEARCH_H +#define GUI_PEAKSEARCH_H + +#include + +#include "crystfel_gui.h" + +extern gint peaksearch_sig(GtkWidget *widget, + struct crystfelproject *proj); + +extern void update_peaks(struct crystfelproject *proj); + +#endif -- cgit v1.2.3