diff options
-rw-r--r-- | libcrystfel/src/index.c | 2 | ||||
-rw-r--r-- | libcrystfel/src/indexers/smallcell.c | 10 | ||||
-rw-r--r-- | libcrystfel/src/utils.c | 26 | ||||
-rw-r--r-- | libcrystfel/src/utils.h | 7 | ||||
-rw-r--r-- | src/crystfel_gui.c | 69 | ||||
-rw-r--r-- | src/gui_index.c | 139 | ||||
-rw-r--r-- | src/gui_project.c | 7 | ||||
-rw-r--r-- | src/gui_project.h | 7 | ||||
-rw-r--r-- | src/indexamajig.c | 37 |
9 files changed, 254 insertions, 50 deletions
diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index cb77c0b2..10de4daf 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -1014,7 +1014,7 @@ void index_pattern_4(struct image *image, IndexingPrivate *ipriv, int *ping, done = finished_retry(ipriv->methods[n], ipriv->flags, r, image); if ( ntry > 5 ) done = 1; - notify_alive(); + if ( notify_alive() ) done = 1; } while ( !done ); diff --git a/libcrystfel/src/indexers/smallcell.c b/libcrystfel/src/indexers/smallcell.c index d3276a8c..df86cd9f 100644 --- a/libcrystfel/src/indexers/smallcell.c +++ b/libcrystfel/src/indexers/smallcell.c @@ -568,7 +568,6 @@ static struct Cliquelist *find_max_cliques(struct PeakInfo *peak_infos, } if ( P->n_mem <= 2 ) { - ERROR("No peaks with neighbours\n"); cffree(P); return NULL; } @@ -707,8 +706,6 @@ int smallcell_index(struct image *image, void *mpriv) image->lambda, &num_peak_infos); - STATUS("Number of matched rings: %i\n", num_peak_infos); - link_nodes(peak_infos, num_peak_infos, priv->g9); cliques = find_max_cliques(peak_infos, num_peak_infos); @@ -717,8 +714,6 @@ int smallcell_index(struct image *image, void *mpriv) return 0; } - STATUS("Number of cliques found: %i\n", cliques->n); - /* Sort the list of cliques by number of members */ qsort(cliques->list, cliques->n, sizeof(struct Nodelist *), compare_cliques); @@ -729,10 +724,7 @@ int smallcell_index(struct image *image, void *mpriv) if ( cliques->list[i]->n_mem < 5 ) continue; UnitCell *uc = fit_cell(cliques->list[i]); - if ( uc == NULL ) { - ERROR("Unit cell not created.. returned NULL\n"); - continue; - } + if ( uc == NULL ) continue; if ( right_handed(uc) && !validate_cell(uc) ) { diff --git a/libcrystfel/src/utils.c b/libcrystfel/src/utils.c index 96e2a371..dd390789 100644 --- a/libcrystfel/src/utils.c +++ b/libcrystfel/src/utils.c @@ -468,37 +468,41 @@ char *safe_strdup(const char *in) /* -------------------------------- Debugging ------------------------------- */ -static void set_last_task_dummy(const char *task) +static void set_last_task_dummy(const char *task, void *vp) { /* Do nothing */ } -static void notify_alive_dummy() +static int notify_alive_dummy(void *vp) { /* Do nothing */ + return 0; } struct _debugconf { - void (*set_last_task)(const char *task); - void (*notify_alive)(void); -} debug_conf = { set_last_task_dummy, notify_alive_dummy }; - -int set_debug_funcs(void (*slt)(const char *), - void (*ping)(void)) + void (*set_last_task)(const char *task, void *vp); + int (*notify_alive)(void *vp); + void *debug_data; +} debug_conf = { set_last_task_dummy, notify_alive_dummy, NULL }; + +int set_debug_funcs(void (*slt)(const char *, void *), + int (*ping)(void *), + void *vp) { debug_conf.set_last_task = slt; debug_conf.notify_alive = ping; + debug_conf.debug_data = vp; return 0; } void set_last_task(const char *task) { - debug_conf.set_last_task(task); + debug_conf.set_last_task(task, debug_conf.debug_data); } -void notify_alive() +int notify_alive() { - debug_conf.notify_alive(); + return debug_conf.notify_alive(debug_conf.debug_data); } diff --git a/libcrystfel/src/utils.h b/libcrystfel/src/utils.h index e295c40b..07a1e1a1 100644 --- a/libcrystfel/src/utils.h +++ b/libcrystfel/src/utils.h @@ -257,9 +257,10 @@ extern int set_mm_funcs(void *(*cfmalloc)(size_t size), /* -------------------------------- Debugging ------------------------------- */ extern void set_last_task(const char *task); -extern void notify_alive(void); -extern int set_debug_funcs(void (*slt)(const char *), - void (*ping)(void)); +extern int notify_alive(void); +extern int set_debug_funcs(void (*slt)(const char *, void *vp), + int (*ping)(void *vp), + void *debug_data); /* ------------------------------ File handling ----------------------------- */ diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c index 53f8fb83..1f0d8401 100644 --- a/src/crystfel_gui.c +++ b/src/crystfel_gui.c @@ -373,6 +373,11 @@ static void goto_frame_response_sig(GtkDialog *dialog, gint response_id, return; } + if ( ctx->proj->index_once_thread != NULL ) { + ERROR("Can't change image while indexing is running.\n"); + return; + } + if ( gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ctx->framenumchk)) ) { int id = atoi(gtk_entry_get_text(GTK_ENTRY(ctx->framenum))); if ( (id<=0) || (id>ctx->proj->n_frames) ) { @@ -604,6 +609,10 @@ static gint reset_range_sig(GtkWidget *widget, struct crystfelproject *proj) static gint first_frame_sig(GtkWidget *widget, struct crystfelproject *proj) { + if ( proj->index_once_thread != NULL ) { + ERROR("Can't change image while indexing is running.\n"); + return FALSE; + } proj->cur_frame = 0; update_imageview(proj); return FALSE; @@ -613,6 +622,10 @@ static gint first_frame_sig(GtkWidget *widget, static gint prev_frame_sig(GtkWidget *widget, struct crystfelproject *proj) { + if ( proj->index_once_thread != NULL ) { + ERROR("Can't change image while indexing is running.\n"); + return FALSE; + } if ( proj->cur_frame == 0 ) return FALSE; proj->cur_frame--; update_imageview(proj); @@ -624,6 +637,10 @@ static gint random_frame_sig(GtkWidget *widget, GdkEventButton *event, struct crystfelproject *proj) { + if ( proj->index_once_thread != NULL ) { + ERROR("Can't change image while indexing is running.\n"); + return FALSE; + } if ( event->state & GDK_SHIFT_MASK ) { if ( proj->n_random_history > 0 ) { proj->cur_frame = pop_random_frame(proj); @@ -641,6 +658,10 @@ static gint random_frame_sig(GtkWidget *widget, static gint next_frame_sig(GtkWidget *widget, struct crystfelproject *proj) { + if ( proj->index_once_thread != NULL ) { + ERROR("Can't change image while indexing is running.\n"); + return FALSE; + } if ( proj->cur_frame == proj->n_frames - 1 ) return FALSE; proj->cur_frame++; update_imageview(proj); @@ -651,6 +672,10 @@ static gint next_frame_sig(GtkWidget *widget, static gint last_frame_sig(GtkWidget *widget, struct crystfelproject *proj) { + if ( proj->index_once_thread != NULL ) { + ERROR("Can't change image while indexing is running.\n"); + return FALSE; + } proj->cur_frame = proj->n_frames - 1; update_imageview(proj); return FALSE; @@ -796,6 +821,10 @@ static gint image_info_clicked_sig(GtkWidget *widget, static gint results_combo_changed_sig(GtkComboBox *w, struct crystfelproject *proj) { + if ( proj->index_once_thread != NULL ) { + ERROR("Can't change image while indexing is running.\n"); + return FALSE; + } update_imageview(proj); return FALSE; } @@ -1010,24 +1039,52 @@ static void add_task_buttons(GtkWidget *vbox, struct crystfelproject *proj) } -static void add_gui_message(enum log_msg_type type, const char *msg, - void *vp) +struct logmsg_data { + struct crystfelproject *proj; + enum log_msg_type type; + char *msg; +}; + + +static gboolean add_gui_message_real(gpointer vp) +{ + struct logmsg_data *data = vp; + GtkTextBuffer *buf; GtkTextIter iter; GtkTextMark *mark; - struct crystfelproject *proj = vp; - buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(proj->report)); + buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data->proj->report)); gtk_text_buffer_get_end_iter(buf, &iter); - gtk_text_buffer_insert(buf, &iter, msg, -1); + gtk_text_buffer_insert(buf, &iter, data->msg, -1); mark = gtk_text_mark_new(NULL, FALSE); gtk_text_buffer_get_end_iter(buf, &iter); gtk_text_buffer_add_mark(buf, mark, &iter); - gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(proj->report), + gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(data->proj->report), mark, 0.0, FALSE, 0.0, 0.0); gtk_text_buffer_delete_mark(buf, mark); + + free(data->msg); + free(data); + + return FALSE; +} + + +static void add_gui_message(enum log_msg_type type, const char *msg, + void *vp) +{ + struct crystfelproject *proj = vp; + struct logmsg_data *data; + + data = malloc(sizeof(struct logmsg_data)); + data->proj = proj; + data->type = type; + data->msg = strdup(msg); + + gdk_threads_add_idle(add_gui_message_real, data); } diff --git a/src/gui_index.c b/src/gui_index.c index ff775efb..2d16503b 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -696,19 +696,144 @@ static void run_indexing_once(struct crystfelproject *proj) } +static gboolean thread_index_once_end(gpointer vp) +{ + struct crystfelproject *proj = vp; + + gtk_widget_destroy(proj->index_once_infobar); + proj->index_once_infobar = NULL; + + g_thread_unref(proj->index_once_thread); + proj->index_once_thread = NULL; + + crystfel_image_view_set_refl_box_size(CRYSTFEL_IMAGE_VIEW(proj->imageview), + proj->indexing_params.ir_inn); + force_refls_on(proj); + redraw_widget(proj->imageview); + + return FALSE; +} + + +static void *thread_index_once(void *vp) +{ + struct crystfelproject *proj = vp; + run_indexing_once(proj); + gdk_threads_add_idle(thread_index_once_end, proj); + return NULL; +} + + +static gboolean index_once_show_task(gpointer vp) +{ + struct crystfelproject *proj = vp; + char tmp[256]; + g_mutex_lock(&proj->index_once_last_task_lock); + snprintf(tmp, 255, "Indexing this frame (%s)", proj->index_once_last_task); + g_mutex_unlock(&proj->index_once_last_task_lock); + if ( proj->index_once_progress_bar != NULL ) { + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(proj->index_once_progress_bar), tmp); + } + return FALSE; +} + + +static void gui_set_last_task(const char *task, void *vp) +{ + struct crystfelproject *proj = vp; + g_mutex_lock(&proj->index_once_last_task_lock); + free(proj->index_once_last_task); + proj->index_once_last_task = strdup(task); + g_mutex_unlock(&proj->index_once_last_task_lock); + gdk_threads_add_idle(index_once_show_task, proj); +} + + +static gboolean index_once_pulse(gpointer vp) +{ + struct crystfelproject *proj = vp; + if ( proj->index_once_progress_bar != NULL ) { + gtk_progress_bar_pulse(GTK_PROGRESS_BAR(proj->index_once_progress_bar)); + } + return FALSE; +} + + +static int gui_notify_alive(void *vp) +{ + struct crystfelproject *proj = vp; + gdk_threads_add_idle(index_once_pulse, proj); + return proj->index_once_cancel; +} + + +static void index_once_infobar_response_sig(GtkInfoBar *infobar, gint resp, + gpointer data) +{ + struct crystfelproject *proj = data; + + if ( resp == GTK_RESPONSE_CANCEL ) { + proj->index_once_cancel = 1; + } +} + + +static void add_ionce_infobar(struct crystfelproject *proj) +{ + GtkWidget *info_bar; + GtkWidget *bar_area; + + info_bar = gtk_info_bar_new(); + gtk_info_bar_set_message_type(GTK_INFO_BAR(info_bar), + GTK_MESSAGE_INFO); + + gtk_info_bar_add_button(GTK_INFO_BAR(info_bar), + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + + gtk_box_pack_end(GTK_BOX(proj->main_vbox), GTK_WIDGET(info_bar), + FALSE, FALSE, 0.0); + + bar_area = gtk_info_bar_get_content_area(GTK_INFO_BAR(info_bar)); + + /* Create progress bar */ + proj->index_once_progress_bar = gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(bar_area), + GTK_WIDGET(proj->index_once_progress_bar), + TRUE, TRUE, 0.0); + gtk_progress_bar_set_text(GTK_PROGRESS_BAR(proj->index_once_progress_bar), + "Indexing this frame"); + gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(proj->index_once_progress_bar), + TRUE); + + g_signal_connect(G_OBJECT(info_bar), "response", + G_CALLBACK(index_once_infobar_response_sig), proj); + + gtk_widget_show_all(info_bar); + +#if GTK_CHECK_VERSION(3,22,29) + gtk_info_bar_set_revealed(GTK_INFO_BAR(info_bar), TRUE); +#endif + + proj->index_once_infobar = info_bar; + + set_debug_funcs(gui_set_last_task, gui_notify_alive, proj); +} + + static void index_one_response_sig(GtkWidget *dialog, gint resp, struct crystfelproject *proj) { - if ( resp == GTK_RESPONSE_OK ) { get_indexing_opts(proj, CRYSTFEL_INDEXING_OPTS(proj->indexing_opts)); - run_indexing_once(proj); - - crystfel_image_view_set_refl_box_size(CRYSTFEL_IMAGE_VIEW(proj->imageview), - proj->indexing_params.ir_inn); - force_refls_on(proj); - redraw_widget(proj->imageview); + if ( proj->index_once_thread != NULL ) { + ERROR("Please wait for previous indexing to finish\n"); + return; + } + proj->index_once_cancel = 0; + proj->index_once_thread = g_thread_new("index-once", thread_index_once, proj); + add_ionce_infobar(proj); } gtk_widget_destroy(dialog); diff --git a/src/gui_project.c b/src/gui_project.c index a8df674d..74c66368 100644 --- a/src/gui_project.c +++ b/src/gui_project.c @@ -1246,6 +1246,13 @@ int default_project(struct crystfelproject *proj) proj->merging_new_job_title = NULL; proj->ambi_new_job_title = NULL; proj->n_unique_files = 0; + proj->index_once_thread = NULL; + proj->index_once_infobar = NULL; + proj->index_once_progress_bar = NULL; + proj->index_once_cancel = 0; + proj->index_once_last_task = NULL; + g_mutex_init(&proj->index_once_last_task_lock); + proj->indexing_backend_selected = 0; proj->merging_backend_selected = 0; diff --git a/src/gui_project.h b/src/gui_project.h index c396459a..b87ed227 100644 --- a/src/gui_project.h +++ b/src/gui_project.h @@ -267,6 +267,13 @@ struct crystfelproject { GtkWidget *last_button; int range_set; + GThread *index_once_thread; + GtkWidget *index_once_infobar; + GtkWidget *index_once_progress_bar; + volatile int index_once_cancel; + GMutex index_once_last_task_lock; + char *index_once_last_task; + int unsaved; int cur_frame; diff --git a/src/indexamajig.c b/src/indexamajig.c index c223230a..db07f0ef 100644 --- a/src/indexamajig.c +++ b/src/indexamajig.c @@ -273,22 +273,30 @@ static void pin_to_cpu(int slot) } -struct sb_shm *shared; -int _worker; +struct indexamajig_debug_data +{ + struct sb_shm *shared; + int worker; +}; + -static void set_last_task_sandbox(const char *task) +static void set_last_task_sandbox(const char *task, void *vp) { + struct indexamajig_debug_data *db = vp; assert(strlen(task) < MAX_TASK_LEN-1); - pthread_mutex_lock(&shared->debug_lock); - strcpy(shared->last_task[_worker], task); - pthread_mutex_unlock(&shared->debug_lock); + pthread_mutex_lock(&db->shared->debug_lock); + strcpy(db->shared->last_task[db->worker], task); + pthread_mutex_unlock(&db->shared->debug_lock); } -static void notify_alive_sandbox() + +static int notify_alive_sandbox(void *vp) { - pthread_mutex_lock(&shared->debug_lock); - shared->pings[_worker]++; - pthread_mutex_unlock(&shared->debug_lock); + struct indexamajig_debug_data *db = vp; + pthread_mutex_lock(&db->shared->debug_lock); + db->shared->pings[db->worker]++; + pthread_mutex_unlock(&db->shared->debug_lock); + return 0; } @@ -307,9 +315,10 @@ static int run_work(struct indexamajig_arguments *args) sem_t *queue_sem; IndexingFlags flags = 0; struct pf8_private_data *pf8_data = NULL; + struct indexamajig_debug_data debugdata; + struct sb_shm *shared; if ( args->cpu_pin ) pin_to_cpu(args->worker_id); - _worker = args->worker_id; ll = 64 + strlen(args->worker_tmpdir); tmp = malloc(ll); @@ -391,7 +400,7 @@ static int run_work(struct indexamajig_arguments *args) return 1; } - if ( _worker == 0 ) { + if ( args->worker_id == 0 ) { print_indexing_info(args->iargs.ipriv); } @@ -446,7 +455,9 @@ static int run_work(struct indexamajig_arguments *args) } } - set_debug_funcs(set_last_task_sandbox, notify_alive_sandbox); + debugdata.shared = shared; + debugdata.worker = args->worker_id; + set_debug_funcs(set_last_task_sandbox, notify_alive_sandbox, &debugdata); mille = crystfel_mille_new_fd(args->fd_mille); |