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 #ifdef HAVE_CONFIG_H
00089 # include <config.h>
00090 #endif
00091
00092
00096
00097
00098
00099
00100
00101
00102 #include <uves_orderpos_hough.h>
00103
00104 #include <uves_utils.h>
00105 #include <uves_utils_wrappers.h>
00106 #include <uves_error.h>
00107 #include <uves_msg.h>
00108
00109 #include <cpl.h>
00110
00111
00112
00113
00114
00115
00116
00117 #define SLOPE(hx) ( MINSLOPE + ( ((double)(hx)) / SLOPERES ) ) * (MAXSLOPE - MINSLOPE)
00118 #define SLOPEINV(a) \
00119 uves_round_double( SLOPERES * ( ((double)(a)) - MINSLOPE ) / (MAXSLOPE - MINSLOPE))
00120
00121
00122 #define INTERSEPT(hy) (minintersept + hy)
00123 #define INTERSEPTINV(b) (b - minintersept)
00124
00126
00127
00128
00129
00130 static cpl_table *detect_lines(cpl_image *htrans, int minintersept,
00131 const cpl_image *inputimage,
00132 int NORDERS, bool norders_is_guess, int SAMPLEWIDTH,
00133 double PTHRES, double MINSLOPE, double MAXSLOPE, int SLOPERES,
00134 bool consecutive);
00135 static cpl_error_code delete_peak(cpl_image *htrans, int minintersept, int hxmax, int hymax,
00136 int SPACING, int imagewidth, int SAMPLEWIDTH,
00137 double MINSLOPE, double MAXSLOPE, int SLOPERES);
00138 static int firsttrace(int nx, int SAMPLEWIDTH);
00139 static int calculate_spacing(const cpl_image *, int x);
00140 static double autocorr(const cpl_image *image, int x, int shift);
00141 static cpl_error_code update_max(const cpl_image *htrans,
00142 int *xmax,
00143 int *ymax,
00144 int SPACING,
00145 int imagewidth,
00146 int SAMPLEWIDTH,
00147 double MINSLOPE,
00148 double MAXSLOPE,
00149 int SLOPERES);
00150
00151
00183
00184
00185 cpl_table *uves_hough(const cpl_image *image, int ymin, int ymax, int NORDERS,
00186 bool norders_is_guess,
00187 int SAMPLEWIDTH, double PTHRES, double MINSLOPE, double MAXSLOPE,
00188 int SLOPERES, bool consecutive,
00189 cpl_image **htrans, cpl_image **htrans_original)
00190 {
00191
00192 cpl_table *ordertable = NULL;
00193
00194 int nx = 0;
00195 int ny = 0;
00196 int minintersept = 0;
00197
00198 int maxintersept = 0;
00199 int firstcol;
00200 const double *image_data = NULL;
00201 double *htrans_data = NULL;
00202
00203 *htrans = NULL;
00204 *htrans_original = NULL;
00205
00206
00207 assure_nomsg( image != NULL, CPL_ERROR_NULL_INPUT);
00208 assure( cpl_image_get_type(image) == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE,
00209 "Input image has wrong type. Must be of type double");
00210 assure( 0 <= MINSLOPE, CPL_ERROR_ILLEGAL_INPUT,
00211 "minslope = %f must be non-negative", MINSLOPE);
00212 assure( 0 <= MAXSLOPE, CPL_ERROR_ILLEGAL_INPUT,
00213 "maxslope = %f must be non-negative", MAXSLOPE);
00214 assure( MINSLOPE < MAXSLOPE, CPL_ERROR_INCOMPATIBLE_INPUT, "minslope = %f; maxslope = %f",
00215 MINSLOPE, MAXSLOPE);
00216 assure( 0 < SLOPERES, CPL_ERROR_ILLEGAL_INPUT,
00217 "Hough image width = %d, must be positive", SLOPERES);
00218
00219
00220
00221 assure (cpl_image_count_rejected(image) == 0,
00222 CPL_ERROR_UNSUPPORTED_MODE, "Input image has %d bad pixels",
00223 cpl_image_count_rejected(image));
00224
00225
00226 if (MAXSLOPE > 0.5)
00227 {
00228 uves_msg_warning("Max possible slope is %f, which is larger than 0.5. "
00229 "Results might be unreliable", MAXSLOPE);
00230 }
00231
00232 nx = cpl_image_get_size_x(image);
00233 ny = cpl_image_get_size_y(image);
00234
00235 assure( 1 <= ymin && ymin <= ymax && ymax <= ny, CPL_ERROR_ILLEGAL_INPUT,
00236 "Illegal y-range: %d - %d (image height is %d)", ymin, ymax, ny);
00237
00238
00239
00240
00241 maxintersept = ny;
00242 minintersept = uves_round_double(0 - nx*MAXSLOPE);
00243
00244
00245 check( *htrans = cpl_image_new(SLOPERES,
00246 maxintersept - minintersept,
00247 CPL_TYPE_DOUBLE),
00248 "Could not create image");
00249
00250 check_nomsg( image_data = cpl_image_get_data_double_const(image) );
00251 check_nomsg( htrans_data = cpl_image_get_data_double(*htrans) );
00252
00253 uves_msg("Calculating Hough transform");
00254
00255
00256 check_nomsg(firstcol = firsttrace(nx, SAMPLEWIDTH));
00257
00258 check_nomsg(UVES_TIME_START("The loop"));
00259
00260
00261 {
00262 int x, y;
00263 for (y = ymin; y <= ymax; y += 1)
00264 {
00265
00266
00267
00268 check_nomsg(uves_msg_progress(y - 1, ymax, "Calculating Hough transform"));
00269
00270 for (x = firstcol; x <= nx; x += SAMPLEWIDTH)
00271 {
00272
00273 double pixelvalue;
00274 int hx, hy;
00275
00276 for (hx = 1; hx <= SLOPERES; hx++)
00277 {
00278 check_nomsg(hy = INTERSEPTINV(uves_round_double(y - x*SLOPE(hx))));
00279
00280
00281
00282
00283
00284 check_nomsg(pixelvalue = image_data[(x-1) + (y-1)*nx]);
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 check_nomsg(htrans_data[(hx-1) + (hy-1)*SLOPERES] += pixelvalue);
00298 }
00299 }
00300 }
00301 }
00302
00303 UVES_TIME_END;
00304
00305 check( *htrans_original = cpl_image_duplicate(*htrans), "Error copying hough image");
00306
00307
00308 check( ordertable = detect_lines(*htrans,
00309 minintersept,
00310 image,
00311 NORDERS,
00312 norders_is_guess,
00313 SAMPLEWIDTH,
00314 PTHRES,
00315 MINSLOPE,
00316 MAXSLOPE,
00317 SLOPERES,
00318 consecutive),
00319 "Could not detect lines in hough image");
00320
00321 passure( cpl_table_get_ncol(ordertable) == 4, "%d", cpl_table_get_ncol(ordertable));
00322 passure( cpl_table_has_column(ordertable, "Slope"), " ");
00323 passure( cpl_table_has_column(ordertable, "Intersept"), " ");
00324 passure( cpl_table_has_column(ordertable, "Spacing"), " ");
00325 passure( cpl_table_has_column(ordertable, "Order"), " ");
00326
00327 cleanup:
00328 if (cpl_error_get_code() != CPL_ERROR_NONE)
00329 {
00330 uves_free_image(htrans);
00331 uves_free_image(htrans_original);
00332 uves_free_table(&ordertable);
00333 }
00334 return ordertable;
00335 }
00336
00337
00386
00387
00388 static cpl_table *detect_lines(cpl_image *htrans, int minintersept,
00389 const cpl_image *inputimage, int NORDERS,
00390 bool norders_is_guess,
00391 int SAMPLEWIDTH, double PTHRES, double MINSLOPE,
00392 double MAXSLOPE, int SLOPERES,
00393 bool consecutive)
00394 {
00395 cpl_table *results = NULL;
00396
00397
00398 cpl_stats *stats = NULL;
00399 uves_propertylist *pl = NULL;
00400
00401 bool automatic = false;
00402 int tablesize = 0;
00403 double intensity = 0;
00404 double prev_intensity = 0;
00405 int norders_detected = 0;
00406 int SPACING = 0;
00407 double globmax = 0;
00408
00409
00410 passure( htrans != NULL, " ");
00411 passure( inputimage != NULL, " ");
00412 passure( NORDERS >= 0, "%d", NORDERS);
00413 passure( SAMPLEWIDTH > 0, "%d", SAMPLEWIDTH);
00414 passure( 0 <= PTHRES && PTHRES <= 1, "%f", PTHRES);
00415 passure( SLOPERES > 0, "%d", SLOPERES);
00416
00417
00418
00419 if (NORDERS == 0)
00420 {
00421 uves_msg("Could not find information about predicted number of orders. "
00422 "Entering automatic mode (threshold = %f)", PTHRES);
00423 automatic = true;
00424 }
00425 else
00426 {
00427 uves_msg("Searching for %d (%s) order lines",
00428 NORDERS, (norders_is_guess) ? "or less" : "exactly");
00429 automatic = false;
00430 }
00431
00432
00433 if (automatic)
00434 {
00435
00436
00437 tablesize = cpl_image_get_size_y(inputimage);
00438 }
00439 else
00440 {
00441 tablesize = NORDERS;
00442 }
00443
00444
00445 check(( results = cpl_table_new(tablesize),
00446 cpl_table_new_column(results, "Slope", CPL_TYPE_DOUBLE),
00447 cpl_table_new_column(results, "Intersept", CPL_TYPE_DOUBLE),
00448 cpl_table_new_column(results, "Spacing", CPL_TYPE_INT)),
00449 "Could not initialize order table");
00450
00451
00452 check( stats = cpl_stats_new_from_image(htrans, CPL_STATS_MAX | CPL_STATS_MAXPOS),
00453 "Could not get statistics on Hough image");
00454
00455
00456
00457
00458
00459 check( globmax = cpl_stats_get_max(stats),
00460 "Could not locate first maximum in hough image" );
00461
00462 prev_intensity = globmax;
00463
00464
00465
00466
00467 while ( (!automatic &&
00468 (norders_detected < NORDERS &&
00469 (!norders_is_guess || cpl_stats_get_max(stats) >= PTHRES*prev_intensity)))
00470 || (automatic
00471 && cpl_stats_get_max(stats) >= PTHRES*prev_intensity)
00472 )
00473 {
00474 int xmax = 0;
00475 int ymax = 0;
00476 double slope = 0;
00477 double isept = 0;
00478
00479 norders_detected += 1;
00480 check((intensity = cpl_stats_get_max(stats),
00481 xmax = cpl_stats_get_max_x(stats),
00482 ymax = cpl_stats_get_max_y(stats)),
00483 "Could not locate maximum");
00484
00485
00486 uves_msg_debug("%d. detection: intensity = %f",
00487 norders_detected, intensity/globmax * 100);
00488
00489
00490 if (intensity < PTHRES * prev_intensity)
00491 {
00492 uves_msg_warning("Intensity of %d. line is only "
00493 "%f %% of %d. line. Detecting too many orders?",
00494 norders_detected, intensity / prev_intensity * 100,
00495 norders_detected - 1);
00496 }
00497 prev_intensity = intensity;
00498
00499
00500 if (norders_detected == 1)
00501 {
00502 if (!automatic)
00503 {
00504 SPACING = uves_round_double(
00505 cpl_image_get_size_y(inputimage) / NORDERS );
00506 }
00507 else
00508 {
00509
00510
00511 check( SPACING = calculate_spacing(htrans, xmax),
00512 "Could not estimate interorder spacing");
00513 }
00514
00515 uves_msg("Estimated order spacing is %d pixels", SPACING);
00516 }
00517
00518
00519 check( update_max(htrans,
00520 &xmax,
00521 &ymax,
00522 SPACING,
00523 cpl_image_get_size_x(inputimage),
00524 SAMPLEWIDTH,
00525 MINSLOPE,
00526 MAXSLOPE,
00527 SLOPERES), "Could not update peak position");
00528
00529 check( delete_peak(htrans,
00530 minintersept, xmax, ymax, SPACING,
00531 cpl_image_get_size_x(inputimage),
00532 SAMPLEWIDTH,
00533 MINSLOPE, MAXSLOPE, SLOPERES),
00534 "Could not delete peak in hough image");
00535
00536 slope = SLOPE(xmax);
00537 isept = minintersept + ymax;
00538
00539
00540 assure( norders_detected <= tablesize, CPL_ERROR_ILLEGAL_OUTPUT,
00541 "%d orders detected. This is way too many. "
00542 "Try to decrease NORDERS (from %d) or increase PTHRES (from %f)",
00543 norders_detected, NORDERS, PTHRES);
00544
00545 check(( cpl_table_set_double(results, "Slope" , norders_detected - 1, slope),
00546 cpl_table_set_double(results, "Intersept" , norders_detected - 1, isept),
00547 cpl_table_set_int (results, "Spacing" , norders_detected - 1, SPACING)),
00548 "Could add order line to order table");
00549
00550
00551 check(( uves_free_stats(&stats),
00552 stats = cpl_stats_new_from_image(htrans, CPL_STATS_MAX | CPL_STATS_MAXPOS)),
00553 "Could not get statistics on hough image");
00554 }
00555
00556 uves_msg("The intensity of the faintest line is %f of "
00557 "the intensity of the brightest line", intensity / globmax);
00558 uves_msg("Intensity of next (undetected) line is %f of the "
00559 "intensity of the brightest line", cpl_stats_get_max(stats)/globmax);
00560
00561 if ( cpl_stats_get_max(stats) > 0.5 * intensity )
00562 {
00563 uves_msg_warning("Brightest undetected line with intensity %.2f %% "
00564 "of faintest line. Detecting too few orders?",
00565 cpl_stats_get_max(stats) / intensity * 100);
00566 }
00567
00568
00569 check( cpl_table_set_size(results, norders_detected),
00570 "Could not remove extra rows from order table");
00571
00572
00573
00574 check( uves_sort_table_1(results, "Intersept", false),
00575 "Could not sort order table");
00576
00577
00578 {
00579 int i;
00580 cpl_table_new_column(results, "Order", CPL_TYPE_INT);
00581 for (i = 0; i < cpl_table_get_nrow(results); i++)
00582 {
00583 cpl_table_set_int(results, "Order", i, i+1);
00584 }
00585 }
00586
00587 if (consecutive)
00588
00589
00590
00591 {
00592 int i;
00593 double dist = 0;
00594 int minorder, maxorder;
00595 int n_removed;
00596
00597
00598 maxorder = -1;
00599 for (i = cpl_table_get_nrow(results)/2;
00600 i <= cpl_table_get_nrow(results) - 2 && maxorder < 0;
00601 i++)
00602 {
00603 if (i == cpl_table_get_nrow(results)/2)
00604
00605 {
00606 dist =
00607 cpl_table_get_double(results, "Intersept", i+1, NULL)-
00608 cpl_table_get_double(results, "Intersept", i, NULL);
00609 }
00610 else
00611 {
00612 double new_dist =
00613 cpl_table_get_double(results, "Intersept", i+1, NULL)-
00614 cpl_table_get_double(results, "Intersept", i, NULL);
00615
00616 uves_msg_debug("Order %d - %d separation = %.4f pixels",
00617 cpl_table_get_int(results, "Order", i, NULL),
00618 cpl_table_get_int(results, "Order", i+1, NULL),
00619 new_dist);
00620
00621 if (0.5*dist <= new_dist && new_dist <= 1.5*dist)
00622 {
00623
00624 }
00625 else
00626 {
00627
00628 maxorder = cpl_table_get_int(results, "Order", i, NULL);
00629
00630 uves_msg_warning("Order separation jumps from %.2f pixels to "
00631 "%.2f pixels. Discarding order(s) %d and above",
00632 dist, new_dist,
00633 maxorder+1);
00634 }
00635 }
00636 }
00637
00638
00639 minorder = -1;
00640 for (i = cpl_table_get_nrow(results)/2;
00641 i >= 1 && minorder < 0;
00642 i--)
00643 {
00644 if (i == cpl_table_get_nrow(results)/2)
00645
00646 {
00647 dist =
00648 cpl_table_get_double(results, "Intersept", i, NULL)-
00649 cpl_table_get_double(results, "Intersept", i-1, NULL);
00650 }
00651 else
00652 {
00653 double new_dist =
00654 cpl_table_get_double(results, "Intersept", i, NULL)-
00655 cpl_table_get_double(results, "Intersept", i-1, NULL);
00656
00657 uves_msg_debug("Order %d - %d separation = %.4f pixels",
00658 cpl_table_get_int(results, "Order", i-1, NULL),
00659 cpl_table_get_int(results, "Order", i, NULL),
00660 new_dist);
00661
00662 if (0.5*dist <= new_dist && new_dist <= 1.5*dist)
00663 {
00664
00665 }
00666 else
00667 {
00668
00669 minorder = cpl_table_get_int(results, "Order", i, NULL);
00670
00671 uves_msg_warning("Order separation jumps from %.2f pixels to "
00672 "%.2f pixels. Discarding order(s) %d and below",
00673 dist, new_dist,
00674 minorder-1);
00675 }
00676 }
00677 }
00678
00679 n_removed = 0;
00680 if (maxorder > 0)
00681 {
00682 check_nomsg( n_removed += uves_erase_table_rows(results, "Order",
00683 CPL_GREATER_THAN, maxorder));
00684 }
00685 if (minorder > 0)
00686 {
00687 check_nomsg( n_removed += uves_erase_table_rows(results, "Order",
00688 CPL_LESS_THAN, minorder));
00689 }
00690
00691 uves_msg_debug("%d order(s) removed", n_removed);
00692 norders_detected -= n_removed;
00693 }
00694
00695
00696 {
00697 int i;
00698 for (i = 0; i < cpl_table_get_nrow(results); i++)
00699 {
00700 cpl_table_set_int(results, "Order", i, i+1);
00701 }
00702 }
00703
00704 uves_msg("Hough transform detected %d orders", norders_detected);
00705
00706 passure( norders_detected == cpl_table_get_nrow(results), "%d %d",
00707 norders_detected, cpl_table_get_nrow(results));
00708
00709 cleanup:
00710 uves_free_stats(&stats);
00711 uves_free_propertylist(&pl);
00712 if (cpl_error_get_code() != CPL_ERROR_NONE)
00713 {
00714 uves_free_table(&results);
00715 }
00716
00717 return results;
00718 }
00719
00720
00721
00745
00746 static cpl_error_code update_max(const cpl_image *htrans,
00747 int *xmax,
00748 int *ymax,
00749 int SPACING,
00750 int imagewidth,
00751 int SAMPLEWIDTH,
00752 double MINSLOPE,
00753 double MAXSLOPE,
00754 int SLOPERES)
00755 {
00756 const int nx = cpl_image_get_size_x(htrans);
00757 const int ny = cpl_image_get_size_y(htrans);
00758 const int slope = -imagewidth/2;
00759 const double numberoftraces = 1 + imagewidth/SAMPLEWIDTH;
00760 int pis_rejected;
00761
00762
00763 double threshold = (1 - 0.5 / numberoftraces) *
00764 cpl_image_get(htrans, *xmax, *ymax, &pis_rejected);
00765 if (threshold < 0.99) threshold = 0.99;
00766
00767 assure (cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
00768 "Could not read Hough image data");
00769
00770 {
00771 double sum = 0;
00772 double mx = 0;
00773 double my = 0;
00774 int hx, hy;
00775 for (hx = 1; hx <= SLOPERES; hx++)
00776 {
00777 int rowcenter =
00778 uves_round_double(
00779 *ymax + slope*(hx - *xmax)/((double)SLOPERES)*(MAXSLOPE - MINSLOPE));
00780
00781
00782
00783
00784
00785
00786 for (hy = rowcenter - 0*SPACING/2; hy <= rowcenter + 0*SPACING/2; hy++)
00787 {
00788 if (1 <= hx && hx <= nx &&
00789 1 <= hy && hy <= ny)
00790 {
00791 double pixelvalue = cpl_image_get(
00792 htrans, hx, hy, &pis_rejected);
00793 if (!pis_rejected && pixelvalue >= threshold)
00794 {
00795 mx += hx*pixelvalue;
00796 my += hy*pixelvalue;
00797 sum += pixelvalue;
00798 }
00799 }
00800 }
00801
00802 }
00803
00804 uves_msg_debug("Peak position in Hough space changed from (%d, %d)", *xmax, *ymax);
00805 *xmax = uves_round_double(mx/sum);
00806 *ymax = uves_round_double(my/sum);
00807 uves_msg_debug("to (%d, %d)", *xmax, *ymax);
00808 }
00809
00810 cleanup:
00811 return cpl_error_get_code();
00812 }
00813
00814
00825
00826
00827 static int calculate_spacing(const cpl_image *image, int x)
00828 {
00829 int shift = 0;
00830 double autoc = autocorr(image, x, shift);
00831 double previous;
00832 assure (cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
00833 "Could not calculate autocorrelation function");
00834
00835 uves_msg_debug("Autocorrelation(shift=%d) = %f", shift, autoc);
00836
00837 do{
00838 previous = autoc;
00839 shift += 1;
00840 check( autoc = autocorr(image, x, shift),
00841 "Could not calculate autocorrelation function");
00842 uves_msg_debug("Autocorrelation(shift=%d) = %f", shift, autoc);
00843 } while (autoc <= previous);
00844
00845 cleanup:
00846 return 2*(shift - 1);
00847
00848 }
00849
00850
00851
00864
00865 static double autocorr(const cpl_image *image, const int x, const int shift)
00866 {
00867 double result = 0;
00868 const int ny = cpl_image_get_size_y(image);
00869 assure (cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
00870 "Could not read image dimensions");
00871
00872 if( shift >= ny ) return 0;
00873
00874 {
00875 double sum = 0;
00876 int y;
00877 int number_of_points = 0;
00878 for (y = 1; y <= ny - shift; y++){
00879 int pis_rejected;
00880 double pixelvalue;
00881
00882 pixelvalue = cpl_image_get(image, x, y, &pis_rejected) *
00883 cpl_image_get(image, x, y + shift, &pis_rejected);
00884
00885 if (!pis_rejected){
00886 sum += pixelvalue;
00887 number_of_points += 1;
00888 }
00889 }
00890 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
00891 "Error reading image pixel values");
00892
00893 if (number_of_points > 0)
00894 {
00895 result = sum / number_of_points;
00896 }
00897 else
00898 {
00899 result = 0;
00900 }
00901 }
00902
00903 cleanup:
00904 return result;
00905 }
00906
00907
00919
00920 static int firsttrace(int nx, int SAMPLEWIDTH)
00921 {
00922 int result = nx/2;
00923
00924 while(result - SAMPLEWIDTH >= 1)
00925 {
00926 result -= SAMPLEWIDTH;
00927 }
00928
00929 return result;
00930 }
00931
00932
00955
00956 static cpl_error_code delete_peak(cpl_image *htrans, int minintersept,
00957 int hxmax, int hymax,
00958 int SPACING, int imagewidth, int SAMPLEWIDTH,
00959 double MINSLOPE, double MAXSLOPE, int SLOPERES)
00960 {
00961 const int ny = cpl_image_get_size_y(htrans);
00962 int tracecol;
00963 int firstcol = firsttrace(imagewidth, SAMPLEWIDTH);
00964
00965 assure (cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
00966 "Could not read hough image data");
00967
00968
00969 for (tracecol = firstcol; tracecol <= imagewidth; tracecol += SAMPLEWIDTH){
00970
00971 double slope = SLOPE(hxmax);
00972 double intersept = minintersept + hymax;
00973 double imagey = intersept + slope*tracecol;
00974
00975
00976
00977 int hx, hy;
00978 for (hx = 1; hx <= SLOPERES; hx++){
00979 slope = SLOPE(hx);
00980 intersept = imagey - slope*tracecol;
00981 for (hy = (intersept - minintersept) - SPACING/3;
00982 hy <= (intersept - minintersept) + SPACING/3;
00983 hy++) {
00984 if (0 < hy && hy <= ny) {
00985 check( cpl_image_set(htrans, hx, hy, 0),
00986 "Could not write pixel at (%d, %d)", hx, hy);
00987 }
00988 }
00989 }
00990 }
00991
00992 cleanup:
00993 return cpl_error_get_code();
00994 }
00995
00996
01007
01008 cpl_error_code uves_draw_orders(const cpl_table *ordertable, cpl_image *image)
01009 {
01010 double penvalue;
01011 int nx;
01012 int ny;
01013 cpl_stats *stats = NULL;
01014 int nrows;
01015 int i;
01016
01017
01018 passure( image != NULL, " ");
01019 passure( ordertable != NULL, " ");
01020 passure( cpl_table_has_column(ordertable, "Intersept"), " ");
01021 passure( cpl_table_has_column(ordertable, "Slope" ), " ");
01022
01023 nx = cpl_image_get_size_x(image);
01024 ny = cpl_image_get_size_y(image);
01025
01026
01027 check( stats = cpl_stats_new_from_image(image, CPL_STATS_MAX),
01028 "Could not get statistics on input image");
01029 check( penvalue = 2*cpl_stats_get_max(stats),
01030 "Could not find image maximum value" );
01031
01032
01033 check ( nrows = cpl_table_get_nrow(ordertable),
01034 "Could not read number of rows in ordertable");
01035 for (i = 0; i < nrows; i++)
01036 {
01037 int x;
01038 double intersept, slope;
01039
01040 check(( intersept = cpl_table_get_double(ordertable, "Intersept", i, NULL),
01041 slope = cpl_table_get_double(ordertable, "Slope", i, NULL)),
01042 "Could not read 'Intersept' and 'Slope' from ordertable");
01043
01044 for (x = 1; x <= nx; x++){
01045 double yd = intersept + x * slope;
01046 int y = uves_round_double(yd);
01047
01048 if (0 < y && y <= ny)
01049 {
01050 cpl_image_set(image, x, y, penvalue);
01051 }
01052 }
01053 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
01054 "Could not draw order in table row #%d", i);
01055 }
01056
01057 cleanup:
01058 uves_free_stats(&stats);
01059 return cpl_error_get_code();
01060 }