1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 c-style: "K&R" -*- */
3 /*----------------------------------------------------------------------
5 gpiv - Graphic program for Particle Image Velocimetry, based on gtk/gnome
8 Copyright (C) 2002 Gerber van der Graaf
10 This file is part of gpiv.
12 Gpiv is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software Foundation,
24 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 ----------------------------------------------------------------------*/
29 * (callback) functions for Piv validation window/tabulator
30 * $Log: pivvalid.c,v $
31 * Revision 1.1 2003-06-17 17:10:52 gerber
42 * Piv validation window/tabulator callbacks
45 on_button_valid_gradient_enter(GtkWidget
* widget
, gpointer data
)
47 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
48 gchar
*msg
= _("Examines PIV data on velocity gradients");
49 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
55 on_button_valid_gradient(GtkWidget
* widget
,
58 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
62 for (row
= gpiv
->first_selected_row
; row
<= gpiv
->last_selected_row
;
64 display_act
= gtk_clist_get_row_data(GTK_CLIST(gpiv
->clist_buf
),
67 ibuf
= display_act
->count
;
68 if (display
[ibuf
] != NULL
69 && display_act
->mwin
!= NULL
70 && GTK_WIDGET_VISIBLE(GTK_WIDGET(display_act
->mwin
)) ) {
71 gdk_window_show(GTK_WIDGET(display_act
->mwin
)->window
);
72 gdk_window_raise(GTK_WIDGET(display_act
->mwin
)->window
);
82 on_radiobutton_valid_disable_0_enter(GtkWidget
* widget
, gpointer data
)
84 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
85 gchar
*msg
= _("No mouse activity within displayer");
86 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
92 on_radiobutton_valid_disable_1_enter(GtkWidget
* widget
, gpointer data
)
94 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
95 gchar
*msg
= _("Enables a single PIV data-point");
96 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
102 on_radiobutton_valid_disable_2_enter(GtkWidget
* widget
, gpointer data
)
104 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
105 gchar
*msg
= _("Disables a single PIV data-point");
106 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
112 on_radiobutton_valid_disable_3_enter(GtkWidget
* widget
, gpointer data
)
114 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
115 gchar
*msg
= _("Enables an area containing PIV data");
116 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
122 on_radiobutton_valid_disable_4_enter(GtkWidget
* widget
, gpointer data
)
124 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
125 gchar
*msg
= _("Disables an area containing PIV data");
126 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
132 on_radiobutton_valid_disable(GtkWidget
* widget
,
135 m_select
= atoi(gtk_object_get_data(GTK_OBJECT(widget
),
139 void on_radiobutton_valid_errvec_residu_enter(GtkWidget
* widget
, gpointer data
)
141 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
142 gchar
*msg
= _("Defines residu type to examine data on");
143 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
147 void on_radiobutton_valid_errvec_residu(GtkWidget
* widget
, gpointer data
)
149 piv_valid_par
.residu_type
= atoi(gtk_object_get_data(GTK_OBJECT(widget
),
152 /* if (piv_valid_par.residu_type == SNR) { */
153 /* fprintf(stderr, "residu_type SNR\n"); */
154 /* } else if (piv_valid_par.residu_type == MEDIAN) { */
155 /* fprintf(stderr, "residu_type MEDIAN\n"); */
157 /* fprintf(stderr, "NO valid residu_type\n"); */
165 on_button_valid_errvec_resstats_enter(GtkWidget
* widget
, gpointer data
)
167 GpivConsole
* gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
168 gchar
*msg
= _("Displays inverse cumulative histogram of residus");
169 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
174 on_button_valid_errvec_resstats(GtkWidget
* widget
, gpointer data
)
176 PivValid
* valid
= gtk_object_get_data(GTK_OBJECT(widget
), "valid");
177 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
180 piv_valid_par
.res_stats
= 1;
183 for (row
= gpiv
->first_selected_row
; row
<= gpiv
->last_selected_row
;
185 display_act
= gtk_clist_get_row_data(GTK_CLIST(gpiv
->clist_buf
),
188 ibuf
= display_act
->count
;
189 if (display
[ibuf
] != NULL
190 && display_act
->mwin
!= NULL
191 && GTK_WIDGET_VISIBLE(GTK_WIDGET(display_act
->mwin
)) ) {
192 gdk_window_show(GTK_WIDGET(display_act
->mwin
)->window
);
193 gdk_window_raise(GTK_WIDGET(display_act
->mwin
)->window
);
199 piv_valid_par
.res_stats
= 0;
206 on_spinbutton_valid_errvec_yield(GtkSpinButton
*widget
,
209 piv_valid_par
.data_yield
= gtk_spin_button_get_value_as_float(widget
);
215 on_spinbutton_valid_errvec_res(GtkSpinButton
*widget
,
218 piv_valid_par
.residu_max
= gtk_spin_button_get_value_as_float(widget
);
219 if (v_color
== SHOW_SNR
&& display_act
->gpd
.exist_piv
) {
220 update_all_vectors(&display_act
->gpd
);
227 on_checkbutton_valid_errvec_disres_enter(GtkWidget
* widget
, gpointer data
)
229 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
230 gchar
*msg
= _("Display PIV vector colors related to residu or SNR value");
231 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
235 on_checkbutton_valid_errvec_disres(GtkSpinButton
*widget
,
238 if (GTK_TOGGLE_BUTTON(widget
)->active
) {
241 v_color
= SHOW_PEAKNR
;
245 if (display_act
->gpd
.exist_piv
&& display_act
->display_piv
) {
246 update_all_vectors(&display_act
->gpd
);
251 void on_radiobutton_valid_errvec_subst_enter(GtkWidget
* widget
, gpointer data
)
253 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
254 gchar
*msg
= _("Defines how to substitute the data");
255 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
260 void on_radiobutton_valid_errvec_subst(GtkWidget
* widget
, gpointer data
)
262 piv_valid_par
.subst_type
= atoi(gtk_object_get_data(GTK_OBJECT(widget
),
265 /* if (piv_valid_par.subst_type == L_MEAN) { */
266 /* fprintf(stderr, "subst_type L_MEAN\n"); */
267 /* } else if (piv_valid_par.subst_type == SUBTYPE_MEDIAN) { */
268 /* fprintf(stderr, "subst_type SUBTYPE_MEDIAN\n"); */
269 /* } else if (piv_valid_par.subst_type == COV_PEAK) { */
270 /* fprintf(stderr, "subst_type COV_PEAK\n"); */
272 /* fprintf(stderr, "NO valid subst_type\n"); */
279 on_button_valid_errvec_enter(GtkWidget
* widget
, gpointer data
)
281 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
282 gchar
*msg
= _("Examines PIV data on outliers and substitutes");
283 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
288 on_button_valid_errvec(GtkWidget
* widget
, gpointer data
)
290 PivValid
* valid
= gtk_object_get_data(GTK_OBJECT(widget
), "valid");
291 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
294 piv_valid_par
.res_stats
= 0;
297 for (row
= gpiv
->first_selected_row
; row
<= gpiv
->last_selected_row
;
299 display_act
= gtk_clist_get_row_data(GTK_CLIST(gpiv
->clist_buf
),
302 ibuf
= display_act
->count
;
303 if (display
[ibuf
] != NULL
304 && display_act
->mwin
!= NULL
305 && GTK_WIDGET_VISIBLE(GTK_WIDGET(display_act
->mwin
)) ) {
306 gdk_window_show(GTK_WIDGET(display_act
->mwin
)->window
);
307 gdk_window_raise(GTK_WIDGET(display_act
->mwin
)->window
);
316 void on_spinbutton_valid_peaklck_bins(GtkSpinButton
* widget
,
319 gpiv_par
.nbins
= gtk_spin_button_get_value_as_int(widget
);
324 void on_button_valid_peaklck_enter(GtkWidget
* widget
, gpointer data
)
326 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
327 gchar
*msg
= _("Calculates a histogram of sub-pixel displacements");
328 gnome_appbar_set_status(GNOME_APPBAR(gpiv
->appbar
), msg
);
333 void on_button_valid_peaklck(GtkWidget
* widget
, gpointer data
)
335 PivValid
* valid
= gtk_object_get_data(GTK_OBJECT(widget
), "valid");
336 GpivConsole
*gpiv
= gtk_object_get_data(GTK_OBJECT(widget
), "gpiv");
340 for (row
= gpiv
->first_selected_row
; row
<= gpiv
->last_selected_row
;
342 display_act
= gtk_clist_get_row_data(GTK_CLIST(gpiv
->clist_buf
),
345 ibuf
= display_act
->count
;
346 if (display
[ibuf
] != NULL
347 && display_act
->mwin
!= NULL
348 && GTK_WIDGET_VISIBLE(GTK_WIDGET(display_act
->mwin
)) ) {
349 gdk_window_show(GTK_WIDGET(display_act
->mwin
)->window
);
350 gdk_window_raise(GTK_WIDGET(display_act
->mwin
)->window
);
353 exec_peaklock(valid
);
361 * Other validation functions than callbacks
364 void exec_gradient(void)
365 /* -----------------------------------------------------------------
366 Testing on gradient of displacements/veocity within Int. Area */
368 if (display_act
->gpd
.exist_piv
&& !cancel_process
) {
370 /* g_warning("on_button_valid_gradient:: gpiv_valid_gradient"); */
371 gpiv_valid_gradient(piv_valid_par
,
373 &display_act
->gpd
.piv_data
);
374 /* g_warning("on_button_valid_gradient:: update_all_vectors"); */
375 update_all_vectors(&display_act
->gpd
);
376 exec_process
= FALSE
;
378 gtk_warning(_("no PIV data"));
380 /* g_warning("on_button_valid_gradient:: LEAVE"); */
385 void exec_errvec(PivValid
* valid
)
390 GnomeCanvasItem
*bg
, *bar
, *fitline
;
391 GnomeCanvasPoints
*points
;
392 double canvas_margin
= 20.;
394 double canvas_startx
= -50.;
395 double canvas_endx
= 150.;
396 double disp_width
= canvas_endx
- canvas_startx
- 2 * canvas_margin
;
398 double canvas_starty
= -50.;
399 double canvas_endy
= 150.;
400 double disp_height
= canvas_endy
- canvas_starty
- 2 * canvas_margin
;
402 double canvas_x1
= canvas_startx
+ canvas_margin
;
403 double canvas_y1
= canvas_starty
+ canvas_margin
+ disp_height
;
405 double x_val
, y_val
, x_normf
, y_normf
;
410 double centre_max
= -10.0E+9;
412 out_data
.point_x
= NULL
;
413 out_data
.point_y
= NULL
;
417 out_data
.peak_no
= NULL
;
430 points
= gnome_canvas_points_new(2);
433 if (display_act
->gpd
.exist_piv
&& !cancel_process
) {
435 out_data
.nx
= display_act
->gpd
.piv_data
.nx
;
436 out_data
.ny
= display_act
->gpd
.piv_data
.ny
;
437 gpiv_alloc_pivdata(&out_data
);
438 klass
.nbins
= out_data
.nx
* out_data
.ny
/ NBINS_DEFAULT
;
439 gpiv_alloc_bindata(&klass
);
441 if (piv_valid_par
.res_stats
== 1) {
442 /* g_warning(" exec_errvec:: will process err_vec res_stats nbins=%d", */
444 bg
= gnome_canvas_item_new(gnome_canvas_root
445 (GNOME_CANVAS(valid
->canvas_peaklck
)),
446 gnome_canvas_rect_get_type(),
447 "x1", (double) canvas_startx
,
448 "y1", (double) canvas_starty
,
449 "x2", (double) canvas_endx
,
450 "y2", (double) canvas_endy
,
451 "fill_color", "darkblue",
452 "outline_color", "red",
456 gpiv_valid_errvec(fname
, image_par
, piv_eval_par
, piv_valid_par
,
457 display_act
->gpd
.piv_data
, &out_data
, &klass
,
458 &linreg
, (int) display_act
->img
.exist_img
,
459 display_act
->img
.img1
, display_act
->img
.img2
);
461 /* --------------------------------------------------------------------
462 normalizing data between 0 and 1 and displaying histo and estimated
464 for (i
= 0; i
< klass
.nbins
; i
++) {
465 if (klass
.centre
[i
] > centre_max
)
466 centre_max
= klass
.centre
[i
];
469 x_normf
= (double) disp_width
/ (klass
.max
- klass
.min
);
470 y_normf
= (double) centre_max
;
472 for (i
= 0; i
< klass
.nbins
- 1; i
++) {
473 x_val
= (double) (klass
.bound
[i
]) / x_normf
;
474 y_val
= (double) klass
.centre
[i
] / y_normf
;
476 gnome_canvas_item_new(gnome_canvas_root
477 (GNOME_CANVAS(valid
->canvas_peaklck
)),
478 gnome_canvas_rect_get_type(),
480 (double) klass
.bound
[i
] * x_normf
,
482 (double) disp_height
* y_val
,
484 (double) klass
.bound
[i
+ 1] * x_normf
,
485 "y2", (double) canvas_y1
,
486 "fill_color", "darkgreen",
487 "outline_color", "blue",
492 piv_valid_par
.residu_max
=
493 gpiv_valid_threshold(display_act
->gpd
.piv_eval_par
,
494 piv_valid_par
, linreg
);
495 gtk_spin_button_set_value(GTK_SPIN_BUTTON
496 (valid
->spinbutton_errvec_res
),
497 piv_valid_par
.residu_max
);
501 points
->coords
[0] = (double) canvas_x1
;
502 points
->coords
[1] = (double) canvas_y1
503 - (double) linreg
.c0
/ y_normf
* (double) disp_height
505 points
->coords
[2] = (double) canvas_x1
506 + (double) disp_width
;
507 points
->coords
[3] = (double) canvas_y1
508 - (double) linreg
.c0
/ y_normf
* (double) disp_height
509 - (double) linreg
.c1
* (double) (disp_width
) * (double) (disp_height
)
510 / ( x_normf
* y_normf
)
513 /* points->coords[0] = (double) canvas_x1; */
514 /* points->coords[1] = (double) canvas_y1; */
515 /* points->coords[2] = (double) canvas_x1 + (double) disp_width; */
516 /* points->coords[3] = (double) canvas_y1 - (double) disp_height; */
519 gnome_canvas_item_new(gnome_canvas_root
520 (GNOME_CANVAS(valid
->canvas_peaklck
)),
521 gnome_canvas_line_get_type(),
524 "width_units", (double) 2.0,
528 /* g_warning(" exec_errvec:: err_vec with subst = %d", piv_valid_par.subst_type); */
529 gpiv_valid_errvec(fname
, image_par
, piv_eval_par
, piv_valid_par
,
530 display_act
->gpd
.piv_data
, &out_data
, &klass
,
531 &linreg
, (int) display_act
->img
.exist_img
,
532 display_act
->img
.img1
, display_act
->img
.img2
);
535 for (i
= 0; i
< out_data
.ny
; i
++) {
536 for (j
= 0; j
< out_data
.nx
; j
++) {
537 display_act
->gpd
.piv_data
.dx
[i
][j
] = out_data
.dx
[i
][j
];
538 display_act
->gpd
.piv_data
.dy
[i
][j
] = out_data
.dy
[i
][j
];
539 display_act
->gpd
.piv_data
.snr
[i
][j
] = out_data
.snr
[i
][j
];
540 display_act
->gpd
.piv_data
.peak_no
[i
][j
] = out_data
.peak_no
[i
][j
];
543 update_all_vectors(&display_act
->gpd
);
546 gpiv_free_bindata(&klass
);
547 gpiv_free_pivdata(&out_data
);
549 display_act
->gpd
.exist_valid
= TRUE
;
551 /* --------------------------------------------------------------------
552 Copy parameters in Buffer structure for saving and, eventual,
555 display_act
->gpd
.piv_valid_par
.auto_thresh
= piv_valid_par
.auto_thresh
;
556 display_act
->gpd
.piv_valid_par
.residu_max
= piv_valid_par
.residu_max
;
557 display_act
->gpd
.piv_valid_par
.res_stats
= piv_valid_par
.res_stats
;
558 display_act
->gpd
.piv_valid_par
.data_yield
= piv_valid_par
.data_yield
;
559 display_act
->gpd
.piv_valid_par
.residu_type
= piv_valid_par
.residu_type
;
560 display_act
->gpd
.piv_valid_par
.subst_type
= piv_valid_par
.subst_type
;
561 display_act
->gpd
.piv_valid_par
.histo_type
= piv_valid_par
.histo_type
;
563 display_act
->gpd
.piv_valid_par
.auto_thresh_logic
= 1;
564 display_act
->gpd
.piv_valid_par
.residu_max_logic
= 1;
565 display_act
->gpd
.piv_valid_par
.res_stats_logic
= 1;
566 display_act
->gpd
.piv_valid_par
.data_yield_logic
= piv_valid_par
.data_yield_logic
;
567 display_act
->gpd
.piv_valid_par
.residu_type_logic
= 1;
568 display_act
->gpd
.piv_valid_par
.subst_type_logic
= 1;
569 display_act
->gpd
.piv_valid_par
.histo_type_logic
= 1;
570 exec_process
= FALSE
;
573 gtk_warning(_("no PIV data"));
576 gnome_canvas_points_free(points
);
582 void exec_peaklock(PivValid
* valid
)
586 GnomeCanvasItem
*bg
, *bar
;
587 double canvas_margin
= 20.;
589 double canvas_startx
= -50.;
590 double canvas_endx
= 150.;
591 double d_width
= canvas_endx
- canvas_startx
- 2 * canvas_margin
;
593 double canvas_starty
= -50.;
594 double canvas_endy
= 150.;
595 double d_height
= canvas_endy
- canvas_starty
- 2 * canvas_margin
;
597 double canvas_x1
= canvas_startx
+ canvas_margin
;
598 double canvas_y1
= canvas_starty
+ canvas_margin
+ d_height
;
601 gint count_max
= -10000;
608 klass
.nbins
= gpiv_par
.nbins
;
610 if (display_act
->gpd
.exist_piv
&& !cancel_process
) {
612 /* g_warning("will process peaklock\n"); */
613 gpiv_alloc_bindata(&klass
);
616 gnome_canvas_item_new(gnome_canvas_root
617 (GNOME_CANVAS(valid
->canvas_peaklck
)),
618 gnome_canvas_rect_get_type(),
619 "x1", (double) canvas_startx
,
620 "y1", (double) canvas_starty
,
621 "x2", (double) canvas_endx
,
622 "y2", (double) canvas_endy
,
623 "fill_color", "darkgreen",
624 "outline_color", "red",
628 gpiv_valid_peaklck(display_act
->gpd
.piv_data
, &klass
);
630 /* --------------------------------------------------------------------
631 normalizing data between 0 and 1 */
632 for (i
= 0; i
< klass
.nbins
; i
++) {
633 if (klass
.count
[i
] > count_max
) count_max
= klass
.count
[i
];
636 for (i
= 0; i
< klass
.nbins
; i
++) {
637 y_val
= (double) klass
.count
[i
] / (double) count_max
;
639 gnome_canvas_item_new(gnome_canvas_root
640 (GNOME_CANVAS(valid
->canvas_peaklck
)),
641 gnome_canvas_rect_get_type(),
643 (double) klass
.bound
[i
] * d_width
,
645 (double) d_height
* y_val
,
647 (double) klass
.bound
[i
+1] * d_width
,
649 "fill_color", "yellow",
650 "outline_color", "blue",
655 gpiv_free_bindata(&klass
);
656 display_act
->gpd
.exist_valid
= TRUE
;
657 exec_process
= FALSE
;
660 gtk_warning(_("no PIV data"));