41 #include <uves_wavecal_body.h>
47 #include <uves_extract.h>
48 #include <uves_flatfield.h>
49 #include <uves_wavecal_search.h>
50 #include <uves_wavecal_firstsolution.h>
51 #include <uves_wavecal_identify.h>
52 #include <uves_rebin.h>
53 #include <uves_merge.h>
56 #include <uves_wavecal_utils.h>
57 #include <uves_utils.h>
58 #include <uves_utils_wrappers.h>
59 #include <uves_plot.h>
60 #include <uves_parameters.h>
62 #include <uves_pfits.h>
63 #include <uves_qclog.h>
64 #include <uves_recipe.h>
65 #include <uves_error.h>
66 #include <flames_reduce_vcorrel.h>
77 #define DRS_PTHRES_MAX 55000
78 #define DRS_PTHRES_MIN -20
79 #define DRS_CVEL_MIN -6.
80 #define DRS_CVEL_MAX +6.
81 #define N_FIBRES_MAX 9
85 static void uves_wavecal_qclog(
const cpl_table* table,
88 const cpl_image *arclamp,
97 static void uves_wavecal_qclog_intmon(cpl_table* table,
98 const cpl_table *line_intmon,
109 const char *
const uves_wavecal_desc_short =
"Performs the wavelength calibration";
111 const char *
const uves_wavecal_desc =
112 "The recipe performs a wavelength calibration for each extraction window.\n"
113 "Conceptually, each chip contains a number of order lines, each of which\n"
114 "contains a number of fibre traces, each of which contains a number of\n"
115 "extraction windows. For UVES data, there is only one trace per order and\n"
116 "three extraction windows (sky, object, sky). For FLAMES/UVES data there\n"
117 "are multiple traces per order but only one extraction window per trace.\n"
118 "The number of traces is defined in the order table while the geometry of\n"
119 "the extraction windows is specified by recipe parameters (see below).\n"
121 "Expected input for this recipe is an arc lamp frame, ARC_LAMP_xxx or\n"
122 "ECH_ARC_LAMP_xxx (where xxx=BLUE, RED), order table(s) for each chip,\n"
123 "ORDER_TABLE_xxxx (where xxxx=BLUE, REDL, REDU), 'guess' line table(s)\n"
124 "for each chip, LINE_TABLE_xxxx, a wavelength catalogue table, \n"
125 "LINE_REFER_TABLE, and optionally a wavelength table of bright lines,\n"
126 "LINE_INTMON_TABLE, used only for computing Quality Control parameters.\n"
128 "The output line table(s), LINE_TABLE_xxxx, contains the columns\n"
129 "X : Horizontal position (from Gaussian fit) of detected line\n"
130 "dX : Uncertainty (one sigma) of X\n"
131 "Ynew : Vertical position of detected line\n"
132 "XWidth : Width (in pixels) of detected line from Gaussian fit\n"
133 "Peak : Intensity of detected line\n"
134 "Background : Fitted background (ADU) of detected line\n"
135 "Slope : Linear background slope (ADU/pixel) of detected line\n"
136 " from Gaussian fit\n"
137 "Intensity : Intensity of detected line scaled to unit exposure\n"
138 " time. (This column only present if a LINE_INTMON_TABLE\n"
140 "Order : Absolute order number of detected line\n"
141 "Y : Relative order number of detected line\n"
142 " (it's not a very descriptive column name)\n"
143 "WaveC : Wavelength of this line (computed using the resulting\n"
144 " dispersion relation)\n"
145 "dLambdaC : Uncertainty (one sigma) of 'WaveC'.\n"
146 "Pixel : The width in w.l.u. of a pixel (computed locally).\n"
147 "Residual : Residual (in w.l.u.) of this line\n"
148 "Residual_pix : Residual (in pixels) of this line\n"
149 "Lambda_candidate : Nearest line in catalogue\n"
150 "dLambda_cat_sq : Squared distance to nearest catalogue line\n"
151 "dLambda_nn_sq : Squared distance to nearest neighbour multiplied by ALPHA\n"
152 "Ident : The wavelength associated with this emission line,\n"
153 " or invalid if this line was not identified\n"
154 "dIdent : Uncertainty of catalogue wavelength\n"
155 "Select : 1 if the line was identified, 0 otherwise\n"
156 "NLinSol : 1 if the line was identified and accepted for the\n"
157 " polynomial fit, 0 otherwise\n"
158 "Intensity : Intensity of detected line scaled to unit exposure\n"
159 " time. (This column is present only if a LINE_INTMON_TABLE\n"
162 "The 2nd table extension contains the dispersion relation (a 2d polynomial).\n"
163 "The 3rd table extension contains the map from (pixel, pixel)-space to\n"
164 " physical order numbers (used internally by the calibration recipe; \n"
165 "another 2d polynomial).\n"
167 "If there is more than one extraction window, the results of each calibration\n"
168 "is stored in subsequent table extensions of the same FITS file. For \n"
169 "example, extensions 4, 5 and 6 would contain the resulting line table \n"
170 "(and its two associated polynomials) for the second extraction window. \n"
171 "The results for the calibration of the n'th extraction window is stored \n"
172 "in extensions (3*n - 2) to 3*n.\n";
189 uves_wavecal_define_parameters_body(cpl_parameterlist *parameters,
190 const char *recipe_id,
double slit)
192 const char *subcontext;
198 if (uves_define_global_parameters(parameters) != CPL_ERROR_NONE)
210 uves_par_new_range(
"nwindows",
212 "Number of extraction windows per trace. "
213 "The windows will be aligned (i.e. no overlap "
214 "and no spacing between adjacent windows). "
215 "Unless an offset is specified, the middle "
216 "window(s) is centered on the trace",
217 strcmp(recipe_id,
"flames_cal_wavecal") == 0 ?
222 uves_par_new_range(
"length",
224 "Length (in pixels) of each extraction window. "
225 "This parameter is also equal to the seperation of "
226 "adjacent window centers, causing the extraction "
227 "windows to always be aligned. The parameter is "
228 "automatically adjusted according to the binning "
229 "of the input raw frame. If negative, the extraction "
230 "window length is determined automatically "
231 "to cover the full slit",
232 slit, -2.0, DBL_MAX);
235 uves_par_new_range(
"offset",
237 "A global offset (in pixels) of all extraction windows",
241 if (uves_propagate_parameters_step(UVES_EXTRACT_ID, parameters,
242 recipe_id, NULL) != 0)
261 const char *profile =
"constant";
264 if (uves_set_parameter_default(parameters,
265 recipe_id, UVES_EXTRACT_ID
".profile",
266 CPL_TYPE_STRING, &profile)
274 if (uves_set_parameter_default(parameters,
275 recipe_id, UVES_EXTRACT_ID
".kappa",
276 CPL_TYPE_DOUBLE, &kappa)
284 const char *method =
"average";
286 if (uves_set_parameter_default(parameters,
287 recipe_id, UVES_EXTRACT_ID
".method",
288 CPL_TYPE_STRING, &method)
301 subcontext =
"search";
304 uves_par_new_range(
"range",
306 "Width (pix) of search window is 2*range + 1. "
307 "This parameter is automatically adjusted "
308 "according to binning.",
312 uves_par_new_range(
"minlines",
314 "Minimum number of lines to detect. If zero, "
315 "the default value (1100 for BLUE/REDL chips; "
316 "1000 for REDU chip) is used.",
320 uves_par_new_range(
"maxlines",
322 "Maximum number of lines to detect. If zero, "
323 "the default value (1600 for BLUE/REDL chip; "
324 "1400 for REDU chip) is used.",
345 subcontext =
"first";
348 uves_par_new_range(
"shiftmax",
350 "The maximum shift (pix) in either direction compared to "
351 "guess solution. This parameter is automatically "
352 "corrected for binning",
356 uves_par_new_range(
"shiftstep",
358 "The step size (pix) used when searching "
359 "for the optimum shift. This parameter is "
360 "automatically corrected for binning",
364 uves_par_new_range(
"shifttoler",
366 "Tolerance (pix) when matching shifted lines. "
367 "This parameter is not adjusted according to binning",
375 subcontext =
"identify";
378 uves_par_new_range(
"alpha",
380 "The parameter that controls the distance to the "
381 "nearest neighbours",
385 uves_par_new_range(
"maxerror",
387 "This parameter controls the graceful exit of "
388 "the identification loop. If the RMS of the "
389 "global fit exceeds this value (pix) the "
394 uves_par_new_range(
"degree",
396 "Degrees of the global 2d dispersion polynomial. If "
397 "a negative number is specified, the polynomial "
398 "degrees are automatically selected by starting from "
399 "(1, 1) and inreasing the degrees as long as the RMS "
400 "residual decreases significantly",
408 subcontext =
"calibrate";
411 uves_par_new_value(
"tolerance",
413 "Tolerance of fit. If positive, the tolerance "
414 "is in pixel units. If negative, abs(tolerance) "
415 "is in wavelength units. Lines with residuals "
416 "worse than the tolerance are excluded from the "
417 "final fit. Unlike in previous versions, this "
418 "parameter is not corrected for CCD binning. "
419 "This rejection based on the absolute residual in "
420 "pixel can be effectively disabled by setting the "
421 "tolerance to a very large number (e.g. 9999). In "
422 "that case outliers will be rejected using only "
423 "kappa sigma clipping.",
430 uves_par_new_range(
"kappa",
432 "Lines with residuals more then kappa stdev "
433 "are rejected from the final fit",
439 if (uves_propagate_parameters_step(UVES_REBIN_ID, parameters,
440 recipe_id, NULL) != 0)
445 return (cpl_error_get_code() != CPL_ERROR_NONE);
521 uves_wavecal_process_window(
const cpl_image *arclamp,
522 const cpl_image *arclamp_noise,
524 const cpl_table *ordertable,
529 const cpl_table *guess,
530 const cpl_table *line_refer,
532 int tab_in_out_oshift,
533 double tab_in_out_yshift,
534 enum uves_chip chip,
int bin_disp,
535 int trace,
int window,
int NWINDOWS,
541 const cpl_parameterlist *parameters,
542 const char *recipe_id,
547 centering_method CENTERING_METHOD,
551 double SHIFT_TOLERANCE,
559 cpl_frame* corvel_frm,
560 cpl_table** flames_qclog,
564 int *first_absolute_order,
565 int *last_absolute_order)
567 cpl_table *linetable = NULL;
568 cpl_table *temp = NULL;
569 cpl_image *spectrum = NULL;
570 cpl_image *spectrum_noise = NULL;
571 cpl_image *debug_image = NULL;
573 int *relative_order = NULL;
577 cpl_image *rebinned = NULL;
579 cpl_image *rebinned_noise = NULL;
582 cpl_image *merged = NULL;
583 cpl_image *merged_noise = NULL;
585 cpl_table *info_tbl = NULL;
588 cpl_image *weights_opt = NULL;
589 cpl_table *cr_table = NULL;
590 cpl_image *cr_image = NULL;
591 cpl_table *order_trace = NULL;
593 merge_method m_method = flat_fielded ? MERGE_OPTIMAL : MERGE_SUM;
596 uves_free_table(&info_tbl);
603 (cpl_image *)arclamp_noise,
622 (weights != NULL) ? &weights : &weights_opt,
625 "Error extracting spectrum");
626 uves_free_table(&info_tbl);
631 "^ESO ", 0),
"error copying hierarch keys");
636 cpl_image_fill_rejected(spectrum, 0);
637 cpl_image_accept_all(spectrum);
638 cpl_image_fill_rejected(spectrum_noise, 1);
639 cpl_image_accept_all(spectrum_noise);
648 "Error copying hieararch keys");
650 check( uves_save_image_local(
"Extracted spectrum",
"spectrum",
651 spectrum, chip, trace, window, spectrum_header,
true),
652 "Error saving spectrum");
654 check( uves_save_image_local(
"Extracted spectrum noise",
"spectrum_noise",
655 spectrum_noise, chip, trace, window, spectrum_header,
true),
656 "Error saving spectrum");
660 debug_image = cpl_image_duplicate(arclamp);
671 bin_disp,trace,window,
673 "Line search failed");
681 cpl_free(relative_order);
682 check( initial_dispersion = uves_wavecal_firstsolution(linetable,
695 first_absolute_order,
696 last_absolute_order),
697 "Could not get first solution");
710 cpl_table_add_scalar(linetable,
"Y", tab_in_out_oshift);
711 cpl_table_add_scalar(linetable,
"Ynew", - tab_in_out_yshift - offset);
721 kappa,trace,window,flames_qclog[0]),
722 "Could not calibrate orders");
731 cpl_table_add_scalar(linetable,
"Ynew", + tab_in_out_yshift + offset);
737 if (flames || (trace == 0 && window == 2)|| (window == 1 && NWINDOWS == 1))
740 check(( cpl_table_duplicate_column(linetable,
"deltaX", linetable,
"Xwidth"),
741 cpl_table_multiply_scalar (linetable,
"deltaX", TWOSQRT2LN2)),
742 "Error creating FWHM column");
746 linetable,
"NLinSol", CPL_NOT_EQUAL_TO, 0) );
748 check( uves_plot_table(temp,
"Order", LINETAB_RESIDUAL,
"Residual of fit"),
751 check( uves_plot_table(temp,
"X",
"deltaX",
"line FWHM (mean = %.2f pixels)",
752 cpl_table_get_column_mean(linetable,
"deltaX")),
769 double lambda_start = 0;
774 bool threshold_to_positive =
true;
776 cpl_table_new_column(linetable,
"deltaLambda", CPL_TYPE_DOUBLE);
782 *dispersion_relation,
783 *first_absolute_order,
784 *last_absolute_order,
786 threshold_to_positive,
789 "Could not rebin noise of arc lamp spectrum");
791 threshold_to_positive =
false;
792 uves_free_propertylist(&rebinned_header);
797 *dispersion_relation,
798 *first_absolute_order,
799 *last_absolute_order,
801 threshold_to_positive,
804 "Could not rebin arc lamp spectrum");
809 check( uves_save_image_local(
"Rebinned spectrum",
810 "wxb", rebinned, chip,
811 trace, window, rebinned_header,
true),
812 "Error saving rebinned spectrum");
814 check( uves_save_image_local(
"Noise of rebinned spectrum",
815 "errwxb", rebinned_noise, chip,
816 trace, window, rebinned_header,
true),
817 "Error saving noise of rebinned spectrum");
828 "Could not merge arc lamp spectrum");
830 check( uves_plot_image_rows(merged, 1, 1, 1,
831 "Wavelength (arbitrary units)",
832 "Flux",
"Resampled arc lamp spectrum"),
838 check( uves_save_image_local(
"Rebinned, merged spectrum",
839 "merged", merged, chip,
840 trace, window, merged_header,
true),
841 "Error saving merged spectrum");
844 nbins = cpl_image_get_size_x(merged);
847 "Error reading resampling step size");
850 "Could not read start wavelength of merged spectrum");
855 if (flames && trace == 0 && corvel_frm != NULL)
897 const char* drs_base_name=NULL;
898 const char* prefid=NULL;
899 double ccf_posmax_zero_point=0;
900 double ccf_posmax_zero_point_iter0=0;
903 if(chip == UVES_CHIP_REDL) {
908 const char* name=NULL;
909 const char* file=NULL;
910 cpl_propertylist* plist=NULL;
911 double drs_cvel_min=0;
912 double drs_cvel_max=0;
915 check( uves_save_image_local(
"Rebinned spectrum",
916 "wxb", rebinned, chip,
917 trace, window, rebinned_header,
true),
918 "Error saving rebinned spectrum");
920 check( uves_save_image_local(
"Rebinned, merged spectrum",
921 "mwxb", merged, chip,
922 trace, window, merged_header,
true),
923 "Error saving merged spectrum");
926 check( file = uves_local_filename(
"wxb", chip, trace, window),
927 "Error getting filename");
930 name=uves_sprintf(
"wfxb_%s%s%4.4d%s",prefid,
"_raw",1,
".fits");
931 drs_base_name=uves_sprintf(
"fxb_%s",prefid);
933 cpl_image_save(rebinned,name, CPL_BPP_IEEE_FLOAT,plist,
937 name=uves_sprintf(
"mwfxb_%s%s%4.4d%s",prefid,
"_raw",1,
".fits");
938 cpl_image_save(merged,name, CPL_BPP_IEEE_FLOAT,plist,
941 cpl_propertylist_delete(plist);
944 int ord_max=(*first_absolute_order-*last_absolute_order)+1;
946 uves_msg(
"cvel max:%g %g",DRS_CVEL_MAX,DRS_CVEL_MIN);
947 drs_cvel_max =DRS_CVEL_MAX;
948 drs_cvel_min =DRS_CVEL_MIN;
959 &ccf_posmax_zero_point,
964 drs_cvel_max +=cvel_max;
965 drs_cvel_min +=cvel_max;
966 ccf_posmax_zero_point_iter0 =cvel_max;
967 uves_msg(
"cvel max:%g %g",drs_cvel_max,drs_cvel_min);
978 &ccf_posmax_zero_point,
983 drs_cvel_max +=cvel_max;
984 drs_cvel_min +=cvel_max;
985 ccf_posmax_zero_point =ccf_posmax_zero_point_iter0;
988 ccf_posmax_zero_point,
989 "CCF pos avg from ThAr calibration",
993 uves_msg(
"cvel max:%g min: %g zp: %g",
994 drs_cvel_max,drs_cvel_min,ccf_posmax_zero_point);
1003 for (i = 0; i < cpl_table_get_nrow(linetable); i++)
1005 double lambda = cpl_table_get_double(
1006 linetable, LINETAB_LAMBDAC, i, NULL);
1008 cpl_table_get_double(linetable,
"Xwidth" , i, NULL) *
1009 fabs(cpl_table_get_double(linetable, LINETAB_PIXELSIZE, i, NULL));
1014 uves_round_double((lambda - lambda_start) / wavestep);
1015 double width_bin = width / wavestep;
1018 int first_bin = uves_max_int( 1, uves_round_double(bin - 5*width_bin));
1019 int last_bin = uves_min_int(nbins, uves_round_double(bin + 5*width_bin));
1021 double my, sigma, norm, background;
1024 if (cpl_table_is_valid(linetable,
"Ident", i) && first_bin < last_bin)
1027 uves_fit_1d_image(merged,
1052 if (cpl_error_get_code() == CPL_ERROR_CONTINUE)
1056 "at lambda = %f wlu, bins = "
1057 "%d - %d, ignoring line",
1058 lambda, first_bin, last_bin);
1060 cpl_table_set_invalid(linetable,
"deltaLambda", i);
1065 assure(cpl_error_get_code() == CPL_ERROR_NONE,
1066 cpl_error_get_code(),
"Gaussian fitting failed");
1069 lambda_fwhm = TWOSQRT2LN2 * sigma * wavestep;
1071 cpl_table_set_double(linetable,
"deltaLambda",
1078 cpl_table_set_invalid(linetable,
"deltaLambda", i);
1084 check(( cpl_table_duplicate_column(linetable,
"Resol",
1085 linetable, LINETAB_LAMBDAC),
1086 cpl_table_divide_columns (linetable,
"Resol",
1088 "Error creating 'Resol' column");
1095 double resol_avg = 0;
1096 double resol_stdev = 0;
1097 double kappar = 10.0;
1098 nrows=cpl_table_get_nrow(linetable);
1099 ninvalid=cpl_table_count_invalid(linetable,
"Resol");
1100 assure(ninvalid < nrows,CPL_ERROR_ILLEGAL_INPUT,
1101 "No valid elements in Resol column. "
1102 "You must decrease parameter rebin.wavestep");
1103 check_nomsg(resol_avg=cpl_table_get_column_median(linetable,
"Resol"));
1104 check_nomsg(resol_stdev=cpl_table_get_column_stdev (linetable,
"Resol"));
1106 for (i = 0; i < cpl_table_get_nrow(linetable); i++)
1108 double r = cpl_table_get_double(linetable,
"Resol", i, NULL);
1109 if (r < resol_avg - kappar*resol_stdev ||
1110 r > resol_avg + kappar*resol_stdev)
1112 cpl_table_set_invalid(linetable,
"Resol", i);
1113 cpl_table_set_invalid(linetable,
"deltaLambda", i);
1123 check( uves_plot_table(linetable, LINETAB_LAMBDAC,
"Resol",
1124 "(l, l / dl)"),
"Plotting failed");
1128 uves_free_table(&temp);
1129 check( temp = cpl_table_duplicate(linetable),
1130 "Error copying line table");
1131 check( uves_erase_invalid_table_rows(temp,
"Ident"),
1132 "Error removing un-identified lines");
1133 check( uves_plot_table(temp,
"X",
"Ynew",
1134 "Line identifications"),
1136 uves_free_table(&temp);
1147 order_locations, guess,
1148 "Ident",
"Order", relative_order,
1151 12),
"Error drawing guess solution");
1155 line_refer,
"Wave", NULL, relative_order,
1156 uves_min_int(*first_absolute_order, *last_absolute_order),
1157 uves_max_int(*first_absolute_order, *last_absolute_order),
1159 8),
"Error drawing catalogue lines");
1163 line_refer,
"Wave", NULL, relative_order,
1164 uves_min_int(*first_absolute_order, *last_absolute_order),
1165 uves_max_int(*first_absolute_order, *last_absolute_order),
1167 16),
"Error drawing catalogue lines");
1171 order_locations, linetable,
1172 LINETAB_LAMBDAC,
"Order", relative_order,
1175 -16),
"Error drawing detected lines");
1178 uves_free_table(&temp);
1179 check(( temp = cpl_table_duplicate(linetable),
1181 uves_erase_invalid_table_rows(temp,
"Ident")),
1182 "Error duplicating table");
1185 temp, LINETAB_LAMBDAC,
"Order", relative_order,
1188 0),
"Error drawing detected lines");
1217 check( uves_save_image_local(
"Debug image",
"rawdebug",
1218 debug_image, chip, trace, window,
1219 rotated_header,
true),
1220 "Error saving spectrum");
1226 int count = cpl_table_get_nrow(linetable);
1228 check_nomsg( cpl_table_new_column(linetable,
"Fibre", CPL_TYPE_INT) );
1230 cpl_table_fill_column_window(linetable,
"Fibre",
1237 uves_free_table(&info_tbl);
1238 uves_free_table(&temp);
1239 uves_free_image(&weights_opt);
1240 uves_free_table(&cr_table);
1241 uves_free_image(&cr_image);
1242 uves_free_image(&spectrum);
1243 uves_free_image(&spectrum_noise);
1244 uves_free_image(&debug_image);
1245 uves_free_image(&rebinned);
1246 uves_free_image(&rebinned_noise);
1247 uves_free_image(&merged);
1248 uves_free_image(&merged_noise);
1249 uves_free_propertylist(&spectrum_header);
1250 uves_free_propertylist(&rebinned_header);
1251 uves_free_propertylist(&merged_header);
1252 cpl_free(relative_order);
1254 uves_free_table(&order_trace);
1288 uves_wavecal_exe_body(cpl_frameset *frames,
1290 const char *recipe_id,
1291 const cpl_parameterlist *parameters,
1292 const char *starttime)
1304 double SLITLENGTH_par;
1310 centering_method CENTERING_METHOD;
1315 double SHIFT_TOLERANCE;
1326 cpl_image *arclamp[2] = {NULL, NULL};
1327 cpl_image *arclamp_noise = NULL;
1332 cpl_table *ordertable = NULL;
1335 cpl_table *traces = NULL;
1338 cpl_image *master_bias = NULL;
1342 cpl_image *master_flat = NULL;
1343 cpl_image *mflat_noise = NULL;
1347 cpl_image *weights = NULL;
1356 int* fibres_mask=NULL;
1357 double* fibres_pos=NULL;
1360 cpl_table *guess = NULL;
1364 cpl_table *corvel = NULL;
1365 cpl_frame *corvel_frm = NULL;
1369 cpl_table *line_refer = NULL;
1370 cpl_table *line_intmon = NULL;
1378 cpl_table *qclog[3] = {NULL, NULL, NULL};
1381 cpl_image *absorder_image = NULL;
1382 const char *arclamp_filename =
"";
1383 const char *line_refer_filename =
"";
1384 const char *line_intmon_filename =
"";
1385 char *product_filename = NULL;
1388 bool sim_cal =
false;
1389 enum uves_chip chip;
1392 bool drs_cvel_sw=
false;
1393 const char* PROCESS_CHIP=NULL;
1398 const char *centering_m =
"gaussian";
1399 const char *profile =
"";
1404 check( uves_get_parameter(parameters, NULL,
"uves",
"debug",
1405 CPL_TYPE_BOOL, &debug_mode),
"Could not read parameter");
1407 check( uves_get_parameter(parameters, NULL,
"uves",
"process_chip", CPL_TYPE_STRING, &PROCESS_CHIP),
1408 "Could not read parameter");
1412 check( uves_get_parameter(parameters, NULL, recipe_id,
"nwindows",
1413 CPL_TYPE_INT , &NWINDOWS ),
"Could not read parameter");
1414 check( uves_get_parameter(parameters, NULL, recipe_id,
"length",
1415 CPL_TYPE_DOUBLE, &SLITLENGTH_par),
"Could not read parameter");
1416 check( uves_get_parameter(parameters, NULL, recipe_id,
"offset",
1417 CPL_TYPE_DOUBLE, &OFFSET ),
"Could not read parameter");
1421 temp = uves_sprintf(
"%s.%s", recipe_id, UVES_EXTRACT_ID);
1423 "Could not read extraction method");
1425 check( uves_get_parameter(parameters, NULL, recipe_id, UVES_EXTRACT_ID
".profile",
1426 CPL_TYPE_STRING, &profile),
"Could not read parameter");
1428 assure( em == EXTRACT_LINEAR || em == EXTRACT_AVERAGE || em == EXTRACT_WEIGHTED ||
1429 (em == EXTRACT_OPTIMAL && strcmp(profile,
"constant") == 0),
1430 CPL_ERROR_UNSUPPORTED_MODE,
1431 "Only linear/average/weighted/optimal(constant profile) extraction "
1432 "methods are supported by this recipe");
1435 check( uves_get_parameter(parameters, NULL, recipe_id,
"search.range",
1436 CPL_TYPE_INT , &RANGE ),
"Could not read parameter");
1437 check( uves_get_parameter(parameters, NULL, recipe_id,
"search.minlines",
1438 CPL_TYPE_INT , &MINLINES ),
"Could not read parameter");
1439 check( uves_get_parameter(parameters, NULL, recipe_id,
"search.maxlines",
1440 CPL_TYPE_INT , &MAXLINES ),
"Could not read parameter");
1445 if (strcmp(centering_m,
"gravity" ) == 0) CENTERING_METHOD = CENTERING_GRAVITY;
1446 else if (strcmp(centering_m,
"gaussian") == 0) CENTERING_METHOD = CENTERING_GAUSSIAN;
1449 assure(
false, CPL_ERROR_ILLEGAL_INPUT,
1450 "Unrecognized parameter value '%s'", centering_m);
1454 check( uves_get_parameter(parameters, NULL, recipe_id,
"first.shiftmax",
1455 CPL_TYPE_DOUBLE , &SHIFT_MAX ),
1456 "Could not read parameter");
1457 check( uves_get_parameter(parameters, NULL, recipe_id,
"first.shiftstep",
1458 CPL_TYPE_DOUBLE , &SHIFT_STEP ),
1459 "Could not read parameter");
1460 check( uves_get_parameter(parameters, NULL, recipe_id,
"first.shifttoler",
1461 CPL_TYPE_DOUBLE , &SHIFT_TOLERANCE),
1462 "Could not read parameter");
1465 check( uves_get_parameter(parameters, NULL, recipe_id,
"identify.alpha",
1466 CPL_TYPE_DOUBLE , &ALPHA ),
"Could not read parameter");
1467 check( uves_get_parameter(parameters, NULL, recipe_id,
"identify.maxerror",
1468 CPL_TYPE_DOUBLE , &MAXERROR ),
"Could not read parameter");
1469 check( uves_get_parameter(parameters, NULL, recipe_id,
"identify.degree",
1470 CPL_TYPE_INT , &DEGREE ),
"Could not read parameter");
1473 check( uves_get_parameter(parameters, NULL, recipe_id,
"calibrate.tolerance",
1474 CPL_TYPE_DOUBLE, &TOLERANCE ),
"Could not read parameter");
1475 check( uves_get_parameter(parameters, NULL, recipe_id,
"calibrate.kappa",
1476 CPL_TYPE_DOUBLE, &KAPPA ),
"Could not read parameter");
1479 if (CENTERING_METHOD == CENTERING_GRAVITY)
1482 "results. Recommended is 'gaussian'");
1487 check( uves_load_arclamp(frames, flames, &arclamp_filename, arclamp, arclamp_header,
1488 rotated_header, &blue, &sim_cal),
"Error loading raw frame");
1491 check( uves_load_linerefertable(frames, &line_refer_filename, &line_refer, NULL),
1492 "Could not load line reference table");
1493 uves_msg(
"Using line reference table '%s'", line_refer_filename);
1496 if (cpl_frameset_find(frames, UVES_LINE_INTMON_TABLE) != NULL)
1498 uves_free_table(&line_intmon);
1499 check( uves_load_lineintmon(frames, &line_intmon_filename,
1501 "Error loading line reference table");
1503 uves_msg(
"Using bright line table '%s'", line_intmon_filename);
1510 "Could not read x binning factor from input header");
1512 "Could not read y binning factor from input header");
1513 SLITLENGTH_par /= (1.0*binx);
1514 RANGE /= (1.0*biny);
1515 SHIFT_MAX /= (1.0*binx);
1516 SHIFT_STEP /= (1.0*binx);
1528 chip != UVES_CHIP_INVALID;
1532 if(strcmp(PROCESS_CHIP,
"REDU") == 0) {
1536 const char *ordertable_filename =
"";
1537 const char *corvel_filename =
"";
1538 const char *master_flat_filename =
"";
1539 const char *master_bias_filename =
"";
1540 const char *weights_filename =
"";
1542 const char *guess_filename =
"";
1543 const char *chip_name =
"";
1547 int current_linetable_extension;
1548 int tab_in_out_oshift = -1;
1549 double tab_in_out_yshift = -1;
1552 uves_msg(
"Processing %s chip in '%s'",
1562 uves_free_table (&ordertable);
1563 uves_free_propertylist(&ordertable_header);
1565 uves_free_table (&traces);
1568 check( uves_load_ordertable(frames,
1571 &ordertable_filename,
1577 (flames) ? &tab_in_out_oshift : NULL,
1578 (flames) ? &tab_in_out_yshift : NULL,
1583 "Could not load order table");
1584 uves_msg(
"Using order table in '%s'", ordertable_filename);
1585 ntraces = cpl_table_get_nrow(traces);
1586 uves_free_double(&fibres_pos);
1587 uves_free_int(&fibres_mask);
1590 uves_free_image(&master_bias);
1591 uves_free_propertylist(&master_bias_header);
1592 if (cpl_frameset_find(frames, UVES_MASTER_BIAS(chip)) != NULL)
1594 check( uves_load_mbias(frames, chip_name, &master_bias_filename, &master_bias,
1595 &master_bias_header, chip),
1596 "Error loading master bias");
1598 uves_msg_low(
"Using master bias in '%s'", master_bias_filename);
1607 uves_free_image(&master_flat);
1608 uves_free_propertylist(&master_flat_header);
1609 if ((cpl_frameset_find(frames, UVES_MASTER_FLAT(chip)) != NULL ||
1610 cpl_frameset_find(frames, UVES_MASTER_DFLAT(chip)) != NULL ||
1611 cpl_frameset_find(frames, UVES_MASTER_IFLAT(chip)) != NULL ||
1612 cpl_frameset_find(frames, UVES_MASTER_TFLAT(chip)) != NULL))
1614 check( uves_load_mflat(frames, chip_name, &master_flat_filename, &master_flat,
1615 &master_flat_header, chip, NULL),
1616 "Error loading master flat");
1618 uves_msg_low(
"Using master flat in '%s'", master_flat_filename);
1626 if (em == EXTRACT_WEIGHTED) {
1627 uves_free_image(&weights);
1628 check( weights = uves_load_weights(frames, &weights_filename, chip),
1629 "Error loading weight map");
1637 if ((corvel_frm=cpl_frameset_find(frames, FLAMES_CORVEL_MASK)))
1639 check( uves_load_corvel(frames,
1640 &corvel, &corvel_header,
1642 "Could not load velocity correction table");
1644 uves_msg(
"Using velocity correction table %s", corvel_filename);
1651 uves_msg(
"No corvel table found. Switch off corvel");
1666 if (debug_mode)
check( uves_save_image_local(
"Arc lamp frame",
"raw",
1668 chip, -1, -1, rotated_header[raw_index],
true),
1669 "Error saving arc lamp frame");
1671 if (master_bias != NULL)
1673 uves_msg(
"Subtracting master bias");
1676 "Error during bias subtraction");
1692 uves_free_image(&arclamp_noise);
1694 arclamp_header[raw_index], 1, chip),
1695 "Could not set arc lamp noise");
1697 if (master_flat != NULL)
1699 uves_msg(
"Dividing by master flat");
1701 uves_free_image(&mflat_noise);
1702 check( mflat_noise =
1706 "Could not set master flat error bars");
1709 master_flat, mflat_noise),
1710 "Error while dividing by flat field");
1713 if (debug_mode)
check( uves_save_image_local(
"Pre-processed arc lamp frame",
1715 arclamp[raw_index], chip, -1, -1,
1716 rotated_header[raw_index],
true),
1717 "Error saving arc lamp frame");
1720 if (SLITLENGTH_par < 0) {
1722 double header_full_slit;
1724 check( header_full_slit =
1726 "Could not read slit length");
1731 slitlength = uves_max_double(1.0, (header_full_slit - 2)/NWINDOWS);
1733 uves_msg(
"Full slit = %.2f pixels", header_full_slit);
1736 slitlength = SLITLENGTH_par;
1741 for(tracerow = 0; tracerow < ntraces; tracerow++) {
1742 double trace_offset;
1746 trace_offset = cpl_table_get_double(traces,
"Offset" , tracerow, NULL);
1747 trace_number = cpl_table_get_int (traces,
"TraceID" , tracerow, NULL);
1748 trace_enabled = cpl_table_get_int (traces,
"Tracemask", tracerow, NULL);
1751 uves_msg(
"Processing trace %d", trace_number);
1754 if (flames && sim_cal)
1757 trace_enabled = (trace_number == 1) ? 1 : 0;
1760 uves_msg_low(
"Trace offset = %.2f pixels ; enabled = %d",
1761 trace_offset, trace_enabled);
1763 assure( flames || trace_number == 0, CPL_ERROR_ILLEGAL_INPUT,
1764 "%s: UVES trace number must be 0, it is %d",
1765 ordertable_filename, trace_number );
1768 if (trace_enabled != 0) {
1772 uves_free_table (&guess);
1775 check( uves_load_linetable(
1776 frames, flames, chip_name, order_locations,
1777 cpl_table_get_column_min(ordertable,
"Order"),
1778 cpl_table_get_column_max(ordertable,
"Order"),
1779 &guess_filename, &guess,
1781 &absolute_order, chip, trace_number, -1),
1782 "Could not load guess line table for trace number %d",
1784 uves_msg(
"Using guess line table '%s'", guess_filename);
1793 absorder_image = cpl_image_new(cpl_image_get_size_x(arclamp[raw_index]),
1794 cpl_image_get_size_y(arclamp[raw_index]),
1798 for (y = 1; y <= cpl_image_get_size_y(arclamp[raw_index]); y++)
1800 for (x = 1; x <= cpl_image_get_size_x(arclamp[raw_index]); x++)
1805 cpl_image_set(absorder_image, x, y, absorder);
1809 check( uves_save_image_local(
"Absolute order image",
"absord",
1810 absorder_image, chip, trace_number,
1811 1, rotated_header[raw_index],
true),
1812 "Error saving absolute order image");
1814 uves_free_image(&absorder_image);
1818 for (window = 1; window <= NWINDOWS; window ++) {
1832 double window_offset =
1833 slitlength * (window - (NWINDOWS+1) / 2.0);
1836 double offset = trace_offset + window_offset + OFFSET;
1841 int lines_min = (MINLINES >= 1) ? MINLINES :
1842 (chip == UVES_CHIP_REDU) ? 1000 : 2000;
1843 int lines_max = (MAXLINES >= 1) ? MAXLINES :
1844 (chip == UVES_CHIP_REDU) ? 1400 : 2400;
1847 int lines_min = (MINLINES >= 1) ? MINLINES :
1848 (chip == UVES_CHIP_REDU) ? 1000 : 1100;
1849 int lines_max = (MAXLINES >= 1) ? MAXLINES :
1850 (chip == UVES_CHIP_REDU) ? 1400 : 1600;
1853 assure( lines_min <= lines_max , CPL_ERROR_ILLEGAL_INPUT,
1854 "Minimum and maximum number of requested line "
1855 "detections don't make sense (min = %d; max = %d)",
1856 lines_min, lines_max);
1859 uves_msg(
"Processing window %d of %d", window, NWINDOWS);
1863 == NULL,
"%d %d", window, trace_number);
1865 == NULL,
"%d %d", window, trace_number);
1868 if (weights != NULL) {
1879 uves_wavecal_process_window(
1883 rotated_header[raw_index],
1885 ordertable, order_locations,
1886 master_flat != NULL,
1895 chip, biny, trace_number, window,NWINDOWS,
1899 offset, slitlength, parameters, recipe_id,
1901 RANGE, lines_min, lines_max, CENTERING_METHOD,
1903 SHIFT_MAX, SHIFT_STEP, SHIFT_TOLERANCE,
1905 ALPHA, MAXERROR, DEGREE,
1914 "Wavelength calibration failed");
1950 (window == 2 && trace_number == 0)||
1951 (window == 1 && NWINDOWS == 1)) {
1953 check( uves_wavecal_qclog(
1961 arclamp_header[raw_index],
1963 trace_number, trace_enabled, trace_offset,
1966 "Could not calculate resolution QC parameters");
1968 if (line_intmon != NULL) {
1969 check( uves_wavecal_qclog_intmon(
1975 arclamp_header[raw_index],
1976 flames, trace_number,
1979 "Could not calculate int.mon. QC parameters");
1997 uves_msg(
"Skipping trace number %d", trace_number);
2005 cpl_free(product_filename);
2006 check( product_filename = uves_line_table_filename(chip),
"Error getting filename");
2007 current_linetable_extension = 1;
2010 for(tracerow = 0; tracerow < cpl_table_get_nrow(traces); tracerow++)
2013 double trace_offset;
2016 trace_offset = cpl_table_get_double(traces,
"Offset" , tracerow, NULL);
2017 trace_number = cpl_table_get_int (traces,
"TraceID" , tracerow, NULL);
2018 trace_enabled = cpl_table_get_int (traces,
"Tracemask" , tracerow, NULL);
2020 if (trace_enabled != 0)
2025 for (window = 1; window <= NWINDOWS; window ++)
2027 double window_offset =
2028 slitlength * (window - (NWINDOWS+1) / 2.0);
2030 double offset = trace_offset + window_offset + OFFSET;
2033 uves_free_propertylist(&table_header);
2036 "Error writing trace ID to product header");
2038 "Error writing trace offset to product header");
2040 "Error writing window number to product header");
2046 "Error writing order number to product header");
2052 "Error writing order number to product header");
2056 if (current_linetable_extension == 1) {
2057 uves_free_propertylist(&primary_header);
2067 primary_header, 0.0) );
2071 uves_propertylist_append_string(primary_header,
2073 "'FIBREMASK','I*4'");
2077 for (i = 0; i < N_FIBRES_MAX; i++) {
2078 snprintf(values, 80,
"%1.1d ",
2079 cpl_table_get_int(traces,
"Tracemask",
2081 uves_propertylist_append_string(primary_header,
2084 cpl_table_get_int(traces,
2089 uves_propertylist_append_string(primary_header,
2098 cpl_table_get_column_mean(
2104 "Error reading mean pixelsize");
2108 wavestep = pixelsize*2.0/3;
2110 uves_propertylist_append_string(primary_header,
2113 snprintf(values,80,
"%14.7g %14.7g",pixelsize,pixelsize);
2114 uves_propertylist_append_string(primary_header,
2116 uves_propertylist_append_string(primary_header,
2123 uves_msg(
"Creating line table '%s'", product_filename);
2124 check( uves_frameset_insert(
2130 CPL_FRAME_GROUP_PRODUCT,
2131 CPL_FRAME_TYPE_TABLE,
2132 CPL_FRAME_LEVEL_INTERMEDIATE,
2134 UVES_LINE_TABLE(flames, chip),
2135 arclamp_header[raw_index],
2140 PACKAGE
"/" PACKAGE_VERSION,
2141 qclog, starttime,
true, 0),
2142 "Could not add line table '%s' (%s) to frameset",
2143 product_filename, UVES_LINE_TABLE(flames, chip));
2145 uves_msg(
"Line table '%s' (%s) added to frameset",
2146 product_filename, UVES_LINE_TABLE(flames, chip));
2151 check( uves_table_save(
2163 "Error appending table to file '%s'",
2166 current_linetable_extension += 1;
2175 "Could not write polynomial to file '%s'",
2177 current_linetable_extension += 1;
2186 "Could not write polynomial to file '%s'",
2188 current_linetable_extension += 1;
2190 uves_msg(
"Line table for trace %d, window #%d "
2191 "saved to extensions %d-%d of '%s'",
2192 trace_number, window,
2193 current_linetable_extension - 3,
2194 current_linetable_extension - 1,
2201 if(strcmp(PROCESS_CHIP,
"REDL") == 0) {
2211 uves_free_image(&arclamp[0]);
2212 uves_free_image(&arclamp[1]);
2213 uves_free_image(&arclamp_noise);
2214 uves_free_image(&absorder_image);
2215 uves_free_propertylist(&arclamp_header[0]);
2216 uves_free_propertylist(&arclamp_header[1]);
2217 uves_free_propertylist(&rotated_header[0]);
2218 uves_free_propertylist(&rotated_header[1]);
2221 uves_free_table(&ordertable);
2222 uves_free_propertylist(&ordertable_header);
2223 uves_free_table(&corvel);
2224 uves_free_propertylist(&corvel_header);
2227 uves_free_table(&traces);
2230 uves_free_image(&master_bias);
2231 uves_free_propertylist(&master_bias_header);
2232 uves_free_image(&master_flat);
2233 uves_free_image(&mflat_noise);
2234 uves_free_propertylist(&master_flat_header);
2235 uves_free_image(&weights);
2243 uves_free_table(&guess);
2245 uves_free_table(&line_refer);
2246 uves_free_table(&line_intmon);
2251 uves_free_propertylist(&primary_header);
2252 uves_free_propertylist(&table_header);
2256 cpl_free(product_filename);
2275 static void uves_wavecal_qclog(
const cpl_table* linetable,
2278 const cpl_image *arclamp,
2284 enum uves_chip chip,
2310 const char *qc_lineresidavg_name =
2312 const char *qc_lineresidrms_name =
2315 cpl_table *selected = NULL;
2322 sprintf(test_id,
"%sResolution-Test-Results",flames ?
"Fibre-" :
"");
2338 "DRS det. fibre seq. pos.",
2345 "det. fibre seq. no.",
2351 "det. fibre seq. rel. pos.",
2357 "DRS det. fibre mask value",
2365 "Error reading exposure time");
2369 cpl_image_get_flux(arclamp) / exptime,
2370 "abs. trans. countrate",
2378 for (y = 1; y <= cpl_image_get_size_y(arclamp); y++)
2379 for (x = 1; x <= cpl_image_get_size_x(arclamp); x++)
2382 int value = cpl_image_get(arclamp, x, y, &pis_rejected);
2384 if (!pis_rejected &&
2385 (value < DRS_PTHRES_MIN || value > DRS_PTHRES_MAX))
2394 "no. of hot pixels",
2402 "Error reading plate ID");
2413 selected = uves_extract_table_rows(linetable,
"NLinSol", CPL_NOT_EQUAL_TO, 0);
2415 sprintf(comment,
"average FWHM in X of sel lines on TRACE%d WIN2 [pix]",trace_number);
2418 cpl_table_get_column_mean(selected,
"Xwidth")*TWOSQRT2LN2,
2422 sprintf(comment,
"stdev FWHM in X of sel lines on TRACE%d WIN2 [pix]",trace_number);
2425 cpl_table_get_column_stdev(selected,
"Xwidth")*TWOSQRT2LN2,
2429 sprintf(comment,
"median FWHM in X of sel lines on TRACE%d WIN2 [pix]",trace_number);
2432 cpl_table_get_column_median(selected,
"Xwidth")*TWOSQRT2LN2,
2436 sprintf(comment,
"mean R of sel lines on TRACE%d WIN2",trace_number);
2439 cpl_table_get_column_mean(selected,
"Resol"),
2443 sprintf(comment,
"stdev R of sel lines on TRACE%d WIN2",trace_number);
2446 cpl_table_get_column_stdev(selected,
"Resol"),
2450 sprintf(comment,
"median R of sel lines on TRACE%d WIN2",trace_number);
2453 cpl_table_get_column_median(selected,
"Resol"),
2458 sprintf(comment,
"mean line pos resid on TRACE%d WIN2 [pm]",trace_number);
2460 qc_lineresidavg_name,
2461 cpl_table_get_column_mean(selected, LINETAB_RESIDUAL)*100,
2465 sprintf(comment,
"sigma line pos resid on TRACE%d WIN2 [pm]",trace_number);
2467 qc_lineresidrms_name,
2468 cpl_table_get_column_stdev(selected, LINETAB_RESIDUAL)*100,
2473 wmin=cpl_table_get_column_min(linetable,LINETAB_LAMBDAC)/10.0;
2474 sprintf(comment,
"minimum wavelength on TRACE%d WIN2 [nm]",trace_number);
2481 wmax=cpl_table_get_column_max(linetable,LINETAB_LAMBDAC)/10.0;
2482 sprintf(comment,
"maximum wavelength on TRACE%d WIN2 [nm]",trace_number);
2489 sprintf(comment,
"minimum order number expected on TRACE%d WIN2",trace_number);
2492 uves_min_int(firstabs, lastabs),
2496 sprintf(comment,
"maximum order number expected on TRACE%d WIN2",trace_number);
2499 uves_max_int(firstabs, lastabs),
2504 sprintf(comment,
"minimum order number detected on TRACE%d WIN2",trace_number);
2506 qc_detected_ordmin_name,
2507 cpl_table_get_column_min(linetable,
"Order"),
2511 sprintf(comment,
"maximum order number detected on TRACE%d WIN2",trace_number);
2513 qc_detected_ordmax_name,
2514 cpl_table_get_column_max(linetable,
"Order"),
2518 sprintf(comment,
"No. of lines found on TRACE%d WIN2",trace_number);
2521 cpl_table_get_nrow(linetable),
2525 sprintf(comment,
"No. of lines selected on TRACE%d WIN2",trace_number);
2528 cpl_table_get_nrow(linetable) -
2529 cpl_table_count_invalid(linetable,
"Ident"),
2533 nfinal=cpl_table_get_nrow(selected);
2534 sprintf(comment,
"Final No. of lines used on TRACE%d WIN2",trace_number);
2541 cpl_table* extracted=NULL;
2543 const char* rms_wlu_alpha=NULL;
2544 double lines_sqrt=0;
2545 double lines_werr=0;
2547 wcen=0.5*(wmin+wmax);
2548 check_nomsg(next=cpl_table_and_selected_string(qclog,
"key_name",
2550 "QC LINE RESIDRMS WLU"));
2551 check_nomsg(extracted=cpl_table_extract_selected(qclog));
2553 check_nomsg(rms_wlu_alpha=cpl_table_get_string(extracted,
"key_value",0));
2554 rms_wlu=atof(rms_wlu_alpha);
2555 lines_sqrt=sqrt(nfinal);
2556 lines_werr=rms_wlu/lines_sqrt;
2557 sprintf(comment,
"Wavelength error on TRACE%d [Angstrom]",trace_number);
2564 uves_free_table(&extracted);
2565 uves_free_table(&selected);
2566 selected = cpl_table_duplicate(linetable);
2570 sprintf(comment,
"Wavelength systematic error on TRACE%d [Angstrom]",trace_number);
2573 wcen*100./SPEED_OF_LIGHT,
2580 check_nomsg( uves_erase_invalid_table_rows(selected,
"Ident") );
2581 check_nomsg( uves_erase_table_rows(selected, LINETAB_RESIDUAL,
2585 sprintf(comment,
"No. of lines with residuals < 0.1 nm on TRACE%d",trace_number);
2588 cpl_table_get_nrow(selected),
2595 uves_free_string_const(&qc_fib_drsno_name);
2596 uves_free_string_const(&qc_fib_seq_name);
2597 uves_free_string_const(&qc_fib_pos_name);
2598 uves_free_string_const(&qc_fib_msk_name);
2599 uves_free_string_const(&qc_fwhmavg_name);
2600 uves_free_string_const(&qc_fwhmrms_name);
2601 uves_free_string_const(&qc_fwhmmed_name);
2603 uves_free_string_const(&qc_resolavg_name);
2604 uves_free_string_const(&qc_resolrms_name);
2605 uves_free_string_const(&qc_resolmed_name);
2606 uves_free_string_const(&qc_wlenmin_name);
2607 uves_free_string_const(&qc_wlenmax_name);
2608 uves_free_string_const(&qc_ordmin_name);
2609 uves_free_string_const(&qc_ordmax_name);
2610 uves_free_string_const(&qc_nlintot_name);
2611 uves_free_string_const(&qc_nlinsel_name);
2612 uves_free_string_const(&qc_line_werr_name);
2613 uves_free_string_const(&qc_line_wsys_name);
2614 uves_free_string_const(&qc_nlinsol_name);
2615 uves_free_string_const(&qc_nlinres1_name);
2616 uves_free_string_const(&qc_lineresidavg_name);
2617 uves_free_string_const(&qc_lineresidrms_name);
2618 uves_free_string_const(&qc_detected_ordmin_name);
2619 uves_free_string_const(&qc_detected_ordmax_name);
2621 uves_free_table(&selected);
2635 static void uves_wavecal_qclog_intmon(cpl_table* table,
2636 const cpl_table *line_intmon,
2640 enum uves_chip chip,
2643 const char *qc_intavg_name = NULL;
2644 const char *qc_nlinint_name = NULL;
2646 cpl_table *temp = NULL;
2650 flames ?
"Fibre-Line-Intensity-Test-Results"
2651 :
"Line-Intensity-Test-Results",
2659 double tolerance = 0.001;
2668 int N_bright = cpl_table_get_nrow(line_intmon);
2672 "Could not get exposure time");
2674 cpl_table_new_column(table,
"Intensity", CPL_TYPE_DOUBLE);
2675 for (i = 0; i < cpl_table_get_nrow(table); i++)
2678 double ident = cpl_table_get_double(table,
"Ident", i, &is_null);
2683 line_intmon, ident, 0, N_bright-1);
2685 double bright = cpl_table_get_double(
2686 line_intmon,
"Wave", bright_index, NULL);
2688 if (fabs(bright - ident) < tolerance)
2690 double peak = cpl_table_get_double(table,
"Peak", i, NULL);
2692 fabs(cpl_table_get_double(table, LINETAB_PIXELSIZE, i, NULL));
2694 double lambda_fwhm = cpl_table_get_double(table,
"Xwidth", i, NULL)
2695 * TWOSQRT2LN2 * pixelsize;
2698 double intensity = peak * lambda_fwhm / exptime;
2701 cpl_table_set_double(table,
"Intensity", i, intensity);
2705 cpl_table_set_invalid(table,
"Intensity", i);
2710 cpl_table_set_invalid(table,
"Intensity", i);
2715 uves_free_table(&temp);
2716 temp = cpl_table_duplicate(table);
2717 uves_erase_invalid_table_rows(temp,
"Intensity");
2721 if (cpl_table_get_nrow(temp) == 0)
2728 mean = cpl_table_get_column_mean(temp,
"Intensity");
2733 qc_intavg_name = uves_sprintf(
"QC FIB%d INTAVG", fibre+1);
2734 qc_nlinint_name = uves_sprintf(
"QC FIB%d NLININT", fibre+1);
2738 qc_intavg_name = uves_sprintf(
"QC INTAVG");
2739 qc_nlinint_name = uves_sprintf(
"QC NLININT");
2745 "average intensity of line list on TRACE0 WIN2",
2750 cpl_table_get_nrow(temp),
2751 "No. of lines to measure INTAVG on TRACE0 WIN2",
2756 uves_free_string_const(&qc_intavg_name);
2757 uves_free_string_const(&qc_nlinint_name);
2758 uves_free_table(&temp);