00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00150
00153 #ifdef HAVE_CONFIG_H
00154 # include <config.h>
00155 #endif
00156
00157 #include <uves_orderpos_follow.h>
00158
00159 #include <uves_plot.h>
00160 #include <uves_utils.h>
00161 #include <uves_utils_wrappers.h>
00162 #include <uves_error.h>
00163 #include <uves_msg.h>
00164
00165 #include <irplib_access.h>
00166 #include <cpl.h>
00167 #include <math.h>
00168 #include <float.h>
00169
00170 static cpl_table * trace_order(const cpl_table *ordertable, int order,
00171 const cpl_image *inputimage, const cpl_image *noise,
00172 const cpl_binary *image_bad,
00173 int TRACESTEP,
00174 double MAXGAP);
00175 static int count_orders(const cpl_table *tracetable);
00176 static double fit_order_linear(cpl_table *singletrace, int order, double KAPPA,
00177 double *slope);
00178 static int get_xcenter(int nx, int ny, cpl_table *ordertab, int row);
00179 static int get_ycenter(int nx, int ny, cpl_table *ordertab, int row);
00180 static int get_orderlength(int nx, int ny, cpl_table *ordertab, int row);
00181 static double estimate_threshold(const cpl_image *inputimage,
00182 const cpl_image *nosie,
00183 cpl_table *ordertable,
00184 int row, double relative_threshold);
00185 static bool find_centroid(const cpl_image *inputimage,
00186 const cpl_image *noise,
00187 const cpl_binary *image_bad,
00188 double threshold, int spacing, int x, double *yguess,
00189 double *dY);
00190
00191
00232
00233 cpl_table *
00234 uves_locate_orders(const cpl_image *inputimage, const cpl_image *noise,
00235 cpl_table *ordertable,
00236 int TRACESTEP,
00237 double MINTHRESH,
00238 double MAXGAP,
00239 double MAXRMS,
00240 int DEFPOL1, int DEFPOL2, double KAPPA,
00241 polynomial **bivariate_fit, int *orders_traced)
00242 {
00243 cpl_table *tracetable = NULL;
00244 cpl_table *singletrace = NULL;
00245 cpl_table *temp = NULL;
00246 const cpl_mask *image_badmap = NULL;
00247 const cpl_binary *image_bad = NULL;
00248 int N;
00249
00250 double mse, red_chisq;
00251 int order;
00252
00253
00254 assure_nomsg( inputimage != NULL, CPL_ERROR_NULL_INPUT);
00255 assure_nomsg( noise != NULL, CPL_ERROR_NULL_INPUT);
00256 assure( cpl_image_get_size_x(inputimage) == cpl_image_get_size_x(noise) &&
00257 cpl_image_get_size_y(inputimage) == cpl_image_get_size_y(noise),
00258 CPL_ERROR_INCOMPATIBLE_INPUT,
00259 "Image sizes are %dx%d and %dx%d",
00260 cpl_image_get_size_x(inputimage), cpl_image_get_size_x(noise),
00261 cpl_image_get_size_y(inputimage), cpl_image_get_size_y(noise));
00262
00263 assure_nomsg( ordertable != NULL, CPL_ERROR_NULL_INPUT);
00264 assure( cpl_table_get_ncol(ordertable) == 4,
00265 CPL_ERROR_ILLEGAL_INPUT,
00266 "%d columns found. 4 expected",
00267 cpl_table_get_ncol(ordertable));
00268 assure( cpl_table_has_column(ordertable, "Intersept"),
00269 CPL_ERROR_DATA_NOT_FOUND,
00270 "Missing column Intersept");
00271 assure( cpl_table_has_column(ordertable, "Slope"),
00272 CPL_ERROR_DATA_NOT_FOUND,
00273 "Missing column Slope");
00274 assure( cpl_table_has_column(ordertable, "Order"),
00275 CPL_ERROR_DATA_NOT_FOUND,
00276 "Missing column Order");
00277 assure( cpl_table_has_column(ordertable, "Spacing"),
00278 CPL_ERROR_DATA_NOT_FOUND,
00279 "Missing column Spacing");
00280
00281 image_badmap = irplib_image_get_bpm_const(inputimage);
00282 image_bad = irplib_mask_get_data_const(image_badmap);
00283
00284 N = cpl_table_get_nrow(ordertable);
00285
00286 *bivariate_fit = NULL;
00287
00288
00289 check(( tracetable = cpl_table_new(0),
00290 cpl_table_new_column(tracetable, "Order" , CPL_TYPE_INT),
00291 cpl_table_new_column(tracetable, "X" , CPL_TYPE_INT),
00292 cpl_table_new_column(tracetable, "Y" , CPL_TYPE_DOUBLE),
00293 cpl_table_new_column(tracetable, "dY" , CPL_TYPE_DOUBLE),
00294 cpl_table_new_column(tracetable, "Residual_Square", CPL_TYPE_DOUBLE),
00295 cpl_table_new_column(tracetable, "OrderRMS" , CPL_TYPE_DOUBLE),
00296 cpl_table_new_column(tracetable, "OrderSlope" , CPL_TYPE_DOUBLE)),
00297
00298 "Could not initialize order trace table");
00299
00300
00301 check(( cpl_table_new_column(ordertable, "Xcenter", CPL_TYPE_INT),
00302 cpl_table_new_column(ordertable, "Ycenter", CPL_TYPE_INT),
00303 cpl_table_new_column(ordertable, "OrderLength", CPL_TYPE_INT),
00304 cpl_table_new_column(ordertable, "Threshold", CPL_TYPE_DOUBLE),
00305 cpl_table_new_column(ordertable, "MinThreshold", CPL_TYPE_DOUBLE),
00306 cpl_table_new_column(ordertable, "RMS", CPL_TYPE_DOUBLE),
00307 cpl_table_new_column(ordertable, "TraceSlope", CPL_TYPE_DOUBLE)),
00308 "Could not add columns to order table");
00309
00310 *orders_traced = 0;
00311
00312
00313 for (order = 1; order <= N; order++)
00314 {
00315
00316 int nx = cpl_image_get_size_x(inputimage);
00317 int ny = cpl_image_get_size_y(inputimage);
00318 int points_traced = 0;
00319 int xc = get_xcenter (nx, ny, ordertable, order - 1);
00320 int yc = get_ycenter (nx, ny, ordertable, order - 1);
00321
00322 check(( cpl_table_set_int(ordertable, "Xcenter" , order - 1, xc),
00323
00324 cpl_table_set_int(ordertable, "Ycenter" , order - 1, yc),
00325 cpl_table_set_int(ordertable, "OrderLength" , order - 1,
00326 get_orderlength (nx, ny, ordertable, order - 1))),
00327 "Could not calculate order line geometry");
00328
00329 if (!(1 <= xc && xc <= nx && 1 <= yc && yc <= ny))
00330 {
00331 uves_msg_warning("Order %d: Center of order (%d, %d) is outside image "
00332 "(intersept = %.2f, slope = %f)",
00333 order, xc, yc,
00334 cpl_table_get_double(ordertable, "Intersept", order-1, NULL),
00335 cpl_table_get_double(ordertable, "Slope", order-1, NULL));
00336 }
00337 else
00338 {
00339 check( cpl_table_set_double(
00340 ordertable, "Threshold" , order - 1,
00341 estimate_threshold(inputimage, noise, ordertable, order - 1, -1)),
00342 "Could not calculate max. threshold");
00343 check( cpl_table_set_double(
00344 ordertable, "MinThreshold", order - 1,
00345 estimate_threshold(inputimage, noise, ordertable, order - 1, MINTHRESH)),
00346 "Could not calculate min. threshold");
00347 }
00348
00349
00350 uves_free_table(&singletrace);
00351 check( singletrace = trace_order(ordertable,
00352 order,
00353 inputimage,
00354 noise,
00355 image_bad,
00356 TRACESTEP,
00357 MAXGAP),
00358 "Error occured while tracing order #%d", order);
00359
00360 check( points_traced = cpl_table_get_nrow(singletrace), "Could not read table size");
00361
00362 passure( cpl_table_get_ncol(singletrace) == 3, "%d", cpl_table_get_ncol(singletrace));
00363 passure( cpl_table_has_column(singletrace, "X"), " ");
00364 passure( cpl_table_has_column(singletrace, "Y"), " ");
00365 passure( cpl_table_has_column(singletrace, "dY"), " ");
00366
00367
00368
00369 if (points_traced == 0)
00370 {
00371 uves_msg_warning("Could not trace order #%d", order);
00372 check( cpl_table_set_invalid(ordertable, "RMS", order - 1),
00373 "Could not flag order %d RMS as invalid", order);
00374 }
00375 else
00376 {
00377 double rms=0;
00378 double slope=0;
00379
00380
00381
00382 check( rms = fit_order_linear(singletrace, order, KAPPA, &slope),
00383 "Creating linear fit of order #%d failed", order);
00384
00385 check(( cpl_table_set_double(ordertable, "RMS", order - 1, rms),
00386 cpl_table_fill_column_window_double(singletrace, "OrderRMS",
00387 0, points_traced, rms)),
00388 "Could not write RMS of order #%d to tables", order);
00389
00390 check(( cpl_table_set_double(ordertable, "TraceSlope", order - 1, slope),
00391 cpl_table_fill_column_window_double(singletrace, "OrderSlope",
00392 0, points_traced, slope)),
00393 "Could not write slope of order #%d to tables", order);
00394
00395
00396 passure( cpl_table_get_ncol(singletrace) == 7, "%d",
00397 cpl_table_get_ncol(singletrace));
00398 passure( cpl_table_has_column(singletrace, "X"), " ");
00399 passure( cpl_table_has_column(singletrace, "Y"), " ");
00400 passure( cpl_table_has_column(singletrace, "dY"), " ");
00401 passure( cpl_table_has_column(singletrace, "Linear fit"), " ");
00402 passure( cpl_table_has_column(singletrace, "Residual_Square"), " ");
00403 passure( cpl_table_has_column(singletrace, "OrderRMS"), " ");
00404 passure( cpl_table_has_column(singletrace, "OrderSlope"), " ");
00405
00406
00407 check( cpl_table_erase_column(singletrace, "Linear fit"),
00408 "Could not delete column 'Linear fit'");
00409
00410
00411 check(( cpl_table_new_column(singletrace, "Order", CPL_TYPE_INT),
00412 cpl_table_fill_column_window_int(
00413 singletrace, "Order",
00414 0, cpl_table_get_nrow(singletrace), order)
00415 ),
00416 "Could not create new column 'Order'");
00417
00418
00419 passure( cpl_table_compare_structure(singletrace, tracetable) == 0, " ");
00420
00421
00422 check( cpl_table_insert(tracetable, singletrace,
00423 cpl_table_get_nrow(tracetable)),
00424 "Could not append single order #%d to trace table", order);
00425
00426 *orders_traced += 1;
00427 }
00428
00429 }
00430
00431
00432 check( uves_plot_table(tracetable, "X", "Y",
00433 "Initial trace (%d orders)", *orders_traced),
00434 "Plotting failed");
00435
00436
00437 passure( cpl_table_get_ncol(tracetable) == 7, "%d", cpl_table_get_ncol(tracetable));
00438 passure( cpl_table_has_column(tracetable, "X"), " ");
00439 passure( cpl_table_has_column(tracetable, "Order"), " ");
00440 passure( cpl_table_has_column(tracetable, "Y"), " ");
00441 passure( cpl_table_has_column(tracetable, "dY"), " ");
00442 passure( cpl_table_has_column(tracetable, "Residual_Square"), " ");
00443 passure( cpl_table_has_column(tracetable, "OrderRMS"), " ");
00444 passure( cpl_table_has_column(tracetable, "OrderSlope"), " ");
00445
00446 assure(*orders_traced >= 1, CPL_ERROR_ILLEGAL_OUTPUT, "No orders could be traced");
00447
00448
00449 {
00450 double maxrms;
00451 int orders_rejected;
00452 check( maxrms =
00453 uves_max_double(0.05, MAXRMS * cpl_table_get_column_median(ordertable, "RMS")),
00454 "Could not read median RMS");
00455
00456 uves_msg_debug("Maximum admissible RMS is %.2f pixels", maxrms);
00457
00458
00459 check( orders_rejected = uves_select_table_rows(
00460 ordertable, "RMS", CPL_GREATER_THAN, maxrms),
00461 "Could not select rows in order table");
00462
00463
00464 if (orders_rejected > 0)
00465 {
00466 uves_msg_warning("%d order(s) rejected because RMS "
00467 "(from linear fit) was too large", orders_rejected);
00468
00469
00470 check( uves_erase_table_rows(tracetable, "OrderRMS",
00471 CPL_GREATER_THAN, maxrms),
00472 "Could not erase bad orders from trace table");
00473
00474
00475 }
00476 else
00477 {
00478 uves_msg_debug("All RMSs are less than %.2f", maxrms);
00479 }
00480
00481
00482
00483
00484
00485
00486 check_nomsg( orders_rejected =
00487 uves_select_table_rows(
00488 ordertable, "TraceSlope", CPL_GREATER_THAN, 0.5) +
00489 uves_select_table_rows(
00490 ordertable, "TraceSlope", CPL_LESS_THAN, -0.5));
00491
00492 if (orders_rejected > 0) {
00493 uves_msg_warning("%d order(s) rejected because slope was outside [-0.5 ; 0.5]",
00494 orders_rejected);
00495
00496 check_nomsg( uves_erase_table_rows(tracetable, "OrderSlope",
00497 CPL_GREATER_THAN, 0.5));
00498 check_nomsg( uves_erase_table_rows(tracetable, "OrderSlope",
00499 CPL_LESS_THAN, -0.5));
00500 }
00501 else {
00502 uves_msg_debug("All line slopes are within [-0.5 ; 0.5]");
00503 }
00504 }
00505
00506
00507
00508
00509 {
00510 double dy_median = cpl_table_get_column_median(tracetable, "dY");
00511 double threshold = 0.40*dy_median;
00512 int nreject;
00513
00514 check_nomsg( nreject = uves_erase_table_rows(tracetable, "dY", CPL_LESS_THAN,
00515 threshold) );
00516
00517 uves_msg_debug("Rejected %d points with dY less than %f pixels (median = %f pixels)",
00518 nreject, threshold, dy_median);
00519 }
00520
00521
00522
00523
00524 if (DEFPOL1 < 0 || DEFPOL2 < 0)
00525 {
00526 int deg1, deg2;
00527 int new_deg1, new_deg2;
00528 double red_chisq1, mse1;
00529 double red_chisq2, mse2;
00530 double red_chisq3, mse3;
00531 bool adjust1 = (DEFPOL1 < 0);
00532
00533 bool adjust2 = (DEFPOL2 < 0);
00534 int finished;
00535
00536
00537
00538 int number_of_orders = 0;
00539
00540 int number_of_orders1 = 0;
00541 int number_of_orders2 = 0;
00542 int number_of_orders3 = 0;
00543
00544 if (adjust1)
00545 {
00546
00547 DEFPOL1 = 1;
00548 deg1 = 1;
00549 }
00550 else
00551 {
00552
00553 deg1 = DEFPOL1;
00554 }
00555 if (adjust2)
00556 {
00557
00558 DEFPOL2 = 1;
00559 deg2 = 1;
00560 }
00561 else
00562 {
00563
00564 deg2 = DEFPOL2;
00565 }
00566
00567 uves_free_table(&temp);
00568 temp = cpl_table_duplicate(tracetable);
00569 uves_polynomial_delete(bivariate_fit);
00570 check( *bivariate_fit = uves_polynomial_regression_2d(
00571 temp,
00572 "X", "Order", "Y", "dY",
00573 deg1,
00574 deg2,
00575 NULL, NULL, NULL,
00576 &mse, &red_chisq,
00577 NULL,
00578 KAPPA, -1),
00579 "Error fitting orders");
00580
00581 check( number_of_orders = count_orders(temp),
00582 "Error counting orders");
00583
00584 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00585 "Red.chi^2 = %.2f (%d orders) *",
00586 deg1,
00587 deg2,
00588 sqrt(mse),
00589 red_chisq,
00590 number_of_orders);
00591
00592
00593
00594
00595
00596 do
00597 {
00598 int maxdegree = 6;
00599 finished = 0;
00600
00601 adjust1 = adjust1 && (deg1 + 1 <= maxdegree);
00602 adjust2 = adjust2 && (deg2 + 1 <= maxdegree);
00603
00604
00605 if (adjust1)
00606 {
00607 uves_free_table(&temp);
00608 temp = cpl_table_duplicate(tracetable);
00609 uves_polynomial_delete(bivariate_fit);
00610 *bivariate_fit = uves_polynomial_regression_2d(
00611 temp,
00612 "X", "Order", "Y", "dY",
00613 deg1 + 1,
00614 deg2,
00615 NULL, NULL, NULL,
00616 &mse1, &red_chisq1,
00617 NULL,
00618 KAPPA, -1);
00619
00620 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
00621 {
00622 uves_error_reset();
00623 mse1 = -1;
00624 red_chisq1 = DBL_MAX/2;
00625 }
00626 else
00627 {
00628 assure( cpl_error_get_code() == CPL_ERROR_NONE,
00629 cpl_error_get_code(),
00630 "Error fitting orders");
00631
00632 check( number_of_orders1 = count_orders(temp),
00633 "Error counting orders");
00634 }
00635 }
00636
00637
00638 if (adjust2)
00639 {
00640 uves_free_table(&temp);
00641 temp = cpl_table_duplicate(tracetable);
00642 uves_polynomial_delete(bivariate_fit);
00643 *bivariate_fit = uves_polynomial_regression_2d(
00644 temp,
00645 "X", "Order", "Y", "dY",
00646 deg1,
00647 deg2 + 1,
00648 NULL, NULL, NULL,
00649 &mse2, &red_chisq2,
00650 NULL,
00651 KAPPA, -1);
00652
00653 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
00654 {
00655 uves_error_reset();
00656 mse2 = -1;
00657 red_chisq2 = DBL_MAX/2;
00658 }
00659 else
00660 {
00661 assure( cpl_error_get_code() == CPL_ERROR_NONE,
00662 cpl_error_get_code(),
00663 "Error fitting orders");
00664
00665 check( number_of_orders2 = count_orders(temp),
00666 "Error counting orders");
00667 }
00668 }
00669
00670
00671 if (adjust1 && adjust2)
00672 {
00673 uves_free_table(&temp);
00674 temp = cpl_table_duplicate(tracetable);
00675 uves_polynomial_delete(bivariate_fit);
00676 *bivariate_fit = uves_polynomial_regression_2d(
00677 temp,
00678 "X", "Order", "Y", "dY",
00679 deg1 + 1,
00680 deg2 + 1,
00681 NULL, NULL, NULL,
00682 &mse3, &red_chisq3,
00683 NULL,
00684 KAPPA, -1);
00685
00686 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
00687 {
00688 uves_error_reset();
00689 mse3 = -1;
00690 red_chisq3 = DBL_MAX/2;
00691 }
00692 else
00693 {
00694 assure( cpl_error_get_code() == CPL_ERROR_NONE,
00695 cpl_error_get_code(),
00696 "Error fitting orders");
00697
00698 check( number_of_orders3 = count_orders(temp),
00699 "Error counting orders");
00700 }
00701 }
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 new_deg1 = deg1;
00715 new_deg2 = deg2;
00716 if (adjust1 && mse1 >= 0 && (red_chisq - red_chisq1)/red_chisq > 0.1 &&
00717 red_chisq1 <= red_chisq2)
00718 {
00719 new_deg1++;
00720 mse = mse1;
00721 red_chisq = red_chisq1;
00722 finished = 1;
00723
00724 if (number_of_orders1 >= number_of_orders)
00725 {
00726 DEFPOL1 = new_deg1;
00727 DEFPOL2 = new_deg2;
00728 number_of_orders = number_of_orders1;
00729 }
00730 }
00731 else if (adjust2 && mse2 >= 0 && (red_chisq - red_chisq2)/red_chisq > 0.1 &&
00732 red_chisq2 < red_chisq1)
00733 {
00734 new_deg2++;
00735 mse = mse2;
00736 red_chisq = red_chisq2;
00737 finished = 2;
00738
00739 if (number_of_orders2 >= number_of_orders)
00740 {
00741 DEFPOL1 = new_deg1;
00742 DEFPOL2 = new_deg2;
00743 number_of_orders = number_of_orders2;
00744 }
00745 }
00746 else if (adjust1 && adjust2 &&
00747 mse3 >= 0 && (red_chisq - red_chisq3)/red_chisq > 0.1)
00748 {
00749 new_deg1++;
00750 new_deg2++;
00751 mse = mse3;
00752 red_chisq = red_chisq3;
00753 finished = 3;
00754
00755 if (number_of_orders3 >= number_of_orders)
00756 {
00757 DEFPOL1 = new_deg1;
00758 DEFPOL2 = new_deg2;
00759 number_of_orders = number_of_orders3;
00760 }
00761 }
00762
00763
00764
00765
00766 if (adjust1)
00767 {
00768 if (mse1 >= 0)
00769 {
00770 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00771 "Red.chi^2 = %.3f (%d orders)%s",
00772 deg1 + 1,
00773 deg2,
00774 sqrt(mse1),
00775 red_chisq1,
00776 number_of_orders1,
00777 (finished == 1) ? " *" : "");
00778 }
00779 else
00780 {
00781 uves_msg_low("(%d, %d)-degree: Singular matrix",
00782 deg1 + 1,
00783 deg2);
00784 }
00785 }
00786
00787 if (adjust2)
00788 {
00789 if (mse2 >= 0)
00790 {
00791 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00792 "Red.chi^2 = %.3f (%d orders)%s",
00793 deg1,
00794 deg2 + 1,
00795 sqrt(mse2),
00796 red_chisq2,
00797 number_of_orders2,
00798 (finished == 2) ? " *" : "");
00799 }
00800 else
00801 {
00802 uves_msg_low("(%d, %d)-degree: Singular matrix",
00803 deg1,
00804 deg2 + 1);
00805 }
00806 }
00807
00808 if (adjust1 && adjust2)
00809 {
00810 if (mse3 >= 0)
00811 {
00812 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00813 "Red.chi^2 = %.3f (%d orders)%s",
00814 deg1 + 1,
00815 deg2 + 1,
00816 sqrt(mse3),
00817 red_chisq3,
00818 number_of_orders3,
00819 (finished == 3) ? " *" : "");
00820 }
00821 else
00822 {
00823 uves_msg_low("(%d, %d)-degree: Singular matrix",
00824 deg1 + 1,
00825 deg2 + 1);
00826 }
00827 }
00828
00829 if (finished != 0)
00830 {
00831 uves_msg_debug("Moved to degree (%d, %d), finished = %d, "
00832 "DEFPOL = %d, %d",
00833 new_deg1, new_deg2, finished, DEFPOL1, DEFPOL2);
00834 }
00835
00836 deg1 = new_deg1;
00837 deg2 = new_deg2;
00838
00839 } while (finished != 0);
00840
00841 uves_msg_low("Using degree (%d, %d)", DEFPOL1, DEFPOL2);
00842
00843 }
00844
00845
00846 uves_polynomial_delete(bivariate_fit);
00847 check( *bivariate_fit = uves_polynomial_regression_2d(tracetable,
00848 "X", "Order", "Y", "dY",
00849 DEFPOL1,
00850 DEFPOL2,
00851 "Yfit", NULL, "dYfit_Square",
00852 &mse, &red_chisq,
00853 NULL,
00854 KAPPA, -1),
00855 "Error fitting orders");
00856
00857 uves_msg("RMS error of (%d, %d)-degree fit is %.3f pixels. Reduced chi^2 is %.3f",
00858 DEFPOL1,
00859 DEFPOL2,
00860 sqrt(mse),
00861 red_chisq);
00862
00863
00864 if (sqrt(mse) > 0.3)
00865 {
00866 uves_msg_warning("RMS of bivariate fit (%.2f pixels) "
00867 "is larger than 0.3 pixels", sqrt(mse));
00868 }
00869 if (red_chisq < .01)
00870 {
00871 uves_msg_warning("Reduced chi^2 of fit is less than 1/100: %f", red_chisq);
00872 }
00873 if (red_chisq > 100)
00874 {
00875 uves_msg_warning("Reduced chi^2 of fit is greater than 100: %f", red_chisq);
00876 }
00877
00878
00879 check(( cpl_table_duplicate_column(tracetable, "Residual", tracetable, "Y"),
00880 cpl_table_subtract_columns(tracetable, "Residual", "Yfit")),
00881 "Error calculating residuals of fit");
00882
00883
00884 {
00885 check( *orders_traced = count_orders(tracetable),
00886 "Error counting orders");
00887
00888 uves_msg("%d order(s) were traced", *orders_traced);
00889 if (*orders_traced < N)
00890 {
00891 uves_msg_warning("Rejected %d order(s)", N - *orders_traced);
00892 }
00893 }
00894
00895
00896 check( uves_plot_table(tracetable, "X", "Yfit", "%d orders detected", *orders_traced),
00897 "Plotting failed");
00898 check( uves_plot_table(tracetable, "X", "Residual",
00899 "Residual of fit (RMS = %.3f pixels; red.chi^2 = %f)",
00900 sqrt(mse), red_chisq), "Plotting failed");
00901 check( uves_plot_table(tracetable, "Y", "Residual",
00902 "Residual of fit (RMS = %.3f pixels; red.chi^2 = %f)",
00903 sqrt(mse), red_chisq), "Plotting failed");
00904
00905 cleanup:
00906 uves_free_table(&temp);
00907 uves_free_table(&singletrace);
00908 if (cpl_error_get_code() != CPL_ERROR_NONE)
00909 {
00910 uves_free_table(&tracetable);
00911 }
00912
00913 return tracetable;
00914 }
00915
00916
00917
00925 static int
00926 count_orders(const cpl_table *tracetable)
00927 {
00928 int number = 0;
00929 int previous = -1;
00930 int row;
00931
00932 passure( tracetable != NULL, " ");
00933 passure( cpl_table_has_column(tracetable, "Order"), " ");
00934
00935 for (row = 0; row < cpl_table_get_nrow(tracetable); row++)
00936 {
00937 int current;
00938 current = cpl_table_get_int(tracetable, "Order", row, NULL);
00939 if (current != previous)
00940 {
00941 number++;
00942 }
00943 previous = current;
00944 }
00945
00946 cleanup:
00947 return number;
00948
00949 }
00950
00951
00952
00967
00968
00969 static double
00970 fit_order_linear(cpl_table *singletrace, int order, double KAPPA,
00971 double *slope)
00972 {
00973 double mse = 0;
00974 double intersept;
00975 cpl_table *temp = NULL;
00976 polynomial *pol = NULL;
00977
00978 passure( slope != NULL, " ");
00979 passure( cpl_table_get_ncol(singletrace) == 3, "%d", cpl_table_get_ncol(singletrace));
00980 passure( cpl_table_has_column(singletrace, "X"), " ");
00981 passure( cpl_table_has_column(singletrace, "Y"), " ");
00982 passure( cpl_table_has_column(singletrace, "dY")," ");
00983
00984 check( temp = cpl_table_duplicate(singletrace),
00985 "Error cloning table");
00986
00987 if (cpl_table_get_nrow(temp) == 1)
00988 {
00989
00990
00991 check(( cpl_table_set_size(temp, 2),
00992 cpl_table_set_int (temp, "X", 1, uves_max_int(
00993 cpl_table_get_int (temp, "X", 0, NULL) - 1, 1)),
00994 cpl_table_set_double(temp, "Y", 1,
00995 cpl_table_get_double(temp, "Y", 0, NULL)),
00996 cpl_table_set_double(temp, "dY", 1,
00997 cpl_table_get_double(temp, "dY",0, NULL))),
00998 "Could not add point");
00999 }
01000
01001
01002
01003 check( pol = uves_polynomial_regression_1d(temp,
01004 "X", "Y", NULL,
01005
01006 1,
01007 NULL, NULL,
01008 &mse,
01009 KAPPA),
01010 "Fitting of order %d failed", order);
01011
01012 intersept = uves_polynomial_get_coeff_1d(pol, 0);
01013 *slope = uves_polynomial_get_coeff_1d(pol, 1);
01014
01015 uves_msg_debug("The RMS error of order #%d is %.2f pixels; "
01016 "slope = %f; intersept = %f",
01017 order, sqrt(mse),
01018 *slope, intersept);
01019
01020
01021 {
01022 int i;
01023
01024 check(( cpl_table_new_column(singletrace, "Linear fit", CPL_TYPE_DOUBLE),
01025 cpl_table_new_column(singletrace, "Residual_Square", CPL_TYPE_DOUBLE)),
01026 "Error adding table columns");
01027
01028 for (i = 0; i < cpl_table_get_nrow(singletrace); i++)
01029 {
01030 int x = cpl_table_get_int (singletrace, "X", i, NULL);
01031 double y = cpl_table_get_double(singletrace, "Y", i, NULL);
01032
01033 double linear_fit, residual;
01034
01035 check (linear_fit = uves_polynomial_evaluate_1d(pol, x),
01036 "Error evaluating polynomial");
01037
01038 residual = y - linear_fit;
01039
01040 check(( cpl_table_set_double(singletrace, "Linear fit", i, linear_fit),
01041 cpl_table_set_double(singletrace, "Residual_Square",
01042 i, residual*residual)),
01043 "Error updating table");
01044 }
01045 }
01046
01047
01048 check(( cpl_table_new_column(singletrace, "OrderRMS", CPL_TYPE_DOUBLE),
01049 cpl_table_new_column(singletrace, "OrderSlope", CPL_TYPE_DOUBLE),
01050 cpl_table_fill_column_window_double(
01051 singletrace, "OrderRMS", 0, cpl_table_get_nrow(singletrace), sqrt(mse)),
01052 cpl_table_fill_column_window_double(
01053 singletrace, "OrderSlope", 0, cpl_table_get_nrow(singletrace), *slope)),
01054 "Could not create columns OrderRMS and OrderSlope");
01055
01056 passure( cpl_table_get_ncol(singletrace) == 7, "%d", cpl_table_get_ncol(singletrace));
01057 passure( cpl_table_has_column(singletrace, "X"), " ");
01058 passure( cpl_table_has_column(singletrace, "Y"), " ");
01059 passure( cpl_table_has_column(singletrace, "dY")," ");
01060 passure( cpl_table_has_column(singletrace, "Linear fit"), " ");
01061 passure( cpl_table_has_column(singletrace, "Residual_Square"), " ");
01062 passure( cpl_table_has_column(singletrace, "OrderRMS"), " ");
01063 passure( cpl_table_has_column(singletrace, "OrderSlope"), " ");
01064
01065 cleanup:
01066 uves_free_table(&temp);
01067 uves_polynomial_delete(&pol);
01068 return sqrt(mse);
01069
01070 }
01071
01072
01099
01100
01101 static cpl_table *
01102 trace_order(const cpl_table *ordertable, int order,
01103 const cpl_image *inputimage, const cpl_image *noise,
01104 const cpl_binary *image_bad,
01105 int TRACESTEP,
01106 double MAXGAP)
01107 {
01108 cpl_table *singletrace = NULL;
01109 int tracerow;
01110 int DIRECTION;
01111 double slope;
01112 double threshold;
01113 double minthreshold;
01114 int nx;
01115 int xcenter;
01116 int ycenter;
01117 int orderlength;
01118 int order_spacing;
01119 int xmax, xmin;
01120
01121 nx = cpl_image_get_size_x(inputimage);
01122
01123 check(( singletrace =
01124 cpl_table_new(nx/TRACESTEP + 2),
01125 cpl_table_new_column(singletrace, "X", CPL_TYPE_INT),
01126 cpl_table_new_column(singletrace, "Y", CPL_TYPE_DOUBLE),
01127 cpl_table_new_column(singletrace, "dY",CPL_TYPE_DOUBLE),
01128 tracerow = 0),
01129 "Could not initialize tracetable");
01130
01131
01132
01133
01134
01135
01136
01137 check((xcenter = cpl_table_get_int (ordertable, "Xcenter" , order - 1, NULL),
01138 ycenter = cpl_table_get_int (ordertable, "Ycenter" , order - 1, NULL),
01139 orderlength = cpl_table_get_int (ordertable, "OrderLength" , order - 1, NULL),
01140 order_spacing= cpl_table_get_int (ordertable, "Spacing" , order - 1, NULL),
01141 threshold = cpl_table_get_double(ordertable, "Threshold" , order - 1, NULL),
01142 minthreshold = cpl_table_get_double(ordertable, "MinThreshold", order - 1, NULL)),
01143 "Reading order table failed");
01144
01145
01146 threshold = minthreshold;
01147
01148
01149
01150 tracerow = 0;
01151
01152 xmax = xmin = xcenter;
01153
01154
01155 for (DIRECTION = -1; DIRECTION <= 1; DIRECTION += 2) {
01156
01157 int x = xcenter;
01158 double y = (double) ycenter;
01159 double dy = 0;
01160 int gap_size = 0;
01161
01162 check( slope = cpl_table_get_double(
01163 ordertable, "Slope", order - 1, NULL),
01164 "Could not read slope from table");
01165
01166 if (xcenter < nx/10 || xcenter > (nx*99)/100) {
01167
01168 x = 0;
01169
01170
01171
01172 }
01173
01174 while(1 <= x && x <= nx && gap_size < MAXGAP*nx) {
01175 bool found;
01176
01177 check( found = find_centroid(
01178 inputimage, noise, image_bad, threshold,
01179 order_spacing, x, &y, &dy),
01180 "Could not get order line position");
01181
01182
01183
01184
01185 if (found &&
01186 (y - ycenter)/(x - xcenter) > -1 &&
01187 (y - ycenter)/(x - xcenter) < 1) {
01188
01189
01190 xmax = uves_max_int(xmax, x);
01191 xmin = uves_min_int(xmin, x);
01192
01193 uves_msg_debug("(Order, x, y, dy, threshold) = "
01194 "(%d, %d, %f, %f, %f)",
01195 order, x, y, dy, threshold);
01196
01197 if (!(x == xcenter && DIRECTION == 1))
01198
01199
01200
01201
01202 {
01203 cpl_table_set_int (
01204 singletrace, "X", tracerow, x);
01205 cpl_table_set_double(
01206 singletrace, "Y", tracerow, y);
01207 if (dy > 0) {
01208 cpl_table_set_double(
01209 singletrace, "dY", tracerow, dy);
01210 }
01211 else {
01212 cpl_table_set_invalid(
01213 singletrace, "dY", tracerow);
01214 }
01215 tracerow++;
01216 }
01217
01218 gap_size = 0;
01219
01220 }
01221 else {
01222 gap_size += TRACESTEP;
01223 }
01224
01225
01226 x = x + DIRECTION * TRACESTEP;
01227 y = y + slope*DIRECTION * TRACESTEP;
01228
01229 slope = (y - ycenter)/(x - xcenter);
01230
01231 }
01232
01233 }
01234
01235
01236
01237 uves_msg_debug("%d points were traced in order %d", tracerow, order);
01238
01239
01240 check( cpl_table_set_size(singletrace, tracerow), "Could not resize tracetable");
01241
01242
01243
01244
01245 {
01246 double dy_median;
01247
01248 if (cpl_table_has_valid(singletrace, "dY"))
01249 {
01250
01251 dy_median = cpl_table_get_column_median(singletrace, "dY");
01252 }
01253 else
01254 {
01255 dy_median = 1.0;
01256 }
01257
01258
01259 cpl_table_select_all(singletrace);
01260 cpl_table_and_selected_invalid(singletrace, "dY");
01261 {
01262 int i;
01263 for (i = 0; i < cpl_table_get_nrow(singletrace); i++)
01264 {
01265 if (cpl_table_is_selected(singletrace, i))
01266 {
01267 cpl_table_set_double(singletrace, "dY", i, dy_median);
01268 }
01269 }
01270 }
01271 }
01272
01273
01274 check( uves_sort_table_1(singletrace, "X", false), "Could not sort order table");
01275
01276 cleanup:
01277 if (cpl_error_get_code() != CPL_ERROR_NONE)
01278 {
01279 uves_free_table(&singletrace);
01280 }
01281
01282 return singletrace;
01283 }
01284
01285
01298
01299 static int
01300 get_orderlength(int nx, int ny, cpl_table *ordertable, int row)
01301 {
01302 int x0 = 0, y_0, x1 = 0, y_1;
01303 double intersept, slope;
01304
01305 check(( intersept = cpl_table_get_double(ordertable, "Intersept", row, NULL),
01306 slope = cpl_table_get_double(ordertable, "Slope", row, NULL)),
01307 "Could not read line from ordertable");
01308
01309
01310 x0 = 1;
01311 y_0 = uves_round_double(intersept + slope*x0);
01312
01313
01314 if (y_0 < 1)
01315 {
01316 y_0 = 1;
01317 x0 = uves_round_double((y_0 - intersept)/slope);
01318 }
01319
01320
01321 x1 = nx;
01322 y_1 = uves_round_double(intersept + slope*nx);
01323 if (y_1 > ny)
01324 {
01325 y_1 = ny;
01326 x1 = uves_round_double((y_1 - intersept)/slope);
01327 }
01328
01329 cleanup:
01330 return (x1 - x0);
01331 }
01332
01333
01334
01347
01348 static int
01349 get_xcenter(int nx, int ny, cpl_table *ordertable, int row)
01350 {
01351 int x0, y_0, x1, y_1, xc = 0;
01352 double intersept, slope;
01353 check(( intersept = cpl_table_get_double(ordertable, "Intersept", row, NULL),
01354 slope = cpl_table_get_double(ordertable, "Slope", row, NULL)),
01355 "Could not read line from ordertable");
01356
01357
01358 x0 = 1;
01359 y_0 = uves_round_double(intersept + slope*x0);
01360
01361
01362 if (y_0 < 1)
01363 {
01364 y_0 = 1;
01365 x0 = uves_round_double((y_0 - intersept)/slope);
01366
01367 }
01368
01369
01370
01371 x1 = nx;
01372 y_1 = uves_round_double(intersept + slope*nx);
01373
01374
01375 if (y_1 > ny)
01376 {
01377 y_1 = ny;
01378 x1 = uves_round_double((y_1 - intersept)/slope);
01379 }
01380
01381 xc = (x0 + x1)/2;
01382
01383 cleanup:
01384 return xc;
01385 }
01386
01387
01399
01400 static int
01401 get_ycenter(int nx, int ny, cpl_table *ordertable, int row)
01402 {
01403 int xc = 0;
01404 int yc = 0;
01405 check( xc = get_xcenter(nx, ny, ordertable, row), "Could not find x-center of order");
01406
01407 check( yc = uves_round_double(
01408 cpl_table_get_double(ordertable, "Slope" , row, NULL)*xc +
01409 cpl_table_get_double(ordertable, "Intersept", row, NULL)
01410 ), "Could not read line from ordertable");
01411
01412 cleanup:
01413 return yc;
01414 }
01415
01416
01432
01433 static double
01434 estimate_threshold(const cpl_image *inputimage, const cpl_image *noise,
01435 cpl_table *ordertable, int row, double relative_threshold)
01436 {
01437 int yupper = 0;
01438 int ylower = 0;
01439 int xc, yc;
01440 int N;
01441 int ny;
01442 double returnvalue = 0;
01443 cpl_stats *stats = NULL;
01444
01445 passure( inputimage != NULL, " ");
01446 passure( ordertable != NULL, " ");
01447 passure( cpl_table_get_int(ordertable, "Order", row, NULL) == row+1, "%d %d",
01448 cpl_table_get_int(ordertable, "Order", row, NULL), row);
01449
01450 check( ny = cpl_image_get_size_y(inputimage), "Could not read input image dimension");
01451
01452 check( N = cpl_table_get_nrow(ordertable), "Could not read size of ordertable");
01453 assure(N > 1, CPL_ERROR_ILLEGAL_INPUT,
01454 "Cannot calculate orderspacing with less than 2 (i.e. %d) orders.", N);
01455 check( xc = cpl_table_get_int(ordertable, "Xcenter", row, NULL),
01456 "Could not read x-center of order #%d", row+1);
01457 check( yc = cpl_table_get_int(ordertable, "Ycenter", row, NULL),
01458 "Could not find y-center of order #%d", row+1);
01459
01460
01461
01462
01463
01464
01465 if (row < N - 1)
01466 {
01467 double ynext;
01468 check(ynext =
01469 cpl_table_get_double(ordertable, "Slope" , row + 1, NULL)*xc +
01470 cpl_table_get_double(ordertable, "Intersept", row + 1, NULL),
01471 "Could not read line from ordertable row %d", row + 1);
01472
01473 yupper = (int)((yc + (uves_round_double(ynext)-1))/2);
01474
01475 }
01476
01477 if (row > 0)
01478 {
01479 double yprev;
01480 check( yprev =
01481 cpl_table_get_double(ordertable, "Slope" , row - 1, NULL)*xc +
01482 cpl_table_get_double(ordertable, "Intersept", row - 1, NULL),
01483 "Could not read line from ordertable row %d", row - 1);
01484
01485 ylower = (int)((yc + uves_round_double(yprev)-1)/2);
01486
01487 }
01488
01489
01490
01491 if (row == N-1)
01492 {
01493 yupper = yc + (yc - ylower);
01494 }
01495 if (row == 0)
01496 {
01497 ylower = yc - (yupper - yc);
01498 }
01499 yupper = uves_min_int(uves_max_int(yupper, 1), ny);
01500 ylower = uves_min_int(uves_max_int(ylower, 1), ny);
01501
01502
01503
01504
01505
01506 assure(yupper > ylower, CPL_ERROR_ILLEGAL_INPUT,
01507 "Initially detected order lines intersept!");
01508
01509
01510 {
01511 double minval = 0;
01512 double maxval = 0;
01513 double noise_level = 0;
01514
01515
01516 check( stats = cpl_stats_new_from_image_window(
01517 inputimage,
01518 CPL_STATS_MIN | CPL_STATS_MAX | CPL_STATS_MINPOS,
01519 xc, ylower,
01520 xc, yupper),
01521 "Could not get statistics on image sub-window (%d,%d)-(%d,%d)",
01522 xc, ylower, xc, yupper);
01523
01524 check(( minval = cpl_stats_get_min(stats),
01525 maxval = cpl_stats_get_max(stats)),
01526 "Could not get minimum and maximum pixel values");
01527
01528
01529 {
01530 int xpos, ypos, pis_rejected;
01531 xpos = cpl_stats_get_min_x(stats);
01532 ypos = cpl_stats_get_min_y(stats);
01533 noise_level = cpl_image_get(noise, xpos, ypos, &pis_rejected);
01534 }
01535
01536
01537 returnvalue = uves_max_double(minval + relative_threshold * (maxval - minval),
01538 (minval + noise_level) + noise_level);
01539
01540 uves_msg_debug("Order: %d \tThreshold: %f \tMinimum: %f \tMaximum: %f"
01541 " \tNoise: %f \tWindow: (%d, %d)-(%d, %d)",
01542 row+1, returnvalue, minval, maxval, noise_level, xc, ylower, xc, yupper);
01543 }
01544
01545 cleanup:
01546 uves_free_stats(&stats);
01547 return returnvalue;
01548 }
01549
01550
01573
01574 static bool
01575 find_centroid(const cpl_image *inputimage, const cpl_image *noise,
01576 const cpl_binary *image_bad,
01577 double threshold, int spacing, int x, double *yguess, double *dY)
01578 {
01579 bool returnvalue = true;
01580 int nx;
01581 int ny;
01582 int y;
01583 double thisvalue = 0;
01584 int pis_rejected;
01585 int ylow = 0;
01586 int yhigh = 0;
01587 cpl_matrix *covariance = NULL;
01588
01589 passure( inputimage != NULL, " ");
01590
01591 nx = cpl_image_get_size_x(inputimage);
01592 ny = cpl_image_get_size_y(inputimage);
01593
01594 passure( 1 <= x && x <= nx, "%d %d", x, nx);
01595
01596 uves_msg_debug("Order location estimate = (%d, %f)", x, *yguess);
01597
01598
01599
01600 y = uves_round_double(*yguess);
01601 if (y < 1 || y > ny)
01602 {
01603 returnvalue = false;
01604 }
01605 else {
01606 bool cont;
01607
01608 do {
01609 cont = false;
01610 thisvalue = cpl_image_get(inputimage, x, y , &pis_rejected);
01611
01612 if (y < ny) {
01613 double uppervalue = cpl_image_get(inputimage, x, y + 1, &pis_rejected);
01614 if (!pis_rejected && uppervalue > thisvalue)
01615 {
01616 y += 1;
01617 cont = true;
01618 }
01619 }
01620
01621
01622 if (y > 1) {
01623 double lowervalue = cpl_image_get(inputimage, x, y - 1, &pis_rejected);
01624 if (!pis_rejected && lowervalue > thisvalue)
01625 {
01626 y -= 1;
01627 cont = true;
01628 }
01629 }
01630
01631 } while (cont);
01632
01633
01634
01635 uves_msg_debug("Local maximum at (%d, %d) (value = %f)\tthreshold = %f",
01636 x, y, thisvalue, threshold);
01637
01638
01639 if (thisvalue < threshold)
01640 {
01641 uves_msg_debug("Order not traced at (%d, %d) (value = %f)\tthreshold = %f",
01642 x, y, thisvalue, threshold);
01643 returnvalue = false;
01644 }
01645 else
01646 {
01647
01648 double minvalue;
01649 double sigmaY;
01650
01651 double mse, rms, chi_sq;
01652 double background;
01653 double norm;
01654
01655
01656 minvalue = 0.5*thisvalue;
01657
01658
01659 while(y > 1 && cpl_image_get(inputimage, x, y - 1, &pis_rejected) >= minvalue)
01660 {
01661 y--;
01662 }
01663
01664 assure( cpl_error_get_code() == CPL_ERROR_NONE,
01665 cpl_error_get_code(), "Could not read pixel from input image" );
01666
01667
01668 ylow = y;
01669
01670
01671 while(y < ny && cpl_image_get(inputimage, x, y + 1, &pis_rejected) >= minvalue)
01672 {
01673 y++;
01674 }
01675
01676 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
01677 "Could not read pixel from input image" );
01678
01679
01680 yhigh = y;
01681
01682
01683
01684 {
01685 double sum = 0;
01686 double sumy = 0;
01687 double sumy2= 0;
01688 for (y = ylow; y <= yhigh; y++)
01689 {
01690 double flux;
01691 flux = cpl_image_get(inputimage, x, y, &pis_rejected) - minvalue;
01692 if (!pis_rejected && flux > 0)
01693 {
01694 sum += flux;
01695 sumy += flux * (y - *yguess*0);
01696 sumy2 += flux * (y - *yguess*0) * (y - *yguess*0);
01697 }
01698 }
01699 if (sum > 0)
01700 {
01701 *yguess = *yguess*0 + sumy / sum;
01702 sigmaY = sqrt( sumy2 / sum - sumy*sumy/(sum*sum) );
01703
01704 if ( sumy2 / sum - sumy*sumy/(sum*sum) < 0 ||
01705 sigmaY < sqrt(1.0/12) )
01706 {
01707
01708
01709
01710
01711 sigmaY = sqrt(1.0/12);
01712 }
01713
01714
01715
01716 *dY = sigmaY/sqrt(sum);
01717
01718 }
01719 else
01720 {
01721
01722 sigmaY = 1.0;
01723 *dY = .1;
01724
01725 }
01726 }
01727
01728
01729
01730
01731
01732 ylow = uves_max_int(1 , uves_round_double(*yguess - spacing/3));
01733 yhigh = uves_min_int(ny, uves_round_double(*yguess + spacing/3));
01734
01735 assure( yhigh - ylow >= 1, CPL_ERROR_ILLEGAL_INPUT,
01736 "Estimated spacing too small: %d pixel(s)", spacing);
01737
01738
01739 uves_fit_1d_image(inputimage, noise,
01740 image_bad,
01741 false, false, false,
01742 ylow, yhigh, x,
01743 yguess, &sigmaY, &norm, &background, NULL,
01744 &mse, &chi_sq, &covariance,
01745 uves_gauss, uves_gauss_derivative, 4);
01746
01747
01748 if (cpl_error_get_code() == CPL_ERROR_NONE)
01749 {
01750
01751 *dY = sqrt(cpl_matrix_get(covariance, 0, 0));
01752 }
01753 else if (cpl_error_get_code() == CPL_ERROR_CONTINUE)
01754 {
01755
01756 uves_error_reset();
01757 uves_msg_debug("Fitting failed at (x,y) = (%d, %e), "
01758 "using centroid", x, *yguess);
01759 *dY = sigmaY / sqrt(norm);
01760 }
01761 else if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
01762 {
01763 uves_error_reset();
01764
01765
01766 uves_msg_debug("Covariance matrix computation failed");
01767 *dY = sigmaY / sqrt(norm);
01768 }
01769
01770 assure(cpl_error_get_code() == CPL_ERROR_NONE,
01771 cpl_error_get_code(), "Gaussian fitting failed");
01772
01773 rms = sqrt(mse);
01774
01775 uves_msg_debug("dy = %f sigma/sqrt(N) = %f", *dY, sigmaY/(norm));
01776
01777
01778
01779 if ( norm > 10 * rms)
01780 {
01781 returnvalue = true;
01782 }
01783 if ( norm < 2 * rms)
01784 {
01785 returnvalue = false;
01786 }
01787
01788 }
01789
01790 }
01791
01792 cleanup:
01793 cpl_matrix_delete(covariance);
01794 return returnvalue;
01795 }