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