175 #include <uves_orderpos_follow.h>
177 #include <uves_plot.h>
178 #include <uves_utils.h>
179 #include <uves_utils_wrappers.h>
180 #include <uves_error.h>
181 #include <uves_msg.h>
187 static cpl_table *
trace_order(
const cpl_table *ordertable,
int order,
188 const cpl_image *inputimage,
const cpl_image *noise,
189 const cpl_binary *image_bad,
193 static double fit_order_linear(cpl_table *singletrace,
int order,
double KAPPA,
195 static int get_xcenter(
int nx,
int ny, cpl_table *ordertab,
int row);
196 static int get_ycenter(
int nx,
int ny, cpl_table *ordertab,
int row);
197 static int get_orderlength(
int nx,
int ny, cpl_table *ordertab,
int row);
199 const cpl_image *nosie,
200 cpl_table *ordertable,
201 int row,
double relative_threshold);
203 const cpl_image *noise,
204 const cpl_binary *image_bad,
205 double threshold,
int spacing,
int x,
double *yguess,
251 const cpl_image *noise,
252 cpl_table *ordertable,
263 cpl_table *tracetable = NULL;
264 cpl_table *singletrace = NULL;
265 cpl_table *temp = NULL;
266 const cpl_mask *image_badmap = NULL;
267 const cpl_binary *image_bad = NULL;
270 double mse, red_chisq;
274 assure_nomsg( inputimage != NULL, CPL_ERROR_NULL_INPUT);
276 assure( cpl_image_get_size_x(inputimage) == cpl_image_get_size_x(noise) &&
277 cpl_image_get_size_y(inputimage) == cpl_image_get_size_y(noise),
278 CPL_ERROR_INCOMPATIBLE_INPUT,
279 "Image sizes are %" CPL_SIZE_FORMAT
"x%" CPL_SIZE_FORMAT
" and %" CPL_SIZE_FORMAT
"x%" CPL_SIZE_FORMAT
"",
280 cpl_image_get_size_x(inputimage), cpl_image_get_size_x(noise),
281 cpl_image_get_size_y(inputimage), cpl_image_get_size_y(noise));
283 assure_nomsg( ordertable != NULL, CPL_ERROR_NULL_INPUT);
284 assure( cpl_table_get_ncol(ordertable) == 4,
285 CPL_ERROR_ILLEGAL_INPUT,
286 "%" CPL_SIZE_FORMAT
" columns found. 4 expected",
287 cpl_table_get_ncol(ordertable));
288 assure( cpl_table_has_column(ordertable,
"Intersept"),
289 CPL_ERROR_DATA_NOT_FOUND,
290 "Missing column Intersept");
291 assure( cpl_table_has_column(ordertable,
"Slope"),
292 CPL_ERROR_DATA_NOT_FOUND,
293 "Missing column Slope");
294 assure( cpl_table_has_column(ordertable,
"Order"),
295 CPL_ERROR_DATA_NOT_FOUND,
296 "Missing column Order");
297 assure( cpl_table_has_column(ordertable,
"Spacing"),
298 CPL_ERROR_DATA_NOT_FOUND,
299 "Missing column Spacing");
303 image_badmap = cpl_image_get_bpm_const(inputimage);
304 image_bad = cpl_mask_get_data_const(image_badmap);
306 N = cpl_table_get_nrow(ordertable);
308 *bivariate_fit = NULL;
311 check(( tracetable = cpl_table_new(0),
312 cpl_table_new_column(tracetable,
"Order" , CPL_TYPE_INT),
313 cpl_table_new_column(tracetable,
"X" , CPL_TYPE_INT),
314 cpl_table_new_column(tracetable,
"Y" , CPL_TYPE_DOUBLE),
315 cpl_table_new_column(tracetable,
"dY" , CPL_TYPE_DOUBLE),
316 cpl_table_new_column(tracetable,
"Residual_Square", CPL_TYPE_DOUBLE),
317 cpl_table_new_column(tracetable,
"OrderRMS" , CPL_TYPE_DOUBLE),
318 cpl_table_new_column(tracetable,
"OrderSlope" , CPL_TYPE_DOUBLE)),
320 "Could not initialize order trace table");
323 check(( cpl_table_new_column(ordertable,
"Xcenter", CPL_TYPE_INT),
324 cpl_table_new_column(ordertable,
"Ycenter", CPL_TYPE_INT),
325 cpl_table_new_column(ordertable,
"OrderLength", CPL_TYPE_INT),
326 cpl_table_new_column(ordertable,
"Threshold", CPL_TYPE_DOUBLE),
327 cpl_table_new_column(ordertable,
"MinThreshold", CPL_TYPE_DOUBLE),
328 cpl_table_new_column(ordertable,
"RMS", CPL_TYPE_DOUBLE),
329 cpl_table_new_column(ordertable,
"TraceSlope", CPL_TYPE_DOUBLE)),
330 "Could not add columns to order table");
335 for (order = 1; order <= N; order++)
338 int nx = cpl_image_get_size_x(inputimage);
339 int ny = cpl_image_get_size_y(inputimage);
340 int points_traced = 0;
341 int xc =
get_xcenter (nx, ny, ordertable, order - 1);
342 int yc =
get_ycenter (nx, ny, ordertable, order - 1);
344 check(( cpl_table_set_int(ordertable,
"Xcenter" , order - 1, xc),
346 cpl_table_set_int(ordertable,
"Ycenter" , order - 1, yc),
347 cpl_table_set_int(ordertable,
"OrderLength" , order - 1,
349 "Could not calculate order line geometry");
351 if (!(1 <= xc && xc <= nx && 1 <= yc && yc <= ny))
354 "(intersept = %.2f, slope = %f)",
356 cpl_table_get_double(ordertable,
"Intersept", order-1, NULL),
357 cpl_table_get_double(ordertable,
"Slope", order-1, NULL));
361 check( cpl_table_set_double(
362 ordertable,
"Threshold" , order - 1,
364 "Could not calculate max. threshold");
365 check( cpl_table_set_double(
366 ordertable,
"MinThreshold", order - 1,
368 "Could not calculate min. threshold");
372 uves_free_table(&singletrace);
380 "Error occured while tracing order #%d", order);
382 check( points_traced = cpl_table_get_nrow(singletrace),
"Could not read table size");
384 passure( cpl_table_get_ncol(singletrace) == 3,
"%" CPL_SIZE_FORMAT
"", cpl_table_get_ncol(singletrace));
385 passure( cpl_table_has_column(singletrace,
"X"),
" ");
386 passure( cpl_table_has_column(singletrace,
"Y"),
" ");
387 passure( cpl_table_has_column(singletrace,
"dY"),
" ");
391 if (points_traced == 0)
394 check( cpl_table_set_invalid(ordertable,
"RMS", order - 1),
395 "Could not flag order %d RMS as invalid", order);
405 "Creating linear fit of order #%d failed", order);
407 check(( cpl_table_set_double(ordertable,
"RMS", order - 1, rms),
408 cpl_table_fill_column_window_double(singletrace,
"OrderRMS",
409 0, points_traced, rms)),
410 "Could not write RMS of order #%d to tables", order);
412 check(( cpl_table_set_double(ordertable,
"TraceSlope", order - 1, slope),
413 cpl_table_fill_column_window_double(singletrace,
"OrderSlope",
414 0, points_traced, slope)),
415 "Could not write slope of order #%d to tables", order);
418 passure( cpl_table_get_ncol(singletrace) == 7,
"%" CPL_SIZE_FORMAT
"",
419 cpl_table_get_ncol(singletrace));
420 passure( cpl_table_has_column(singletrace,
"X"),
" ");
421 passure( cpl_table_has_column(singletrace,
"Y"),
" ");
422 passure( cpl_table_has_column(singletrace,
"dY"),
" ");
423 passure( cpl_table_has_column(singletrace,
"Linear fit"),
" ");
424 passure( cpl_table_has_column(singletrace,
"Residual_Square"),
" ");
425 passure( cpl_table_has_column(singletrace,
"OrderRMS"),
" ");
426 passure( cpl_table_has_column(singletrace,
"OrderSlope"),
" ");
429 check( cpl_table_erase_column(singletrace,
"Linear fit"),
430 "Could not delete column 'Linear fit'");
433 check(( cpl_table_new_column(singletrace,
"Order", CPL_TYPE_INT),
434 cpl_table_fill_column_window_int(
435 singletrace,
"Order",
436 0, cpl_table_get_nrow(singletrace), order)
438 "Could not create new column 'Order'");
441 passure( cpl_table_compare_structure(singletrace, tracetable) == 0,
" ");
444 check( cpl_table_insert(tracetable, singletrace,
445 cpl_table_get_nrow(tracetable)),
446 "Could not append single order #%d to trace table", order);
454 check( uves_plot_table(tracetable,
"X",
"Y",
455 "Initial trace (%d orders)", *orders_traced),
459 passure( cpl_table_get_ncol(tracetable) == 7,
"%" CPL_SIZE_FORMAT
"", cpl_table_get_ncol(tracetable));
460 passure( cpl_table_has_column(tracetable,
"X"),
" ");
461 passure( cpl_table_has_column(tracetable,
"Order"),
" ");
462 passure( cpl_table_has_column(tracetable,
"Y"),
" ");
463 passure( cpl_table_has_column(tracetable,
"dY"),
" ");
464 passure( cpl_table_has_column(tracetable,
"Residual_Square"),
" ");
465 passure( cpl_table_has_column(tracetable,
"OrderRMS"),
" ");
466 passure( cpl_table_has_column(tracetable,
"OrderSlope"),
" ");
468 assure(*orders_traced >= 1, CPL_ERROR_ILLEGAL_OUTPUT,
"No orders could be traced");
475 uves_max_double(0.05, MAXRMS * cpl_table_get_column_median(ordertable,
"RMS")),
476 "Could not read median RMS");
481 check( orders_rejected = uves_select_table_rows(
482 ordertable,
"RMS", CPL_GREATER_THAN, maxrms),
483 "Could not select rows in order table");
486 if (orders_rejected > 0)
489 "(from linear fit) was too large", orders_rejected);
492 check( uves_erase_table_rows(tracetable,
"OrderRMS",
493 CPL_GREATER_THAN, maxrms),
494 "Could not erase bad orders from trace table");
509 uves_select_table_rows(
510 ordertable,
"TraceSlope", CPL_GREATER_THAN, 0.5) +
511 uves_select_table_rows(
512 ordertable,
"TraceSlope", CPL_LESS_THAN, -0.5));
514 if (orders_rejected > 0) {
515 uves_msg_warning(
"%d order(s) rejected because slope was outside [-0.5 ; 0.5]",
518 check_nomsg( uves_erase_table_rows(tracetable,
"OrderSlope",
519 CPL_GREATER_THAN, 0.5));
520 check_nomsg( uves_erase_table_rows(tracetable,
"OrderSlope",
521 CPL_LESS_THAN, -0.5));
532 double dy_median = cpl_table_get_column_median(tracetable,
"dY");
533 double threshold = 0.40*dy_median;
536 check_nomsg( nreject = uves_erase_table_rows(tracetable,
"dY", CPL_LESS_THAN,
539 uves_msg_debug(
"Rejected %d points with dY less than %f pixels (median = %f pixels)",
540 nreject, threshold, dy_median);
546 if (*DEFPOL1 < 0 || *DEFPOL2 < 0)
549 int new_deg1, new_deg2;
550 double red_chisq1, mse1;
551 double red_chisq2, mse2;
552 double red_chisq3, mse3;
553 bool adjust1 = (*DEFPOL1 < 0);
555 bool adjust2 = (*DEFPOL2 < 0);
560 int number_of_orders = 0;
562 int number_of_orders1 = 0;
563 int number_of_orders2 = 0;
564 int number_of_orders3 = 0;
589 uves_free_table(&temp);
590 temp = cpl_table_duplicate(tracetable);
594 "X",
"Order",
"Y",
"dY",
601 "Error fitting orders");
604 "Error counting orders");
607 "Red.chi^2 = %.2f (%d orders) *",
623 adjust1 = adjust1 && (deg1 + 1 <= maxdegree);
624 adjust2 = adjust2 && (deg2 + 1 <= maxdegree);
629 uves_free_table(&temp);
630 temp = cpl_table_duplicate(tracetable);
634 "X",
"Order",
"Y",
"dY",
642 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
646 red_chisq1 = DBL_MAX/2;
650 assure( cpl_error_get_code() == CPL_ERROR_NONE,
651 cpl_error_get_code(),
652 "Error fitting orders");
655 "Error counting orders");
662 uves_free_table(&temp);
663 temp = cpl_table_duplicate(tracetable);
667 "X",
"Order",
"Y",
"dY",
675 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
679 red_chisq2 = DBL_MAX/2;
683 assure( cpl_error_get_code() == CPL_ERROR_NONE,
684 cpl_error_get_code(),
685 "Error fitting orders");
688 "Error counting orders");
693 if (adjust1 && adjust2)
695 uves_free_table(&temp);
696 temp = cpl_table_duplicate(tracetable);
700 "X",
"Order",
"Y",
"dY",
708 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
712 red_chisq3 = DBL_MAX/2;
716 assure( cpl_error_get_code() == CPL_ERROR_NONE,
717 cpl_error_get_code(),
718 "Error fitting orders");
721 "Error counting orders");
738 if (adjust1 && mse1 >= 0 && (red_chisq - red_chisq1)/red_chisq > 0.1 &&
739 red_chisq1 <= red_chisq2)
743 red_chisq = red_chisq1;
746 if (number_of_orders1 >= number_of_orders)
750 number_of_orders = number_of_orders1;
753 else if (adjust2 && mse2 >= 0 && (red_chisq - red_chisq2)/red_chisq > 0.1 &&
754 red_chisq2 < red_chisq1)
758 red_chisq = red_chisq2;
761 if (number_of_orders2 >= number_of_orders)
765 number_of_orders = number_of_orders2;
768 else if (adjust1 && adjust2 &&
769 mse3 >= 0 && (red_chisq - red_chisq3)/red_chisq > 0.1)
774 red_chisq = red_chisq3;
777 if (number_of_orders3 >= number_of_orders)
781 number_of_orders = number_of_orders3;
793 "Red.chi^2 = %.3f (%d orders)%s",
799 (finished == 1) ?
" *" :
"");
814 "Red.chi^2 = %.3f (%d orders)%s",
820 (finished == 2) ?
" *" :
"");
830 if (adjust1 && adjust2)
835 "Red.chi^2 = %.3f (%d orders)%s",
841 (finished == 3) ?
" *" :
"");
855 new_deg1, new_deg2, finished, *DEFPOL1, *DEFPOL2);
861 }
while (finished != 0);
863 uves_msg_low(
"Using degree (%d, %d)", *DEFPOL1, *DEFPOL2);
870 "X",
"Order",
"Y",
"dY",
873 "Yfit", NULL,
"dYfit_Square",
877 "Error fitting orders");
879 uves_msg(
"RMS error of (%d, %d)-degree fit is %.3f pixels. Reduced chi^2 is %.3f",
889 "is larger than 0.3 pixels", sqrt(mse));
897 uves_msg_warning(
"Reduced chi^2 of fit is greater than 100: %f", red_chisq);
901 check(( cpl_table_duplicate_column(tracetable,
"Residual", tracetable,
"Y"),
902 cpl_table_subtract_columns(tracetable,
"Residual",
"Yfit")),
903 "Error calculating residuals of fit");
908 "Error counting orders");
910 uves_msg(
"%d order(s) were traced", *orders_traced);
911 if (*orders_traced < N)
918 check( uves_plot_table(tracetable,
"X",
"Yfit",
"%d orders detected", *orders_traced),
920 check( uves_plot_table(tracetable,
"X",
"Residual",
921 "Residual of fit (RMS = %.3f pixels; red.chi^2 = %f)",
922 sqrt(mse), red_chisq),
"Plotting failed");
923 check( uves_plot_table(tracetable,
"Y",
"Residual",
924 "Residual of fit (RMS = %.3f pixels; red.chi^2 = %f)",
925 sqrt(mse), red_chisq),
"Plotting failed");
928 uves_free_table(&temp);
929 uves_free_table(&singletrace);
930 if (cpl_error_get_code() != CPL_ERROR_NONE)
932 uves_free_table(&tracetable);
954 passure( tracetable != NULL,
" ");
955 passure( cpl_table_has_column(tracetable,
"Order"),
" ");
957 for (row = 0; row < cpl_table_get_nrow(tracetable); row++)
960 current = cpl_table_get_int(tracetable,
"Order", row, NULL);
961 if (current != previous)
999 cpl_table *temp = NULL;
1003 passure( cpl_table_get_ncol(singletrace) == 3,
"%" CPL_SIZE_FORMAT
"", cpl_table_get_ncol(singletrace));
1004 passure( cpl_table_has_column(singletrace,
"X"),
" ");
1005 passure( cpl_table_has_column(singletrace,
"Y"),
" ");
1006 passure( cpl_table_has_column(singletrace,
"dY"),
" ");
1008 check( temp = cpl_table_duplicate(singletrace),
1009 "Error cloning table");
1011 if (cpl_table_get_nrow(temp) == 1)
1015 check(( cpl_table_set_size(temp, 2),
1016 cpl_table_set_int (temp,
"X", 1, uves_max_int(
1017 cpl_table_get_int (temp,
"X", 0, NULL) - 1, 1)),
1018 cpl_table_set_double(temp,
"Y", 1,
1019 cpl_table_get_double(temp,
"Y", 0, NULL)),
1020 cpl_table_set_double(temp,
"dY", 1,
1021 cpl_table_get_double(temp,
"dY",0, NULL))),
1022 "Could not add point");
1034 "Fitting of order %d failed. You may have to increase value of kappa",
1041 "slope = %f; intersept = %f",
1049 check(( cpl_table_new_column(singletrace,
"Linear fit", CPL_TYPE_DOUBLE),
1050 cpl_table_new_column(singletrace,
"Residual_Square", CPL_TYPE_DOUBLE)),
1051 "Error adding table columns");
1053 for (i = 0; i < cpl_table_get_nrow(singletrace); i++)
1055 int x = cpl_table_get_int (singletrace,
"X", i, NULL);
1056 double y = cpl_table_get_double(singletrace,
"Y", i, NULL);
1058 double linear_fit, residual;
1061 "Error evaluating polynomial");
1063 residual = y - linear_fit;
1065 check(( cpl_table_set_double(singletrace,
"Linear fit", i, linear_fit),
1066 cpl_table_set_double(singletrace,
"Residual_Square",
1067 i, residual*residual)),
1068 "Error updating table");
1073 check(( cpl_table_new_column(singletrace,
"OrderRMS", CPL_TYPE_DOUBLE),
1074 cpl_table_new_column(singletrace,
"OrderSlope", CPL_TYPE_DOUBLE),
1075 cpl_table_fill_column_window_double(
1076 singletrace,
"OrderRMS", 0, cpl_table_get_nrow(singletrace), sqrt(mse)),
1077 cpl_table_fill_column_window_double(
1078 singletrace,
"OrderSlope", 0, cpl_table_get_nrow(singletrace), *slope)),
1079 "Could not create columns OrderRMS and OrderSlope");
1081 passure( cpl_table_get_ncol(singletrace) == 7,
"%" CPL_SIZE_FORMAT
"", cpl_table_get_ncol(singletrace));
1082 passure( cpl_table_has_column(singletrace,
"X"),
" ");
1083 passure( cpl_table_has_column(singletrace,
"Y"),
" ");
1084 passure( cpl_table_has_column(singletrace,
"dY"),
" ");
1085 passure( cpl_table_has_column(singletrace,
"Linear fit"),
" ");
1086 passure( cpl_table_has_column(singletrace,
"Residual_Square"),
" ");
1087 passure( cpl_table_has_column(singletrace,
"OrderRMS"),
" ");
1088 passure( cpl_table_has_column(singletrace,
"OrderSlope"),
" ");
1091 uves_free_table(&temp);
1128 const cpl_image *inputimage,
const cpl_image *noise,
1129 const cpl_binary *image_bad,
1133 cpl_table *singletrace = NULL;
1138 double minthreshold;
1146 nx = cpl_image_get_size_x(inputimage);
1148 check(( singletrace =
1149 cpl_table_new(nx/TRACESTEP + 2),
1150 cpl_table_new_column(singletrace,
"X", CPL_TYPE_INT),
1151 cpl_table_new_column(singletrace,
"Y", CPL_TYPE_DOUBLE),
1152 cpl_table_new_column(singletrace,
"dY",CPL_TYPE_DOUBLE),
1154 "Could not initialize tracetable");
1162 check((xcenter = cpl_table_get_int (ordertable,
"Xcenter" , order - 1, NULL),
1163 ycenter = cpl_table_get_int (ordertable,
"Ycenter" , order - 1, NULL),
1164 orderlength = cpl_table_get_int (ordertable,
"OrderLength" , order - 1, NULL),
1165 order_spacing= cpl_table_get_int (ordertable,
"Spacing" , order - 1, NULL),
1166 threshold = cpl_table_get_double(ordertable,
"Threshold" , order - 1, NULL),
1167 minthreshold = cpl_table_get_double(ordertable,
"MinThreshold", order - 1, NULL)),
1168 "Reading order table failed");
1171 threshold = minthreshold;
1180 for (DIRECTION = -1; DIRECTION <= 1; DIRECTION += 2) {
1183 double y = (double) ycenter;
1187 check( slope = cpl_table_get_double(
1188 ordertable,
"Slope", order - 1, NULL),
1189 "Could not read slope from table");
1191 if (xcenter < nx/10 || xcenter > (nx*99)/100) {
1199 while(1 <= x && x <= nx && gap_size < MAXGAP*nx) {
1203 inputimage, noise, image_bad, threshold,
1204 order_spacing, x, &y, &dy),
1205 "Could not get order line position");
1211 (y - ycenter)/(x - xcenter) > -1 &&
1212 (y - ycenter)/(x - xcenter) < 1) {
1215 xmax = uves_max_int(xmax, x);
1216 xmin = uves_min_int(xmin, x);
1219 "(%d, %d, %f, %f, %f)",
1220 order, x, y, dy, threshold);
1222 if (!(x == xcenter && DIRECTION == 1))
1229 singletrace,
"X", tracerow, x);
1230 cpl_table_set_double(
1231 singletrace,
"Y", tracerow, y);
1233 cpl_table_set_double(
1234 singletrace,
"dY", tracerow, dy);
1237 cpl_table_set_invalid(
1238 singletrace,
"dY", tracerow);
1247 gap_size += TRACESTEP;
1251 x = x + DIRECTION * TRACESTEP;
1252 y = y + slope*DIRECTION * TRACESTEP;
1254 slope = (y - ycenter)/(x - xcenter);
1262 uves_msg_debug(
"%d points were traced in order %d", tracerow, order);
1265 check( cpl_table_set_size(singletrace, tracerow),
"Could not resize tracetable");
1273 if (cpl_table_has_valid(singletrace,
"dY"))
1276 dy_median = cpl_table_get_column_median(singletrace,
"dY");
1284 cpl_table_select_all(singletrace);
1285 cpl_table_and_selected_invalid(singletrace,
"dY");
1288 for (i = 0; i < cpl_table_get_nrow(singletrace); i++)
1290 if (cpl_table_is_selected(singletrace, i))
1292 cpl_table_set_double(singletrace,
"dY", i, dy_median);
1299 check( uves_sort_table_1(singletrace,
"X",
false),
"Could not sort order table");
1302 if (cpl_error_get_code() != CPL_ERROR_NONE)
1304 uves_free_table(&singletrace);
1327 int x0 = 0, y_0, x1 = 0, y_1;
1328 double intersept, slope;
1330 check(( intersept = cpl_table_get_double(ordertable,
"Intersept", row, NULL),
1331 slope = cpl_table_get_double(ordertable,
"Slope", row, NULL)),
1332 "Could not read line from ordertable");
1336 y_0 = uves_round_double(intersept + slope*x0);
1342 x0 = uves_round_double((y_0 - intersept)/slope);
1347 y_1 = uves_round_double(intersept + slope*nx);
1351 x1 = uves_round_double((y_1 - intersept)/slope);
1376 int x0, y_0, x1, y_1, xc = 0;
1377 double intersept, slope;
1378 check(( intersept = cpl_table_get_double(ordertable,
"Intersept", row, NULL),
1379 slope = cpl_table_get_double(ordertable,
"Slope", row, NULL)),
1380 "Could not read line from ordertable");
1384 y_0 = uves_round_double(intersept + slope*x0);
1390 x0 = uves_round_double((y_0 - intersept)/slope);
1397 y_1 = uves_round_double(intersept + slope*nx);
1403 x1 = uves_round_double((y_1 - intersept)/slope);
1430 check( xc =
get_xcenter(nx, ny, ordertable, row),
"Could not find x-center of order");
1432 check( yc = uves_round_double(
1433 cpl_table_get_double(ordertable,
"Slope" , row, NULL)*xc +
1434 cpl_table_get_double(ordertable,
"Intersept", row, NULL)
1435 ),
"Could not read line from ordertable");
1460 cpl_table *ordertable,
int row,
double relative_threshold)
1467 double returnvalue = 0;
1468 cpl_stats *stats = NULL;
1470 passure( inputimage != NULL,
" ");
1471 passure( ordertable != NULL,
" ");
1472 passure( cpl_table_get_int(ordertable,
"Order", row, NULL) == row+1,
"%d %d",
1473 cpl_table_get_int(ordertable,
"Order", row, NULL), row);
1475 check( ny = cpl_image_get_size_y(inputimage),
"Could not read input image dimension");
1477 check( N = cpl_table_get_nrow(ordertable),
"Could not read size of ordertable");
1478 assure(N > 1, CPL_ERROR_ILLEGAL_INPUT,
1479 "Cannot calculate orderspacing with less than 2 (i.e. %d) orders.", N);
1480 check( xc = cpl_table_get_int(ordertable,
"Xcenter", row, NULL),
1481 "Could not read x-center of order #%d", row+1);
1482 check( yc = cpl_table_get_int(ordertable,
"Ycenter", row, NULL),
1483 "Could not find y-center of order #%d", row+1);
1494 cpl_table_get_double(ordertable,
"Slope" , row + 1, NULL)*xc +
1495 cpl_table_get_double(ordertable,
"Intersept", row + 1, NULL),
1496 "Could not read line from ordertable row %d", row + 1);
1498 yupper = (int)((yc + (uves_round_double(ynext)-1))/2);
1506 cpl_table_get_double(ordertable,
"Slope" , row - 1, NULL)*xc +
1507 cpl_table_get_double(ordertable,
"Intersept", row - 1, NULL),
1508 "Could not read line from ordertable row %d", row - 1);
1510 ylower = (int)((yc + uves_round_double(yprev)-1)/2);
1518 yupper = yc + (yc - ylower);
1522 ylower = yc - (yupper - yc);
1524 yupper = uves_min_int(uves_max_int(yupper, 1), ny);
1525 ylower = uves_min_int(uves_max_int(ylower, 1), ny);
1531 assure(yupper > ylower, CPL_ERROR_ILLEGAL_INPUT,
1532 "Initially detected order lines intersept!");
1538 double noise_level = 0;
1541 check( stats = cpl_stats_new_from_image_window(
1543 CPL_STATS_MIN | CPL_STATS_MAX | CPL_STATS_MINPOS,
1546 "Could not get statistics on image sub-window (%d,%d)-(%d,%d)",
1547 xc, ylower, xc, yupper);
1549 check(( minval = cpl_stats_get_min(stats),
1550 maxval = cpl_stats_get_max(stats)),
1551 "Could not get minimum and maximum pixel values");
1555 int xpos, ypos, pis_rejected;
1556 xpos = cpl_stats_get_min_x(stats);
1557 ypos = cpl_stats_get_min_y(stats);
1558 noise_level = cpl_image_get(noise, xpos, ypos, &pis_rejected);
1562 returnvalue = uves_max_double(minval + relative_threshold * (maxval - minval),
1563 (minval + noise_level) + noise_level);
1565 uves_msg_debug(
"Order: %d \tThreshold: %f \tMinimum: %f \tMaximum: %f"
1566 " \tNoise: %f \tWindow: (%d, %d)-(%d, %d)",
1567 row+1, returnvalue, minval, maxval, noise_level, xc, ylower, xc, yupper);
1571 uves_free_stats(&stats);
1601 const cpl_binary *image_bad,
1602 double threshold,
int spacing,
int x,
double *yguess,
double *dY)
1604 bool returnvalue =
true;
1608 double thisvalue = 0;
1612 cpl_matrix *covariance = NULL;
1614 passure( inputimage != NULL,
" ");
1616 nx = cpl_image_get_size_x(inputimage);
1617 ny = cpl_image_get_size_y(inputimage);
1619 passure( 1 <= x && x <= nx,
"%d %d", x, nx);
1621 uves_msg_debug(
"Order location estimate = (%d, %f)", x, *yguess);
1625 y = uves_round_double(*yguess);
1626 if (y < 1 || y > ny)
1628 returnvalue =
false;
1635 thisvalue = cpl_image_get(inputimage, x, y , &pis_rejected);
1638 double uppervalue = cpl_image_get(inputimage, x, y + 1, &pis_rejected);
1639 if (!pis_rejected && uppervalue > thisvalue)
1648 double lowervalue = cpl_image_get(inputimage, x, y - 1, &pis_rejected);
1649 if (!pis_rejected && lowervalue > thisvalue)
1660 uves_msg_debug(
"Local maximum at (%d, %d) (value = %f)\tthreshold = %f",
1661 x, y, thisvalue, threshold);
1664 if (thisvalue < threshold)
1666 uves_msg_debug(
"Order not traced at (%d, %d) (value = %f)\tthreshold = %f",
1667 x, y, thisvalue, threshold);
1668 returnvalue =
false;
1676 double mse, rms, chi_sq;
1681 minvalue = 0.5*thisvalue;
1684 while(y > 1 && cpl_image_get(inputimage, x, y - 1, &pis_rejected) >= minvalue)
1689 assure( cpl_error_get_code() == CPL_ERROR_NONE,
1690 cpl_error_get_code(),
"Could not read pixel from input image" );
1696 while(y < ny && cpl_image_get(inputimage, x, y + 1, &pis_rejected) >= minvalue)
1701 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
1702 "Could not read pixel from input image" );
1713 for (y = ylow; y <= yhigh; y++)
1716 flux = cpl_image_get(inputimage, x, y, &pis_rejected) - minvalue;
1717 if (!pis_rejected && flux > 0)
1720 sumy += flux * (y - *yguess*0);
1721 sumy2 += flux * (y - *yguess*0) * (y - *yguess*0);
1726 *yguess = *yguess*0 + sumy / sum;
1727 sigmaY = sqrt( sumy2 / sum - sumy*sumy/(sum*sum) );
1729 if ( sumy2 / sum - sumy*sumy/(sum*sum) < 0 ||
1730 sigmaY < sqrt(1.0/12) )
1736 sigmaY = sqrt(1.0/12);
1741 *dY = sigmaY/sqrt(sum);
1757 ylow = uves_max_int(1 , uves_round_double(*yguess - spacing/3));
1758 yhigh = uves_min_int(ny, uves_round_double(*yguess + spacing/3));
1760 assure( yhigh - ylow >= 1, CPL_ERROR_ILLEGAL_INPUT,
1761 "Estimated spacing too small: %d pixel(s)", spacing);
1764 uves_fit_1d_image(inputimage, noise,
1766 false,
false,
false,
1768 yguess, &sigmaY, &norm, &background, NULL,
1769 &mse, &chi_sq, &covariance,
1773 if (cpl_error_get_code() == CPL_ERROR_NONE)
1776 *dY = sqrt(cpl_matrix_get(covariance, 0, 0));
1778 else if (cpl_error_get_code() == CPL_ERROR_CONTINUE)
1783 "using centroid", x, *yguess);
1784 *dY = sigmaY / sqrt(norm);
1786 else if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
1792 *dY = sigmaY / sqrt(norm);
1795 assure(cpl_error_get_code() == CPL_ERROR_NONE,
1796 cpl_error_get_code(),
"Gaussian fitting failed");
1800 uves_msg_debug(
"dy = %f sigma/sqrt(N) = %f", *dY, sigmaY/(norm));
1804 if ( norm > 10 * rms)
1808 if ( norm < 2 * rms)
1810 returnvalue =
false;
1818 cpl_matrix_delete(covariance);