added piveval_interrogate routines
[gpiv.git] / src / piveval_interrogate.c
blob5098c47696a8860ccb87a25b7d4ac0ce6e0a4df4
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
6 libraries.
8 Copyright (C) 2006 Gerber van der Graaf
9 This file is part of gpiv.
11 Gpiv is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2, or (at your option)
14 any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software Foundation,
23 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 ----------------------------------------------------------------------*/
27 /* $Log: piveval_interrogate.c,v $
28 /* Revision 1.1 2008-09-16 10:17:36 gerber
29 /* added piveval_interrogate routines
33 #include "gpiv_gui.h"
34 /* #include "utils.h" */
35 #include "piveval.h"
36 #include "piveval_interrogate.h"
38 #undef USE_MTRACE
39 #ifdef USE_MTRACE
40 #include <mcheck.h>
41 #endif
44 static void
45 report_progress (const guint index_y,
46 const guint index_x,
47 gdouble *progress_value_prev,
48 const GpivPivData *piv_data,
49 const GpivPivPar *piv_par,
50 const guint sweep,
51 const gfloat cum_residu,
52 const GpivConsole *gpiv,
53 const Display *disp
56 static GpivPivData *
57 alloc_pivdata_gridgen (const GpivImagePar *image_par,
58 const GpivPivPar *piv_par
61 static gchar *
62 update_pivdata_imgdeform_zoff (const GpivImage *image,
63 GpivImage *lo_image,
64 const GpivPivPar *piv_par,
65 const GpivValidPar *valid_par,
66 GpivPivData *piv_data,
67 GpivPivData *lo_piv_data,
68 gfloat *cum_residu,
69 gboolean *cum_residu_reached,
70 gfloat *sum_dxdy,
71 gfloat *sum_dxdy_old,
72 gboolean isi_last,
73 gboolean grid_last,
74 gboolean sweep_last,
75 gboolean verbose
79 * Program-wide public piv interrogation functions
83 void
84 exec_piv (GpivConsole *gpiv
86 /*-----------------------------------------------------------------------------
89 char *err_msg = NULL;
90 char message[2 * GPIV_MAX_CHARS];
91 guint nx = 0, ny = 0;
94 if (display_act == NULL
95 || display_act->img->exist_img == FALSE
96 || cancel_process) {
97 err_msg =
98 _("At first, open an image. \n"
99 "Than we'll further see what will happen.");
100 g_warning (err_msg);
101 warning_gpiv (err_msg);
102 return;
106 * Free memory of pivdata and clean the display from its vectors
108 if (display_act->pida->exist_piv
109 /* && (m_select != SINGLE_AREA_MS */
110 /* || m_select != DRAG_AREA_MS) */
112 destroy_all_vectors (display_act->pida);
113 gpiv_free_pivdata (display_act->pida->piv_data);
114 display_act->pida->exist_piv = FALSE;
115 display_act->pida->averaged_piv = FALSE;
116 if (display_act->pida->scaled_piv) {
117 gpiv_free_pivdata (display_act->pida->piv_data_scaled);
118 display_act->pida->scaled_piv = FALSE;
123 * Free eventually existing memory of vor_data and cleanup the display
124 * as they do not belong to the piv data anymore
126 free_post_bufmems (display_act);
128 exec_process = TRUE;
131 * Set mouse selection to None for using correct AOI
133 /* if (m_select != NO_MS) { */
134 /* gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON */
135 /* (gpiv->piveval->radiobutton_mouse_1), */
136 /* TRUE); */
137 /* } */
140 * Setting interrogation scheme to GPIV_ZERO_OFF_CENTRAL if image deformation
141 * is impossible with too small (initial or final) grid.
143 if (gl_piv_par->int_scheme == GPIV_IMG_DEFORM) {
144 gpiv_piv_count_pivdata_fromimage (display_act->img->image->header,
145 gl_piv_par, &nx, &ny);
146 if (nx < 2 || ny < 2) {
147 g_snprintf (message, 2 * GPIV_MAX_CHARS,
148 _("Image deformation is impossibe with grid of nx = %d ny =%d.\n\
149 Setting Interrogation scheme to Central difference.\n \
150 This will be reset automatically."),
151 nx, ny);
152 warning_gpiv ("%s", message);
153 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON
154 (gpiv->piveval->radiobutton_centraldiff),
155 TRUE);
156 int_scheme_autochanged = TRUE;
161 * checking parameters and interrogating image by local function
163 display_act->pida->piv_par = gpiv_piv_cp_parameters (gl_piv_par);
164 if ((err_msg =
165 gpiv_piv_testadjust_parameters (display_act->img->image->header,
166 display_act->pida->piv_par))
167 != NULL) {
168 warning_gpiv ("%s", err_msg);
169 return;
172 display_act->pida->valid_par = gpiv_valid_cp_parameters (gl_valid_par);
173 gpiv_valid_print_parameters (stdout, display_act->pida->valid_par);
174 if ((err_msg =
175 gpiv_valid_testadjust_parameters (display_act->pida->valid_par))
176 != NULL) {
177 warning_gpiv ("%s", err_msg);
178 return;
180 gpiv_valid_print_parameters (stdout, display_act->pida->valid_par);
182 if ((display_act->pida->piv_data =
183 #define USE_MY_INTERR
184 #ifdef USE_MY_INTERR
185 /* Gpiv's own function for image interrogation */
186 interrogate_img (display_act->img->image,
187 display_act->pida->piv_par,
188 display_act->pida->valid_par,
189 gpiv)
190 #else
191 /* Library function */
192 gpiv_piv_interrogate_img (display_act->img->image,
193 display_act->pida->piv_par,
194 display_act->pida->valid_par,
195 TRUE)
196 #endif
197 #ifdef USE_MY_INTERR
198 #undef USE_MY_INTERR
199 #endif
200 ) == NULL) {
201 warning_gpiv ("exec_piv: failing interrogate_img");
202 return;
204 display_act->pida->exist_piv = TRUE;
207 * Adding some comment to piv_data
209 display_act->pida->piv_data->comment =
210 g_strdup_printf ("# Software: %s %s\n", PACKAGE, VERSION);
211 display_act->pida->piv_data->comment =
212 gpiv_add_datetime_to_comment (display_act->pida->piv_data->comment);
213 display_act->pida->piv_data->comment =
214 g_strconcat (display_act->pida->piv_data->comment,
215 "# Data type: Particle Image Velocities\n", NULL);
218 * Drawing and displaying PIV vectors
220 if (gl_piv_par->int_geo == GPIV_POINT
221 || m_select == SINGLE_AREA_MS
222 || m_select == SINGLE_POINT_MS
223 || m_select == DRAG_MS) {
224 } else {
225 if (display_act->display_piv) {
226 create_all_vectors (display_act->pida);
228 display_act->display_piv = TRUE;
232 * Some settings for displaying features
233 * Update vectors to correct for colors/gray-scale
235 display_act->pida->scaled_piv = FALSE;
236 display_act->pida->saved_piv = FALSE;
237 display_act->pida->averaged_piv = FALSE;
238 display_act->pida->exist_cov = TRUE;
239 update_all_vectors (display_act->pida);
240 exec_process = FALSE;
243 * Resetting interrogation scheme
245 if (int_scheme_autochanged) {
246 int_scheme_autochanged = FALSE;
247 gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON
248 (gpiv->piveval->radiobutton_imgdeform),
249 TRUE);
252 gtk_progress_set_value (GTK_PROGRESS (gnome_appbar_get_progress
253 (GNOME_APPBAR (gpiv->appbar))),
254 0.0);
259 GpivPivData *
260 interrogate_img (const GpivImage *image,
261 const GpivPivPar *piv_par,
262 const GpivValidPar *valid_par,
263 GpivConsole *gpiv
265 /* ----------------------------------------------------------------------------
266 * PIV interrogation of an image pair at an entire grid or single point
267 * Similar to gpiv_piv_interr_img, but adapted for the GUI
270 GpivPivData *piv_data = NULL; /* piv data to be returned */
271 gchar *err_msg = NULL; /* error message */
272 guint index_x = 0, index_y = 0; /* array indices */
275 * Local variables with prefix lo_ to distinguish from global or from
276 * parameter list
278 GpivImage *lo_image = NULL; /* local image that might be deformed */
279 GpivPivData *lo_piv_data = NULL; /* local piv data */
280 GpivPivPar *lo_piv_par = NULL; /* local piv parameters */
282 gfloat **intreg1 = display_act->pida->intreg1; /* first interrogation area */
283 gfloat **intreg2 = display_act->pida->intreg2; /* second interrogation area */
284 guint int_size_0; /* zero-padded interrogation area size */
286 GpivCov *cov = NULL; /* covariance */
287 guint sweep = 1; /* itaration counter */
288 gboolean grid_last = FALSE; /* flag if final grid refinement has been reached */
289 gboolean isi_last = FALSE; /* flag if final interrogation area shift has been reached */
290 gboolean cum_residu_reached = FALSE;/* flag if max. cumulative residu has been reached */
291 gboolean sweep_last = FALSE; /* perform the last iteration sweep */
292 gboolean sweep_stop = FALSE; /* stop the current iteration at the end */
293 gfloat sum_dxdy = 0.0, sum_dxdy_old = 0.0; /* */
294 gfloat cum_residu = 914.6; /* initial, large, arbitrary cumulative residu */
295 gdouble progress = 0.0; /* for monitoring calculation progress */
299 * Testing parameters on consistency and initializing derived
300 * parameters/variables
302 if ((err_msg =
303 gpiv_piv_testonly_parameters (image->header, piv_par))
304 != NULL) {
305 warning_gpiv ("%s", err_msg);
306 return NULL;
309 if ((err_msg =
310 gpiv_valid_testonly_parameters (valid_par))
311 != NULL) {
312 warning_gpiv ("%s", err_msg);
313 return NULL;
317 * Local (actualized) parameters
318 * Setting initial parameters and variables for adaptive grid and
319 * Interrogation Area dimensions
321 lo_piv_par = gpiv_piv_cp_parameters (piv_par);
323 if (lo_piv_par->int_scheme == GPIV_ZERO_OFF_FORWARD
324 || lo_piv_par->int_scheme == GPIV_ZERO_OFF_CENTRAL
325 || lo_piv_par->int_scheme == GPIV_IMG_DEFORM
326 || lo_piv_par->int_size_i > lo_piv_par->int_size_f) {
327 lo_piv_par->int_size_f = lo_piv_par->int_size_i;
328 sweep_last = FALSE;
329 } else {
330 sweep_last = TRUE;
333 if (lo_piv_par->int_shift < lo_piv_par->int_size_i / GPIV_SHIFT_FACTOR) {
334 lo_piv_par->int_shift = lo_piv_par->int_size_i / GPIV_SHIFT_FACTOR;
338 * A copy of the image and PIV data are needed when image deformation is used.
339 * To keep the algorithm simple, copies are made unconditionally.
341 lo_image = gpiv_cp_img (image);
342 piv_data = alloc_pivdata_gridgen (image->header, lo_piv_par);
343 lo_piv_data = gpiv_cp_pivdata (piv_data);
344 gpiv_0_pivdata (lo_piv_data);
347 * Reads eventually existing fftw wisdom
349 gpiv_fread_fftw_wisdom(1);
350 gpiv_fread_fftw_wisdom(-1);
352 #ifdef USE_MTRACE
353 mtrace();
354 #endif
356 while (sweep <= GPIV_MAX_PIV_SWEEP
357 && !sweep_stop
358 && !cancel_process) {
361 * Memory allocation of interrogation area's and covariance.
362 * These memory chunks are allocated here to optimize calculation
363 * speed and for eventually monitoring their contents.
365 int_size_0 = GPIV_ZEROPAD_FACT * lo_piv_par->int_size_i;
366 intreg1 = gpiv_matrix (int_size_0, int_size_0);
367 intreg2 = gpiv_matrix (int_size_0, int_size_0);
368 cov = gpiv_alloc_cov (int_size_0, image->header->x_corr);
369 display_act->pida->cov = cov;
372 * Interrogates a single interrogation area
374 if (m_select != SINGLE_AREA_MS
375 && m_select != DRAG_MS) {
376 destroy_all_vectors (display_act->pida);
377 gnome_canvas_update_now (GNOME_CANVAS (display_act->canvas));
380 if (lo_piv_par->int_geo == GPIV_POINT
381 || m_select == SINGLE_AREA_MS
382 || m_select == SINGLE_POINT_MS
383 || m_select == DRAG_MS) {
385 if ((err_msg =
386 gpiv_piv_interrogate_ia (m_select_index_y,
387 m_select_index_x,
388 lo_image,
389 lo_piv_par,
390 sweep,
391 sweep_last,
392 intreg1,
393 intreg2,
394 cov,
395 lo_piv_data
397 != NULL) {
398 gpiv_free_img (lo_image);
399 gpiv_free_pivdata (lo_piv_data);
400 gpiv_free_pivdata (piv_data);
401 gpiv_free_matrix (intreg1);
402 gpiv_free_matrix (intreg2);
403 gpiv_free_cov (cov);
404 error_gpiv ("interrogate_img: %s", err_msg);
408 * display piv values, draw interrogation areas and
409 * covariance function
411 if (gpiv_var->piv_disproc == TRUE) {
412 display_piv_vector (m_select_index_y,
413 m_select_index_x,
414 piv_data,
415 gpiv->piveval);
416 display_img_intreg1 (intreg1,
417 lo_piv_par->int_size_i,
418 gpiv->piveval);
419 display_img_intreg2 (intreg2,
420 lo_piv_par->int_size_i,
421 gpiv->piveval);
422 display_img_cov (cov,
423 lo_piv_par->int_size_i,
424 gpiv->piveval);
428 } else {
431 * Interrogates at a rectangular grid of points within the Area Of
432 * Interest of the image
434 for (index_y = 0; index_y < lo_piv_data->ny; index_y++) {
435 for (index_x = 0; index_x < lo_piv_data->nx; index_x++) {
436 if (cancel_process) break;
439 * Interrogates a single interrogation area.
441 if ((err_msg =
442 gpiv_piv_interrogate_ia (index_y,
443 index_x,
444 lo_image,
445 lo_piv_par,
446 sweep,
447 sweep_last,
448 intreg1,
449 intreg2,
450 cov,
451 lo_piv_data
453 != NULL) {
454 gpiv_free_img (lo_image);
455 gpiv_free_pivdata (lo_piv_data);
456 gpiv_free_pivdata (piv_data);
457 gpiv_free_matrix (intreg1);
458 gpiv_free_matrix (intreg2);
459 gpiv_free_cov (cov);
460 error_gpiv ("interrogate_img: %s", err_msg);
463 #ifdef DEBUG
464 gpiv_warning("interrogate_img:: back from gpiv_piv_interr_ia: sweep=%d x[%d][%d]=%f y[%d][%d]=%f dx[%d][%d]=%f dy[%d][%d]=%f snr=%f p_no=%d",
465 sweep,
466 index_y, index_x, lo_piv_data->point_x[index_y][index_x],
467 index_y, index_x, lo_piv_data->point_y[index_y][index_x],
468 index_y, index_x, lo_piv_data->dx[index_y][index_x],
469 index_y, index_x, lo_piv_data->dy[index_y][index_x],
470 lo_piv_data->snr[index_y][index_x],
471 lo_piv_data->peak_no[index_y][index_x]
473 #endif
475 * Printing the progress of processing
477 report_progress (index_y,
478 index_x,
479 &progress,
480 piv_data,
481 lo_piv_par,
482 sweep,
483 cum_residu,
484 gpiv,
485 display_act
488 * Draw interrogation areas, covariance function,
489 * display piv vector to monitor the process.
490 * Includes report_rogress to include
491 * as an argument in gpiv_piv_interr_img
493 if (gpiv_var->piv_disproc == TRUE) {
494 display_piv_vector (index_y,
495 index_x,
496 piv_data,
497 gpiv->piveval);
498 display_img_intreg1 (intreg1,
499 lo_piv_par->int_size_i,
500 gpiv->piveval);
501 display_img_intreg2 (intreg2,
502 lo_piv_par->int_size_i,
503 gpiv->piveval);
504 display_img_cov (cov,
505 lo_piv_par->int_size_i,
506 gpiv->piveval);
516 * De-allocating memory: other (smaller) sizes are eventually needed
517 * for a next iteration sweep
519 gpiv_free_matrix (intreg1);
520 gpiv_free_matrix (intreg2);
521 gpiv_free_cov (cov);
523 if (sweep_last) {
524 sweep_stop = TRUE;
527 if ((lo_piv_par->int_scheme == GPIV_IMG_DEFORM
528 || lo_piv_par->int_scheme == GPIV_ZERO_OFF_FORWARD
529 || lo_piv_par->int_scheme == GPIV_ZERO_OFF_CENTRAL)
530 /* BUGFIX: crashes with single point */
531 && (lo_piv_par->int_geo != GPIV_POINT
532 && m_select != SINGLE_AREA_MS
533 && m_select != SINGLE_POINT_MS
534 && m_select != DRAG_MS)
537 if ((err_msg =
538 update_pivdata_imgdeform_zoff (image, lo_image,
539 lo_piv_par, valid_par,
540 piv_data, lo_piv_data,
541 &cum_residu,
542 &cum_residu_reached,
543 &sum_dxdy, &sum_dxdy_old,
544 isi_last, grid_last,
545 sweep_last, gpiv_par->verbose))
546 != NULL) {
547 g_warning ("GPIV_PIV_INTERR_IMG: %s", err_msg);
548 gpiv_free_img (lo_image);
549 gpiv_free_pivdata (lo_piv_data);
550 gpiv_free_pivdata (piv_data);
551 return NULL;
554 } else {
557 * Apply results to output piv_data
559 gpiv_free_pivdata (piv_data);
560 piv_data = gpiv_cp_pivdata (lo_piv_data);
561 cum_residu_reached = TRUE;
565 * Adapt grid.
566 * If final grid has been reached, grid_last will be set.
568 if (lo_piv_par->int_shift > piv_par->int_shift
569 && !sweep_stop) {
570 GpivPivData *pd = NULL;
572 pd = gpiv_piv_gridadapt (image->header,
573 piv_par,
574 lo_piv_par,
575 piv_data,
576 sweep,
577 &grid_last);
578 gpiv_free_pivdata (piv_data);
579 piv_data = gpiv_cp_pivdata (pd);
580 gpiv_free_pivdata (pd);
582 gpiv_free_pivdata (lo_piv_data);
583 lo_piv_data = gpiv_cp_pivdata (piv_data);
585 if (lo_piv_par->int_scheme == GPIV_IMG_DEFORM) {
586 gpiv_0_pivdata (lo_piv_data);
589 } else {
590 grid_last = TRUE;
594 * Adapt interrogation area size.
595 * If final size has been reached, isi_last will be set.
597 gpiv_piv_isizadapt (piv_par,
598 lo_piv_par,
599 &isi_last);
601 if (cum_residu_reached && isi_last && grid_last) {
602 sweep_last = TRUE;
603 /* if (lo_piv_par->int_scheme == GPIV_ZERO_OFF_FORWARD */
604 /* || lo_piv_par->int_scheme == GPIV_ZERO_OFF_CENTRAL) { */
605 /* lo_piv_par->ifit = piv_par->ifit; */
606 /* } */
608 sweep++;
612 * Writes existing fftw wisdom
614 gpiv_fwrite_fftw_wisdom (1);
615 gpiv_fwrite_fftw_wisdom (-1);
616 fftw_forget_wisdom();
617 fftw_cleanup ();
619 #ifdef USE_MTRACE
620 muntrace();
621 #endif
622 gpiv_free_img (lo_image);
623 gpiv_free_pivdata (lo_piv_data);
626 return piv_data;
632 * Private piv interrogation functions
634 static GpivPivData *
635 alloc_pivdata_gridgen (const GpivImagePar *image_par,
636 const GpivPivPar *piv_par
638 /*-----------------------------------------------------------------------------
639 * Determining the number of grid points, allocating memory for output data
640 * and calculate locations of Interrogation Area's. If ad_int is enabled, a
641 * course grid is started with and adapted for subsequent sweeps.
642 ----------------------------------------------------------------------------*/
644 GpivPivData *piv_data = NULL;
645 gchar *err_msg = NULL;
646 GpivPivPar *lo_piv_par = NULL;
647 guint nx, ny;
650 if ((lo_piv_par = gpiv_piv_cp_parameters (piv_par)) == NULL) {
651 gpiv_error ("alloc_pivdata_gridgen: failing gpiv_piv_cp_parameters");
654 if (piv_par->int_size_i > piv_par->int_size_f
655 && piv_par->int_shift < piv_par->int_size_i / GPIV_SHIFT_FACTOR) {
656 lo_piv_par->int_shift = lo_piv_par->int_size_i / GPIV_SHIFT_FACTOR;
659 if ((err_msg =
660 gpiv_piv_count_pivdata_fromimage (image_par, lo_piv_par, &nx, &ny))
661 != NULL) {
662 warning_gpiv ("%s", err_msg);
663 return NULL;
667 if ((piv_data = gpiv_piv_gridgen (nx, ny, image_par, lo_piv_par))
668 == NULL) error_gpiv ("%s: %s", RCSID, err_msg);
671 return piv_data;
676 static void
677 report_progress (const guint index_y,
678 const guint index_x,
679 gdouble *progress_value_prev,
680 const GpivPivData *piv_data,
681 const GpivPivPar *piv_par,
682 const guint sweep,
683 const gfloat cum_residu,
684 const GpivConsole *gpiv,
685 const Display *disp
687 /*-----------------------------------------------------------------------------
688 * Calculates progress of interrogation processing and other variables
689 * and prints to message bar of the console if progress value has been changed
692 gchar progress_string[GPIV_MAX_CHARS];
693 gdouble progress_value = 100 * (index_y * piv_data->nx + index_x +1) /
694 (piv_data->nx * piv_data->ny);
697 if (progress_value != *progress_value_prev) {
698 *progress_value_prev = progress_value;
699 if (piv_par->int_scheme == GPIV_ZERO_OFF_FORWARD
700 || piv_par->int_scheme == GPIV_ZERO_OFF_CENTRAL
701 || piv_par->int_scheme == GPIV_IMG_DEFORM) {
702 if (piv_par->int_size_i > piv_par->int_size_f /* substitutes ad_int == TRUE */
705 g_snprintf (progress_string, GPIV_MAX_CHARS,
706 "Interrogating image #%d:"
707 " sweep #%d"
708 " size=%d"
709 " shift=%d"
710 " residu=%.3f"
712 disp->id,
713 sweep,
714 piv_par->int_size_i,
715 piv_par->int_shift,
716 cum_residu
719 } else {
721 g_snprintf (progress_string, GPIV_MAX_CHARS,
722 "Interrogating image #%d:"
723 " sweep #%d"
724 " shift=%d"
725 " residu=%.3f"
727 disp->id,
728 sweep,
729 piv_par->int_shift,
730 cum_residu
736 } else {
738 g_snprintf (progress_string, GPIV_MAX_CHARS,
739 "Interrogating image #%d: "
740 " shift=%d "
742 disp->id,
743 piv_par/* _dest */ ->int_shift
747 while (g_main_context_iteration (NULL, FALSE));
748 gtk_progress_set_value (GTK_PROGRESS (gnome_appbar_get_progress
749 (GNOME_APPBAR (gpiv->appbar))),
750 progress_value);
752 gnome_appbar_set_status (GNOME_APPBAR(gpiv->appbar),
753 progress_string);
759 static gchar *
760 update_pivdata_imgdeform_zoff (const GpivImage *image,
761 GpivImage *lo_image,
762 const GpivPivPar *piv_par,
763 const GpivValidPar *valid_par,
764 GpivPivData *piv_data,
765 GpivPivData *lo_piv_data,
766 gfloat *cum_residu,
767 gboolean *cum_residu_reached,
768 gfloat *sum_dxdy,
769 gfloat *sum_dxdy_old,
770 gboolean isi_last,
771 gboolean grid_last,
772 gboolean sweep_last,
773 gboolean verbose
775 /*-----------------------------------------------------------------------------
776 * Validates and updates / renews pivdata and some other variables when image
777 * deformation or zero-offset interrogation scheme is used
781 gchar *err_msg = NULL;
785 * Test on outliers
787 if ((err_msg =
788 gpiv_valid_errvec (lo_piv_data,
789 image,
790 piv_par,
791 valid_par,
792 TRUE))
793 != NULL) {
794 return err_msg;
798 if (piv_par->int_scheme == GPIV_IMG_DEFORM) {
801 * Update PIV estimators with those from the last interrogation
802 * Resetting local PIV estimators for eventual next interrogation
804 if ((err_msg = gpiv_add_dxdy_pivdata (lo_piv_data, piv_data))
805 != NULL) {
806 return err_msg;
809 if ((err_msg = gpiv_0_pivdata (lo_piv_data))
810 != NULL) {
811 return err_msg;
815 * Deform image with updated PIV estimators.
816 * First, copy local from original image.
817 * Deform with newly updated PIV estimators.
818 * Eventually write deformed image.
821 if ((err_msg = gpiv_cp_img_data (image, lo_image))
822 != NULL) {
823 return err_msg;
826 if ((err_msg = gpiv_imgproc_deform (lo_image, piv_data))
827 != NULL) {
828 return err_msg;
830 /* #define DEBUG */
831 #ifdef DEBUG
832 if (sweep_last && verbose) {
833 printf ("\n");
834 if ((err_msg =
835 gpiv_piv_write_deformed_image (lo_image))
836 != NULL) {
837 return err_msg;
840 #endif /* DEBUG */
841 /* #undef DEBUG */
843 } else {
846 * Renew PIV estimators with those from the last interrogation
848 if ((err_msg = gpiv_0_pivdata (piv_data))
849 != NULL) {
850 return err_msg;
852 if ((err_msg = gpiv_add_dxdy_pivdata (lo_piv_data, piv_data))
853 != NULL) {
854 return err_msg;
859 * Checking the relative cumulative residu for convergence
860 * if final residu has been reached, cum_residu_reached will be set.
862 if (isi_last && grid_last) {
863 *sum_dxdy_old = *sum_dxdy;
864 *sum_dxdy = 0.0;
865 gpiv_sum_dxdy_pivdata (piv_data, sum_dxdy);
866 *cum_residu = fabsf ((*sum_dxdy - *sum_dxdy_old) /
867 ((gfloat)piv_data->nx * (gfloat)piv_data->ny));
868 if (*cum_residu < GPIV_CUM_RESIDU_MIN) {
869 *cum_residu_reached = TRUE;
874 return err_msg;