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