300 #include <uves_orderpos_body.h>
302 #include <uves_orderpos_hough.h>
303 #include <uves_orderpos_follow.h>
305 #include <uves_physmod_chop_otab.h>
306 #include <uves_corrbadpix.h>
307 #include <uves_utils.h>
308 #include <uves_recipe.h>
309 #include <uves_parameters.h>
310 #include <uves_backsub.h>
311 #include <uves_pfits.h>
312 #include <uves_dfs.h>
313 #include <uves_qclog.h>
314 #include <uves_utils_wrappers.h>
315 #include <uves_utils_cpl.h>
316 #include <uves_error.h>
317 #include <uves_msg.h>
327 static void uves_orderpos_qclog(cpl_table* table,
331 int samples_per_order,
342 const char *
const uves_orderpos_desc_short =
"Defines echelle order positions";
343 const char *
const uves_orderpos_desc =
344 "The recipe defines the order positions in an echelle image. The orders are\n"
345 "initially detected by means of a Hough transformation, the orders are then \n"
346 "traced, and the positions are finally fitted with a global polynomial.\n"
348 "Expected input frames are narrow flat fields, ORDER_FLAT_xxx, or standard \n"
349 "stars, STANDARD_xxx, where xxx is 'BLUE' or 'RED', and optionally for each \n"
350 "chip a DRS setup table (DRS_TABLE_BLUE, DRS_TABLE_REDL, DRS_TABLE_REDU) or \n"
351 "guess order table (ORDER_GUESS_TAB_BLUE, ORDER_GUESS_TAB_REDL, \n"
352 "ORDER_GUESS_TAB_REDU, \n"
353 "or, for backward compatibility, ORDER_TABLE_BLUE, ORDER_TABLE_REDL, \n"
354 "ORDER_TABLE_REDU). The recipe processes only the first raw frame found.\n"
356 "Output is one (or two if input is a red frame) order table(s) \n"
357 "(UVES: ORDER_TABLE_(BLUE|REDL|REDU); FLAMES: FIB_ORDEF_(REDL|REDU) contaning\n"
359 "X : Position along x\n"
360 "Order : Relative order number\n"
361 "Y : Order line centroid location\n"
362 "Yfit : The fitted order location\n"
363 "dY : Uncertainty of Y\n"
364 "dYfit_Square : Variance of Yfit\n"
365 "Residual : Y - Yfit\n"
366 "Residual_Square : Residual^2\n"
367 "OrderRMS : Root mean squared residual of initial\n"
368 " one-dimensional linear fit of order\n"
370 "The bivariate fit polynomial itself is stored in table extension no. 2.\n"
371 "The 3rd table extension contains a table that defines the active fibre traces\n"
372 "and their positions (for support of FLAMES/UVES)\n";
387 uves_orderpos_define_parameters_body(cpl_parameterlist *parameters,
388 const char *recipe_id)
390 const char *subcontext;
391 double min_thresh=0.2;
397 if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
406 subcontext =
"preproc";
409 uves_par_new_enum(
"use_guess_tab",
411 "If a Guess order table is provided this parameter set how it is used:"
413 "1: use it to set lower/upper Y raws where order are searched "
414 "2: the order table try to fully match the guess",
420 uves_par_new_range(
"radx",
422 "Half X size of median filtering window",
425 uves_par_new_range(
"rady",
427 "Half Y size of median filtering window",
431 uves_par_new_enum(
"mmethod",
433 "Background subtraction method. If equal "
434 "to 'median' the background is sampled using "
435 "the median of a sub-window. If 'minimum', "
436 "the minimum sub-window value is used. If "
437 "'no', no background subtraction is done.",
440 "median",
"minimum",
"no");
443 uves_par_new_range(
"backsubgrid",
445 "Number of grid points (in x- and y-direction) "
447 "the background (mode=poly).",
451 uves_par_new_range(
"backsubradiusy",
453 "The height (in pixels) of the background "
454 "sampling window is (2*radiusy + 1). "
455 "This parameter is not corrected for binning.",
459 uves_par_new_range(
"backsubkappa",
461 "The value of kappa in the one-sided kappa-sigma "
463 "estimate the background (mode=poly).",
467 uves_par_new_range(
"backsubdegx",
469 "Degree (in x) of polynomial used "
470 "to estimate the background (mode=poly).",
473 uves_par_new_range(
"backsubdegy",
475 "Degree (in y) of polynomial used "
476 "to estimate the background (mode=poly).",
482 subcontext =
"hough";
485 uves_par_new_range(
"samplewidth",
487 "Separation of sample traces "
488 "(used by Hough transform) in input image",
492 uves_par_new_range(
"minslope",
494 "Minimum possible line slope. This should "
495 "be the 'physical' slope on the chip, "
496 "i.e. not taking binning factors into "
497 "account, which is handled by the recipe",
500 uves_par_new_range(
"maxslope",
502 "Maximum possible line slope",
506 uves_par_new_range(
"sloperes",
508 "Resolution (width in pixels) of Hough space",
529 uves_par_new_range(
"pthres",
531 "In automatic mode, or if the number of orders "
532 "to detect is read from a guess table, the detection "
533 "of new lines stops when the intensity of a candidate "
534 "line drops to less than 'pthres' times the intensity "
535 "of the previous detection. "
548 subcontext =
"trace";
551 uves_par_new_range(
"tracestep",
553 "The step size used when tracing the orders",
558 uves_par_new_range(
"minthresh",
560 "The minimum threshold value is (min + "
561 "minthres*(max - min)). Here 'min' "
562 "and 'max' are the lowest and highest pixel "
563 "values in the central bin of the order",
564 min_thresh, 0.0, 1.0);
567 uves_par_new_range(
"maxgap",
569 "If the order line drops below detection "
570 "threshold, the order tracing algorithm "
571 "will try to jump a gap of maximum size 'maxgap' "
572 "multiplied by the image width",
579 subcontext =
"reject";
582 uves_par_new_range(
"maxrms",
584 "When fitting the orders with straight lines, "
585 "this is the maximum allowed RMS relative to "
586 "the median RMS of all orders",
587 100.0, 0.0, DBL_MAX);
592 uves_par_new_range(
"defpol1",
594 "The degree of the bivarite fit (cross "
595 "dispersion direction). If negative, "
596 "the degree is optimized to give the best fit",
601 uves_par_new_range(
"defpol2",
603 "The degree of the bivarite fit (order number). "
605 "the degree is optimized to give the best fit",
610 uves_par_new_range(
"kappa",
612 "Used for kappa-sigma clipping of the final "
613 "polynomial fit. If negative, no clipping is done",
616 return (cpl_error_get_code() != CPL_ERROR_NONE);
671 uves_orderpos_process_chip(
const cpl_image *raw_image,
682 background_measure_method BM_METHOD,
694 bool norders_is_guess,
708 cpl_table* guess_table)
711 cpl_table *tracetable = NULL;
713 cpl_image *noise = NULL;
715 cpl_image *back_subbed = NULL;
716 cpl_image *hough_trans = NULL;
720 cpl_image *inputlines = NULL;
722 cpl_table *ordertable = NULL;
724 cpl_image *hough_original = NULL;
727 int badpixels_marked = 0;
731 bool red_ccd_is_new=0;
734 check( back_subbed = cpl_image_duplicate(raw_image),
"Error duplicating image");
736 ymax = cpl_image_get_size_y(back_subbed);
740 if(guess_table != NULL)
742 if(USE_GUESS_TAB == 1) {
747 cpl_table* tmp_tbl=NULL;
749 uves_msg(
"Use input guess order table to define the detector area");
753 tmp_tbl=cpl_table_duplicate(guess_table);
756 uves_msg(
"On Guess Found %d orders.",omax-omin+1);
757 if(omax < cpl_table_get_column_max(guess_table,
"Order")) {
758 uves_free_table(&tmp_tbl);
759 check(tmp_tbl=uves_extract_table_rows(guess_table,
"Order",
760 CPL_EQUAL_TO,omax+1),
761 "Error selecting Order");
763 check(ymax_guess=(
int)cpl_table_get_column_min(tmp_tbl,
"Yfit")-1,
764 "error getting ymax_guess");
765 uves_free_table(&tmp_tbl);
768 if(omin > cpl_table_get_column_min(guess_table,
"Order")) {
769 uves_free_table(&tmp_tbl);
770 check(tmp_tbl=uves_extract_table_rows(guess_table,
"Order",
771 CPL_EQUAL_TO,omin-1),
772 "Error selecting Order");
774 check(ymin_guess=(
int)cpl_table_get_column_max(tmp_tbl,
"Yfit")+1,
775 "error getting ymin_guess");
777 uves_free_table(&tmp_tbl);
779 ymin = (ymin_guess>ymin) ? ymin_guess : ymin;
780 ymax = (ymax_guess<ymax) ? ymax_guess : ymax;
782 uves_msg(
"Serching them in the region [ymin,ymax]=[%d,%d]",ymin,ymax);
783 uves_free_table(&tmp_tbl);
786 }
else if (USE_GUESS_TAB == 2) {
791 int minorder = uves_round_double(
792 cpl_table_get_column_min(guess_table,
"Order"));
793 int maxorder = uves_round_double(
794 cpl_table_get_column_max(guess_table,
"Order"));
795 int nx = cpl_image_get_size_x(back_subbed);
799 uves_msg(
"Create a table with order lines in the same format as the");
800 uves_msg(
"Hough transform would do it, ");
801 uves_msg(
"i.e. intersept + slope for each order.");
806 double min_rms = 0.1;
810 "X",
"Order",
"Yfit", NULL,
814 max_degree, max_degree, min_rms, -1,
816 NULL, NULL, -1, NULL),
817 "Could not fit polynomial to provided table");
819 uves_msg(
"Provided table contains orders %d - %d. RMS = %.3f pixels",
820 minorder, maxorder, sqrt(mse));
825 ordertable = cpl_table_new(maxorder - minorder + 1);
826 cpl_table_new_column(ordertable,
"Order", CPL_TYPE_INT);
827 cpl_table_new_column(ordertable,
"Intersept", CPL_TYPE_DOUBLE);
828 cpl_table_new_column(ordertable,
"Slope", CPL_TYPE_DOUBLE);
829 cpl_table_new_column(ordertable,
"Spacing", CPL_TYPE_INT);
831 for (order = minorder; order <= maxorder; order++)
833 int row = order - minorder;
840 guess_locations, nx/2, order, 2));
842 cpl_table_set_int (ordertable,
"Order", row, order);
843 cpl_table_set_double(ordertable,
"Slope", row, slope);
844 cpl_table_set_int (ordertable,
"Spacing", row, spacing);
845 cpl_table_set_double(ordertable,
"Intersept", row, intersept);
851 if( (guess_table == NULL) || (USE_GUESS_TAB != 2) )
855 uves_msg(
"Detect orders from scratch ");
864 bool extrapolate_border =
true;
869 uves_msg(
"Applying %dx%d median filter", RADX*2+1, RADY*2+1);
871 "Could not filter image");
875 uves_msg(
"Subtracting background (grid sampling)");
877 check( uves_backsub_poly(back_subbed,
885 "Could not subtract background");
889 NORDERS, norders_is_guess,
898 "Could not locate echelle orders");
905 "Error copying hieararch keys");
907 check( uves_save_image_local(
"Hough transform",
"hough",
908 hough_original, chip, -1, -1,
909 rotated_header,
true),
910 "Error saving hough image");
912 check( uves_save_image_local(
"Hough transform (peaks deleted)",
913 "hough_delete", hough_trans,
914 chip, -1, -1, rotated_header,
916 "Error saving hough image");
920 check( inputlines = cpl_image_duplicate(raw_image),
921 "Could not duplicate image");
923 "Could not draw hough orders on image");
925 check( uves_save_image_local(
"Lines detected by Hough transform",
926 "inputlines", inputlines, chip, -1, -1, rotated_header,
true),
927 "Error saving hough image");
929 uves_free_image(&inputlines);
933 uves_free_image(&hough_trans);
934 uves_free_image(&hough_original);
939 check(( uves_free_image(&back_subbed),
940 back_subbed = cpl_image_duplicate(raw_image)),
941 "Error duplicating image");
943 uves_msg(
"Subtracting background (inter-order sampling)");
944 check( uves_backsub_poly(back_subbed,
952 "Could not subtract background");
961 "Error creating noise image");
967 check( uves_save_image_local(
"Pre-processed raw frame",
"preproc",
968 back_subbed, chip, -1, -1, rotated_header,
true),
969 "Error saving image");
972 check( uves_save_image_local(
"Noise of pre-processed image",
974 noise, chip, -1, -1, rotated_header,
true),
975 "Error saving image");
979 check( badpixels_marked =
987 "Error marking bad pixels");
989 uves_msg(
"%d pixels marked as bad", badpixels_marked);
994 if(USE_GUESS_TAB==2) {
995 ord_min=cpl_table_get_column_min(ordertable,
"Order");
997 cpl_table_subtract_scalar(ordertable,
"Order",ord_min-1);
1011 norders),
"Could not trace orders");
1013 if(USE_GUESS_TAB==2) {
1015 cpl_table_add_scalar(ordertable,
"Order",ord_min-1);
1025 &abs_ord_min,&abs_ord_max),
1026 "Could not run uves_physmod_chop_otab on trace order table");
1034 if (debug_mode)
check( uves_save_table_local(
"Basic order table",
"basic",
1035 ordertable, chip, -1, -1, raw_header, NULL),
1036 "Error saving table");
1039 uves_free_image(&back_subbed);
1040 uves_free_image(&noise);
1041 uves_free_image(&hough_trans);
1045 uves_free_image(&hough_original);
1046 uves_free_image(&inputlines);
1047 uves_free_table(&ordertable);
1069 uves_orderpos_exe_body(cpl_frameset *frames,
1071 const char *recipe_id,
1072 const cpl_parameterlist *parameters,
1073 const char *starttime)
1082 int USE_GUESS_TAB, RADX, RADY;
1083 background_measure_method BM_METHOD;
1086 double BACKSUBKAPPA;
1091 double MINSLOPE, MAXSLOPE;
1104 const char* PROCESS_CHIP=NULL;
1107 cpl_image *master_bias = NULL;
1112 cpl_image *raw_image[2] = {NULL, NULL};
1115 cpl_image *raw_image_int = NULL;
1119 cpl_table *guess_table = NULL;
1122 cpl_table *tracetable = NULL;
1124 cpl_table *traces = NULL;
1126 cpl_table* qclog[2] = {NULL, NULL};
1129 const char *raw_filename =
"";
1130 char *product_filename = NULL;
1131 int ord_predict = 0;
1132 bool norders_is_guess =
false;
1134 enum uves_chip chip;
1139 const char *guess_filename =
"";
1140 const char *chip_name =
"";
1141 const char *master_bias_filename =
"";
1149 bool load_guess =
false;
1153 int samples_per_order =0;
1165 check( uves_get_parameter(parameters, NULL,
"uves",
"debug", CPL_TYPE_BOOL, &debug_mode),
1166 "Could not read parameter");
1167 check( uves_get_parameter(parameters, NULL,
"uves",
"process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
1168 "Could not read parameter");
1172 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.use_guess_tab",
1173 CPL_TYPE_INT , &USE_GUESS_TAB),
"Could not read parameter");
1174 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.radx",
1175 CPL_TYPE_INT , &RADX),
"Could not read parameter");
1176 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.rady",
1177 CPL_TYPE_INT , &RADY),
"Could not read parameter");
1179 check( BM_METHOD = uves_get_bm_method(parameters, recipe_id,
"preproc"),
1180 "Could not read background measuring method");
1182 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.backsubgrid",
1183 CPL_TYPE_INT , &BACKSUBGRID),
1184 "Could not read parameter");
1185 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.backsubradiusy",
1186 CPL_TYPE_INT, &BACKSUBRADIUSY),
"Could not read parameter");
1187 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.backsubkappa",
1188 CPL_TYPE_DOUBLE,&BACKSUBKAPPA),
"Could not read parameter");
1189 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.backsubdegx",
1190 CPL_TYPE_INT , &BACKSUBDEGX),
"Could not read parameter");
1191 check( uves_get_parameter(parameters, NULL, recipe_id,
"preproc.backsubdegy",
1192 CPL_TYPE_INT , &BACKSUBDEGY),
"Could not read parameter");
1194 check( uves_get_parameter(parameters, NULL, recipe_id,
"hough.samplewidth" ,
1195 CPL_TYPE_INT , &SAMPLEWIDTH),
"Could not read parameter");
1196 check( uves_get_parameter(parameters, NULL, recipe_id,
"hough.minslope" ,
1197 CPL_TYPE_DOUBLE, &MINSLOPE ),
"Could not read parameter");
1198 check( uves_get_parameter(parameters, NULL, recipe_id,
"hough.maxslope" ,
1199 CPL_TYPE_DOUBLE, &MAXSLOPE ),
"Could not read parameter");
1200 check( uves_get_parameter(parameters, NULL, recipe_id,
"hough.sloperes" ,
1201 CPL_TYPE_INT , &SLOPERES ),
"Could not read parameter");
1206 check( uves_get_parameter(parameters, NULL, recipe_id,
"hough.pthres" ,
1207 CPL_TYPE_DOUBLE, &PTHRES ),
"Could not read parameter");
1209 check( uves_get_parameter(parameters, NULL, recipe_id,
"trace.tracestep" ,
1210 CPL_TYPE_INT , &TRACESTEP ),
"Could not read parameter");
1211 check( uves_get_parameter(parameters, NULL, recipe_id,
"trace.minthresh" ,
1212 CPL_TYPE_DOUBLE, &MINTHRESH ),
"Could not read parameter");
1213 check( uves_get_parameter(parameters, NULL, recipe_id,
"trace.maxgap" ,
1214 CPL_TYPE_DOUBLE, &MAXGAP ),
"Could not read parameter");
1216 check( uves_get_parameter(parameters, NULL, recipe_id,
"reject.maxrms" ,
1217 CPL_TYPE_DOUBLE, &MAXRMS ),
"Could not read parameter");
1218 check( uves_get_parameter(parameters, NULL, recipe_id,
"reject.defpol1" ,
1219 CPL_TYPE_INT , &DEFPOL1_par ),
"Could not read parameter");
1220 check( uves_get_parameter(parameters, NULL, recipe_id,
"reject.defpol2" ,
1221 CPL_TYPE_INT , &DEFPOL2_par),
"Could not read parameter");
1222 check( uves_get_parameter(parameters, NULL, recipe_id,
"reject.kappa" ,
1223 CPL_TYPE_DOUBLE, &KAPPA ),
"Could not read parameter");
1227 assure( MINSLOPE < MAXSLOPE , CPL_ERROR_ILLEGAL_INPUT,
1228 "Minimum slope must be smaller than maximum slope (min = %f; max = %f)",
1229 MINSLOPE, MAXSLOPE);
1230 if (MAXSLOPE > 0.5){
1232 "lines with slope larger than 0.5 (maxslope = %f)", MAXSLOPE);
1235 if (DEFPOL1_par >= 6 || DEFPOL2_par >= 6)
1238 "polynomial degrees higher than 5");
1244 check( uves_load_orderpos(frames,
1246 &raw_filename, raw_image,
1247 raw_header, rotated_header, &blue),
"Error loading raw frame");
1251 "Could not read x binning factor from input header");
1253 "Could not read y binning factor from input header");
1261 MINSLOPE = (MINSLOPE*biny)/binx;
1262 MAXSLOPE = (MAXSLOPE*biny)/binx;
1264 ord_predict = NORDERS;
1268 chip != UVES_CHIP_INVALID;
1272 if(strcmp(PROCESS_CHIP,
"REDU") == 0) {
1281 DEFPOL1 = DEFPOL1_par;
1282 DEFPOL2 = DEFPOL2_par;
1284 uves_msg(
"Processing %s chip in '%s'",
1301 norders_is_guess =
true;
1303 uves_free_propertylist(&guess_header);
1305 if (cpl_frameset_find(frames, UVES_DRS_SETUP(flames, chip)) != NULL)
1309 check( uves_load_drs(frames, flames, chip_name, &guess_filename,
1310 &guess_header, chip),
1311 "Error loading setup table");
1313 uves_msg(
"Using setup table in '%s'", guess_filename);
1316 "Could not read predicted number "
1317 "of orders from DRS table header");
1319 else if (cpl_frameset_find(frames,
1320 UVES_ORDER_TABLE(flames, chip)) != NULL ||
1321 cpl_frameset_find(frames,
1322 UVES_GUESS_ORDER_TABLE(flames, chip)) != NULL)
1325 cpl_frameset_find(frames,
1326 UVES_GUESS_ORDER_TABLE(flames, chip))
1329 uves_free_table(&guess_table);
1331 check( uves_load_ordertable(
1345 "Error loading guess order table");
1347 uves_msg(
"Using guess order table in '%s'", guess_filename);
1350 "Could not read predicted number of orders from "
1351 "guess order table header");
1364 norders_is_guess =
false;
1368 uves_free_image(&master_bias);
1369 uves_free_propertylist(&master_bias_header);
1370 if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
1372 uves_free_image(&master_bias);
1373 uves_free_propertylist(&master_bias_header);
1374 check( uves_load_mbias(frames,
1376 &master_bias_filename, &master_bias,
1377 &master_bias_header, chip),
1378 "Error loading master bias");
1380 uves_msg_low(
"Using master bias in '%s'", master_bias_filename);
1381 cpl_image_subtract(raw_image[raw_index],master_bias);
1386 uves_msg_low(
"No master bias in SOF. Bias subtraction not done");
1390 check((uves_free_table (&tracetable),
1392 tracetable = uves_orderpos_process_chip(
1393 raw_image[raw_index],
1394 raw_header[raw_index],
1395 rotated_header[raw_index],
1404 BACKSUBDEGX, BACKSUBDEGY,
1421 "Error processing chip");
1429 uves_free_propertylist(&product_header);
1434 "Error writing number of detected orders");
1440 "Error reading plate id");
1448 cpl_image_get_size_x(raw_image[raw_index]) / TRACESTEP;
1457 raw_header[raw_index],chip,qclog[0]));
1465 snprintf(values, 80,
"-1 -1 -1 -1 -1 %d %d", DEFPOL1, DEFPOL2);
1467 uves_propertylist_append_string(product_header,
1468 "HISTORY",
"'COEFFI','I*4'");
1469 uves_propertylist_append_string(product_header,
1471 uves_propertylist_append_string(product_header,
1475 uves_propertylist_append_string(product_header,
1476 "HISTORY",
"'COEFFD','R*8'");
1479 for (j = 0; j <= DEFPOL2; j++) {
1480 for (i = 0; i <= DEFPOL1; i++) {
1481 snprintf(values, 80,
"%g",
1483 uves_propertylist_append_string(product_header,
1488 uves_propertylist_append_string(product_header,
1492 uves_propertylist_append_string(product_header,
1493 "HISTORY",
"'COEFFR','R*4'");
1494 snprintf(values, 80,
"%g %g",
1495 cpl_table_get_column_min(tracetable,
"X"),
1496 cpl_table_get_column_max(tracetable,
"X"));
1497 uves_propertylist_append_string(product_header,
1500 snprintf(values, 80,
"%g %g",
1501 cpl_table_get_column_min(tracetable,
"Order"),
1502 cpl_table_get_column_max(tracetable,
"Order"));
1503 uves_propertylist_append_string(product_header,
1506 uves_propertylist_append_string(product_header,
1511 sprintf(extname,
"ORDER_TAB");
1513 check(( cpl_free(product_filename),
1514 product_filename = uves_order_table_filename(chip),
1515 uves_frameset_insert(frames,
1517 CPL_FRAME_GROUP_PRODUCT,
1518 CPL_FRAME_TYPE_TABLE,
1519 CPL_FRAME_LEVEL_INTERMEDIATE,
1521 UVES_ORD_TAB(flames, chip),
1522 raw_header[raw_index],
1527 PACKAGE
"/" PACKAGE_VERSION,
1529 starttime,
true, 0)),
1530 "Could not add trace table %s to frameset", product_filename);
1532 uves_msg(
"Trace table %s added to frameset", product_filename);
1533 sprintf(extname,
"ORDER_POL");
1537 check( uves_save_polynomial(bivariate_fit, product_filename, table_header),
1538 "Could not write polynomial to file %s", product_filename);
1551 uves_free_table(&traces);
1554 sprintf(extname,
"ORDER_INFO");
1557 check( cpl_table_save(traces,
1564 "Error appending table to file '%s'", product_filename);
1572 uves_free_image(&raw_image_int);
1573 raw_image_int = cpl_image_cast(raw_image[raw_index],
1576 check(( cpl_free(product_filename),
1577 product_filename = uves_ordef_filename(chip),
1578 uves_frameset_insert(frames,
1580 CPL_FRAME_GROUP_PRODUCT,
1581 CPL_FRAME_TYPE_IMAGE,
1582 CPL_FRAME_LEVEL_INTERMEDIATE,
1584 FLAMES_ORDEF(flames, chip),
1585 raw_header[raw_index],
1586 rotated_header[raw_index],
1590 PACKAGE
"/" PACKAGE_VERSION,
1593 CPL_STATS_MIN | CPL_STATS_MAX)),
1594 "Could not add raw frame %s to frameset", product_filename);
1596 uves_msg(
"Raw frame %s added to frameset", product_filename);
1597 uves_free_image(&raw_image_int);
1600 if(strcmp(PROCESS_CHIP,
"REDL") == 0) {
1604 uves_free_propertylist(&table_header);
1609 uves_free_image(&(raw_image[0]));
1610 uves_free_image(&(raw_image[1]));
1611 uves_free_image(&raw_image_int);
1612 uves_free_propertylist(&(raw_header[0]));
1613 uves_free_propertylist(&(raw_header[1]));
1614 uves_free_propertylist(&(rotated_header[0]));
1615 uves_free_propertylist(&(rotated_header[1]));
1618 uves_free_image(&master_bias);
1619 uves_free_propertylist(&master_bias_header);
1622 uves_free_propertylist(&guess_header);
1623 uves_free_table (&guess_table);
1627 uves_free_table (&tracetable);
1629 uves_free_table (&traces);
1630 uves_free_propertylist(&product_header);
1631 cpl_free(product_filename);
1645 static void uves_orderpos_qclog(cpl_table* table,
1649 int samples_per_order,
1651 enum uves_chip chip,
1654 const char* chip_name;
1655 const char* grat_name;
1656 const char* ins_mode;
1662 "Single-Fibre-Order-Definition-Results" :
1663 "Order-Definition-Results",
1673 "Grating unique ID",
1684 "Cross disperser ID",
1692 "Instrument mode used.",
1700 "Grating central wavelength [nm]",
1703 uves_msg_debug(
"chip_name=%s grat_name=%s ins_mode=%s grat_wlen=%f",
1704 chip_name,grat_name,ins_mode,grat_wlen);
1708 cpl_table_get_column_min(table,
"Residual"),
1709 "min resid in ord def",
1714 cpl_table_get_column_max(table,
"Residual"),
1715 "max resid in ord def",
1720 cpl_table_get_column_mean(table,
"Residual"),
1721 "mean resid in ord def",
1726 cpl_table_get_column_stdev(table,
"Residual"),
1727 "rms resid in ord def",
1733 "predicted number of orders",
1739 "detected number of orders",
1744 dord * samples_per_order,
1745 "Number of position found",
1750 cpl_table_get_nrow(table),
1751 "Number of position selected",
1756 cpl_table_get_column_min(table,
"Order"),
1757 "Number of position selected",
1762 cpl_table_get_column_max(table,
"Order"),
1763 "Number of position selected",
1779 "Binning factor along X",
1785 "Binning factor along Y",
1791 "Optical path used (h).",
cpl_error_code uves_filter_image_median(cpl_image **image, int xwindow, int ywindow, bool extrapolate_border)
Median filter.
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
#define uves_msg_warning(...)
Print an warning message.
int uves_flames_pfits_get_plateid(const uves_propertylist *raw_header)
read the plate id
int uves_qclog_add_string(cpl_table *table, const char *key_name, const char *value, const char *key_help, const char *format)
Add string key to QC-LOG table.
cpl_image * uves_define_noise(const cpl_image *image, const uves_propertylist *image_header, int ncom, enum uves_chip chip)
Create noise image.
cpl_table * uves_ordertable_traces_new(void)
Create the table that describes fibre traces.
int uves_pfits_get_ordpred(const uves_propertylist *plist)
Read the predicted number of orders.
cpl_table * uves_hough(const cpl_image *image, int ymin, int ymax, int NORDERS, bool norders_is_guess, int SAMPLEWIDTH, double PTHRES, double MINSLOPE, double MAXSLOPE, int SLOPERES, bool consecutive, cpl_image **htrans, cpl_image **htrans_original)
Compute Hough transform and detect lines.
int uves_qclog_delete(cpl_table **table)
delete QC-LOG table
double uves_pfits_get_gratwlen(const uves_propertylist *plist, enum uves_chip chip)
find out the central wavelength
int uves_qclog_add_double(cpl_table *table, const char *key_name, const double value, const char *key_help, const char *format)
Add double key to QC-LOG table.
cpl_table * uves_locate_orders(const cpl_image *inputimage, const cpl_image *noise, cpl_table *ordertable, int TRACESTEP, double MINTHRESH, double MAXGAP, double MAXRMS, int *DEFPOL1, int *DEFPOL2, double KAPPA, polynomial **bivariate_fit, int *orders_traced)
Trace all orders.
void uves_flames_pfits_set_newplateid(uves_propertylist *plist, int plate_no)
Write the plate number.
double uves_polynomial_get_coeff_2d(const polynomial *p, int degree1, int degree2)
Get a coefficient of a 2D polynomial.
const char * uves_pfits_get_chip_name(const uves_propertylist *plist, enum uves_chip chip)
Find out the chip name.
int uves_qclog_add_int(cpl_table *table, const char *key_name, const int value, const char *key_help, const char *format)
Add integer key to QC-LOG table.
double uves_polynomial_derivative_2d(const polynomial *p, double x1, double x2, int varno)
Evaluate the partial derivative of a 2d polynomial.
uves_propertylist * uves_propertylist_new(void)
Create an empty property list.
int uves_pfits_get_binx(const uves_propertylist *plist)
Find out the x binning factor.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
int uves_pfits_get_biny(const uves_propertylist *plist)
Find out the y binning factor.
cpl_error_code uves_propertylist_copy_property_regexp(uves_propertylist *self, const uves_propertylist *other, const char *regexp, int invert)
Copy matching properties from another property list.
polynomial * uves_polynomial_regression_2d_autodegree(cpl_table *t, const char *X1, const char *X2, const char *Y, const char *sigmaY, const char *polynomial_fit, const char *residual_square, const char *variance_fit, double *mean_squared_error, double *red_chisq, polynomial **variance, double kappa, int maxdeg1, int maxdeg2, double min_rms, double min_reject, bool verbose, const double *min_val, const double *max_val, int npos, double positions[][2])
Fit a 2d polynomial to three table columns.
bool uves_ccd_is_new(const uves_propertylist *plist)
Find out if CCD header is new.
const char * uves_remove_string_prefix(const char *s, const char *prefix)
Remove named prefix from string.
const char * uves_pfits_get_gratname(const uves_propertylist *plist, enum uves_chip chip)
find out the grating name value
double uves_polynomial_evaluate_2d(const polynomial *p, double x1, double x2)
Evaluate a 2d polynomial.
int uves_physmod_chop_otab(const uves_propertylist *raw_header, enum uves_chip chip, cpl_table **ord_tbl, const char *col_name, int *ord_min, int *ord_max)
Chop off orders which are not fully in the detector chip.
const char * uves_pfits_get_insmode(const uves_propertylist *plist)
find out the chip name value
const char * uves_pfits_get_inspath(const uves_propertylist *plist)
find out the chip name value
int uves_chip_get_index(enum uves_chip chip)
Convert to integer.
enum uves_chip uves_chip_get_first(bool blue)
Get first chip for blue or red arm.
const char * uves_pfits_get_readspeed(const uves_propertylist *plist)
find out the readout speed
cpl_error_code uves_ordertable_traces_add(cpl_table *traces, int fibre_ID, double fibre_offset, int fibre_mask)
Add a trace.
cpl_error_code uves_pfits_set_extname(uves_propertylist *plist, const char *extname)
Write the EXTNAME keyword.
#define uves_msg_low(...)
Print a message on a lower message level.
enum uves_chip uves_chip_get_next(enum uves_chip chip)
Get next chip.
#define uves_msg_debug(...)
Print a debug message.
const char * uves_chip_tostring_upper(enum uves_chip chip)
Convert to string.
cpl_error_code uves_draw_orders(const cpl_table *ordertable, cpl_image *image)
Draw detected order lines.
int uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header, enum uves_chip chip, int binx, int biny, int mark_bad, bool red_ccd_new)
Correct all bad pixels on a chip.
const char * uves_string_toupper(char *s)
Convert all lowercase characters in a string into uppercase characters.
cpl_error_code uves_pfits_set_ordpred(uves_propertylist *plist, int nord)
Write the predicted number of order.
cpl_table * uves_qclog_init(const uves_propertylist *raw_header, enum uves_chip chip)
Init QC-LOG table.
const char * uves_pfits_get_chipid(const uves_propertylist *plist, enum uves_chip chip)
Find out the chip ID.