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
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00171
00174 #ifdef HAVE_CONFIG_H
00175 # include <config.h>
00176 #endif
00177
00178 #include <uves_orderpos_follow.h>
00179
00180 #include <uves_plot.h>
00181 #include <uves_utils.h>
00182 #include <uves_utils_wrappers.h>
00183 #include <uves_error.h>
00184 #include <uves_msg.h>
00185
00186 #include <cpl.h>
00187 #include <math.h>
00188 #include <float.h>
00189
00190 static cpl_table * trace_order(const cpl_table *ordertable, int order,
00191 const cpl_image *inputimage, const cpl_image *noise,
00192 const cpl_binary *image_bad,
00193 int TRACESTEP,
00194 double MAXGAP);
00195 static int count_orders(const cpl_table *tracetable);
00196 static double fit_order_linear(cpl_table *singletrace, int order, double KAPPA,
00197 double *slope);
00198 static int get_xcenter(int nx, int ny, cpl_table *ordertab, int row);
00199 static int get_ycenter(int nx, int ny, cpl_table *ordertab, int row);
00200 static int get_orderlength(int nx, int ny, cpl_table *ordertab, int row);
00201 static double estimate_threshold(const cpl_image *inputimage,
00202 const cpl_image *nosie,
00203 cpl_table *ordertable,
00204 int row, double relative_threshold);
00205 static bool find_centroid(const cpl_image *inputimage,
00206 const cpl_image *noise,
00207 const cpl_binary *image_bad,
00208 double threshold, int spacing, int x, double *yguess,
00209 double *dY);
00210
00211
00251
00252 cpl_table *
00253 uves_locate_orders(const cpl_image *inputimage,
00254 const cpl_image *noise,
00255 cpl_table *ordertable,
00256 int TRACESTEP,
00257 double MINTHRESH,
00258 double MAXGAP,
00259 double MAXRMS,
00260 int *DEFPOL1,
00261 int *DEFPOL2,
00262 double KAPPA,
00263 polynomial **bivariate_fit,
00264 int *orders_traced)
00265 {
00266 cpl_table *tracetable = NULL;
00267 cpl_table *singletrace = NULL;
00268 cpl_table *temp = NULL;
00269 const cpl_mask *image_badmap = NULL;
00270 const cpl_binary *image_bad = NULL;
00271 int N;
00272
00273 double mse, red_chisq;
00274 int order;
00275
00276
00277 assure_nomsg( inputimage != NULL, CPL_ERROR_NULL_INPUT);
00278 assure_nomsg( noise != NULL, CPL_ERROR_NULL_INPUT);
00279 assure( cpl_image_get_size_x(inputimage) == cpl_image_get_size_x(noise) &&
00280 cpl_image_get_size_y(inputimage) == cpl_image_get_size_y(noise),
00281 CPL_ERROR_INCOMPATIBLE_INPUT,
00282 "Image sizes are %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT " and %" CPL_SIZE_FORMAT "x%" CPL_SIZE_FORMAT "",
00283 cpl_image_get_size_x(inputimage), cpl_image_get_size_x(noise),
00284 cpl_image_get_size_y(inputimage), cpl_image_get_size_y(noise));
00285
00286 assure_nomsg( ordertable != NULL, CPL_ERROR_NULL_INPUT);
00287 assure( cpl_table_get_ncol(ordertable) == 4,
00288 CPL_ERROR_ILLEGAL_INPUT,
00289 "%" CPL_SIZE_FORMAT " columns found. 4 expected",
00290 cpl_table_get_ncol(ordertable));
00291 assure( cpl_table_has_column(ordertable, "Intersept"),
00292 CPL_ERROR_DATA_NOT_FOUND,
00293 "Missing column Intersept");
00294 assure( cpl_table_has_column(ordertable, "Slope"),
00295 CPL_ERROR_DATA_NOT_FOUND,
00296 "Missing column Slope");
00297 assure( cpl_table_has_column(ordertable, "Order"),
00298 CPL_ERROR_DATA_NOT_FOUND,
00299 "Missing column Order");
00300 assure( cpl_table_has_column(ordertable, "Spacing"),
00301 CPL_ERROR_DATA_NOT_FOUND,
00302 "Missing column Spacing");
00303 assure_nomsg( DEFPOL1 != NULL, CPL_ERROR_NULL_INPUT );
00304 assure_nomsg( DEFPOL2 != NULL, CPL_ERROR_NULL_INPUT );
00305
00306 image_badmap = cpl_image_get_bpm_const(inputimage);
00307 image_bad = cpl_mask_get_data_const(image_badmap);
00308
00309 N = cpl_table_get_nrow(ordertable);
00310
00311 *bivariate_fit = NULL;
00312
00313
00314 check(( tracetable = cpl_table_new(0),
00315 cpl_table_new_column(tracetable, "Order" , CPL_TYPE_INT),
00316 cpl_table_new_column(tracetable, "X" , CPL_TYPE_INT),
00317 cpl_table_new_column(tracetable, "Y" , CPL_TYPE_DOUBLE),
00318 cpl_table_new_column(tracetable, "dY" , CPL_TYPE_DOUBLE),
00319 cpl_table_new_column(tracetable, "Residual_Square", CPL_TYPE_DOUBLE),
00320 cpl_table_new_column(tracetable, "OrderRMS" , CPL_TYPE_DOUBLE),
00321 cpl_table_new_column(tracetable, "OrderSlope" , CPL_TYPE_DOUBLE)),
00322
00323 "Could not initialize order trace table");
00324
00325
00326 check(( cpl_table_new_column(ordertable, "Xcenter", CPL_TYPE_INT),
00327 cpl_table_new_column(ordertable, "Ycenter", CPL_TYPE_INT),
00328 cpl_table_new_column(ordertable, "OrderLength", CPL_TYPE_INT),
00329 cpl_table_new_column(ordertable, "Threshold", CPL_TYPE_DOUBLE),
00330 cpl_table_new_column(ordertable, "MinThreshold", CPL_TYPE_DOUBLE),
00331 cpl_table_new_column(ordertable, "RMS", CPL_TYPE_DOUBLE),
00332 cpl_table_new_column(ordertable, "TraceSlope", CPL_TYPE_DOUBLE)),
00333 "Could not add columns to order table");
00334
00335 *orders_traced = 0;
00336
00337
00338 for (order = 1; order <= N; order++)
00339 {
00340
00341 int nx = cpl_image_get_size_x(inputimage);
00342 int ny = cpl_image_get_size_y(inputimage);
00343 int points_traced = 0;
00344 int xc = get_xcenter (nx, ny, ordertable, order - 1);
00345 int yc = get_ycenter (nx, ny, ordertable, order - 1);
00346
00347 check(( cpl_table_set_int(ordertable, "Xcenter" , order - 1, xc),
00348
00349 cpl_table_set_int(ordertable, "Ycenter" , order - 1, yc),
00350 cpl_table_set_int(ordertable, "OrderLength" , order - 1,
00351 get_orderlength (nx, ny, ordertable, order - 1))),
00352 "Could not calculate order line geometry");
00353
00354 if (!(1 <= xc && xc <= nx && 1 <= yc && yc <= ny))
00355 {
00356 uves_msg_warning("Order %d: Center of order (%d, %d) is outside image "
00357 "(intersept = %.2f, slope = %f)",
00358 order, xc, yc,
00359 cpl_table_get_double(ordertable, "Intersept", order-1, NULL),
00360 cpl_table_get_double(ordertable, "Slope", order-1, NULL));
00361 }
00362 else
00363 {
00364 check( cpl_table_set_double(
00365 ordertable, "Threshold" , order - 1,
00366 estimate_threshold(inputimage, noise, ordertable, order - 1, -1)),
00367 "Could not calculate max. threshold");
00368 check( cpl_table_set_double(
00369 ordertable, "MinThreshold", order - 1,
00370 estimate_threshold(inputimage, noise, ordertable, order - 1, MINTHRESH)),
00371 "Could not calculate min. threshold");
00372 }
00373
00374
00375 uves_free_table(&singletrace);
00376 check( singletrace = trace_order(ordertable,
00377 order,
00378 inputimage,
00379 noise,
00380 image_bad,
00381 TRACESTEP,
00382 MAXGAP),
00383 "Error occured while tracing order #%d", order);
00384
00385 check( points_traced = cpl_table_get_nrow(singletrace), "Could not read table size");
00386
00387 passure( cpl_table_get_ncol(singletrace) == 3, "%" CPL_SIZE_FORMAT "", cpl_table_get_ncol(singletrace));
00388 passure( cpl_table_has_column(singletrace, "X"), " ");
00389 passure( cpl_table_has_column(singletrace, "Y"), " ");
00390 passure( cpl_table_has_column(singletrace, "dY"), " ");
00391
00392
00393
00394 if (points_traced == 0)
00395 {
00396 uves_msg_warning("Could not trace order #%d", order);
00397 check( cpl_table_set_invalid(ordertable, "RMS", order - 1),
00398 "Could not flag order %d RMS as invalid", order);
00399 }
00400 else
00401 {
00402 double rms=0;
00403 double slope=0;
00404
00405
00406
00407 check( rms = fit_order_linear(singletrace, order, KAPPA, &slope),
00408 "Creating linear fit of order #%d failed", order);
00409
00410 check(( cpl_table_set_double(ordertable, "RMS", order - 1, rms),
00411 cpl_table_fill_column_window_double(singletrace, "OrderRMS",
00412 0, points_traced, rms)),
00413 "Could not write RMS of order #%d to tables", order);
00414
00415 check(( cpl_table_set_double(ordertable, "TraceSlope", order - 1, slope),
00416 cpl_table_fill_column_window_double(singletrace, "OrderSlope",
00417 0, points_traced, slope)),
00418 "Could not write slope of order #%d to tables", order);
00419
00420
00421 passure( cpl_table_get_ncol(singletrace) == 7, "%" CPL_SIZE_FORMAT "",
00422 cpl_table_get_ncol(singletrace));
00423 passure( cpl_table_has_column(singletrace, "X"), " ");
00424 passure( cpl_table_has_column(singletrace, "Y"), " ");
00425 passure( cpl_table_has_column(singletrace, "dY"), " ");
00426 passure( cpl_table_has_column(singletrace, "Linear fit"), " ");
00427 passure( cpl_table_has_column(singletrace, "Residual_Square"), " ");
00428 passure( cpl_table_has_column(singletrace, "OrderRMS"), " ");
00429 passure( cpl_table_has_column(singletrace, "OrderSlope"), " ");
00430
00431
00432 check( cpl_table_erase_column(singletrace, "Linear fit"),
00433 "Could not delete column 'Linear fit'");
00434
00435
00436 check(( cpl_table_new_column(singletrace, "Order", CPL_TYPE_INT),
00437 cpl_table_fill_column_window_int(
00438 singletrace, "Order",
00439 0, cpl_table_get_nrow(singletrace), order)
00440 ),
00441 "Could not create new column 'Order'");
00442
00443
00444 passure( cpl_table_compare_structure(singletrace, tracetable) == 0, " ");
00445
00446
00447 check( cpl_table_insert(tracetable, singletrace,
00448 cpl_table_get_nrow(tracetable)),
00449 "Could not append single order #%d to trace table", order);
00450
00451 *orders_traced += 1;
00452 }
00453
00454 }
00455
00456
00457 check( uves_plot_table(tracetable, "X", "Y",
00458 "Initial trace (%d orders)", *orders_traced),
00459 "Plotting failed");
00460
00461
00462 passure( cpl_table_get_ncol(tracetable) == 7, "%" CPL_SIZE_FORMAT "", cpl_table_get_ncol(tracetable));
00463 passure( cpl_table_has_column(tracetable, "X"), " ");
00464 passure( cpl_table_has_column(tracetable, "Order"), " ");
00465 passure( cpl_table_has_column(tracetable, "Y"), " ");
00466 passure( cpl_table_has_column(tracetable, "dY"), " ");
00467 passure( cpl_table_has_column(tracetable, "Residual_Square"), " ");
00468 passure( cpl_table_has_column(tracetable, "OrderRMS"), " ");
00469 passure( cpl_table_has_column(tracetable, "OrderSlope"), " ");
00470
00471 assure(*orders_traced >= 1, CPL_ERROR_ILLEGAL_OUTPUT, "No orders could be traced");
00472
00473
00474 {
00475 double maxrms;
00476 int orders_rejected;
00477 check( maxrms =
00478 uves_max_double(0.05, MAXRMS * cpl_table_get_column_median(ordertable, "RMS")),
00479 "Could not read median RMS");
00480
00481 uves_msg_debug("Maximum admissible RMS is %.2f pixels", maxrms);
00482
00483
00484 check( orders_rejected = uves_select_table_rows(
00485 ordertable, "RMS", CPL_GREATER_THAN, maxrms),
00486 "Could not select rows in order table");
00487
00488
00489 if (orders_rejected > 0)
00490 {
00491 uves_msg_warning("%d order(s) rejected because RMS "
00492 "(from linear fit) was too large", orders_rejected);
00493
00494
00495 check( uves_erase_table_rows(tracetable, "OrderRMS",
00496 CPL_GREATER_THAN, maxrms),
00497 "Could not erase bad orders from trace table");
00498
00499
00500 }
00501 else
00502 {
00503 uves_msg_debug("All RMSs are less than %.2f", maxrms);
00504 }
00505
00506
00507
00508
00509
00510
00511 check_nomsg( orders_rejected =
00512 uves_select_table_rows(
00513 ordertable, "TraceSlope", CPL_GREATER_THAN, 0.5) +
00514 uves_select_table_rows(
00515 ordertable, "TraceSlope", CPL_LESS_THAN, -0.5));
00516
00517 if (orders_rejected > 0) {
00518 uves_msg_warning("%d order(s) rejected because slope was outside [-0.5 ; 0.5]",
00519 orders_rejected);
00520
00521 check_nomsg( uves_erase_table_rows(tracetable, "OrderSlope",
00522 CPL_GREATER_THAN, 0.5));
00523 check_nomsg( uves_erase_table_rows(tracetable, "OrderSlope",
00524 CPL_LESS_THAN, -0.5));
00525 }
00526 else {
00527 uves_msg_debug("All line slopes are within [-0.5 ; 0.5]");
00528 }
00529 }
00530
00531
00532
00533
00534 {
00535 double dy_median = cpl_table_get_column_median(tracetable, "dY");
00536 double threshold = 0.40*dy_median;
00537 int nreject;
00538
00539 check_nomsg( nreject = uves_erase_table_rows(tracetable, "dY", CPL_LESS_THAN,
00540 threshold) );
00541
00542 uves_msg_debug("Rejected %d points with dY less than %f pixels (median = %f pixels)",
00543 nreject, threshold, dy_median);
00544 }
00545
00546
00547
00548
00549 if (*DEFPOL1 < 0 || *DEFPOL2 < 0)
00550 {
00551 int deg1, deg2;
00552 int new_deg1, new_deg2;
00553 double red_chisq1, mse1;
00554 double red_chisq2, mse2;
00555 double red_chisq3, mse3;
00556 bool adjust1 = (*DEFPOL1 < 0);
00557
00558 bool adjust2 = (*DEFPOL2 < 0);
00559 int finished;
00560
00561
00562
00563 int number_of_orders = 0;
00564
00565 int number_of_orders1 = 0;
00566 int number_of_orders2 = 0;
00567 int number_of_orders3 = 0;
00568
00569 if (adjust1)
00570 {
00571
00572 *DEFPOL1 = 1;
00573 deg1 = 1;
00574 }
00575 else
00576 {
00577
00578 deg1 = *DEFPOL1;
00579 }
00580 if (adjust2)
00581 {
00582
00583 *DEFPOL2 = 1;
00584 deg2 = 1;
00585 }
00586 else
00587 {
00588
00589 deg2 = *DEFPOL2;
00590 }
00591
00592 uves_free_table(&temp);
00593 temp = cpl_table_duplicate(tracetable);
00594 uves_polynomial_delete(bivariate_fit);
00595 check( *bivariate_fit = uves_polynomial_regression_2d(
00596 temp,
00597 "X", "Order", "Y", "dY",
00598 deg1,
00599 deg2,
00600 NULL, NULL, NULL,
00601 &mse, &red_chisq,
00602 NULL,
00603 KAPPA, -1),
00604 "Error fitting orders");
00605
00606 check( number_of_orders = count_orders(temp),
00607 "Error counting orders");
00608
00609 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00610 "Red.chi^2 = %.2f (%d orders) *",
00611 deg1,
00612 deg2,
00613 sqrt(mse),
00614 red_chisq,
00615 number_of_orders);
00616
00617
00618
00619
00620
00621 do
00622 {
00623 int maxdegree = 6;
00624 finished = 0;
00625
00626 adjust1 = adjust1 && (deg1 + 1 <= maxdegree);
00627 adjust2 = adjust2 && (deg2 + 1 <= maxdegree);
00628
00629
00630 if (adjust1)
00631 {
00632 uves_free_table(&temp);
00633 temp = cpl_table_duplicate(tracetable);
00634 uves_polynomial_delete(bivariate_fit);
00635 *bivariate_fit = uves_polynomial_regression_2d(
00636 temp,
00637 "X", "Order", "Y", "dY",
00638 deg1 + 1,
00639 deg2,
00640 NULL, NULL, NULL,
00641 &mse1, &red_chisq1,
00642 NULL,
00643 KAPPA, -1);
00644
00645 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
00646 {
00647 uves_error_reset();
00648 mse1 = -1;
00649 red_chisq1 = DBL_MAX/2;
00650 }
00651 else
00652 {
00653 assure( cpl_error_get_code() == CPL_ERROR_NONE,
00654 cpl_error_get_code(),
00655 "Error fitting orders");
00656
00657 check( number_of_orders1 = count_orders(temp),
00658 "Error counting orders");
00659 }
00660 }
00661
00662
00663 if (adjust2)
00664 {
00665 uves_free_table(&temp);
00666 temp = cpl_table_duplicate(tracetable);
00667 uves_polynomial_delete(bivariate_fit);
00668 *bivariate_fit = uves_polynomial_regression_2d(
00669 temp,
00670 "X", "Order", "Y", "dY",
00671 deg1,
00672 deg2 + 1,
00673 NULL, NULL, NULL,
00674 &mse2, &red_chisq2,
00675 NULL,
00676 KAPPA, -1);
00677
00678 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
00679 {
00680 uves_error_reset();
00681 mse2 = -1;
00682 red_chisq2 = DBL_MAX/2;
00683 }
00684 else
00685 {
00686 assure( cpl_error_get_code() == CPL_ERROR_NONE,
00687 cpl_error_get_code(),
00688 "Error fitting orders");
00689
00690 check( number_of_orders2 = count_orders(temp),
00691 "Error counting orders");
00692 }
00693 }
00694
00695
00696 if (adjust1 && adjust2)
00697 {
00698 uves_free_table(&temp);
00699 temp = cpl_table_duplicate(tracetable);
00700 uves_polynomial_delete(bivariate_fit);
00701 *bivariate_fit = uves_polynomial_regression_2d(
00702 temp,
00703 "X", "Order", "Y", "dY",
00704 deg1 + 1,
00705 deg2 + 1,
00706 NULL, NULL, NULL,
00707 &mse3, &red_chisq3,
00708 NULL,
00709 KAPPA, -1);
00710
00711 if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
00712 {
00713 uves_error_reset();
00714 mse3 = -1;
00715 red_chisq3 = DBL_MAX/2;
00716 }
00717 else
00718 {
00719 assure( cpl_error_get_code() == CPL_ERROR_NONE,
00720 cpl_error_get_code(),
00721 "Error fitting orders");
00722
00723 check( number_of_orders3 = count_orders(temp),
00724 "Error counting orders");
00725 }
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 new_deg1 = deg1;
00740 new_deg2 = deg2;
00741 if (adjust1 && mse1 >= 0 && (red_chisq - red_chisq1)/red_chisq > 0.1 &&
00742 red_chisq1 <= red_chisq2)
00743 {
00744 new_deg1++;
00745 mse = mse1;
00746 red_chisq = red_chisq1;
00747 finished = 1;
00748
00749 if (number_of_orders1 >= number_of_orders)
00750 {
00751 *DEFPOL1 = new_deg1;
00752 *DEFPOL2 = new_deg2;
00753 number_of_orders = number_of_orders1;
00754 }
00755 }
00756 else if (adjust2 && mse2 >= 0 && (red_chisq - red_chisq2)/red_chisq > 0.1 &&
00757 red_chisq2 < red_chisq1)
00758 {
00759 new_deg2++;
00760 mse = mse2;
00761 red_chisq = red_chisq2;
00762 finished = 2;
00763
00764 if (number_of_orders2 >= number_of_orders)
00765 {
00766 *DEFPOL1 = new_deg1;
00767 *DEFPOL2 = new_deg2;
00768 number_of_orders = number_of_orders2;
00769 }
00770 }
00771 else if (adjust1 && adjust2 &&
00772 mse3 >= 0 && (red_chisq - red_chisq3)/red_chisq > 0.1)
00773 {
00774 new_deg1++;
00775 new_deg2++;
00776 mse = mse3;
00777 red_chisq = red_chisq3;
00778 finished = 3;
00779
00780 if (number_of_orders3 >= number_of_orders)
00781 {
00782 *DEFPOL1 = new_deg1;
00783 *DEFPOL2 = new_deg2;
00784 number_of_orders = number_of_orders3;
00785 }
00786 }
00787
00788
00789
00790
00791 if (adjust1)
00792 {
00793 if (mse1 >= 0)
00794 {
00795 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00796 "Red.chi^2 = %.3f (%d orders)%s",
00797 deg1 + 1,
00798 deg2,
00799 sqrt(mse1),
00800 red_chisq1,
00801 number_of_orders1,
00802 (finished == 1) ? " *" : "");
00803 }
00804 else
00805 {
00806 uves_msg_low("(%d, %d)-degree: Singular matrix",
00807 deg1 + 1,
00808 deg2);
00809 }
00810 }
00811
00812 if (adjust2)
00813 {
00814 if (mse2 >= 0)
00815 {
00816 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00817 "Red.chi^2 = %.3f (%d orders)%s",
00818 deg1,
00819 deg2 + 1,
00820 sqrt(mse2),
00821 red_chisq2,
00822 number_of_orders2,
00823 (finished == 2) ? " *" : "");
00824 }
00825 else
00826 {
00827 uves_msg_low("(%d, %d)-degree: Singular matrix",
00828 deg1,
00829 deg2 + 1);
00830 }
00831 }
00832
00833 if (adjust1 && adjust2)
00834 {
00835 if (mse3 >= 0)
00836 {
00837 uves_msg_low("(%d, %d)-degree: RMS = %.3f pixels. "
00838 "Red.chi^2 = %.3f (%d orders)%s",
00839 deg1 + 1,
00840 deg2 + 1,
00841 sqrt(mse3),
00842 red_chisq3,
00843 number_of_orders3,
00844 (finished == 3) ? " *" : "");
00845 }
00846 else
00847 {
00848 uves_msg_low("(%d, %d)-degree: Singular matrix",
00849 deg1 + 1,
00850 deg2 + 1);
00851 }
00852 }
00853
00854 if (finished != 0)
00855 {
00856 uves_msg_debug("Moved to degree (%d, %d), finished = %d, "
00857 "DEFPOL = %d, %d",
00858 new_deg1, new_deg2, finished, *DEFPOL1, *DEFPOL2);
00859 }
00860
00861 deg1 = new_deg1;
00862 deg2 = new_deg2;
00863
00864 } while (finished != 0);
00865
00866 uves_msg_low("Using degree (%d, %d)", *DEFPOL1, *DEFPOL2);
00867
00868 }
00869
00870
00871 uves_polynomial_delete(bivariate_fit);
00872 check( *bivariate_fit = uves_polynomial_regression_2d(tracetable,
00873 "X", "Order", "Y", "dY",
00874 *DEFPOL1,
00875 *DEFPOL2,
00876 "Yfit", NULL, "dYfit_Square",
00877 &mse, &red_chisq,
00878 NULL,
00879 KAPPA, -1),
00880 "Error fitting orders");
00881
00882 uves_msg("RMS error of (%d, %d)-degree fit is %.3f pixels. Reduced chi^2 is %.3f",
00883 *DEFPOL1,
00884 *DEFPOL2,
00885 sqrt(mse),
00886 red_chisq);
00887
00888
00889 if (sqrt(mse) > 0.3)
00890 {
00891 uves_msg_warning("RMS of bivariate fit (%.2f pixels) "
00892 "is larger than 0.3 pixels", sqrt(mse));
00893 }
00894 if (red_chisq < .01)
00895 {
00896 uves_msg_warning("Reduced chi^2 of fit is less than 1/100: %f", red_chisq);
00897 }
00898 if (red_chisq > 100)
00899 {
00900 uves_msg_warning("Reduced chi^2 of fit is greater than 100: %f", red_chisq);
00901 }
00902
00903
00904 check(( cpl_table_duplicate_column(tracetable, "Residual", tracetable, "Y"),
00905 cpl_table_subtract_columns(tracetable, "Residual", "Yfit")),
00906 "Error calculating residuals of fit");
00907
00908
00909 {
00910 check( *orders_traced = count_orders(tracetable),
00911 "Error counting orders");
00912
00913 uves_msg("%d order(s) were traced", *orders_traced);
00914 if (*orders_traced < N)
00915 {
00916 uves_msg_warning("Rejected %d order(s)", N - *orders_traced);
00917 }
00918 }
00919
00920
00921 check( uves_plot_table(tracetable, "X", "Yfit", "%d orders detected", *orders_traced),
00922 "Plotting failed");
00923 check( uves_plot_table(tracetable, "X", "Residual",
00924 "Residual of fit (RMS = %.3f pixels; red.chi^2 = %f)",
00925 sqrt(mse), red_chisq), "Plotting failed");
00926 check( uves_plot_table(tracetable, "Y", "Residual",
00927 "Residual of fit (RMS = %.3f pixels; red.chi^2 = %f)",
00928 sqrt(mse), red_chisq), "Plotting failed");
00929
00930 cleanup:
00931 uves_free_table(&temp);
00932 uves_free_table(&singletrace);
00933 if (cpl_error_get_code() != CPL_ERROR_NONE)
00934 {
00935 uves_free_table(&tracetable);
00936 }
00937
00938 return tracetable;
00939 }
00940
00941
00942
00950 static int
00951 count_orders(const cpl_table *tracetable)
00952 {
00953 int number = 0;
00954 int previous = -1;
00955 int row;
00956
00957 passure( tracetable != NULL, " ");
00958 passure( cpl_table_has_column(tracetable, "Order"), " ");
00959
00960 for (row = 0; row < cpl_table_get_nrow(tracetable); row++)
00961 {
00962 int current;
00963 current = cpl_table_get_int(tracetable, "Order", row, NULL);
00964 if (current != previous)
00965 {
00966 number++;
00967 }
00968 previous = current;
00969 }
00970
00971 cleanup:
00972 return number;
00973
00974 }
00975
00976
00977
00992
00993
00994 static double
00995 fit_order_linear(cpl_table *singletrace,
00996 int order,
00997 double KAPPA,
00998 double *slope)
00999 {
01000 double mse = 0;
01001 double intersept;
01002 cpl_table *temp = NULL;
01003 polynomial *pol = NULL;
01004
01005 passure( slope != NULL, " ");
01006 passure( cpl_table_get_ncol(singletrace) == 3, "%" CPL_SIZE_FORMAT "", cpl_table_get_ncol(singletrace));
01007 passure( cpl_table_has_column(singletrace, "X"), " ");
01008 passure( cpl_table_has_column(singletrace, "Y"), " ");
01009 passure( cpl_table_has_column(singletrace, "dY")," ");
01010
01011 check( temp = cpl_table_duplicate(singletrace),
01012 "Error cloning table");
01013
01014 if (cpl_table_get_nrow(temp) == 1)
01015 {
01016
01017
01018 check(( cpl_table_set_size(temp, 2),
01019 cpl_table_set_int (temp, "X", 1, uves_max_int(
01020 cpl_table_get_int (temp, "X", 0, NULL) - 1, 1)),
01021 cpl_table_set_double(temp, "Y", 1,
01022 cpl_table_get_double(temp, "Y", 0, NULL)),
01023 cpl_table_set_double(temp, "dY", 1,
01024 cpl_table_get_double(temp, "dY",0, NULL))),
01025 "Could not add point");
01026 }
01027
01028
01029
01030 check( pol = uves_polynomial_regression_1d(temp,
01031 "X", "Y", NULL,
01032
01033 1,
01034 NULL, NULL,
01035 &mse,
01036 KAPPA),
01037 "Fitting of order %d failed. You may have to increase value of kappa",
01038 order);
01039
01040 intersept = uves_polynomial_get_coeff_1d(pol, 0);
01041 *slope = uves_polynomial_get_coeff_1d(pol, 1);
01042
01043 uves_msg_debug("The RMS error of order #%d is %.2f pixels; "
01044 "slope = %f; intersept = %f",
01045 order, sqrt(mse),
01046 *slope, intersept);
01047
01048
01049 {
01050 int i;
01051
01052 check(( cpl_table_new_column(singletrace, "Linear fit", CPL_TYPE_DOUBLE),
01053 cpl_table_new_column(singletrace, "Residual_Square", CPL_TYPE_DOUBLE)),
01054 "Error adding table columns");
01055
01056 for (i = 0; i < cpl_table_get_nrow(singletrace); i++)
01057 {
01058 int x = cpl_table_get_int (singletrace, "X", i, NULL);
01059 double y = cpl_table_get_double(singletrace, "Y", i, NULL);
01060
01061 double linear_fit, residual;
01062
01063 check (linear_fit = uves_polynomial_evaluate_1d(pol, x),
01064 "Error evaluating polynomial");
01065
01066 residual = y - linear_fit;
01067
01068 check(( cpl_table_set_double(singletrace, "Linear fit", i, linear_fit),
01069 cpl_table_set_double(singletrace, "Residual_Square",
01070 i, residual*residual)),
01071 "Error updating table");
01072 }
01073 }
01074
01075
01076 check(( cpl_table_new_column(singletrace, "OrderRMS", CPL_TYPE_DOUBLE),
01077 cpl_table_new_column(singletrace, "OrderSlope", CPL_TYPE_DOUBLE),
01078 cpl_table_fill_column_window_double(
01079 singletrace, "OrderRMS", 0, cpl_table_get_nrow(singletrace), sqrt(mse)),
01080 cpl_table_fill_column_window_double(
01081 singletrace, "OrderSlope", 0, cpl_table_get_nrow(singletrace), *slope)),
01082 "Could not create columns OrderRMS and OrderSlope");
01083
01084 passure( cpl_table_get_ncol(singletrace) == 7, "%" CPL_SIZE_FORMAT "", cpl_table_get_ncol(singletrace));
01085 passure( cpl_table_has_column(singletrace, "X"), " ");
01086 passure( cpl_table_has_column(singletrace, "Y"), " ");
01087 passure( cpl_table_has_column(singletrace, "dY")," ");
01088 passure( cpl_table_has_column(singletrace, "Linear fit"), " ");
01089 passure( cpl_table_has_column(singletrace, "Residual_Square"), " ");
01090 passure( cpl_table_has_column(singletrace, "OrderRMS"), " ");
01091 passure( cpl_table_has_column(singletrace, "OrderSlope"), " ");
01092
01093 cleanup:
01094 uves_free_table(&temp);
01095 uves_polynomial_delete(&pol);
01096 return sqrt(mse);
01097
01098 }
01099
01100
01127
01128
01129 static cpl_table *
01130 trace_order(const cpl_table *ordertable, int order,
01131 const cpl_image *inputimage, const cpl_image *noise,
01132 const cpl_binary *image_bad,
01133 int TRACESTEP,
01134 double MAXGAP)
01135 {
01136 cpl_table *singletrace = NULL;
01137 int tracerow;
01138 int DIRECTION;
01139 double slope;
01140 double threshold;
01141 double minthreshold;
01142 int nx;
01143 int xcenter;
01144 int ycenter;
01145 int orderlength;
01146 int order_spacing;
01147 int xmax, xmin;
01148
01149 nx = cpl_image_get_size_x(inputimage);
01150
01151 check(( singletrace =
01152 cpl_table_new(nx/TRACESTEP + 2),
01153 cpl_table_new_column(singletrace, "X", CPL_TYPE_INT),
01154 cpl_table_new_column(singletrace, "Y", CPL_TYPE_DOUBLE),
01155 cpl_table_new_column(singletrace, "dY",CPL_TYPE_DOUBLE),
01156 tracerow = 0),
01157 "Could not initialize tracetable");
01158
01159
01160
01161
01162
01163
01164
01165 check((xcenter = cpl_table_get_int (ordertable, "Xcenter" , order - 1, NULL),
01166 ycenter = cpl_table_get_int (ordertable, "Ycenter" , order - 1, NULL),
01167 orderlength = cpl_table_get_int (ordertable, "OrderLength" , order - 1, NULL),
01168 order_spacing= cpl_table_get_int (ordertable, "Spacing" , order - 1, NULL),
01169 threshold = cpl_table_get_double(ordertable, "Threshold" , order - 1, NULL),
01170 minthreshold = cpl_table_get_double(ordertable, "MinThreshold", order - 1, NULL)),
01171 "Reading order table failed");
01172
01173
01174 threshold = minthreshold;
01175
01176
01177
01178 tracerow = 0;
01179
01180 xmax = xmin = xcenter;
01181
01182
01183 for (DIRECTION = -1; DIRECTION <= 1; DIRECTION += 2) {
01184
01185 int x = xcenter;
01186 double y = (double) ycenter;
01187 double dy = 0;
01188 int gap_size = 0;
01189
01190 check( slope = cpl_table_get_double(
01191 ordertable, "Slope", order - 1, NULL),
01192 "Could not read slope from table");
01193
01194 if (xcenter < nx/10 || xcenter > (nx*99)/100) {
01195
01196 x = 0;
01197
01198
01199
01200 }
01201
01202 while(1 <= x && x <= nx && gap_size < MAXGAP*nx) {
01203 bool found;
01204
01205 check( found = find_centroid(
01206 inputimage, noise, image_bad, threshold,
01207 order_spacing, x, &y, &dy),
01208 "Could not get order line position");
01209
01210
01211
01212
01213 if (found &&
01214 (y - ycenter)/(x - xcenter) > -1 &&
01215 (y - ycenter)/(x - xcenter) < 1) {
01216
01217
01218 xmax = uves_max_int(xmax, x);
01219 xmin = uves_min_int(xmin, x);
01220
01221 uves_msg_debug("(Order, x, y, dy, threshold) = "
01222 "(%d, %d, %f, %f, %f)",
01223 order, x, y, dy, threshold);
01224
01225 if (!(x == xcenter && DIRECTION == 1))
01226
01227
01228
01229
01230 {
01231 cpl_table_set_int (
01232 singletrace, "X", tracerow, x);
01233 cpl_table_set_double(
01234 singletrace, "Y", tracerow, y);
01235 if (dy > 0) {
01236 cpl_table_set_double(
01237 singletrace, "dY", tracerow, dy);
01238 }
01239 else {
01240 cpl_table_set_invalid(
01241 singletrace, "dY", tracerow);
01242 }
01243 tracerow++;
01244 }
01245
01246 gap_size = 0;
01247
01248 }
01249 else {
01250 gap_size += TRACESTEP;
01251 }
01252
01253
01254 x = x + DIRECTION * TRACESTEP;
01255 y = y + slope*DIRECTION * TRACESTEP;
01256
01257 slope = (y - ycenter)/(x - xcenter);
01258
01259 }
01260
01261 }
01262
01263
01264
01265 uves_msg_debug("%d points were traced in order %d", tracerow, order);
01266
01267
01268 check( cpl_table_set_size(singletrace, tracerow), "Could not resize tracetable");
01269
01270
01271
01272
01273 {
01274 double dy_median;
01275
01276 if (cpl_table_has_valid(singletrace, "dY"))
01277 {
01278
01279 dy_median = cpl_table_get_column_median(singletrace, "dY");
01280 }
01281 else
01282 {
01283 dy_median = 1.0;
01284 }
01285
01286
01287 cpl_table_select_all(singletrace);
01288 cpl_table_and_selected_invalid(singletrace, "dY");
01289 {
01290 int i;
01291 for (i = 0; i < cpl_table_get_nrow(singletrace); i++)
01292 {
01293 if (cpl_table_is_selected(singletrace, i))
01294 {
01295 cpl_table_set_double(singletrace, "dY", i, dy_median);
01296 }
01297 }
01298 }
01299 }
01300
01301
01302 check( uves_sort_table_1(singletrace, "X", false), "Could not sort order table");
01303
01304 cleanup:
01305 if (cpl_error_get_code() != CPL_ERROR_NONE)
01306 {
01307 uves_free_table(&singletrace);
01308 }
01309
01310 return singletrace;
01311 }
01312
01313
01326
01327 static int
01328 get_orderlength(int nx, int ny, cpl_table *ordertable, int row)
01329 {
01330 int x0 = 0, y_0, x1 = 0, y_1;
01331 double intersept, slope;
01332
01333 check(( intersept = cpl_table_get_double(ordertable, "Intersept", row, NULL),
01334 slope = cpl_table_get_double(ordertable, "Slope", row, NULL)),
01335 "Could not read line from ordertable");
01336
01337
01338 x0 = 1;
01339 y_0 = uves_round_double(intersept + slope*x0);
01340
01341
01342 if (y_0 < 1)
01343 {
01344 y_0 = 1;
01345 x0 = uves_round_double((y_0 - intersept)/slope);
01346 }
01347
01348
01349 x1 = nx;
01350 y_1 = uves_round_double(intersept + slope*nx);
01351 if (y_1 > ny)
01352 {
01353 y_1 = ny;
01354 x1 = uves_round_double((y_1 - intersept)/slope);
01355 }
01356
01357 cleanup:
01358 return (x1 - x0);
01359 }
01360
01361
01362
01375
01376 static int
01377 get_xcenter(int nx, int ny, cpl_table *ordertable, int row)
01378 {
01379 int x0, y_0, x1, y_1, xc = 0;
01380 double intersept, slope;
01381 check(( intersept = cpl_table_get_double(ordertable, "Intersept", row, NULL),
01382 slope = cpl_table_get_double(ordertable, "Slope", row, NULL)),
01383 "Could not read line from ordertable");
01384
01385
01386 x0 = 1;
01387 y_0 = uves_round_double(intersept + slope*x0);
01388
01389
01390 if (y_0 < 1)
01391 {
01392 y_0 = 1;
01393 x0 = uves_round_double((y_0 - intersept)/slope);
01394
01395 }
01396
01397
01398
01399 x1 = nx;
01400 y_1 = uves_round_double(intersept + slope*nx);
01401
01402
01403 if (y_1 > ny)
01404 {
01405 y_1 = ny;
01406 x1 = uves_round_double((y_1 - intersept)/slope);
01407 }
01408
01409 xc = (x0 + x1)/2;
01410
01411 cleanup:
01412 return xc;
01413 }
01414
01415
01427
01428 static int
01429 get_ycenter(int nx, int ny, cpl_table *ordertable, int row)
01430 {
01431 int xc = 0;
01432 int yc = 0;
01433 check( xc = get_xcenter(nx, ny, ordertable, row), "Could not find x-center of order");
01434
01435 check( yc = uves_round_double(
01436 cpl_table_get_double(ordertable, "Slope" , row, NULL)*xc +
01437 cpl_table_get_double(ordertable, "Intersept", row, NULL)
01438 ), "Could not read line from ordertable");
01439
01440 cleanup:
01441 return yc;
01442 }
01443
01444
01460
01461 static double
01462 estimate_threshold(const cpl_image *inputimage, const cpl_image *noise,
01463 cpl_table *ordertable, int row, double relative_threshold)
01464 {
01465 int yupper = 0;
01466 int ylower = 0;
01467 int xc, yc;
01468 int N;
01469 int ny;
01470 double returnvalue = 0;
01471 cpl_stats *stats = NULL;
01472
01473 passure( inputimage != NULL, " ");
01474 passure( ordertable != NULL, " ");
01475 passure( cpl_table_get_int(ordertable, "Order", row, NULL) == row+1, "%d %d",
01476 cpl_table_get_int(ordertable, "Order", row, NULL), row);
01477
01478 check( ny = cpl_image_get_size_y(inputimage), "Could not read input image dimension");
01479
01480 check( N = cpl_table_get_nrow(ordertable), "Could not read size of ordertable");
01481 assure(N > 1, CPL_ERROR_ILLEGAL_INPUT,
01482 "Cannot calculate orderspacing with less than 2 (i.e. %d) orders.", N);
01483 check( xc = cpl_table_get_int(ordertable, "Xcenter", row, NULL),
01484 "Could not read x-center of order #%d", row+1);
01485 check( yc = cpl_table_get_int(ordertable, "Ycenter", row, NULL),
01486 "Could not find y-center of order #%d", row+1);
01487
01488
01489
01490
01491
01492
01493 if (row < N - 1)
01494 {
01495 double ynext;
01496 check(ynext =
01497 cpl_table_get_double(ordertable, "Slope" , row + 1, NULL)*xc +
01498 cpl_table_get_double(ordertable, "Intersept", row + 1, NULL),
01499 "Could not read line from ordertable row %d", row + 1);
01500
01501 yupper = (int)((yc + (uves_round_double(ynext)-1))/2);
01502
01503 }
01504
01505 if (row > 0)
01506 {
01507 double yprev;
01508 check( yprev =
01509 cpl_table_get_double(ordertable, "Slope" , row - 1, NULL)*xc +
01510 cpl_table_get_double(ordertable, "Intersept", row - 1, NULL),
01511 "Could not read line from ordertable row %d", row - 1);
01512
01513 ylower = (int)((yc + uves_round_double(yprev)-1)/2);
01514
01515 }
01516
01517
01518
01519 if (row == N-1)
01520 {
01521 yupper = yc + (yc - ylower);
01522 }
01523 if (row == 0)
01524 {
01525 ylower = yc - (yupper - yc);
01526 }
01527 yupper = uves_min_int(uves_max_int(yupper, 1), ny);
01528 ylower = uves_min_int(uves_max_int(ylower, 1), ny);
01529
01530
01531
01532
01533
01534 assure(yupper > ylower, CPL_ERROR_ILLEGAL_INPUT,
01535 "Initially detected order lines intersept!");
01536
01537
01538 {
01539 double minval = 0;
01540 double maxval = 0;
01541 double noise_level = 0;
01542
01543
01544 check( stats = cpl_stats_new_from_image_window(
01545 inputimage,
01546 CPL_STATS_MIN | CPL_STATS_MAX | CPL_STATS_MINPOS,
01547 xc, ylower,
01548 xc, yupper),
01549 "Could not get statistics on image sub-window (%d,%d)-(%d,%d)",
01550 xc, ylower, xc, yupper);
01551
01552 check(( minval = cpl_stats_get_min(stats),
01553 maxval = cpl_stats_get_max(stats)),
01554 "Could not get minimum and maximum pixel values");
01555
01556
01557 {
01558 int xpos, ypos, pis_rejected;
01559 xpos = cpl_stats_get_min_x(stats);
01560 ypos = cpl_stats_get_min_y(stats);
01561 noise_level = cpl_image_get(noise, xpos, ypos, &pis_rejected);
01562 }
01563
01564
01565 returnvalue = uves_max_double(minval + relative_threshold * (maxval - minval),
01566 (minval + noise_level) + noise_level);
01567
01568 uves_msg_debug("Order: %d \tThreshold: %f \tMinimum: %f \tMaximum: %f"
01569 " \tNoise: %f \tWindow: (%d, %d)-(%d, %d)",
01570 row+1, returnvalue, minval, maxval, noise_level, xc, ylower, xc, yupper);
01571 }
01572
01573 cleanup:
01574 uves_free_stats(&stats);
01575 return returnvalue;
01576 }
01577
01578
01601
01602 static bool
01603 find_centroid(const cpl_image *inputimage, const cpl_image *noise,
01604 const cpl_binary *image_bad,
01605 double threshold, int spacing, int x, double *yguess, double *dY)
01606 {
01607 bool returnvalue = true;
01608 int nx;
01609 int ny;
01610 int y;
01611 double thisvalue = 0;
01612 int pis_rejected;
01613 int ylow = 0;
01614 int yhigh = 0;
01615 cpl_matrix *covariance = NULL;
01616
01617 passure( inputimage != NULL, " ");
01618
01619 nx = cpl_image_get_size_x(inputimage);
01620 ny = cpl_image_get_size_y(inputimage);
01621
01622 passure( 1 <= x && x <= nx, "%d %d", x, nx);
01623
01624 uves_msg_debug("Order location estimate = (%d, %f)", x, *yguess);
01625
01626
01627
01628 y = uves_round_double(*yguess);
01629 if (y < 1 || y > ny)
01630 {
01631 returnvalue = false;
01632 }
01633 else {
01634 bool cont;
01635
01636 do {
01637 cont = false;
01638 thisvalue = cpl_image_get(inputimage, x, y , &pis_rejected);
01639
01640 if (y < ny) {
01641 double uppervalue = cpl_image_get(inputimage, x, y + 1, &pis_rejected);
01642 if (!pis_rejected && uppervalue > thisvalue)
01643 {
01644 y += 1;
01645 cont = true;
01646 }
01647 }
01648
01649
01650 if (y > 1) {
01651 double lowervalue = cpl_image_get(inputimage, x, y - 1, &pis_rejected);
01652 if (!pis_rejected && lowervalue > thisvalue)
01653 {
01654 y -= 1;
01655 cont = true;
01656 }
01657 }
01658
01659 } while (cont);
01660
01661
01662
01663 uves_msg_debug("Local maximum at (%d, %d) (value = %f)\tthreshold = %f",
01664 x, y, thisvalue, threshold);
01665
01666
01667 if (thisvalue < threshold)
01668 {
01669 uves_msg_debug("Order not traced at (%d, %d) (value = %f)\tthreshold = %f",
01670 x, y, thisvalue, threshold);
01671 returnvalue = false;
01672 }
01673 else
01674 {
01675
01676 double minvalue;
01677 double sigmaY;
01678
01679 double mse, rms, chi_sq;
01680 double background;
01681 double norm;
01682
01683
01684 minvalue = 0.5*thisvalue;
01685
01686
01687 while(y > 1 && cpl_image_get(inputimage, x, y - 1, &pis_rejected) >= minvalue)
01688 {
01689 y--;
01690 }
01691
01692 assure( cpl_error_get_code() == CPL_ERROR_NONE,
01693 cpl_error_get_code(), "Could not read pixel from input image" );
01694
01695
01696 ylow = y;
01697
01698
01699 while(y < ny && cpl_image_get(inputimage, x, y + 1, &pis_rejected) >= minvalue)
01700 {
01701 y++;
01702 }
01703
01704 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
01705 "Could not read pixel from input image" );
01706
01707
01708 yhigh = y;
01709
01710
01711
01712 {
01713 double sum = 0;
01714 double sumy = 0;
01715 double sumy2= 0;
01716 for (y = ylow; y <= yhigh; y++)
01717 {
01718 double flux;
01719 flux = cpl_image_get(inputimage, x, y, &pis_rejected) - minvalue;
01720 if (!pis_rejected && flux > 0)
01721 {
01722 sum += flux;
01723 sumy += flux * (y - *yguess*0);
01724 sumy2 += flux * (y - *yguess*0) * (y - *yguess*0);
01725 }
01726 }
01727 if (sum > 0)
01728 {
01729 *yguess = *yguess*0 + sumy / sum;
01730 sigmaY = sqrt( sumy2 / sum - sumy*sumy/(sum*sum) );
01731
01732 if ( sumy2 / sum - sumy*sumy/(sum*sum) < 0 ||
01733 sigmaY < sqrt(1.0/12) )
01734 {
01735
01736
01737
01738
01739 sigmaY = sqrt(1.0/12);
01740 }
01741
01742
01743
01744 *dY = sigmaY/sqrt(sum);
01745
01746 }
01747 else
01748 {
01749
01750 sigmaY = 1.0;
01751 *dY = .1;
01752
01753 }
01754 }
01755
01756
01757
01758
01759
01760 ylow = uves_max_int(1 , uves_round_double(*yguess - spacing/3));
01761 yhigh = uves_min_int(ny, uves_round_double(*yguess + spacing/3));
01762
01763 assure( yhigh - ylow >= 1, CPL_ERROR_ILLEGAL_INPUT,
01764 "Estimated spacing too small: %d pixel(s)", spacing);
01765
01766
01767 uves_fit_1d_image(inputimage, noise,
01768 image_bad,
01769 false, false, false,
01770 ylow, yhigh, x,
01771 yguess, &sigmaY, &norm, &background, NULL,
01772 &mse, &chi_sq, &covariance,
01773 uves_gauss, uves_gauss_derivative, 4);
01774
01775
01776 if (cpl_error_get_code() == CPL_ERROR_NONE)
01777 {
01778
01779 *dY = sqrt(cpl_matrix_get(covariance, 0, 0));
01780 }
01781 else if (cpl_error_get_code() == CPL_ERROR_CONTINUE)
01782 {
01783
01784 uves_error_reset();
01785 uves_msg_debug("Fitting failed at (x,y) = (%d, %e), "
01786 "using centroid", x, *yguess);
01787 *dY = sigmaY / sqrt(norm);
01788 }
01789 else if (cpl_error_get_code() == CPL_ERROR_SINGULAR_MATRIX)
01790 {
01791 uves_error_reset();
01792
01793
01794 uves_msg_debug("Covariance matrix computation failed");
01795 *dY = sigmaY / sqrt(norm);
01796 }
01797
01798 assure(cpl_error_get_code() == CPL_ERROR_NONE,
01799 cpl_error_get_code(), "Gaussian fitting failed");
01800
01801 rms = sqrt(mse);
01802
01803 uves_msg_debug("dy = %f sigma/sqrt(N) = %f", *dY, sigmaY/(norm));
01804
01805
01806
01807 if ( norm > 10 * rms)
01808 {
01809 returnvalue = true;
01810 }
01811 if ( norm < 2 * rms)
01812 {
01813 returnvalue = false;
01814 }
01815
01816 }
01817
01818 }
01819
01820 cleanup:
01821 cpl_matrix_delete(covariance);
01822 return returnvalue;
01823 }