42 #include <uves_backsub.h>
44 #include <uves_parameters.h>
45 #include <uves_pfits.h>
46 #include <uves_dump.h>
47 #include <uves_utils.h>
48 #include <uves_utils_wrappers.h>
49 #include <uves_utils_cpl.h>
50 #include <uves_error.h>
61 static int first_order(
const polynomial *order_locations,
int nx);
62 static int last_order (
const polynomial *order_locations,
int nx,
int ny);
63 static cpl_error_code lower_to_average(cpl_image *image,
int RADX,
int RADY);
64 static double sample_background(
const cpl_image *image,
int x0,
double y_0,
65 int radius_x,
int radius_y,
int nx,
int ny,
66 background_measure_method BM_METHOD);
67 static cpl_error_code subtract_background(cpl_image *image, cpl_image *background_im,
80 #define BACKSUB_FLAT_SMOOTHX_BLUE (25.0/4096)
81 #define BACKSUB_FLAT_SMOOTHX_RED (50.0/4096)
82 #define BACKSUB_FLAT_SMOOTHY_BLUE (100.0/2048)
83 #define BACKSUB_FLAT_SMOOTHY_RED (300.0/2048)
85 #define BACKSUB_SCI_SMOOTHX_BLUE (300.0/4096)
86 #define BACKSUB_SCI_SMOOTHX_RED (300.0/4096)
87 #define BACKSUB_SCI_SMOOTHY_BLUE (200.0/2048)
88 #define BACKSUB_SCI_SMOOTHY_RED (500.0/2048)
90 #define BACKSUB_SMOOTHY_WLEN 859.9
109 uves_backsub_define_parameters(
void)
112 char *full_name = NULL;
113 cpl_parameterlist *parameters = NULL;
114 cpl_parameter *p = NULL;
116 parameters = cpl_parameterlist_new();
119 const char* name =
"mmethod";
120 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
122 uves_parameter_new_enum(p, full_name,
124 "Background measuring method. If equal to 'median' "
125 "the background is sampled using the median of a subwindow. "
126 "If 'minimum', the subwindow minimum value is used. "
127 "If 'no', no background subtraction is done.",
131 "median",
"minimum",
"no");
132 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
133 cpl_parameterlist_append(parameters, p);
138 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
139 uves_parameter_new_range(p, full_name,
141 "This is the number of columns in interorder space "
142 "used to sample the background.",
145 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
146 cpl_parameterlist_append(parameters, p);
151 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
152 uves_parameter_new_range(p, full_name,
154 "The height (in pixels) of the background sampling "
155 "window is (2*radiusy + 1). "
156 "This parameter is not corrected for binning.",
159 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
160 cpl_parameterlist_append(parameters, p);
165 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
166 uves_parameter_new_range(p, full_name,
168 "Degree of interpolating splines. Currently "
169 "only degree = 1 is supported",
172 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
173 cpl_parameterlist_append(parameters, p);
178 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
179 uves_parameter_new_range(p, full_name,
181 "If spline interpolation is used to measure the background, "
182 "the x-radius of the post-smoothing window is "
183 "(smoothx * image_width). Here, 'image_width' is the image "
184 "width after binning. If negative, the default values are used: "
185 make_str(BACKSUB_FLAT_SMOOTHX_BLUE)
" for blue flat-field frames, "
186 make_str(BACKSUB_FLAT_SMOOTHX_RED)
" for red flat-field frames, "
187 make_str(BACKSUB_SCI_SMOOTHX_BLUE)
" for blue science frames and "
188 make_str(BACKSUB_SCI_SMOOTHX_RED)
" for red science frames.",
190 -1.0, -DBL_MAX, DBL_MAX);
191 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
192 cpl_parameterlist_append(parameters, p);
197 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
198 uves_parameter_new_range(p, full_name,
200 "If spline interpolation is used to measure the "
201 "background, the y-radius of the post-smoothing "
202 "window is (smoothy * image_height). Here, "
203 "'image_height' is the image height after binning. "
204 "If negative, the default values are used: "
205 make_str(BACKSUB_FLAT_SMOOTHY_BLUE)
" for blue flat-field frames, "
206 make_str(BACKSUB_FLAT_SMOOTHY_RED)
" for red flat-field frames, "
207 make_str(BACKSUB_SCI_SMOOTHY_BLUE)
" for blue science frames and "
208 make_str(BACKSUB_SCI_SMOOTHY_RED)
" for red science frames.",
210 -1.0, -DBL_MAX, DBL_MAX);
211 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
212 cpl_parameterlist_append(parameters, p);
215 if (cpl_error_get_code() != CPL_ERROR_NONE)
217 cpl_msg_error(__func__,
"Creation of spline background subtraction "
218 "parameters failed: '%s'", cpl_error_get_where());
219 cpl_parameterlist_delete(parameters);
239 background_measure_method
240 uves_get_bm_method(
const cpl_parameterlist *parameters,
const char *context,
241 const char *subcontext)
244 background_measure_method result = 0;
246 check( uves_get_parameter(parameters, context, subcontext,
"mmethod", CPL_TYPE_STRING, &bm),
247 "Could not read parameter");
249 if (strcmp(bm,
"median" ) == 0) result = BM_MEDIAN;
250 else if (strcmp(bm,
"minimum") == 0) result = BM_MINIMUM;
251 else if (strcmp(bm,
"no" ) == 0) result = BM_NO;
254 assure(
false, CPL_ERROR_ILLEGAL_INPUT,
255 "No such background measuring method: '%s'", bm);
300 const cpl_table *ordertable,
const polynomial *order_locations,
301 const cpl_parameterlist *parameters,
const char *context,
304 cpl_image **background)
307 background_measure_method BM_METHOD;
322 int smooth_x, smooth_y;
325 passure( raw_header != NULL,
" ");
326 passure( ordertable != NULL,
" ");
327 passure( order_locations != NULL,
" ");
328 passure( parameters != NULL,
" ");
329 passure( context != NULL,
" ");
332 passure( background != NULL,
" ");
335 check( BM_METHOD = uves_get_bm_method(parameters, context, UVES_BACKSUB_ID),
336 "Error getting background measuring method");
338 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
339 "npoints", CPL_TYPE_INT , &npoints) ,
"Could not read parameter");
340 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
341 "radiusy", CPL_TYPE_INT , &radius_y),
"Could not read parameter");
346 radius_y = uves_round_double((
double)radius_y/bin_y);
348 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
349 "sdegree", CPL_TYPE_INT , &sdegree) ,
"Could not read parameter");
350 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
351 "smoothx", CPL_TYPE_DOUBLE, &SMOOTHX) ,
"Could not read parameter");
352 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
353 "smoothy", CPL_TYPE_DOUBLE, &SMOOTHY) ,
"Could not read parameter");
357 nx = cpl_image_get_size_x(image);
358 ny = cpl_image_get_size_y(image);
361 if (BM_METHOD == BM_NO)
363 uves_msg(
"Skipping background subtraction");
366 check( *background = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE),
367 "Error allocating image");
373 if (chip == UVES_CHIP_BLUE)
375 SMOOTHX = (flat_field) ?
376 BACKSUB_FLAT_SMOOTHX_BLUE : BACKSUB_SCI_SMOOTHX_BLUE;
380 SMOOTHX = (flat_field) ?
381 BACKSUB_FLAT_SMOOTHX_RED : BACKSUB_SCI_SMOOTHX_RED;
391 "Error reading central wavelength");
395 if (wlen < BACKSUB_SMOOTHY_WLEN)
397 SMOOTHY = (flat_field) ?
398 BACKSUB_FLAT_SMOOTHY_BLUE : BACKSUB_SCI_SMOOTHY_BLUE;
402 SMOOTHY = (flat_field) ?
403 BACKSUB_FLAT_SMOOTHY_RED : BACKSUB_SCI_SMOOTHY_RED;
407 assure( 0 < SMOOTHX, CPL_ERROR_ILLEGAL_INPUT,
"Illegal smoothx factor: %e", SMOOTHX);
408 assure( 0 < SMOOTHY, CPL_ERROR_ILLEGAL_INPUT,
"Illegal smoothy factor: %e", SMOOTHY);
410 smooth_x = uves_round_double(SMOOTHX * nx - 0.5);
411 smooth_y = uves_round_double(SMOOTHY * ny - 0.5);
413 assure( 0 < npoints, CPL_ERROR_ILLEGAL_INPUT,
414 "Illegal number of sample points: %d", npoints);
415 stepx = nx / npoints;
416 assure( 0 < stepx, CPL_ERROR_ILLEGAL_INPUT,
"Illegal step size: %d", stepx);
418 assure( 0 < radius_x, CPL_ERROR_ILLEGAL_INPUT,
"Illegal x sample radius: %d", radius_x);
419 assure( 0 < radius_y, CPL_ERROR_ILLEGAL_INPUT,
"Illegal y sample radius: %d", radius_y);
420 assure( 0 < smooth_x, CPL_ERROR_ILLEGAL_INPUT,
"Illegal x sample smooth: %d", smooth_x);
421 assure( 0 < smooth_y, CPL_ERROR_ILLEGAL_INPUT,
"Illegal y sample smooth: %d", smooth_y);
422 assure( sdegree == 1, CPL_ERROR_UNSUPPORTED_MODE,
423 "Spline degree must be 1. It is %d", sdegree);
425 uves_msg(
"Sample window (pixels): radx, rady = %d, %d", radius_x, radius_y);
427 check( *background = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE),
428 "Error allocating background image");
432 for (x = stepx; x <= nx; x += stepx) {
433 int order, minorder, maxorder;
436 minorder = cpl_table_get_column_min(ordertable,
"Order");
439 while (uves_round_double(
448 for (sign = -1; sign <= 1; sign += 2)
452 x + sign*radius_x, minorder+1 - 0.5) >
454 x + sign*radius_x, minorder - 0.5),
455 CPL_ERROR_ILLEGAL_INPUT,
456 "Order polynomial is not well-formed: "
457 "p(%d, %f) = %e; p(%d, %f) = %e",
459 order_locations, x + sign*radius_x, minorder+1 - 0.5
462 order_locations, x + sign*radius_x, minorder - 0.5)
469 maxorder = cpl_table_get_column_max(ordertable,
"Order");
472 while (uves_round_double(
477 ) + radius_y > ny ) {
479 for (sign = -1; sign <= 1; sign += 2)
483 order_locations, x + sign*radius_x, maxorder-1 - 0.5) <
485 x + sign*radius_x, maxorder - 0.5),
486 CPL_ERROR_ILLEGAL_INPUT,
487 "Order polynomial is not well-formed: "
488 "p(%d, %f) = %e; p(%d, %f) = %e",
490 order_locations, x + sign*radius_x, maxorder-1 - 0.5),
492 order_locations, x + sign*radius_x, maxorder - 0.5)
501 order_locations, x + radius_x, minorder - 1.5)
504 order_locations, x - radius_x, minorder - 1.5)
508 for (sign = -1; sign <= 1; sign += 2)
512 order_locations, x + sign*radius_x, minorder-1 - 1.5) <
514 order_locations, x + sign*radius_x, minorder - 1.5),
515 CPL_ERROR_ILLEGAL_INPUT,
516 "Order polynomial is not well-formed: "
517 "p(%d, %f) = %e ; p(%d, %f) = %e",
518 x + sign*radius_x, minorder-1 - 1.5,
520 order_locations, x + sign*radius_x, minorder-1 - 1.5),
521 x + sign*radius_x, minorder - 1.5,
523 order_locations, x + sign*radius_x, minorder - 1.5));
531 order_locations, x + radius_x, maxorder + 1.5)
532 ) + radius_y <= ny &&
534 order_locations, x - radius_x, maxorder + 1.5)
535 ) + radius_y <= ny ) {
537 for (sign = -1; sign <= 1; sign += 2)
541 order_locations, x + sign*radius_x, maxorder+1 + 1.5)
544 order_locations, x + sign*radius_x, maxorder + 1.5),
545 CPL_ERROR_ILLEGAL_INPUT,
546 "Order polynomial is not well-formed: "
547 "p(%d, %f) = %e ; p(%d, %f) = %e",
548 x + sign*radius_x, maxorder+1 + 1.5,
550 order_locations, x + sign*radius_x, maxorder+1 + 1.5),
551 x + sign*radius_x, maxorder + 1.5,
553 order_locations, x + sign*radius_x, maxorder + 1.5));
559 uves_msg_debug(
"(x, order) = (%d, %f - %f) ", x, minorder-.5, maxorder+.5);
561 for (order = minorder; order <= maxorder; order++) {
563 double backlo, backhi;
569 ylo = uves_round_double(
571 yhi = uves_round_double(
575 assure( yhi > ylo, CPL_ERROR_ILLEGAL_INPUT,
576 "Order polynomial is not well-formed: "
577 "p(%d, %f) = %d ; p(%d, %f) = %d",
579 x, order + 0.5, yhi);
584 image, x, ylo, radius_x, radius_y, nx, ny, BM_METHOD),
585 "Error sampling background level");
587 check( backhi = sample_background(
588 image, x, yhi, radius_x, radius_y, nx, ny, BM_METHOD),
589 "Error sampling background level");
591 uves_msg_debug(
"Background sample at (x, y, order) = (%d, %d, %f) = %f",
592 x, ylo, order-0.5, backlo);
593 uves_msg_debug(
"Background sample at (x, y, order) = (%d, %d, %f) = %f",
594 x, yhi, order+0.5, backhi);
597 if (order == minorder) {
598 for (y = 1; y <= ylo; y++) {
599 double back = backlo + (backhi - backlo)*(y - ylo)/(yhi - ylo);
600 cpl_image_set(*background, x, y, back);
602 cpl_image_set(*background, x, y, back);
607 for (y = ylo; y <= yhi; y++) {
609 back = backlo + (backhi - backlo) * (y - ylo) / (yhi - ylo);
611 cpl_image_set(*background, x, y, back);
615 if (order == maxorder) {
616 for (y = yhi; y <= ny; y++) {
618 back = backlo + (backhi - backlo) * (y - ylo) / (yhi - ylo);
620 cpl_image_set(*background, x, y, back);
627 for (y = 1; y <= ny; y++) {
629 for (col = stepx; col+stepx <= nx; col += stepx) {
632 double backlo, backhi;
635 backlo = cpl_image_get(*background, col , y, &pis_rejected);
636 backhi = cpl_image_get(*background, col+stepx, y, &pis_rejected);
640 for (x = 1; x <= col; x++)
642 double back = backlo + (backhi - backlo) * (x - col) / stepx;
643 cpl_image_set(*background, x, y, back);
647 for (x = col; x <= col + stepx; x++)
649 double back = backlo + (backhi - backlo) * (x - col) / stepx;
650 cpl_image_set(*background, x, y, back);
654 if (col+stepx+stepx > nx)
655 for (x = col; x <= nx; x++)
657 double back = backlo + (backhi - backlo) * (x - col) / stepx;
658 cpl_image_set(*background, x, y, back);
667 uves_msg(
"Smoothing window (pixels): smox, smoy = %d, %d", smooth_x, smooth_y);
669 "Error applying average filter to background image");
671 uves_msg(
"Subtracting background image");
673 check( subtract_background(image, *background, NULL),
674 "Error subtracting background image");
681 return cpl_error_get_code();
731 uves_backsub_poly(cpl_image *image,
732 const cpl_table *orders,
const polynomial *order_locations,
733 background_measure_method BM_METHOD,
746 cpl_size total_clipped = 0;
748 if (BM_METHOD == BM_NO)
750 uves_msg(
"Skipping background subtraction");
755 passure( orders == NULL || order_locations == NULL,
" ");
757 nx = cpl_image_get_size_x(image);
758 ny = cpl_image_get_size_y(image);
760 assure( NPOINTS < nx, CPL_ERROR_ILLEGAL_INPUT,
761 "Number of sample columns (%d) larger than image width (%d pixels)",
774 int x, ordersrow, row;
777 passure( cpl_table_has_column(orders,
"Slope"),
" ");
778 passure( cpl_table_has_column(orders,
"Intersept"),
" ");
780 passure( cpl_table_get_column_type(orders,
"Slope") == CPL_TYPE_DOUBLE,
784 passure( cpl_table_get_column_type(orders,
"Intersept") == CPL_TYPE_DOUBLE,
793 assure ( cpl_table_get_nrow(orders) >= 2, CPL_ERROR_ILLEGAL_INPUT,
794 "Only %" CPL_SIZE_FORMAT
" line(s) in order table", cpl_table_get_nrow(orders));
796 t = cpl_table_new( (nx/stepx + 1)*(cpl_table_get_nrow(orders) + 1) );
797 cpl_table_new_column(t,
"X", CPL_TYPE_INT);
798 cpl_table_new_column(t,
"Y", CPL_TYPE_INT);
799 cpl_table_new_column(t,
"Z", CPL_TYPE_DOUBLE);
802 for (ordersrow = -1; ordersrow < cpl_table_get_nrow(orders); ordersrow++)
804 double slope, intersept;
811 slope = cpl_table_get_double(
812 orders,
"Slope" , 0, NULL);
817 0.5*cpl_table_get_double(orders,
"Intersept", 0, NULL) -
818 0.5*cpl_table_get_double(orders,
"Intersept", 1, NULL) ;
820 else if (ordersrow == cpl_table_get_nrow(orders) - 1)
822 slope = cpl_table_get_double(
823 orders,
"Slope" , ordersrow, NULL);
828 0.5*cpl_table_get_double(
829 orders,
"Intersept", ordersrow, NULL) -
830 0.5*cpl_table_get_double(
831 orders,
"Intersept", ordersrow-1, NULL) ;
836 (cpl_table_get_double(
837 orders,
"Slope", ordersrow , NULL) +
838 cpl_table_get_double(
839 orders,
"Slope", ordersrow+1, NULL) ) / 2;
842 (cpl_table_get_double(
843 orders,
"Intersept", ordersrow , NULL) +
844 cpl_table_get_double(
845 orders,
"Intersept", ordersrow+1, NULL) ) / 2;
849 for (x = 1 + stepx/2; x <= nx; x += stepx)
851 int y = uves_round_double(intersept + slope * x);
853 if (1 <= y && y <= ny)
857 check( z = sample_background(
863 "Error sampling background "
864 "(x, y) = (%d, %d)", x, y);
866 cpl_table_set_int (t,
"X" , row, x);
867 cpl_table_set_int (t,
"Y" , row, y);
868 cpl_table_set_double(t,
"Z" , row, z);
874 cpl_table_set_size(t, row);
878 else if (order_locations != NULL)
882 int x, minorder, maxorder, order;
887 CPL_ERROR_ILLEGAL_INPUT,
888 "Order location polynomial must be 2d. It is %d!",
891 check(( minorder = first_order(order_locations, nx),
892 maxorder = last_order(order_locations, nx, ny)),
893 "Error getting min. and max. order numbers");
895 t = cpl_table_new( (nx/stepx + 1) * (maxorder-minorder+1));
896 cpl_table_new_column(t,
"X", CPL_TYPE_INT);
897 cpl_table_new_column(t,
"Y", CPL_TYPE_INT);
898 cpl_table_new_column(t,
"Z", CPL_TYPE_DOUBLE);
901 for (order = minorder; order <= maxorder; order++) {
903 for (x = 1+stepx/2; x <= nx; x += stepx) {
904 int y = uves_round_double(
907 if (1 <= y && y <= ny) {
910 check( z = sample_background(image,
915 "Error sampling background (x, order) = (%d, %d+0.5)",
918 cpl_table_set_int (t,
"X" , row, x);
919 cpl_table_set_int (t,
"Y" , row, y);
920 cpl_table_set_double(t,
"Z" , row, z);
926 cpl_table_set_size(t, row);
933 t = cpl_table_new((nx/stepx + 1) * (ny/stepy + 1));
934 cpl_table_new_column(t,
"X" , CPL_TYPE_INT);
935 cpl_table_new_column(t,
"Y" , CPL_TYPE_INT);
936 cpl_table_new_column(t,
"Z" , CPL_TYPE_DOUBLE);
939 for (y = 1 + stepy/2; y <= ny; y += stepy)
941 for (x = 1+stepx/2; x <= nx; x += stepx)
945 check( z = sample_background(image,
950 "Error sampling background (x, y) = (%d, %d)", x, y);
952 cpl_table_set_int (t,
"X" , row, x);
953 cpl_table_set_int (t,
"Y" , row, y);
954 cpl_table_set_double(t,
"Z" , row, z);
958 cpl_table_set_size(t, row);
966 cpl_size deg_xy=(DEGX + 1)*(DEGY + 1);
968 assure( cpl_table_get_nrow(t) > (DEGX + 1)*(DEGY + 1),
969 CPL_ERROR_ILLEGAL_OUTPUT,
970 "Too few sample points available (%" CPL_SIZE_FORMAT
" point(s)) to make the fit "
971 "(more than %" CPL_SIZE_FORMAT
" points needed). "
972 "Increase number of sample points or increase kappa",
973 cpl_table_get_nrow(t), deg_xy);
978 t,
"X",
"Y",
"Z", NULL,
979 DEGX, DEGY,
"Zfit", NULL, NULL, &mse,
981 "Error fitting polynomial");
984 cpl_table_duplicate_column(t,
"Residual", t,
"Z");
985 cpl_table_subtract_columns(t,
"Residual",
"Zfit");
992 cpl_table_subtract_scalar(t,
"Residual",
993 cpl_table_get_column_median(t,
"Residual"));
994 rmse = cpl_table_get_column_stdev(t,
"Residual");
999 check( n_clipped = uves_select_table_rows(
1000 t,
"Residual", CPL_GREATER_THAN, KAPPA * rmse),
1001 "Error selecting rows");
1008 total_clipped += n_clipped;
1010 uves_msg_debug(
"RMS = %f. %" CPL_SIZE_FORMAT
" of %" CPL_SIZE_FORMAT
" points rejected in kappa-sigma clipping",
1011 rmse, n_clipped, cpl_table_get_nrow(t));
1013 cpl_table_erase_selected(t);
1017 cpl_table_erase_column(t,
"Zfit");
1018 cpl_table_erase_column(t,
"Residual");
1021 }
while (n_clipped > 0);
1028 100.0 * ( (double)total_clipped ) / (total_clipped + cpl_table_get_nrow(t));
1031 uves_msg(
"%" CPL_SIZE_FORMAT
" of %" CPL_SIZE_FORMAT
" points (%.2f %%) were rejected in "
1032 "kappa-sigma clipping. RMS = %.2f ADU",
1034 cpl_table_get_nrow(t) + total_clipped,
1040 if (orders == NULL && order_locations == NULL)
1042 if (total_clipped == 0)
1045 "estimation. Background subtraction is "
1046 "uncertain. Try to decrease KAPPA "
1047 "(current value is %f)", KAPPA);
1049 if (percentage > 40)
1053 "background estimation", percentage);
1058 check( subtract_background(image, NULL, background),
1059 "Error subtracting background polynomial");
1063 uves_free_table(&t);
1066 return cpl_error_get_code();
1115 uves_backsub_smooth(cpl_image *image,
int RADX,
int RADY,
int ITER)
1117 cpl_image *background = NULL;
1120 assure( RADX >= 0 && RADY >= 0, CPL_ERROR_ILLEGAL_INPUT,
1121 "Negative radius ((%d)x(%d))", RADX, RADY);
1122 assure( ITER >= 1, CPL_ERROR_ILLEGAL_INPUT,
1123 "Non-positive number of iterations (%d)", ITER);
1126 background = cpl_image_duplicate(image);
1128 for (i = 0; i < ITER; i++) {
1131 check( lower_to_average(background,
1132 RADX, RADY),
"Error smoothing image");
1136 check( cpl_image_subtract(image, background),
"Could not subtract background image");
1139 uves_free_image(&background);
1141 return cpl_error_get_code();
1166 sample_background(
const cpl_image *image,
int x0,
double y_0,
1167 int radius_x,
int radius_y,
int nx,
int ny,
1168 background_measure_method BM_METHOD)
1172 cpl_table *temp = NULL;
1173 bool found_good =
false;
1178 (temp = cpl_table_new( (2*radius_x + 1) * (2*radius_y + 1) ),
1180 cpl_table_new_column(temp,
"Flux", CPL_TYPE_DOUBLE)),
1181 "Error allocating table");
1183 for(y = y_0 - radius_y; y <= y_0 + radius_y; y++)
1185 for (x = x0 - radius_x; x <= x0 + radius_x; x++)
1187 if (1 <= x && x <= nx &&
1191 double flux = cpl_image_get(image, x, y, &pis_rejected);
1194 cpl_table_set(temp,
"Flux", row, flux);
1199 cpl_table_set_invalid(temp,
"Flux", row);
1204 cpl_table_set_invalid(temp,
"Flux", row);
1211 assure( found_good, CPL_ERROR_ILLEGAL_INPUT,
"No valid pixels in sample window");
1213 if (BM_METHOD == BM_MEDIAN)
1215 result = cpl_table_get_column_median(temp,
"Flux");
1217 else if (BM_METHOD == BM_MINIMUM)
1219 result = cpl_table_get_column_min(temp,
"Flux");
1223 assure(
false, CPL_ERROR_UNSUPPORTED_MODE,
1224 "Unsupported background sample method: %d", BM_METHOD);
1228 uves_free_table(&temp);
1243 first_order(
const polynomial *order_locations,
int nx)
1260 assure( result > -100000,
1262 "Invalid polynomial: p(x=1, order=%d) = %f p(x=%d, order=%d) = %f",
1284 last_order(
const polynomial *order_locations,
int nx,
int ny)
1301 assure( result < 100000,
1303 "Invalid polynomial: p(x=1, order=%d) = %f p(x=%d, order=%d) = %f",
1325 static cpl_error_code
1326 lower_to_average(cpl_image *image,
int RADX,
int RADY)
1328 cpl_image *average = NULL;
1329 double *image_data = NULL;
1330 double *average_data = NULL;
1334 passure( image != NULL,
"Null image");
1335 nx = cpl_image_get_size_x(image);
1336 ny = cpl_image_get_size_y(image);
1340 check( average = cpl_image_duplicate(image),
"Error copying image");
1344 image_data = cpl_image_get_data(image);
1345 average_data = cpl_image_get_data(average);
1347 for (y = 0; y < ny; y++)
1349 for (x = 0; x < nx; x++)
1351 if (image_data[x + y*nx] > average_data[x + y*nx])
1353 image_data[x + y*nx] = average_data[x + y*nx];
1360 uves_free_image(&average);
1362 return cpl_error_get_code();
1379 static cpl_error_code
1380 subtract_background(cpl_image *image, cpl_image *background_im,
1387 double *background_data = NULL;
1391 passure((background_im == NULL) != (background_pol == NULL),
" ");
1398 assure(cpl_image_get_type(image) == CPL_TYPE_DOUBLE,
1399 CPL_ERROR_UNSUPPORTED_MODE,
1400 "Input image is of type %s. double expected",
1403 if (background_im != NULL)
1405 assure(cpl_image_count_rejected(background_im) == 0,
1406 CPL_ERROR_UNSUPPORTED_MODE,
"Background image contains bad pixels");
1407 assure(cpl_image_get_type(background_im) == CPL_TYPE_DOUBLE,
1408 CPL_ERROR_UNSUPPORTED_MODE,
1409 "Background image is of type %s. double expected",
1413 image_data = cpl_image_get_data_double(image);
1414 if (background_im != NULL)
1416 background_data = cpl_image_get_data_double(background_im);
1419 nx = cpl_image_get_size_x(image);
1420 ny = cpl_image_get_size_y(image);
1422 for (y = 1; y <= ny; y++)
1424 for (x = 1; x <= nx; x++)
1427 double flux, new_flux;
1429 if (background_im != NULL)
1432 back = background_data[(x-1) + (y-1) * nx];
1443 flux = image_data[(x-1) + (y-1) * nx];
1460 new_flux = uves_max_double(0, flux - back);
1462 new_flux = flux-back;
1466 image_data[(x-1) + (y-1) * nx] = new_flux;
1468 if (background_im != NULL)
1471 background_data[(x-1) + (y-1) * nx] = flux - new_flux;
1477 return cpl_error_get_code();
int uves_polynomial_get_dimension(const polynomial *p)
Get the dimension of a polynomial.
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
#define uves_msg_warning(...)
Print an warning message.
bool uves_table_is_sorted_double(const cpl_table *t, const char *column, const bool reverse)
Determine if a table is sorted.
cpl_error_code uves_filter_image_average(cpl_image *image, int radius_x, int radius_y)
Average filter.
#define passure(BOOL,...)
double uves_pfits_get_gratwlen(const uves_propertylist *plist, enum uves_chip chip)
find out the central wavelength
int uves_pfits_get_binx(const uves_propertylist *plist)
Find out the x binning factor.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
polynomial * uves_polynomial_regression_2d(cpl_table *t, const char *X1, const char *X2, const char *Y, const char *sigmaY, int degree1, int degree2, const char *polynomial_fit, const char *residual_square, const char *variance_fit, double *mse, double *red_chisq, polynomial **variance, double kappa, double min_reject)
Fit a 2d polynomial to three table columns.
int uves_pfits_get_biny(const uves_propertylist *plist)
Find out the y binning factor.
double uves_polynomial_evaluate_2d(const polynomial *p, double x1, double x2)
Evaluate a 2d polynomial.
const char * uves_tostring_cpl_type(cpl_type t)
Convert a CPL type to a string.
#define uves_msg_debug(...)
Print a debug message.