170 #include <uves_utils_cpl.h>
172 #include <uves_utils.h>
173 #include <uves_utils_wrappers.h>
174 #include <uves_dump.h>
175 #include <uves_error.h>
181 static cpl_image *
filter_median(
const cpl_image *image,
int radx,
int rady,
182 bool extrapolate_border);
205 assure( number >= 0, CPL_ERROR_ILLEGAL_INPUT,
"Number (%d) must be non-negative",
208 for (i = 0; i < size; i++)
212 if (strcmp(cpl_property_get_name(p), name) == 0)
252 cpl_image *aux = NULL;
253 double *image_data = NULL;
254 double *aux_data = NULL;
260 assure( image != NULL, CPL_ERROR_NULL_INPUT,
"Null image");
261 assure( radius_x >= 0, CPL_ERROR_ILLEGAL_INPUT,
"Negative x-radius (%d)", radius_x);
262 assure( radius_y >= 0, CPL_ERROR_ILLEGAL_INPUT,
"Negative y-radius (%d)", radius_y);
263 assure( cpl_image_get_type(image) == CPL_TYPE_DOUBLE, CPL_ERROR_TYPE_MISMATCH,
266 nx = cpl_image_get_size_x(image);
267 ny = cpl_image_get_size_y(image);
268 image_data = cpl_image_get_data_double(image);
281 aux = cpl_image_new(nx+1, ny+1, CPL_TYPE_DOUBLE);
282 aux_data = cpl_image_get_data(aux);
292 for (i = 0; i < (nx+1)*(ny+1); i++)
297 if ( x >= 1 && y >= 1)
299 aux_data[x + y*(nx+1)] = image_data[x-1 + (y-1) * nx]
300 + aux_data [x-1 + y * (nx+1)]
301 + aux_data [x + (y-1)* (nx+1)]
302 - aux_data [x-1 + (y-1)* (nx+1)];
325 uves_msg_debug(
"Finished setting up auxillary image. Get average");
328 for (i = 0; i < nx*ny; i++)
336 lower = y - radius_y;
if (lower < 0) lower = 0;
337 upper = y + radius_y;
if (upper >= ny) upper = ny - 1;
339 left = x - radius_x;
if (left < 0) left = 0;
340 right = x + radius_x;
if (right >= nx) right = nx - 1;
342 image_data[x + y*nx] =
344 aux_data[(right+1) + (upper+1)*(nx+1)] +
345 aux_data[ left + lower *(nx+1)] -
346 aux_data[ left + (upper+1)*(nx+1)] -
347 aux_data[(right+1) + lower *(nx+1)]
350 ( (
double) (upper-lower+1) * (right-left+1) );
354 uves_free_image(&aux);
355 return cpl_error_get_code();
377 cpl_matrix *
id = NULL;
378 cpl_image *temp = NULL;
380 assure( xwindow >= 0 && ywindow >= 0, CPL_ERROR_ILLEGAL_INPUT,
381 "Illegal window radius: %d x %d",
385 UVES_TIME_START(
"median filter");
387 if (xwindow <= 1 && ywindow <= 1)
390 check((
id = cpl_matrix_new(2*xwindow+1, 2*ywindow+1),
391 cpl_matrix_fill(
id, 1)),
"Could not create kernel matrix");
394 if (cpl_image_get_type(*image) == CPL_TYPE_INT)
396 temp = cpl_image_cast(*image, CPL_TYPE_DOUBLE);
397 uves_free_image(image);
401 temp = cpl_image_duplicate(*image);
402 uves_free_image(image);
404 check( *image = uves_image_filter_median(temp,
id),
"Error applying median filter");
405 uves_free_image(&temp);
414 "Error applying median filter");
415 uves_free_image(&temp);
421 uves_free_matrix(&
id);
422 uves_free_image(&temp);
423 return cpl_error_get_code();
427 #define DOUBLE_SWAP(a,b) { register double t=(a);(a)=(b);(b)=t; }
445 register int i, j, l, m ;
456 DOUBLE_SWAP(a[i],a[j]) ;
516 filter_median(
const cpl_image *image,
int radx,
int rady,
bool extrapolate_border)
519 int nx = cpl_image_get_size_x(image);
520 int ny = cpl_image_get_size_y(image);
521 cpl_image *result = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
523 const double *image_data;
524 double *window = NULL;
526 window = cpl_malloc(
sizeof(
double) * (2*radx+1)*(2*rady+1));
528 assure( cpl_image_get_type(image) == CPL_TYPE_DOUBLE,
529 CPL_ERROR_UNSUPPORTED_MODE,
"Type is %s",
532 result_data = cpl_image_get_data_double(result);
533 image_data = cpl_image_get_data_double_const(image);
535 for (y = 1; y <= ny; y++)
537 for (x = 1; x <= nx; x++)
541 x1 = x - radx; y_1 = y - rady;
542 x2 = x + radx; y2 = y + rady;
544 if (extrapolate_border)
573 result_data[(x-1) + (y-1)*nx] =
574 cpl_image_get_median_window(image,
576 uves_max_int(1, y_1),
577 uves_min_int(nx, x2),
578 uves_min_int(ny, y2));
586 for (j = uves_max_int(1 , y_1)-1;
587 j <= uves_min_int(ny, y2 )-1;
589 for (i = uves_max_int(1, x1)-1;
590 i <= uves_min_int(nx, x2)-1;
593 window[k++] = image_data[i + j*nx];
596 result_data[(x-1) + (y-1)*nx] =
604 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
605 "Error calculating %dx%d median filter", radx, rady);
647 double *x0,
double *y_0,
double *sigmax,
double *sigmay,
649 double *dx0,
double *dy0
652 cpl_image *marginal_x = NULL;
653 cpl_image *marginal_y = NULL;
654 cpl_image *marginal_x_noise = NULL;
655 cpl_image *marginal_y_noise = NULL;
656 cpl_image *variance = NULL;
657 cpl_matrix *covariance = NULL;
660 double norm_x, norm_y;
661 double background_x, background_y;
664 assure( image != NULL, CPL_ERROR_NULL_INPUT,
"Null image");
665 nx = cpl_image_get_size_x(image);
666 ny = cpl_image_get_size_y(image);
667 assure( noise != NULL || (dx0 == NULL && dy0 == NULL), CPL_ERROR_INCOMPATIBLE_INPUT,
668 "Cannot compute uncertainty of fit with no noise image specified");
669 assure( noise == NULL ||
670 (cpl_image_get_size_x(noise) == nx &&
671 cpl_image_get_size_y(noise) == ny),
672 CPL_ERROR_INCOMPATIBLE_INPUT,
673 "Size of input image (%dx%d) and noise image (%" CPL_SIZE_FORMAT
"x%" CPL_SIZE_FORMAT
") differ",
675 cpl_image_get_size_x(noise),
676 cpl_image_get_size_y(noise));
677 assure( 1 <= x1 && x1 <= x2 && x2 <= nx &&
678 1 <= y_1 && y_1 <= y2 && y2 <= ny, CPL_ERROR_ILLEGAL_INPUT,
679 "Illegal window: (%d, %d)-(%d, %d)", x1, y_1, x2, y2);
680 assure( x0 != NULL, CPL_ERROR_NULL_INPUT,
"Null x-center");
681 assure( y_0 != NULL, CPL_ERROR_NULL_INPUT,
"Null y-center");
682 assure( sigmax != NULL, CPL_ERROR_NULL_INPUT,
"Null sigma_x");
683 assure( sigmay != NULL, CPL_ERROR_NULL_INPUT,
"Null sigma_y");
689 check(( variance = cpl_image_extract(noise, x1, y_1, x2, y2),
690 cpl_image_power(variance, 2.0)),
691 "Error creating variance image");
695 check( marginal_x = cpl_image_collapse_window_create(image,
698 "Error collapsing window (%d, %d) - (%d, %d)", x1, y_1, x2, y2);
704 check( marginal_x_noise = cpl_image_collapse_window_create(variance,
708 "Error collapsing window (1, 1) - (%d, %d)", x2-x1+1, y2-y_1+1);
711 cpl_image_power(marginal_x_noise, 0.5);
715 check( marginal_y = cpl_image_collapse_window_create(image,
718 "Error collapsing window (%d, %d) - (%d, %d)", x1, y_1, x2, y2);
722 check( marginal_y_noise = cpl_image_collapse_window_create(variance,
726 "Error collapsing window (1, 1) - (%d, %d)", x2-x1+1, y2-y_1+1);
729 cpl_image_power(marginal_y_noise, 0.5);
733 uves_fit_1d_image(marginal_x, marginal_x_noise, NULL,
737 x0, sigmax, &norm_x, &background_x, NULL,
739 (dx0 != NULL) ? &covariance : NULL,
743 assure( cpl_error_get_code() != CPL_ERROR_CONTINUE ||
744 cpl_error_get_code() != CPL_ERROR_SINGULAR_MATRIX,
745 CPL_ERROR_CONTINUE,
"Fitting along x failed");
746 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
747 "Fitting along x failed");
754 *dx0 = cpl_matrix_get(covariance, 0, 0);
759 uves_free_matrix(&covariance);
760 uves_fit_1d_image(marginal_y, marginal_y_noise, NULL,
764 y_0, sigmay, &norm_y, &background_y, NULL,
766 (dy0 != NULL) ? &covariance : NULL,
770 assure( cpl_error_get_code() != CPL_ERROR_CONTINUE ||
771 cpl_error_get_code() != CPL_ERROR_SINGULAR_MATRIX,
772 CPL_ERROR_CONTINUE,
"Fitting along y failed");
773 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
774 "Fitting along y failed");
781 *dy0 = cpl_matrix_get(covariance, 0, 0);
789 if (amplitude != NULL)
791 *amplitude = sqrt(norm_x * norm_y) / (2*M_PI * (*sigmax) * (*sigmay));
795 uves_free_matrix(&covariance);
796 uves_free_image(&variance);
797 uves_free_image(&marginal_x);
798 uves_free_image(&marginal_x_noise);
799 uves_free_image(&marginal_y);
800 uves_free_image(&marginal_y_noise);
802 return cpl_error_get_code();