157 #include <uves_backsub.h>
159 #include <uves_parameters.h>
160 #include <uves_pfits.h>
161 #include <uves_dump.h>
162 #include <uves_utils.h>
163 #include <uves_utils_wrappers.h>
164 #include <uves_utils_cpl.h>
165 #include <uves_error.h>
166 #include <uves_msg.h>
176 static int first_order(
const polynomial *order_locations,
int nx);
177 static int last_order (
const polynomial *order_locations,
int nx,
int ny);
178 static cpl_error_code lower_to_average(cpl_image *image,
int RADX,
int RADY);
179 static double sample_background(
const cpl_image *image,
int x0,
double y_0,
180 int radius_x,
int radius_y,
int nx,
int ny,
181 background_measure_method BM_METHOD);
182 static cpl_error_code subtract_background(cpl_image *image, cpl_image *background_im,
195 #define BACKSUB_FLAT_SMOOTHX_BLUE (25.0/4096)
196 #define BACKSUB_FLAT_SMOOTHX_RED (50.0/4096)
197 #define BACKSUB_FLAT_SMOOTHY_BLUE (100.0/2048)
198 #define BACKSUB_FLAT_SMOOTHY_RED (300.0/2048)
200 #define BACKSUB_SCI_SMOOTHX_BLUE (300.0/4096)
201 #define BACKSUB_SCI_SMOOTHX_RED (300.0/4096)
202 #define BACKSUB_SCI_SMOOTHY_BLUE (200.0/2048)
203 #define BACKSUB_SCI_SMOOTHY_RED (500.0/2048)
205 #define BACKSUB_SMOOTHY_WLEN 859.9
224 uves_backsub_define_parameters(
void)
226 const char *name =
"";
227 char *full_name = NULL;
228 cpl_parameterlist *parameters = NULL;
229 cpl_parameter *p = NULL;
231 parameters = cpl_parameterlist_new();
235 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
237 uves_parameter_new_enum(p, full_name,
239 "Background measuring method. If equal to 'median' "
240 "the background is sampled using the median of a subwindow. "
241 "If 'minimum', the subwindow minimum value is used. "
242 "If 'no', no background subtraction is done.",
246 "median",
"minimum",
"no");
247 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
248 cpl_parameterlist_append(parameters, p);
253 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
254 uves_parameter_new_range(p, full_name,
256 "This is the number of columns in interorder space "
257 "used to sample the background.",
260 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
261 cpl_parameterlist_append(parameters, p);
266 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
267 uves_parameter_new_range(p, full_name,
269 "The height (in pixels) of the background sampling "
270 "window is (2*radiusy + 1). "
271 "This parameter is not corrected for binning.",
274 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
275 cpl_parameterlist_append(parameters, p);
280 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
281 uves_parameter_new_range(p, full_name,
283 "Degree of interpolating splines. Currently "
284 "only degree = 1 is supported",
287 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
288 cpl_parameterlist_append(parameters, p);
293 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
294 uves_parameter_new_range(p, full_name,
296 "If spline interpolation is used to measure the background, "
297 "the x-radius of the post-smoothing window is "
298 "(smoothx * image_width). Here, 'image_width' is the image "
299 "width after binning. If negative, the default values are used: "
300 make_str(BACKSUB_FLAT_SMOOTHX_BLUE)
" for blue flat-field frames, "
301 make_str(BACKSUB_FLAT_SMOOTHX_RED)
" for red flat-field frames, "
302 make_str(BACKSUB_SCI_SMOOTHX_BLUE)
" for blue science frames and "
303 make_str(BACKSUB_SCI_SMOOTHX_RED)
" for red science frames.",
305 -1.0, -DBL_MAX, DBL_MAX);
306 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
307 cpl_parameterlist_append(parameters, p);
312 full_name = uves_sprintf(
"%s.%s", UVES_BACKSUB_ID, name);
313 uves_parameter_new_range(p, full_name,
315 "If spline interpolation is used to measure the "
316 "background, the y-radius of the post-smoothing "
317 "window is (smoothy * image_height). Here, "
318 "'image_height' is the image height after binning. "
319 "If negative, the default values are used: "
320 make_str(BACKSUB_FLAT_SMOOTHY_BLUE)
" for blue flat-field frames, "
321 make_str(BACKSUB_FLAT_SMOOTHY_RED)
" for red flat-field frames, "
322 make_str(BACKSUB_SCI_SMOOTHY_BLUE)
" for blue science frames and "
323 make_str(BACKSUB_SCI_SMOOTHY_RED)
" for red science frames.",
325 -1.0, -DBL_MAX, DBL_MAX);
326 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
327 cpl_parameterlist_append(parameters, p);
330 if (cpl_error_get_code() != CPL_ERROR_NONE)
332 cpl_msg_error(__func__,
"Creation of spline background subtraction "
333 "parameters failed: '%s'", cpl_error_get_where());
334 cpl_parameterlist_delete(parameters);
354 background_measure_method
355 uves_get_bm_method(
const cpl_parameterlist *parameters,
const char *context,
356 const char *subcontext)
359 background_measure_method result = 0;
361 check( uves_get_parameter(parameters, context, subcontext,
"mmethod", CPL_TYPE_STRING, &bm),
362 "Could not read parameter");
364 if (strcmp(bm,
"median" ) == 0) result = BM_MEDIAN;
365 else if (strcmp(bm,
"minimum") == 0) result = BM_MINIMUM;
366 else if (strcmp(bm,
"no" ) == 0) result = BM_NO;
369 assure(
false, CPL_ERROR_ILLEGAL_INPUT,
370 "No such background measuring method: '%s'", bm);
415 const cpl_table *ordertable,
const polynomial *order_locations,
416 const cpl_parameterlist *parameters,
const char *context,
419 cpl_image **background)
422 background_measure_method BM_METHOD;
437 int smooth_x, smooth_y;
440 passure( raw_header != NULL,
" ");
441 passure( ordertable != NULL,
" ");
442 passure( order_locations != NULL,
" ");
443 passure( parameters != NULL,
" ");
444 passure( context != NULL,
" ");
447 passure( background != NULL,
" ");
450 check( BM_METHOD = uves_get_bm_method(parameters, context, UVES_BACKSUB_ID),
451 "Error getting background measuring method");
453 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
454 "npoints", CPL_TYPE_INT , &npoints) ,
"Could not read parameter");
455 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
456 "radiusy", CPL_TYPE_INT , &radius_y),
"Could not read parameter");
461 radius_y = uves_round_double((
double)radius_y/bin_y);
463 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
464 "sdegree", CPL_TYPE_INT , &sdegree) ,
"Could not read parameter");
465 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
466 "smoothx", CPL_TYPE_DOUBLE, &SMOOTHX) ,
"Could not read parameter");
467 check( uves_get_parameter(parameters, context, UVES_BACKSUB_ID,
468 "smoothy", CPL_TYPE_DOUBLE, &SMOOTHY) ,
"Could not read parameter");
472 nx = cpl_image_get_size_x(image);
473 ny = cpl_image_get_size_y(image);
476 if (BM_METHOD == BM_NO)
478 uves_msg(
"Skipping background subtraction");
481 check( *background = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE),
482 "Error allocating image");
488 if (chip == UVES_CHIP_BLUE)
490 SMOOTHX = (flat_field) ?
491 BACKSUB_FLAT_SMOOTHX_BLUE : BACKSUB_SCI_SMOOTHX_BLUE;
495 SMOOTHX = (flat_field) ?
496 BACKSUB_FLAT_SMOOTHX_RED : BACKSUB_SCI_SMOOTHX_RED;
506 "Error reading central wavelength");
510 if (wlen < BACKSUB_SMOOTHY_WLEN)
512 SMOOTHY = (flat_field) ?
513 BACKSUB_FLAT_SMOOTHY_BLUE : BACKSUB_SCI_SMOOTHY_BLUE;
517 SMOOTHY = (flat_field) ?
518 BACKSUB_FLAT_SMOOTHY_RED : BACKSUB_SCI_SMOOTHY_RED;
522 assure( 0 < SMOOTHX, CPL_ERROR_ILLEGAL_INPUT,
"Illegal smoothx factor: %e", SMOOTHX);
523 assure( 0 < SMOOTHY, CPL_ERROR_ILLEGAL_INPUT,
"Illegal smoothy factor: %e", SMOOTHY);
525 smooth_x = uves_round_double(SMOOTHX * nx - 0.5);
526 smooth_y = uves_round_double(SMOOTHY * ny - 0.5);
528 assure( 0 < npoints, CPL_ERROR_ILLEGAL_INPUT,
529 "Illegal number of sample points: %d", npoints);
530 stepx = nx / npoints;
531 assure( 0 < stepx, CPL_ERROR_ILLEGAL_INPUT,
"Illegal step size: %d", stepx);
533 assure( 0 < radius_x, CPL_ERROR_ILLEGAL_INPUT,
"Illegal x sample radius: %d", radius_x);
534 assure( 0 < radius_y, CPL_ERROR_ILLEGAL_INPUT,
"Illegal y sample radius: %d", radius_y);
535 assure( 0 < smooth_x, CPL_ERROR_ILLEGAL_INPUT,
"Illegal x sample smooth: %d", smooth_x);
536 assure( 0 < smooth_y, CPL_ERROR_ILLEGAL_INPUT,
"Illegal y sample smooth: %d", smooth_y);
537 assure( sdegree == 1, CPL_ERROR_UNSUPPORTED_MODE,
538 "Spline degree must be 1. It is %d", sdegree);
540 uves_msg(
"Sample window (pixels): radx, rady = %d, %d", radius_x, radius_y);
542 check( *background = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE),
543 "Error allocating background image");
547 for (x = stepx; x <= nx; x += stepx) {
548 int order, minorder, maxorder;
551 minorder = cpl_table_get_column_min(ordertable,
"Order");
554 while (uves_round_double(
563 for (sign = -1; sign <= 1; sign += 2)
567 x + sign*radius_x, minorder+1 - 0.5) >
569 x + sign*radius_x, minorder - 0.5),
570 CPL_ERROR_ILLEGAL_INPUT,
571 "Order polynomial is not well-formed: "
572 "p(%d, %f) = %e; p(%d, %f) = %e",
574 order_locations, x + sign*radius_x, minorder+1 - 0.5
577 order_locations, x + sign*radius_x, minorder - 0.5)
584 maxorder = cpl_table_get_column_max(ordertable,
"Order");
587 while (uves_round_double(
592 ) + radius_y > ny ) {
594 for (sign = -1; sign <= 1; sign += 2)
598 order_locations, x + sign*radius_x, maxorder-1 - 0.5) <
600 x + sign*radius_x, maxorder - 0.5),
601 CPL_ERROR_ILLEGAL_INPUT,
602 "Order polynomial is not well-formed: "
603 "p(%d, %f) = %e; p(%d, %f) = %e",
605 order_locations, x + sign*radius_x, maxorder-1 - 0.5),
607 order_locations, x + sign*radius_x, maxorder - 0.5)
616 order_locations, x + radius_x, minorder - 1.5)
619 order_locations, x - radius_x, minorder - 1.5)
623 for (sign = -1; sign <= 1; sign += 2)
627 order_locations, x + sign*radius_x, minorder-1 - 1.5) <
629 order_locations, x + sign*radius_x, minorder - 1.5),
630 CPL_ERROR_ILLEGAL_INPUT,
631 "Order polynomial is not well-formed: "
632 "p(%d, %f) = %e ; p(%d, %f) = %e",
633 x + sign*radius_x, minorder-1 - 1.5,
635 order_locations, x + sign*radius_x, minorder-1 - 1.5),
636 x + sign*radius_x, minorder - 1.5,
638 order_locations, x + sign*radius_x, minorder - 1.5));
646 order_locations, x + radius_x, maxorder + 1.5)
647 ) + radius_y <= ny &&
649 order_locations, x - radius_x, maxorder + 1.5)
650 ) + radius_y <= ny ) {
652 for (sign = -1; sign <= 1; sign += 2)
656 order_locations, x + sign*radius_x, maxorder+1 + 1.5)
659 order_locations, x + sign*radius_x, maxorder + 1.5),
660 CPL_ERROR_ILLEGAL_INPUT,
661 "Order polynomial is not well-formed: "
662 "p(%d, %f) = %e ; p(%d, %f) = %e",
663 x + sign*radius_x, maxorder+1 + 1.5,
665 order_locations, x + sign*radius_x, maxorder+1 + 1.5),
666 x + sign*radius_x, maxorder + 1.5,
668 order_locations, x + sign*radius_x, maxorder + 1.5));
674 uves_msg_debug(
"(x, order) = (%d, %f - %f) ", x, minorder-.5, maxorder+.5);
676 for (order = minorder; order <= maxorder; order++) {
678 double backlo, backhi;
684 ylo = uves_round_double(
686 yhi = uves_round_double(
690 assure( yhi > ylo, CPL_ERROR_ILLEGAL_INPUT,
691 "Order polynomial is not well-formed: "
692 "p(%d, %f) = %d ; p(%d, %f) = %d",
694 x, order + 0.5, yhi);
699 image, x, ylo, radius_x, radius_y, nx, ny, BM_METHOD),
700 "Error sampling background level");
702 check( backhi = sample_background(
703 image, x, yhi, radius_x, radius_y, nx, ny, BM_METHOD),
704 "Error sampling background level");
706 uves_msg_debug(
"Background sample at (x, y, order) = (%d, %d, %f) = %f",
707 x, ylo, order-0.5, backlo);
708 uves_msg_debug(
"Background sample at (x, y, order) = (%d, %d, %f) = %f",
709 x, yhi, order+0.5, backhi);
712 if (order == minorder) {
713 for (y = 1; y <= ylo; y++) {
714 double back = backlo + (backhi - backlo)*(y - ylo)/(yhi - ylo);
715 cpl_image_set(*background, x, y, back);
717 cpl_image_set(*background, x, y, back);
722 for (y = ylo; y <= yhi; y++) {
724 back = backlo + (backhi - backlo) * (y - ylo) / (yhi - ylo);
726 cpl_image_set(*background, x, y, back);
730 if (order == maxorder) {
731 for (y = yhi; y <= ny; y++) {
733 back = backlo + (backhi - backlo) * (y - ylo) / (yhi - ylo);
735 cpl_image_set(*background, x, y, back);
742 for (y = 1; y <= ny; y++) {
744 for (col = stepx; col+stepx <= nx; col += stepx) {
747 double backlo, backhi;
750 backlo = cpl_image_get(*background, col , y, &pis_rejected);
751 backhi = cpl_image_get(*background, col+stepx, y, &pis_rejected);
755 for (x = 1; x <= col; x++)
757 double back = backlo + (backhi - backlo) * (x - col) / stepx;
758 cpl_image_set(*background, x, y, back);
762 for (x = col; x <= col + stepx; x++)
764 double back = backlo + (backhi - backlo) * (x - col) / stepx;
765 cpl_image_set(*background, x, y, back);
769 if (col+stepx+stepx > nx)
770 for (x = col; x <= nx; x++)
772 double back = backlo + (backhi - backlo) * (x - col) / stepx;
773 cpl_image_set(*background, x, y, back);
782 uves_msg(
"Smoothing window (pixels): smox, smoy = %d, %d", smooth_x, smooth_y);
784 "Error applying average filter to background image");
786 uves_msg(
"Subtracting background image");
788 check( subtract_background(image, *background, NULL),
789 "Error subtracting background image");
796 return cpl_error_get_code();
846 uves_backsub_poly(cpl_image *image,
847 const cpl_table *orders,
const polynomial *order_locations,
848 background_measure_method BM_METHOD,
861 cpl_size total_clipped = 0;
863 if (BM_METHOD == BM_NO)
865 uves_msg(
"Skipping background subtraction");
870 passure( orders == NULL || order_locations == NULL,
" ");
872 nx = cpl_image_get_size_x(image);
873 ny = cpl_image_get_size_y(image);
875 assure( NPOINTS < nx, CPL_ERROR_ILLEGAL_INPUT,
876 "Number of sample columns (%d) larger than image width (%d pixels)",
889 int x, ordersrow, row;
892 passure( cpl_table_has_column(orders,
"Slope"),
" ");
893 passure( cpl_table_has_column(orders,
"Intersept"),
" ");
895 passure( cpl_table_get_column_type(orders,
"Slope") == CPL_TYPE_DOUBLE,
899 passure( cpl_table_get_column_type(orders,
"Intersept") == CPL_TYPE_DOUBLE,
908 assure ( cpl_table_get_nrow(orders) >= 2, CPL_ERROR_ILLEGAL_INPUT,
909 "Only %" CPL_SIZE_FORMAT
" line(s) in order table", cpl_table_get_nrow(orders));
911 t = cpl_table_new( (nx/stepx + 1)*(cpl_table_get_nrow(orders) + 1) );
912 cpl_table_new_column(t,
"X", CPL_TYPE_INT);
913 cpl_table_new_column(t,
"Y", CPL_TYPE_INT);
914 cpl_table_new_column(t,
"Z", CPL_TYPE_DOUBLE);
917 for (ordersrow = -1; ordersrow < cpl_table_get_nrow(orders); ordersrow++)
919 double slope, intersept;
926 slope = cpl_table_get_double(
927 orders,
"Slope" , 0, NULL);
932 0.5*cpl_table_get_double(orders,
"Intersept", 0, NULL) -
933 0.5*cpl_table_get_double(orders,
"Intersept", 1, NULL) ;
935 else if (ordersrow == cpl_table_get_nrow(orders) - 1)
937 slope = cpl_table_get_double(
938 orders,
"Slope" , ordersrow, NULL);
943 0.5*cpl_table_get_double(
944 orders,
"Intersept", ordersrow, NULL) -
945 0.5*cpl_table_get_double(
946 orders,
"Intersept", ordersrow-1, NULL) ;
951 (cpl_table_get_double(
952 orders,
"Slope", ordersrow , NULL) +
953 cpl_table_get_double(
954 orders,
"Slope", ordersrow+1, NULL) ) / 2;
957 (cpl_table_get_double(
958 orders,
"Intersept", ordersrow , NULL) +
959 cpl_table_get_double(
960 orders,
"Intersept", ordersrow+1, NULL) ) / 2;
964 for (x = 1 + stepx/2; x <= nx; x += stepx)
966 int y = uves_round_double(intersept + slope * x);
968 if (1 <= y && y <= ny)
972 check( z = sample_background(
978 "Error sampling background "
979 "(x, y) = (%d, %d)", x, y);
981 cpl_table_set_int (t,
"X" , row, x);
982 cpl_table_set_int (t,
"Y" , row, y);
983 cpl_table_set_double(t,
"Z" , row, z);
989 cpl_table_set_size(t, row);
993 else if (order_locations != NULL)
997 int x, minorder, maxorder, order;
1002 CPL_ERROR_ILLEGAL_INPUT,
1003 "Order location polynomial must be 2d. It is %d!",
1006 check(( minorder = first_order(order_locations, nx),
1007 maxorder = last_order(order_locations, nx, ny)),
1008 "Error getting min. and max. order numbers");
1010 t = cpl_table_new( (nx/stepx + 1) * (maxorder-minorder+1));
1011 cpl_table_new_column(t,
"X", CPL_TYPE_INT);
1012 cpl_table_new_column(t,
"Y", CPL_TYPE_INT);
1013 cpl_table_new_column(t,
"Z", CPL_TYPE_DOUBLE);
1016 for (order = minorder; order <= maxorder; order++) {
1018 for (x = 1+stepx/2; x <= nx; x += stepx) {
1019 int y = uves_round_double(
1022 if (1 <= y && y <= ny) {
1025 check( z = sample_background(image,
1030 "Error sampling background (x, order) = (%d, %d+0.5)",
1033 cpl_table_set_int (t,
"X" , row, x);
1034 cpl_table_set_int (t,
"Y" , row, y);
1035 cpl_table_set_double(t,
"Z" , row, z);
1041 cpl_table_set_size(t, row);
1048 t = cpl_table_new((nx/stepx + 1) * (ny/stepy + 1));
1049 cpl_table_new_column(t,
"X" , CPL_TYPE_INT);
1050 cpl_table_new_column(t,
"Y" , CPL_TYPE_INT);
1051 cpl_table_new_column(t,
"Z" , CPL_TYPE_DOUBLE);
1054 for (y = 1 + stepy/2; y <= ny; y += stepy)
1056 for (x = 1+stepx/2; x <= nx; x += stepx)
1060 check( z = sample_background(image,
1065 "Error sampling background (x, y) = (%d, %d)", x, y);
1067 cpl_table_set_int (t,
"X" , row, x);
1068 cpl_table_set_int (t,
"Y" , row, y);
1069 cpl_table_set_double(t,
"Z" , row, z);
1073 cpl_table_set_size(t, row);
1081 cpl_size deg_xy=(DEGX + 1)*(DEGY + 1);
1083 assure( cpl_table_get_nrow(t) > (DEGX + 1)*(DEGY + 1),
1084 CPL_ERROR_ILLEGAL_OUTPUT,
1085 "Too few sample points available (%" CPL_SIZE_FORMAT
" point(s)) to make the fit "
1086 "(more than %" CPL_SIZE_FORMAT
" points needed). "
1087 "Increase number of sample points or increase kappa",
1088 cpl_table_get_nrow(t), deg_xy);
1093 t,
"X",
"Y",
"Z", NULL,
1094 DEGX, DEGY,
"Zfit", NULL, NULL, &mse,
1095 NULL, NULL, -1, -1),
1096 "Error fitting polynomial");
1099 cpl_table_duplicate_column(t,
"Residual", t,
"Z");
1100 cpl_table_subtract_columns(t,
"Residual",
"Zfit");
1107 cpl_table_subtract_scalar(t,
"Residual",
1108 cpl_table_get_column_median(t,
"Residual"));
1109 rmse = cpl_table_get_column_stdev(t,
"Residual");
1114 check( n_clipped = uves_select_table_rows(
1115 t,
"Residual", CPL_GREATER_THAN, KAPPA * rmse),
1116 "Error selecting rows");
1123 total_clipped += n_clipped;
1125 uves_msg_debug(
"RMS = %f. %" CPL_SIZE_FORMAT
" of %" CPL_SIZE_FORMAT
" points rejected in kappa-sigma clipping",
1126 rmse, n_clipped, cpl_table_get_nrow(t));
1128 cpl_table_erase_selected(t);
1132 cpl_table_erase_column(t,
"Zfit");
1133 cpl_table_erase_column(t,
"Residual");
1136 }
while (n_clipped > 0);
1143 100.0 * ( (double)total_clipped ) / (total_clipped + cpl_table_get_nrow(t));
1146 uves_msg(
"%" CPL_SIZE_FORMAT
" of %" CPL_SIZE_FORMAT
" points (%.2f %%) were rejected in "
1147 "kappa-sigma clipping. RMS = %.2f ADU",
1149 cpl_table_get_nrow(t) + total_clipped,
1155 if (orders == NULL && order_locations == NULL)
1157 if (total_clipped == 0)
1160 "estimation. Background subtraction is "
1161 "uncertain. Try to decrease KAPPA "
1162 "(current value is %f)", KAPPA);
1164 if (percentage > 40)
1168 "background estimation", percentage);
1173 check( subtract_background(image, NULL, background),
1174 "Error subtracting background polynomial");
1178 uves_free_table(&t);
1181 return cpl_error_get_code();
1230 uves_backsub_smooth(cpl_image *image,
int RADX,
int RADY,
int ITER)
1232 cpl_image *background = NULL;
1235 assure( RADX >= 0 && RADY >= 0, CPL_ERROR_ILLEGAL_INPUT,
1236 "Negative radius ((%d)x(%d))", RADX, RADY);
1237 assure( ITER >= 1, CPL_ERROR_ILLEGAL_INPUT,
1238 "Non-positive number of iterations (%d)", ITER);
1241 background = cpl_image_duplicate(image);
1243 for (i = 0; i < ITER; i++) {
1246 check( lower_to_average(background,
1247 RADX, RADY),
"Error smoothing image");
1251 check( cpl_image_subtract(image, background),
"Could not subtract background image");
1254 uves_free_image(&background);
1256 return cpl_error_get_code();
1281 sample_background(
const cpl_image *image,
int x0,
double y_0,
1282 int radius_x,
int radius_y,
int nx,
int ny,
1283 background_measure_method BM_METHOD)
1287 cpl_table *temp = NULL;
1288 bool found_good =
false;
1293 (temp = cpl_table_new( (2*radius_x + 1) * (2*radius_y + 1) ),
1295 cpl_table_new_column(temp,
"Flux", CPL_TYPE_DOUBLE)),
1296 "Error allocating table");
1298 for(y = y_0 - radius_y; y <= y_0 + radius_y; y++)
1300 for (x = x0 - radius_x; x <= x0 + radius_x; x++)
1302 if (1 <= x && x <= nx &&
1306 double flux = cpl_image_get(image, x, y, &pis_rejected);
1309 cpl_table_set(temp,
"Flux", row, flux);
1314 cpl_table_set_invalid(temp,
"Flux", row);
1319 cpl_table_set_invalid(temp,
"Flux", row);
1326 assure( found_good, CPL_ERROR_ILLEGAL_INPUT,
"No valid pixels in sample window");
1328 if (BM_METHOD == BM_MEDIAN)
1330 result = cpl_table_get_column_median(temp,
"Flux");
1332 else if (BM_METHOD == BM_MINIMUM)
1334 result = cpl_table_get_column_min(temp,
"Flux");
1338 assure(
false, CPL_ERROR_UNSUPPORTED_MODE,
1339 "Unsupported background sample method: %d", BM_METHOD);
1343 uves_free_table(&temp);
1358 first_order(
const polynomial *order_locations,
int nx)
1375 assure( result > -100000,
1377 "Invalid polynomial: p(x=1, order=%d) = %f p(x=%d, order=%d) = %f",
1399 last_order(
const polynomial *order_locations,
int nx,
int ny)
1416 assure( result < 100000,
1418 "Invalid polynomial: p(x=1, order=%d) = %f p(x=%d, order=%d) = %f",
1440 static cpl_error_code
1441 lower_to_average(cpl_image *image,
int RADX,
int RADY)
1443 cpl_image *average = NULL;
1444 double *image_data = NULL;
1445 double *average_data = NULL;
1449 passure( image != NULL,
"Null image");
1450 nx = cpl_image_get_size_x(image);
1451 ny = cpl_image_get_size_y(image);
1455 check( average = cpl_image_duplicate(image),
"Error copying image");
1459 image_data = cpl_image_get_data(image);
1460 average_data = cpl_image_get_data(average);
1462 for (y = 0; y < ny; y++)
1464 for (x = 0; x < nx; x++)
1466 if (image_data[x + y*nx] > average_data[x + y*nx])
1468 image_data[x + y*nx] = average_data[x + y*nx];
1475 uves_free_image(&average);
1477 return cpl_error_get_code();
1494 static cpl_error_code
1495 subtract_background(cpl_image *image, cpl_image *background_im,
1502 double *background_data = NULL;
1506 passure((background_im == NULL) != (background_pol == NULL),
" ");
1509 assure(cpl_image_count_rejected(image) == 0,
1510 CPL_ERROR_UNSUPPORTED_MODE,
"Input image contains bad pixels");
1511 assure(cpl_image_get_type(image) == CPL_TYPE_DOUBLE,
1512 CPL_ERROR_UNSUPPORTED_MODE,
1513 "Input image is of type %s. double expected",
1516 if (background_im != NULL)
1518 assure(cpl_image_count_rejected(background_im) == 0,
1519 CPL_ERROR_UNSUPPORTED_MODE,
"Background image contains bad pixels");
1520 assure(cpl_image_get_type(background_im) == CPL_TYPE_DOUBLE,
1521 CPL_ERROR_UNSUPPORTED_MODE,
1522 "Background image is of type %s. double expected",
1526 image_data = cpl_image_get_data_double(image);
1527 if (background_im != NULL)
1529 background_data = cpl_image_get_data_double(background_im);
1532 nx = cpl_image_get_size_x(image);
1533 ny = cpl_image_get_size_y(image);
1535 for (y = 1; y <= ny; y++)
1537 for (x = 1; x <= nx; x++)
1540 double flux, new_flux;
1542 if (background_im != NULL)
1545 back = background_data[(x-1) + (y-1) * nx];
1556 flux = image_data[(x-1) + (y-1) * nx];
1573 new_flux = uves_max_double(0, flux - back);
1575 new_flux = flux-back;
1579 image_data[(x-1) + (y-1) * nx] = new_flux;
1581 if (background_im != NULL)
1584 background_data[(x-1) + (y-1) * nx] = flux - new_flux;
1590 return cpl_error_get_code();