150 #include <uves_wavecal_identify.h>
152 #include <uves_wavecal_utils.h>
153 #include <uves_utils.h>
154 #include <uves_utils_wrappers.h>
155 #include <uves_error.h>
156 #include <uves_msg.h>
158 #include <uves_qclog.h>
167 const cpl_table *linetable,
169 double red_chisq,cpl_table* qclog);
176 const cpl_table *line_refer,
180 cpl_table **selected,
181 int degree,
bool verbose,
235 const cpl_table *line_refer,
237 int DEGREE,
double TOLERANCE,
238 double ALPHA,
double MAXERROR,
240 const int trace,
const int window,cpl_table* qclog)
251 cpl_table *selected = NULL;
254 passure( linetable != NULL,
" ");
255 passure( line_refer != NULL,
" ");
256 passure( guess_dispersion != NULL,
" ");
258 assure( 0 < ALPHA && ALPHA <= 1, CPL_ERROR_ILLEGAL_INPUT,
259 "Illegal alpha = %e", ALPHA);
263 cpl_table_new_column(linetable, LINETAB_LAMBDAC , CPL_TYPE_DOUBLE);
264 cpl_table_new_column(linetable,
"dLambdaC" , CPL_TYPE_DOUBLE);
265 cpl_table_new_column(linetable, LINETAB_PIXELSIZE , CPL_TYPE_DOUBLE);
266 cpl_table_new_column(linetable, LINETAB_RESIDUAL , CPL_TYPE_DOUBLE);
267 cpl_table_new_column(linetable,
"Residual_pix" , CPL_TYPE_DOUBLE);
268 cpl_table_new_column(linetable,
"Lambda_candidate" , CPL_TYPE_DOUBLE);
269 cpl_table_new_column(linetable,
"dLambda_candidate", CPL_TYPE_DOUBLE);
270 cpl_table_new_column(linetable,
"dLambda_cat_sq" , CPL_TYPE_DOUBLE);
271 cpl_table_new_column(linetable,
"dLambda_nn_sq" , CPL_TYPE_DOUBLE);
275 cpl_table_new_column(linetable,
"Ident", CPL_TYPE_DOUBLE);
276 cpl_table_new_column(linetable,
"dIdent",CPL_TYPE_DOUBLE);
277 cpl_table_set_column_invalid(linetable,
"Ident", 0, cpl_table_get_nrow(linetable));
278 cpl_table_set_column_invalid(linetable,
"dIdent",0, cpl_table_get_nrow(linetable));
280 cpl_table_set_column_unit(linetable,LINETAB_LAMBDAC,
"Angstrom" );
281 cpl_table_set_column_unit(linetable,
"dLambdaC",
"Angstrom" );
282 cpl_table_set_column_unit(linetable,LINETAB_PIXELSIZE,
"Angstrom" );
283 cpl_table_set_column_unit(linetable,LINETAB_RESIDUAL,
"Angstrom" );
284 cpl_table_set_column_unit(linetable,
"Residual_pix",
"Angstrom" );
285 cpl_table_set_column_unit(linetable,
"Lambda_candidate",
"Angstrom" );
286 cpl_table_set_column_unit(linetable,
"dLambda_candidate",
"Angstrom" );
287 cpl_table_set_column_unit(linetable,
"dLambda_cat_sq",
"Angstrom" );
288 cpl_table_set_column_unit(linetable,
"dLambda_nn_sq",
"Angstrom" );
289 cpl_table_set_column_unit(linetable,
"Ident",
"Angstrom" );
290 cpl_table_set_column_unit(linetable,
"dIdent",
"Angstrom" );
293 "Error applying dispersion relation");
298 for (idloop = 2; idloop <= 2; idloop += 1)
300 for (idloop = 1; idloop <= 2; idloop += 1)
310 bool reject = (idloop == 2);
315 previous_id = current_id;
320 "Error identifying lines");
326 "Error during point pattern matching");
328 cpl_table_erase_column(linetable,
"Ident");
329 cpl_table_duplicate_column(linetable,
"Ident", linetable,
"Ident_ppm");
330 current_id = nident_ppm;
334 cpl_table_fill_column_window(linetable,
"dIdent",
335 0, cpl_table_get_nrow(linetable),
336 cpl_table_get_column_mean(linetable,
"dIdent"));
353 &dispersion_variance,
357 "Could not perform global calibration");
362 uves_msg(
"%d identifications made. RMS = %.5f wlu = %.3f "
363 "pixels (no rejection)",
364 current_id, rms_wlu, rms_pixels);
372 uves_msg(
"%d identifications made. RMS = %.5f wlu = %.3f "
373 "pixels (%f %s rejection, kappa = %.1f)",
374 current_id, rms_wlu, rms_pixels,
375 fabs(TOLERANCE), (TOLERANCE > 0) ?
"pixels" :
"wlu",
379 sprintf(qc_key,
"QC TRACE%d WIN%d NLINID%d",trace,window,idloop);
381 "ThAr lamp identified lines",
385 uves_msg(
"%d identifications from point pattern matching",
389 assure( rms_pixels < MAXERROR, CPL_ERROR_CONTINUE,
390 "Wavelength calibration did not converge. "
391 "After %d iterations the RMS was %f pixels. "
392 "Try to improve on the initial solution", n, rms_pixels);
398 "Error applying dispersion relation");
402 while (current_id > previous_id) ;
404 sprintf(qc_key,
"QC TRACE%d WIN%d NLINID NITERS",trace,window);
406 "Number of iterations",
417 uves_msg(
"Identification loop converged. Resetting identifications");
418 cpl_table_set_column_invalid(linetable,
"Ident", 0,
419 cpl_table_get_nrow(linetable));
427 uves_free_table(&selected);
436 &dispersion_variance,
438 "Could not perform global calibration");
443 "Error applying dispersion relation");
453 cpl_table_new_column(linetable,
"NLinSol", CPL_TYPE_INT);
454 cpl_table_new_column(linetable,
"Select", CPL_TYPE_INT);
456 cpl_table_fill_column_window_int(linetable,
"NLinSol",
457 0, cpl_table_get_nrow(linetable),
459 cpl_table_fill_column_window_int(linetable,
"Select",
460 0, cpl_table_get_nrow(linetable),
464 for (i = 0; i < cpl_table_get_nrow(selected); i++) {
465 int order = cpl_table_get_int(selected,
"Order", i, NULL);
466 double x = cpl_table_get_double(selected,
"X", i, NULL);
471 passure( j < cpl_table_get_nrow(linetable),
"%d %" CPL_SIZE_FORMAT
"",
472 j, cpl_table_get_nrow(linetable));
474 order2 = cpl_table_get_int(linetable,
"Order", j, NULL);
475 x2 = cpl_table_get_double(linetable,
"X", j, NULL);
476 if (cpl_table_is_valid(linetable,
"Ident", j))
478 cpl_table_set_int(linetable,
"Select", j, 1);
482 }
while (order2 < order || x2 < x - 0.1);
484 passure( order2 == order && fabs(x2 - x) < 0.1,
485 "%d %d %g %g", order2, order, x2, x);
487 cpl_table_set_int(linetable,
"NLinSol", j-1, 1);
493 "Error verifying calibration");
496 uves_free_table(&selected);
498 return dispersion_relation;
516 static cpl_error_code
518 const cpl_table *linetable,
double TOLERANCE,
519 double red_chisq, cpl_table* qclog)
521 cpl_table *brightest = NULL;
522 double median_intensity;
534 check(( mean = cpl_table_get_column_mean (selected, LINETAB_RESIDUAL),
535 stdev= cpl_table_get_column_stdev(selected, LINETAB_RESIDUAL),
536 rms_wlu = sqrt(mean*mean + stdev*stdev),
538 mean = cpl_table_get_column_mean (selected,
"Residual_pix"),
539 stdev= cpl_table_get_column_stdev(selected,
"Residual_pix"),
540 rms_pixels = sqrt(mean*mean + stdev*stdev)),
541 "Error reading RMS of fit");
543 rms_speed=rms_wlu * SPEED_OF_LIGHT/
544 cpl_table_get_column_mean(selected,LINETAB_LAMBDAC);
545 uves_msg(
"%" CPL_SIZE_FORMAT
" lines accepted", cpl_table_get_nrow(selected));
546 uves_msg(
"Average RMS of calibration (tolerance = %.3f %s) = %.5f wlu = %.4f pixels ~ %.1f m/s",
548 (TOLERANCE > 0) ?
"pixels" :
"wlu",
549 rms_wlu, rms_pixels, rms_speed);
551 sprintf(qc_key,
"QC LINE RESIDRMS WLU");
553 "Line ID RMS TRACE0 WIN2 [Angstrom]",
555 sprintf(qc_key,
"QC LINE RESIDRMS PIX");
557 "Line ID RMS TRACE0 WIN2 [pix]",
559 sprintf(qc_key,
"QC LINE RESIDRMS SPEED");
561 "Line ID RMS TRACE0 WIN2 [m/s]",
565 uves_msg(
"Reduced chi^2 of calibration = %f", red_chisq);
566 sprintf(qc_key,
"QC LINE IDCHI2");
568 "Reduced chi^2 of line ID TRACE0 WIN2",
582 check(( median_intensity = cpl_table_get_column_median(linetable,
"Peak"),
583 brightest = uves_extract_table_rows(linetable,
"Peak",
586 ninvalid = cpl_table_count_invalid(brightest,
"Ident")),
587 "Error counting identifications");
589 ratio = 1 - ((double) ninvalid)/cpl_table_get_nrow(brightest);
590 uves_msg(
"Percentage of identifications among the half brighter lines : %.2f %%",
593 sprintf(qc_key,
"QC LINE HALFBRIG");
595 "Half brighter lines frac TRACE0 WIN2",
599 uves_free_table(&brightest);
601 return cpl_error_get_code();
619 static cpl_error_code
626 bool printed_warning =
false;
629 passure(linetable != NULL,
" ");
630 passure(dispersion_relation != NULL,
" ");
637 passure(cpl_table_has_column(linetable,
"X") ,
" ");
638 passure(cpl_table_has_column(linetable,
"Order") ,
" ");
639 passure(cpl_table_has_column(linetable,
"Ident") ,
" ");
641 passure(cpl_table_has_column(linetable, LINETAB_LAMBDAC) ,
" ");
643 passure(cpl_table_has_column(linetable,
"dLambdaC") ,
" ");
644 passure(cpl_table_has_column(linetable,
"dIdent") ,
" ");
645 passure(cpl_table_has_column(linetable, LINETAB_RESIDUAL),
" ");
646 passure(cpl_table_has_column(linetable,
"Residual_pix"),
" ");
647 passure(cpl_table_has_column(linetable, LINETAB_PIXELSIZE) ,
" ");
651 for(i = 0; i < cpl_table_get_nrow(linetable); i++)
655 double lambdac, dlambdac, pixelsize;
656 order = cpl_table_get_int(linetable,
"Order", i, NULL);
658 x = cpl_table_get_double(linetable,
"X", i, NULL);
669 if (!printed_warning && verbose) {
671 "(x, order) = (%f, %d)", x, order);
672 printed_warning =
true;
676 "(x, order) = (%f, %d)", x, order);
679 pixelsize = dfdx / order;
681 check(( cpl_table_set_double(linetable, LINETAB_LAMBDAC , i, lambdac),
682 cpl_table_set_double(linetable, LINETAB_PIXELSIZE, i, pixelsize)),
683 "Error writing table");
685 if (dispersion_variance != NULL)
693 cpl_table_set_double(linetable,
"dLambdaC" , i, dlambdac);
701 cpl_table_set_double(linetable,
"dLambdaC" , i, 1.0);
705 if (cpl_table_is_valid(linetable,
"Ident", i))
707 double ident = cpl_table_get_double(linetable,
"Ident", i, NULL);
708 cpl_table_set_double(linetable, LINETAB_RESIDUAL, i,
710 cpl_table_set_double(linetable,
"Residual_pix", i,
711 (ident - lambdac)/pixelsize);
715 cpl_table_set_invalid(linetable, LINETAB_RESIDUAL, i);
716 cpl_table_set_invalid(linetable,
"Residual_pix", i);
721 check( uves_sort_table_2(linetable,
"Order",
"X",
false,
false),
722 "Error sorting table");
725 return cpl_error_get_code();
771 int number_identifications = 0;
775 int *histogram = NULL;
776 const double minlog = -5.0;
779 const double maxlog = 15.0;
780 const int nbins = 400;
783 double average_dlambda_com = 0;
787 passure( linetable != NULL,
" ");
789 passure( cpl_table_has_column(linetable, LINETAB_LAMBDAC ),
" ");
791 passure( cpl_table_has_column(linetable,
"dLambdaC" ),
" ");
793 passure( cpl_table_has_column(linetable,
"X" ),
" ");
795 passure( cpl_table_has_column(linetable,
"Order" ),
" ");
797 passure( cpl_table_has_column(linetable,
"Xwidth" ),
" ");
798 passure( cpl_table_has_column(linetable, LINETAB_PIXELSIZE),
" ");
801 passure( cpl_table_has_column(linetable,
"Ident" ),
" ");
803 passure( cpl_table_has_column(linetable,
"dIdent" ),
" ");
807 passure( line_refer != NULL,
" ");
808 passure( cpl_table_has_column(line_refer,
"Wave" ),
" ");
809 passure( cpl_table_has_column(line_refer,
"dWave"),
" ");
812 linetable_size = cpl_table_get_nrow(linetable);
813 linerefer_size = cpl_table_get_nrow(line_refer);
814 assure(linerefer_size >= 1, CPL_ERROR_ILLEGAL_INPUT,
"Empty line reference table");
817 passure( 0 < ALPHA && ALPHA <= 1,
"%e", ALPHA);
820 average_dlambda_com = cpl_table_get_column_median(linetable,
"dLambdaC");
823 histogram = cpl_calloc(nbins,
sizeof(
int));
830 for (row = 0; row < linetable_size; row++) {
836 double lambda_cat_sigma;
837 double distance_cat_sq;
838 double nn_distance_sq;
842 lambda_com = cpl_table_get_double(linetable, LINETAB_LAMBDAC , row, NULL);
843 order = cpl_table_get_int (linetable,
"Order" , row, NULL);
847 cpl_table_get_double(linetable,
"Xwidth" , row, NULL) *
848 fabs(cpl_table_get_double(linetable, LINETAB_PIXELSIZE , row, NULL));
851 line_fwhm = TWOSQRT2LN2 * line_width;
855 line_refer, lambda_com, 0, linerefer_size - 1);
856 lambda_cat = cpl_table_get_double(line_refer,
"Wave", row_cat, NULL);
857 lambda_cat_sigma = cpl_table_get_double(line_refer,
"dWave",row_cat, NULL);
860 distance_cat_sq = (lambda_com - lambda_cat)*(lambda_com - lambda_cat);
867 double lambda_com_prev, lambda_com_next;
868 int order_prev, order_next;
869 double lambda_cat_prev, lambda_cat_next;
871 nn_distance_sq = DBL_MAX;
876 order_prev = cpl_table_get_int (
877 linetable,
"Order" , row - 1, NULL);
878 lambda_com_prev = cpl_table_get_double(
879 linetable, LINETAB_LAMBDAC, row - 1, NULL);
881 if (order == order_prev)
883 nn_distance_sq = uves_min_double(nn_distance_sq,
884 (lambda_com_prev - lambda_com)*
885 (lambda_com_prev - lambda_com)
890 if (row <= linetable_size - 2)
892 order_next = cpl_table_get_int (linetable,
"Order",
894 lambda_com_next = cpl_table_get_double(linetable, LINETAB_LAMBDAC,
897 if (order == order_next)
899 nn_distance_sq = uves_min_double(nn_distance_sq,
900 (lambda_com_next - lambda_com)*
901 (lambda_com_next - lambda_com)
909 lambda_cat_prev = cpl_table_get_double(
910 line_refer,
"Wave", row_cat - 1, NULL);
912 nn_distance_sq = uves_min_double(
914 (lambda_cat_prev - lambda_cat)*
915 (lambda_cat_prev - lambda_cat)
918 if (row_cat <= linerefer_size - 2)
920 lambda_cat_next = cpl_table_get_double(
921 line_refer,
"Wave", row_cat + 1, NULL);
923 nn_distance_sq = uves_min_double(
925 (lambda_cat_next - lambda_cat)*
926 (lambda_cat_next - lambda_cat)
932 if (nn_distance_sq < DBL_MAX)
934 nn_distance_sq *= ALPHA*ALPHA;
940 cpl_table_set_double(linetable,
"Lambda_candidate", row, lambda_cat);
941 cpl_table_set_double(linetable,
"dLambda_candidate",row, lambda_cat_sigma);
942 cpl_table_set_double(linetable,
"dLambda_cat_sq", row, distance_cat_sq);
943 cpl_table_set_double(linetable,
"dLambda_nn_sq", row, nn_distance_sq);
948 int ilow = uves_round_double((0.5*log(distance_cat_sq/(line_fwhm*line_fwhm))
949 - minlog)/(maxlog - minlog) * nbins);
950 int ihigh = uves_round_double((0.5*log(nn_distance_sq /(line_fwhm*line_fwhm))
951 - minlog)/(maxlog - minlog) * nbins);
954 for (i = uves_max_int(ilow, 0); i < uves_min_int(ihigh, nbins); i++)
965 for (i = 0; i < nbins; i++)
968 if (histogram[i] > maxfreq)
970 maxfreq = histogram[i];
971 error = exp( i / ((
double)nbins) * (maxlog - minlog) + minlog ) ;
1010 for (row = 0; row < linetable_size; row++)
1012 double distance_cat_sq;
1013 double nn_distance_sq;
1014 double tolerance_sq;
1019 double lambda_cat_sigma;
1021 lambda_cat = cpl_table_get_double(linetable,
"Lambda_candidate", row, NULL);
1022 lambda_cat_sigma = cpl_table_get_double(linetable,
"dLambda_candidate", row, NULL);
1032 uves_max_double(1, cpl_table_get_double(linetable,
"Xwidth" , row, NULL)) *
1033 fabs(cpl_table_get_double(linetable, LINETAB_PIXELSIZE , row, NULL));
1036 line_fwhm = TWOSQRT2LN2 * line_width;
1048 dlambda_com = line_fwhm
1049 * cpl_table_get_double(linetable,
"dLambdaC" , row, NULL)
1050 / average_dlambda_com;
1052 tolerance_sq = line_fwhm*line_fwhm * error*error;
1054 distance_cat_sq = cpl_table_get_double(linetable,
"dLambda_cat_sq", row, NULL);
1055 nn_distance_sq = cpl_table_get_double(linetable,
"dLambda_nn_sq" , row, NULL);
1057 #if WANT_BIG_LOGFILE
1059 "dist_cat = %f (%f pixels) tolerance = %.3f error = %f "
1060 "nn = %f (%f pixels)",
1061 cpl_table_get_int (linetable,
"Order" , row, NULL),
1062 cpl_table_get_double(linetable,
"X" , row, NULL),
1063 cpl_table_get_double(linetable, LINETAB_LAMBDAC, row, NULL),
1066 sqrt(distance_cat_sq),
1067 sqrt(distance_cat_sq)
1068 /cpl_table_get_double(linetable, LINETAB_PIXELSIZE, row, NULL),
1071 sqrt(nn_distance_sq),
1072 sqrt(nn_distance_sq)
1073 /cpl_table_get_double(linetable, LINETAB_PIXELSIZE, row, NULL));
1077 if (distance_cat_sq < (dlambda_com)*(dlambda_com)
1078 && tolerance_sq < nn_distance_sq
1079 && distance_cat_sq < nn_distance_sq)
1081 number_identifications++;
1082 cpl_table_set_double(linetable,
"Ident", row, lambda_cat);
1083 cpl_table_set_double(linetable,
"dIdent",row, lambda_cat_sigma);
1084 #if WANT_BIG_LOGFILE
1090 if (cpl_table_is_valid(linetable,
"Ident", row)) {
1091 number_identifications++;
1093 uves_msg_debug(
"Line at (%d,%f) does not match ID criterion anymore",
1094 cpl_table_get_int (linetable,
"Order", row, NULL),
1095 cpl_table_get_double(linetable,
"X", row, NULL)
1102 cpl_free(histogram);
1103 return number_identifications;
1135 cpl_table **selected,
1136 int degree,
bool verbose,
1140 double *red_chisq,
polynomial **dispersion_variance,
1146 cpl_table *identified = NULL;
1148 cpl_table_get_nrow(linetable) -
1149 cpl_table_count_invalid(linetable,
"Ident");
1152 passure( (pixelsize == NULL) == (rms_wlu == NULL) &&
1153 (pixelsize == NULL) == (rms_pixels == NULL),
" ");
1155 assure( degree < 0 ||
1156 valid_ids >= (degree + 1)*(degree + 1), CPL_ERROR_ILLEGAL_INPUT,
1157 "There are not enough identifications to create a %d.-degree global fit. "
1158 "%d needed. %d found", degree, (degree + 1)*(degree + 1), valid_ids);
1160 identified = cpl_table_duplicate(linetable);
1167 uves_msg_debug(
"%d lines rejected %f %f", rejected, TOLERANCE, kappa);
1171 check( uves_erase_invalid_table_rows(identified,
"Ident"),
1172 "Error erasing un-identified lines");
1177 check(( cpl_table_duplicate_column(identified,
"Aux", identified,
"Ident"),
1178 cpl_table_multiply_columns(identified,
"Aux",
"Order"),
1181 cpl_table_duplicate_column(identified,
"dAux", identified,
"dIdent"),
1182 cpl_table_multiply_columns(identified,
"dAux",
"Order")),
1183 "Error setting up temporary table");
1188 check( dispersion_relation =
1190 "X",
"Order",
"Aux",
1202 dispersion_variance,
1203 reject ? kappa : -1, -1),
1204 "Error fitting polynomial. Possible cause: too few (%d) "
1205 "line identifications", valid_ids);
1209 double min_rms = -1;
1210 double min_reject = -1;
1211 check( dispersion_relation =
1213 "X",
"Order",
"Aux",
1218 dispersion_variance,
1219 reject ? kappa : -1,
1220 max_degree, max_degree,
1221 min_rms, min_reject,
1223 NULL, NULL, 0, NULL),
1224 "Error fitting polynomial. Possible cause: too few (%d) "
1225 "line identifications", valid_ids);
1228 if (pixelsize != NULL)
1234 "Error applying dispersion relation");
1236 *pixelsize = cpl_table_get_column_median(identified, LINETAB_PIXELSIZE);
1237 *rms_wlu = cpl_table_get_column_stdev (identified, LINETAB_RESIDUAL);
1238 *rms_pixels= cpl_table_get_column_stdev (identified,
"Residual_pix");
1241 if (selected != NULL) {
1242 *selected = cpl_table_duplicate(identified);
1246 uves_free_table(&identified);
1247 if (cpl_error_get_code() != CPL_ERROR_NONE)
1252 return dispersion_relation;
1270 int minorder, maxorder;
1272 cpl_table *lt_order = NULL;
1273 cpl_table *refer_order = NULL;
1274 cpl_vector *peaks = NULL;
1275 cpl_vector *lines = NULL;
1276 cpl_bivector *ids = NULL;
1278 assure( cpl_table_has_column(linetable, LINETAB_LAMBDAC), CPL_ERROR_DATA_NOT_FOUND,
1279 "Missing column %s", LINETAB_LAMBDAC);
1281 assure( cpl_table_has_column(linetable, LINETAB_PIXELSIZE), CPL_ERROR_DATA_NOT_FOUND,
1282 "Missing column %s", LINETAB_PIXELSIZE);
1284 assure( cpl_table_has_column(linetable,
"Order"), CPL_ERROR_DATA_NOT_FOUND,
1285 "Missing column %s",
"Order");
1287 minorder = uves_round_double( cpl_table_get_column_min(linetable,
"Order"));
1288 maxorder = uves_round_double( cpl_table_get_column_max(linetable,
"Order"));
1291 if (cpl_table_has_column(linetable,
"Ident_ppm"))
1293 cpl_table_erase_column(linetable,
"Ident_ppm");
1296 cpl_table_new_column(linetable,
"Ident_ppm", CPL_TYPE_DOUBLE);
1298 for (order = minorder; order <= maxorder; order++)
1300 const double tolerance = 0.05;
1301 double min_lambda, max_lambda;
1302 double min_disp, max_disp;
1306 uves_free_table(<_order);
1307 lt_order = uves_extract_table_rows(linetable,
"Order",
1308 CPL_EQUAL_TO, order);
1310 check_nomsg((min_lambda = cpl_table_get_column_min(lt_order, LINETAB_LAMBDAC),
1311 max_lambda = cpl_table_get_column_max(lt_order, LINETAB_LAMBDAC),
1312 min_disp = cpl_table_get_column_min(lt_order, LINETAB_PIXELSIZE)*0.99,
1313 max_disp = cpl_table_get_column_max(lt_order, LINETAB_PIXELSIZE)*1.01));
1315 uves_free_table(&refer_order);
1316 refer_order = uves_extract_table_rows(line_refer,
"Wave", CPL_GREATER_THAN,
1318 uves_extract_table_rows_local(refer_order,
"Wave", CPL_LESS_THAN,
1324 uves_free_vector(&peaks);
1325 peaks = cpl_vector_new(cpl_table_get_nrow(lt_order));
1326 for (i = 0; i < cpl_vector_get_size(peaks); i++)
1328 cpl_vector_set(peaks, i, cpl_table_get_double(lt_order,
"X", i, NULL));
1331 uves_free_vector(&lines);
1332 lines = cpl_vector_new(cpl_table_get_nrow(refer_order));
1333 for (i = 0; i < cpl_vector_get_size(lines); i++)
1335 cpl_vector_set(lines, i, cpl_table_get_double(refer_order,
"Wave", i, NULL));
1340 cpl_vector_sort(peaks, 1);
1341 cpl_vector_sort(lines, 1);
1343 uves_msg_debug(
"Call ppm with %" CPL_SIZE_FORMAT
" peaks, %" CPL_SIZE_FORMAT
" lines, dispersion range = %f - %f A/pixel",
1344 cpl_vector_get_size(peaks),
1345 cpl_vector_get_size(lines),
1346 min_disp, max_disp);
1348 uves_free_bivector(&ids);
1350 ids = cpl_ppm_match_positions(peaks, lines,
1359 if (cpl_error_get_code() != CPL_ERROR_NONE)
1362 cpl_error_get_where());
1370 uves_msg_debug(
"%" CPL_SIZE_FORMAT
" identifications from point pattern matching (order %d)",
1371 cpl_bivector_get_size(ids), order);
1373 result += cpl_bivector_get_size(ids);
1375 for (i = 0; i < cpl_table_get_nrow(linetable); i++) {
1377 if (cpl_table_get_int(linetable,
"Order", i, NULL) == order)
1378 for (j = 0; j < cpl_bivector_get_size(ids); j++)
1380 if (fabs(cpl_table_get_double(linetable,
"X", i, NULL) -
1381 cpl_bivector_get_x_data(ids)[j]) < 0.001)
1382 cpl_table_set_double(linetable,
"Ident_ppm", i,
1383 cpl_bivector_get_y_data(ids)[j]);
1390 uves_free_table(<_order);
1391 uves_free_table(&refer_order);
1392 uves_free_vector(&peaks);
1393 uves_free_vector(&lines);
1394 uves_free_bivector(&ids);
int uves_polynomial_get_dimension(const polynomial *p)
Get the dimension of a polynomial.
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
#define uves_msg_warning(...)
Print an warning message.
int uves_wavecal_identify_lines_ppm(cpl_table *linetable, const cpl_table *line_refer)
Identify lines using point pattern matching.
#define passure(BOOL,...)
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.
static polynomial * calibrate_global(const cpl_table *linetable, cpl_table **selected, int degree, bool verbose, bool reject, double TOLERANCE, double kappa, double *red_chisq, polynomial **dispersion_variance, double *pixelsize, double *rms_wlu, double *rms_pixels)
Create a fit of all orders.
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.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
polynomial * uves_polynomial_regression_2d(cpl_table *t, const char *X1, const char *X2, const char *Y, const char *sigmaY, int degree1, int degree2, const char *polynomial_fit, const char *residual_square, const char *variance_fit, double *mse, double *red_chisq, polynomial **variance, double kappa, double min_reject)
Fit a 2d polynomial to three table columns.
polynomial * uves_wavecal_identify(cpl_table *linetable, const cpl_table *line_refer, const polynomial *guess_dispersion, int DEGREE, double TOLERANCE, double ALPHA, double MAXERROR, double kappa, const int trace, const int window, cpl_table *qclog)
Obtain final dispersion relation.
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.
int uves_delete_bad_lines(cpl_table *table, double TOLERANCE, double kappa)
Delete bad lines from line table.
double uves_polynomial_evaluate_2d(const polynomial *p, double x1, double x2)
Evaluate a 2d polynomial.
static cpl_error_code verify_calibration(const cpl_table *selected, const cpl_table *linetable, double TOLERANCE, double red_chisq, cpl_table *qclog)
Report quality of calibration.
#define uves_error_reset()
#define uves_msg_debug(...)
Print a debug message.
static int identify_lines(cpl_table *linetable, const cpl_table *line_refer, double ALPHA)
Identify lines by comparing to catalogue wavelengths.
static cpl_error_code compute_lambda(cpl_table *linetable, const polynomial *dispersion_relation, const polynomial *dispersion_variance, bool verbose)
Apply dispersion relation to line table.
int uves_wavecal_find_nearest(const cpl_table *line_refer, double lambda, int lo, int hi)
Find best matching catalogue wavelength.