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