151 cpl_ensure (spectrum_table, CPL_ERROR_NULL_INPUT, NULL);
154 cpl_size nwave = cpl_table_get_column_depth (spectrum_table,
"DATA1");
158 cpl_msg_info (cpl_func,
"spectrum_table = %lld",cpl_table_get_column_depth (spectrum_table,
"DATA1"));
165 cpl_size nlines = 14;
166 double plines_str[] = {60,
182 double plines_lbd[] = {1.982291,
198 cpl_vector * lines_lbd = cpl_vector_wrap (nlines,plines_lbd);
199 cpl_vector * lines_str = cpl_vector_wrap (nlines,plines_str);
200 cpl_bivector * lines = cpl_bivector_wrap_vectors (lines_lbd, lines_str);
203 cpl_wlcalib_slitmodel * model = cpl_wlcalib_slitmodel_new ();
204 cpl_wlcalib_slitmodel_set_wslit (model, 0.1);
205 cpl_wlcalib_slitmodel_set_wfwhm (model, 1.25);
206 cpl_wlcalib_slitmodel_set_threshold (model, 5.0);
207 cpl_wlcalib_slitmodel_set_catalog (model, lines);
210 double values_hr[] = {1.97048,0.2228e-3,2.7728e-08,-4.72e-12};
211 double values_mr[] = {1.9697,0.2179e-2,2.5e-07,-5e-10};
212 double * values = nwave > 1000 ? values_hr : values_mr;
215 cpl_polynomial * dispersion0 = cpl_polynomial_new (1);
216 for (cpl_size order = 0 ; order < 4 ; order ++) {
217 cpl_polynomial_set_coeff (dispersion0, &order, values[order]);
221 double minwave = -1e10;
222 double maxwave = +1e10;
224 cpl_vector * spectrum = cpl_vector_new (nwave);
225 cpl_vector * input_spectrum = cpl_vector_new (nwave);
226 cpl_vector * model_spectrum = cpl_vector_new (nwave);
229 cpl_table * fit_table = cpl_table_new (nregion);
235 cpl_polynomial * dispersion = cpl_polynomial_duplicate (dispersion0);
238 for (cpl_size reg = 0; reg < nregion ; reg ++ ) {
239 cpl_msg_info (cpl_func,
"Fit region %lld over %lld", reg+1, nregion);
242 const cpl_array * data = cpl_table_get_array (spectrum_table,
GRAVI_DATA[reg], 0);
243 for (cpl_size wave=0; wave < nwave; wave ++) {
244 cpl_vector_set (spectrum, wave, log (CPL_MAX (cpl_array_get (data, wave, NULL), 1.0)));
245 cpl_vector_set (input_spectrum, wave, cpl_array_get (data, wave, NULL));
253 int maxdeg = 3, nmaxima = 0, linelim = 99;
254 int maxite = 100 * maxdeg, maxfail = 10, maxcont = 10;
255 int hsize = (reg == 0 ? 40 : 5);
256 double pixtol = 1e-6, pixstep = 0.5, pxc = 0.0;
260 irplib_polynomial_find_1d_from_correlation_all (dispersion, maxdeg, spectrum,
262 (irplib_base_spectrum_model*)model,
263 &irplib_vector_fill_logline_spectrum,
265 hsize, maxite, maxfail, maxcont,
270 irplib_vector_fill_line_spectrum (model_spectrum, dispersion, (
void *)model);
271 cpl_polynomial_dump (dispersion, stdout);
274 cpl_array *
wave_data = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
275 for (cpl_size pix = 0; pix < nwave ; pix++)
276 cpl_array_set (
wave_data, pix, cpl_polynomial_eval_1d (dispersion, (
double)pix, NULL) * 1e-6);
279 minwave = CPL_MAX (cpl_array_get_min (
wave_data), minwave);
280 maxwave = CPL_MIN (cpl_array_get_max (
wave_data), maxwave);
288 cpl_array * tmp_array;
289 tmp_array = cpl_array_wrap_double (cpl_vector_get_data (input_spectrum), nwave);
290 cpl_table_set_array (fit_table,
"DATA", reg, tmp_array);
291 cpl_array_unwrap (tmp_array);
292 tmp_array = cpl_array_wrap_double (cpl_vector_get_data (model_spectrum), nwave);
293 cpl_table_set_array (fit_table,
"DATA_MODEL", reg, tmp_array);
294 cpl_array_unwrap (tmp_array);
295 tmp_array = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
296 for (cpl_size wave = 0; wave < nwave; wave ++)
297 cpl_array_set (tmp_array, wave, cpl_polynomial_eval_1d (dispersion, (
double)wave, NULL) * 1e-6);
298 cpl_table_set_array (fit_table,
"DATA_WAVE", reg, tmp_array);
299 cpl_array_delete (tmp_array);
305 FREE (cpl_table_delete, fit_table);
308 FREE (cpl_vector_delete, spectrum);
309 FREE (cpl_vector_delete, input_spectrum);
310 FREE (cpl_vector_delete, model_spectrum);
311 FREE (cpl_polynomial_delete, dispersion0);
312 FREE (cpl_polynomial_delete, dispersion);
461 cpl_ensure (ft_table, CPL_ERROR_NULL_INPUT, NULL);
465 cpl_size nrow = cpl_table_get_nrow (ft_table) /
GRAVI_NBASE;
468 double * opd_sc = cpl_table_get_data_double (ft_table,
"OPD_SC");
469 double * opd_ft = cpl_table_get_data_double (ft_table,
"OPD");
470 double * phase_met = cpl_table_get_data_double (ft_table,
"PHASE_MET_FC");
474 cpl_size nrow_valid = 0;
475 for (cpl_size row = 0; row < nrow; row++)
if (opd_sc[row*
GRAVI_NBASE] != 0) nrow_valid++;
476 cpl_msg_info (cpl_func,
"nrow_valid = %lld", nrow_valid);
478 cpl_ensure (nrow_valid > 100, CPL_ERROR_ILLEGAL_INPUT, NULL);
482 cpl_matrix * rhs_matrix = cpl_matrix_new (nrow_valid*
GRAVI_NBASE, 1);
486 cpl_size row_valid = 0;
488 for (cpl_size row=0; row<nrow; row++) {
495 cpl_matrix_set (rhs_matrix, idv, 0, phase_met[
id] * lbd_met / CPL_MATH_2PI);
499 cpl_matrix_set (model_matrix, idv, 0, 1*opd_sc[
id]);
500 cpl_matrix_set (model_matrix, idv, 1, -1*opd_ft[
id]);
504 cpl_matrix_set (model_matrix, idv, 2 + base, 1.0);
512 cpl_matrix * res_matrix = cpl_matrix_solve_normal (model_matrix, rhs_matrix);
515 cpl_matrix * residual_matrix = cpl_matrix_product_create (model_matrix, res_matrix);
516 cpl_matrix_subtract (residual_matrix, rhs_matrix);
517 double rms_fit = cpl_matrix_get_stdev (residual_matrix);
521 cpl_msg_info (cpl_func,
"coeff SC = %.20g ", cpl_matrix_get (res_matrix, 0, 0));
522 cpl_msg_info (cpl_func,
"coeff FT = %.20g ", cpl_matrix_get (res_matrix, 1, 0));
523 cpl_msg_info (cpl_func,
"residual stdev = %.20g [m]", rms_fit);
526 cpl_vector * opd_coeff = cpl_vector_new(3);
527 cpl_vector_set (opd_coeff,
GRAVI_SC, cpl_matrix_get (res_matrix, 0, 0));
528 cpl_vector_set (opd_coeff,
GRAVI_FT, cpl_matrix_get (res_matrix, 1, 0));
529 cpl_vector_set (opd_coeff, 2, rms_fit);
532 FREE (cpl_matrix_delete, residual_matrix);
533 FREE (cpl_matrix_delete, res_matrix);
534 FREE (cpl_matrix_delete, model_matrix);
535 FREE (cpl_matrix_delete, rhs_matrix);
820 cpl_table * met_table,
821 const cpl_parameterlist * parlist)
824 cpl_ensure_code (spectrum_data, CPL_ERROR_NULL_INPUT);
825 cpl_ensure_code (met_table, CPL_ERROR_NULL_INPUT);
857 cpl_msg_info (cpl_func,
"Compute OPD of FT from ellipse");
859 cpl_table * ft_table;
863 cpl_msg_info (cpl_func,
"Compute OPD of SC from ellipse");
865 cpl_table * guess_table;
868 cpl_table * sc_table;
871 FREE (cpl_table_delete, guess_table);
879 cpl_msg_info (cpl_func,
"Fit MET = a.SC - b.FT + c to get absolute modulation");
884 CPLCHECK_MSG (
"Cannot resample SC or MET at the FT frequency");
896 cpl_vector_get (coeff_vector, 2));
897 cpl_propertylist_set_comment (spectrum_header,
QC_PHASECHI2,
898 "chi2 of a.SC-b.FT+c=MET");
901 for (
int type_data = 0; type_data < 2; type_data++) {
902 double tmp = cpl_vector_get (coeff_vector, type_data);
903 cpl_propertylist_update_float (spectrum_header,
OPD_COEFF_SIGN(type_data), tmp);
904 cpl_propertylist_set_comment (spectrum_header,
OPD_COEFF_SIGN(type_data),
"wavelength correction");
908 if (cpl_vector_get (coeff_vector, 2) > 1e-7) {
912 if (cpl_vector_get (coeff_vector, 2) > 1.2e-7) {
913 cpl_msg_warning (cpl_func,
"*************************************************");
914 cpl_msg_warning (cpl_func,
"**** !!! residuals of the fit too high !!! ****");
915 cpl_msg_warning (cpl_func,
"**** Residuals are:%7.0f nm ****",cpl_vector_get (coeff_vector, 2)*1e9);
916 cpl_msg_warning (cpl_func,
"**** SC and RMN may be desynchronized ****");
917 cpl_msg_warning (cpl_func,
"**** (or out of the envelope in LOW) ****");
918 cpl_msg_warning (cpl_func,
"*************************************************");
926 double coeff_sc = cpl_vector_get (coeff_vector,
GRAVI_SC);
927 cpl_table_multiply_scalar (sc_table,
"OPD", coeff_sc);
929 double coeff_ft = cpl_vector_get (coeff_vector,
GRAVI_FT);
930 cpl_table_multiply_scalar (ft_table,
"OPD", coeff_ft);
932 FREE (cpl_vector_delete, coeff_vector);
933 CPLCHECK_MSG (
"Cannot correct OPDs from scaling coefficients");
959 return CPL_ERROR_NONE;
989 cpl_table * detector_table,
990 cpl_table * opd_table)
993 cpl_ensure (spectrum_table, CPL_ERROR_NULL_INPUT, NULL);
994 cpl_ensure (detector_table, CPL_ERROR_NULL_INPUT, NULL);
995 cpl_ensure (opd_table, CPL_ERROR_NULL_INPUT, NULL);
1000 cpl_table * wave_fibre = cpl_table_new (1);
1003 cpl_size nwave = cpl_table_get_column_depth (spectrum_table,
"DATA1");
1004 cpl_size n_region = cpl_table_get_nrow (detector_table);
1005 cpl_size nrow = cpl_table_get_nrow (spectrum_table);
1007 int npol = (n_region > 24 ? 2 : 1);
1013 for (
int pol = 0; pol < npol; pol++) {
1015 cpl_msg_info (cpl_func,
"Compute wave fibre for pol %i over %i, base %i over %i",
1023 if (iA<0 || iB<0 || iC<0 || iD<0){
1024 cpl_msg_warning (cpl_func,
"Don't found the A, B, C or D !!!");
1031 cpl_matrix * opd_matrix = cpl_matrix_new (1, nrow);
1032 cpl_vector * opd_vector = cpl_vector_new (nrow);
1033 for (cpl_size row = 0; row < nrow; row ++ ) {
1034 double value = cpl_table_get (opd_table,
"OPD", row*
GRAVI_NBASE+base, NULL);
1035 cpl_matrix_set (opd_matrix, 0, row, value);
1036 cpl_vector_set (opd_vector, row, value);
1041 cpl_array * wavelength = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1042 cpl_array * wavechi2 = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1043 cpl_array_fill_window (wavelength, 0, nwave, 0.0);
1044 cpl_array_fill_window (wavechi2, 0, nwave, 1e10);
1049 for (cpl_size wave = 0; wave < nwave; wave++) {
1051 cpl_vector * vector_T = NULL, * vector_X, * vector_Y;
1056 cpl_vector_subtract (vector_X, vector_T);
1057 FREE (cpl_vector_delete, vector_T);
1062 cpl_vector_subtract (vector_Y, vector_T);
1063 FREE (cpl_vector_delete, vector_T);
1074 FREE (cpl_vector_delete, vector_X);
1075 FREE (cpl_vector_delete, vector_Y);
1076 FREE (cpl_vector_delete, envelope_vector);
1079 if (phase == NULL) {
1080 cpl_msg_warning (cpl_func,
"Cannot compute wave for %lld and base %d", wave, base);
1085 cpl_vector_multiply_scalar (phase, phi_sign);
1088 double lbd_channel = 1.95e-6 + (2.46e-6 - 1.95e-6) / nwave * wave;
1093 const cpl_size mindeg = 0, maxdeg = 1;
1094 cpl_polynomial * fit_slope = cpl_polynomial_new (1);
1095 cpl_polynomial_fit (fit_slope, opd_matrix, NULL, phase, NULL, CPL_FALSE, &mindeg, &maxdeg);
1098 cpl_vector * residuals = cpl_vector_new (nwave);
1100 cpl_vector_fill_polynomial_fit_residual (residuals, phase, NULL, fit_slope, opd_matrix, &rechisq);
1104 char gnuplot_str[200];
1105 sprintf (gnuplot_str,
"set title 'Wavelength (base %d)'; set xlabel 'Phase [rad]'; set ylabel 'OPD (m)';", base);
1106 cpl_plot_vector (gnuplot_str, NULL, NULL, opd_vector);
1107 sprintf (gnuplot_str,
"set title 'Wavelength residuals (base %d)'; set xlabel 'Phase [rad]'; set ylabel 'OPD (m)';", base);
1108 cpl_plot_vector (gnuplot_str, NULL, NULL, residuals);
1115 const cpl_size pow_slope = 1;
1116 double slope = cpl_polynomial_get_coeff (fit_slope, &pow_slope);
1119 if (slope < 0.0 && wave == 0) {
1120 cpl_msg_warning (cpl_func,
"Negative wavelength!! "
1121 "Report to DRS team");
1125 cpl_array_set (wavechi2, wave, sqrt(rechisq));
1126 cpl_array_set (wavelength, wave, CPL_MATH_2PI / fabs(slope));
1129 cpl_vector_delete (phase);
1130 cpl_vector_delete (residuals);
1131 cpl_polynomial_delete (fit_slope);
1135 cpl_matrix_delete (opd_matrix);
1136 cpl_vector_delete (opd_vector);
1140 cpl_table_new_column_array (wave_fibre, name, CPL_TYPE_DOUBLE, nwave);
1141 cpl_table_set_column_unit (wave_fibre, name,
"m");
1142 cpl_table_set_array (wave_fibre, name, 0, wavelength);
1143 cpl_array_delete (wavelength);
1147 cpl_table_new_column_array (wave_fibre, name, CPL_TYPE_DOUBLE, nwave);
1148 cpl_table_set_array (wave_fibre, name, 0, wavechi2);
1149 cpl_array_delete (wavechi2);
1179 cpl_table * detector_table,
1181 cpl_size fullstartx,
1184 double * rms_residuals)
1187 cpl_ensure (wavefibre_table, CPL_ERROR_NULL_INPUT, NULL);
1188 cpl_ensure (detector_table, CPL_ERROR_NULL_INPUT, NULL);
1194 cpl_size n_region = cpl_table_get_nrow (detector_table);
1195 int npol = n_region > 24 ? 2 : 1;
1196 cpl_size nwave = cpl_table_get_column_depth (wavefibre_table, npol > 1 ?
"BASE_12_S" :
"BASE_12_C");
1203 cpl_vector * odd_index = cpl_vector_new (nwave);
1204 for (
int i = fullstartx; i < fullstartx + nwave; i++) {
1205 if (nwave >
GRAVI_LBD_FTSC) cpl_vector_set (odd_index, i - fullstartx, ((i/64)%2 == 0) ? 0 : 1);
1206 else cpl_vector_set (odd_index, i - fullstartx, 0);
1212 cpl_polynomial ** coef_poly = cpl_calloc (npol,
sizeof (cpl_polynomial*));
1215 for (
int pol = 0; pol < npol; pol++) {
1219 cpl_vector * coord_X = cpl_vector_new (
GRAVI_NBASE * nwave);
1220 cpl_vector * coord_Y = cpl_vector_new (
GRAVI_NBASE * nwave);
1222 cpl_vector * all_wavelength = cpl_vector_new (
GRAVI_NBASE * nwave);
1223 cpl_vector * all_wavechi2 = cpl_vector_new (
GRAVI_NBASE * nwave);
1224 cpl_vector * all_valid = cpl_vector_new (
GRAVI_NBASE * nwave);
1240 cpl_array * wavelength = cpl_table_get_data_array (wavefibre_table, name)[0];
1243 cpl_array * wavechi2 = cpl_table_get_data_array (wavefibre_table, name)[0];
1246 for (cpl_size wave = 0; wave < nwave; wave++) {
1247 cpl_size pos = base * nwave + wave;
1251 double wave_value = cpl_array_get (wavelength, wave, &nv);
1252 double chi2_value = cpl_array_get (wavechi2, wave, &nv);
1255 cpl_vector_set (all_valid, pos, 1);
1259 if ((chi2_value > M_PI_4 ||
1262 cpl_vector_set (all_valid, pos, 0);
1264 else if (nwave > 100) {
1266 if ((chi2_value > M_PI_4 ||
1269 cpl_vector_set (all_valid, pos, 0);
1273 if ((chi2_value > M_PI_4 ||
1277 wave == 0 || wave == nwave-1))
1278 cpl_vector_set (all_valid, pos, 0);
1282 if ((chi2_value > M_PI_4 ||
1284 wave_value < 1.99e-6 ||
1285 wave_value > 2.5e-6))
1286 cpl_vector_set (all_valid, pos, 0);
1290 cpl_vector_set (all_wavelength, pos, wave_value);
1291 cpl_vector_set (all_wavechi2, pos, chi2_value);
1294 cpl_vector_set (coord_X, pos, (
double)(iA + iB + iC + iD) / 4.);
1298 cpl_vector_set (coord_Y, pos, wave + cpl_vector_get (odd_index, wave)*0.15);
1308 cpl_size nvalid = cpl_vector_get_sum (all_valid);
1313 cpl_vector * vector = cpl_vector_new (nvalid);
1314 cpl_matrix * matrix = cpl_matrix_new (2, nvalid);
1316 for (cpl_size c = 0, i = 0 ; i < nwave *
GRAVI_NBASE; i ++) {
1317 if (!cpl_vector_get (all_valid, i))
continue;
1318 cpl_vector_set (vector, c, cpl_vector_get (all_wavelength, i));
1319 cpl_matrix_set (matrix, 0, c, cpl_vector_get (coord_X, i));
1320 cpl_matrix_set (matrix, 1, c, cpl_vector_get (coord_Y, i));
1330 cpl_size deg2d[2] = {2, 3};
1331 if ( (nwave < 20) && (nwave > 8) ) {deg2d[0] = 2; deg2d[1] = 7;}
1332 deg2d[0] = spatial_order;
1333 deg2d[1] = spectral_order;
1335 cpl_msg_info (cpl_func,
"Fit a 2d polynomial {%lli..%lli} to the wavelengths map", deg2d[0], deg2d[1]);
1337 cpl_polynomial * fit2d = cpl_polynomial_new (2);
1338 cpl_polynomial_fit (fit2d, matrix, NULL, vector, NULL, CPL_TRUE, NULL, deg2d);
1339 coef_poly[pol] = fit2d;
1346 double rechisq = 0.0;
1347 cpl_vector * residuals = cpl_vector_new (nvalid);
1348 cpl_vector_fill_polynomial_fit_residual (residuals, vector, NULL, fit2d, matrix, &rechisq);
1349 *rms_residuals += cpl_vector_get_stdev(residuals)/npol;
1350 FREE (cpl_vector_delete, residuals);
1354 FREE (cpl_matrix_delete, matrix);
1355 FREE (cpl_vector_delete, vector);
1356 FREE (cpl_vector_delete, all_wavelength);
1357 FREE (cpl_vector_delete, all_wavechi2);
1358 FREE (cpl_vector_delete, all_valid);
1359 FREE (cpl_vector_delete, coord_X);
1360 FREE (cpl_vector_delete, coord_Y);
1369 cpl_table * wavedata_table = cpl_table_new (1);
1370 cpl_vector * pos = cpl_vector_new (2);
1371 cpl_array * value = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1373 for (cpl_size region = 0 ; region < n_region; region ++) {
1377 for (cpl_size wave = 0; wave < nwave; wave ++) {
1380 cpl_vector_set (pos, 0, region);
1381 cpl_vector_set (pos, 1, wave + cpl_vector_get (odd_index, wave)*0.15);
1383 double result = cpl_polynomial_eval (coef_poly[pol], pos);
1384 cpl_array_set (value, wave, result);
1388 double previous_wave = cpl_array_get(value, nwave/2, NULL);
1389 for (cpl_size wave_loop = nwave/2 ; wave_loop >= 0 ; wave_loop --){
1390 if (previous_wave < cpl_array_get(value, wave_loop, NULL))
1391 cpl_array_set(value, wave_loop, previous_wave);
1392 else previous_wave = cpl_array_get(value, wave_loop, NULL);
1395 previous_wave = cpl_array_get(value, nwave/2, NULL);
1396 for (cpl_size wave_loop = nwave/2 ; wave_loop < nwave ; wave_loop ++){
1397 if (previous_wave > cpl_array_get(value, wave_loop, NULL))
1398 cpl_array_set(value, wave_loop, previous_wave);
1399 else previous_wave = cpl_array_get(value, wave_loop, NULL);
1404 cpl_table_new_column_array (wavedata_table, data_x, CPL_TYPE_DOUBLE, nwave);
1405 cpl_table_set_array (wavedata_table, data_x, 0, value);
1410 FREE (cpl_vector_delete, pos);
1411 FREE (cpl_array_delete, value);
1412 FREELOOP (cpl_polynomial_delete, coef_poly, npol);
1413 FREE (cpl_vector_delete, odd_index);
1416 return wavedata_table;
1428 cpl_table * weight_individual_table,
1429 cpl_table * wave_fitted_table,
1430 cpl_table * opd_table,
1431 cpl_table * spectrum_table,
1432 cpl_table * detector_table,
1433 double n0,
double n1,
double n2)
1438 cpl_ensure (wave_individual_table, CPL_ERROR_NULL_INPUT, NULL);
1439 cpl_ensure (weight_individual_table, CPL_ERROR_NULL_INPUT, NULL);
1440 cpl_ensure (wave_fitted_table, CPL_ERROR_NULL_INPUT, NULL);
1441 cpl_ensure (opd_table, CPL_ERROR_NULL_INPUT, NULL);
1442 cpl_ensure (spectrum_table, CPL_ERROR_NULL_INPUT, NULL);
1443 cpl_ensure (detector_table, CPL_ERROR_NULL_INPUT, NULL);
1446 cpl_size nwave = cpl_table_get_column_depth (spectrum_table,
"DATA1");
1447 cpl_size n_region = cpl_table_get_nrow (detector_table);
1448 cpl_size nrow = cpl_table_get_nrow (spectrum_table);
1449 int npol = (n_region > 24 ? 2 : 1);
1450 cpl_size nwave_ref=3000;
1451 if (nwave<10) nwave_ref=600;
1461 cpl_array * wave_individual_array = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1462 cpl_array * weight_individual_array = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1463 cpl_matrix * data_flux_matrix = cpl_matrix_new (nrow, nwave);
1464 cpl_matrix * vis_to_flux_matrix = cpl_matrix_new (nrow, 3);
1465 cpl_matrix * signal_matrix = cpl_matrix_new (nwave, nwave_ref);
1466 cpl_matrix * residual_matrix = cpl_matrix_new (nwave, nwave_ref);
1467 cpl_array * wave_reference_array = cpl_array_new (nwave_ref, CPL_TYPE_DOUBLE);
1471 cpl_matrix_fill_column(vis_to_flux_matrix,1,2);
1472 for (cpl_size wave_ref = 0; wave_ref < nwave_ref; wave_ref+=1)
1475 double wave_value=1.95e-6+wave_ref*0.6e-6/((double) nwave_ref);
1476 cpl_array_set_double(wave_reference_array,wave_ref,wave_value);
1479 CPLCHECK_NUL (
"Cannot initialize arrays for wavelength fit");
1482 for (cpl_size region = 0 ; region < n_region; region ++) {
1487 cpl_msg_info_overwritable (cpl_func,
"Least square fitting of wavelength for region %s", data_x);
1490 for (cpl_size row = 0; row < nrow; row ++ ) {
1491 cpl_array * flux_array= cpl_table_get_data_array(spectrum_table,data_x)[row];
1492 for (cpl_size wave = 0; wave < nwave; wave ++) {
1493 cpl_matrix_set (data_flux_matrix, row, wave, cpl_array_get(flux_array,wave, NULL));
1498 for (cpl_size wave_ref = 0; wave_ref < nwave_ref; wave_ref+=1)
1501 double wave_value=cpl_array_get(wave_reference_array,wave_ref,NULL);
1503 for (cpl_size row = 0; row < nrow; row ++ ) {
1504 double opd = cpl_table_get (opd_table,
"OPD", row*
GRAVI_NBASE+base, NULL);
1505 double coherence_loss=1;
1506 if (fabs(opd) > 1e-9)
1510 coherence_loss=sin(opd*19500)/(opd*19500);
1513 cpl_matrix_set(vis_to_flux_matrix,row,0,cos(opd*6.28318530718/wave_value)*coherence_loss);
1514 cpl_matrix_set(vis_to_flux_matrix,row,1,sin(opd*6.28318530718/wave_value)*coherence_loss);
1517 cpl_matrix * coef_vis = cpl_matrix_solve_normal(vis_to_flux_matrix,data_flux_matrix);
1518 cpl_matrix * data_flux_fit = cpl_matrix_product_create(vis_to_flux_matrix,coef_vis);
1519 cpl_matrix * residuals_fit = cpl_matrix_duplicate(data_flux_fit);
1520 cpl_matrix_subtract (residuals_fit,data_flux_matrix);
1522 for (cpl_size wave = 0; wave < nwave; wave ++ ) {
1523 cpl_matrix * temp_matrix = cpl_matrix_extract_column (data_flux_fit, wave);
1524 cpl_matrix_set(signal_matrix,wave,wave_ref,cpl_matrix_get_stdev(temp_matrix));
1525 FREE (cpl_matrix_delete, temp_matrix);
1526 cpl_matrix * temp_matrix2 = cpl_matrix_extract_column (residuals_fit, wave);
1527 cpl_matrix_set(residual_matrix,wave,wave_ref,cpl_matrix_get_stdev(temp_matrix2));
1528 FREE (cpl_matrix_delete, temp_matrix2);
1531 FREE (cpl_matrix_delete, coef_vis);
1532 FREE (cpl_matrix_delete, data_flux_fit);
1533 FREE (cpl_matrix_delete, residuals_fit);
1535 CPLCHECK_NUL (
"Cannot do Matrix inversion to calculate optimum wavelength");
1540 cpl_size wave_ref=1;
1541 cpl_size discarded=1;
1542 for (cpl_size wave = 0; wave < nwave; wave ++ ) {
1544 cpl_matrix * chi2_extract=cpl_matrix_extract_row(residual_matrix,wave);
1546 cpl_matrix_get_minpos(chi2_extract,&discarded, &wave_ref );
1548 double wave_value = cpl_array_get(wave_reference_array, wave_ref, NULL );
1549 double weight_value = cpl_matrix_get(signal_matrix, wave , wave_ref )/(0.1+cpl_matrix_get(residual_matrix, wave, wave_ref ));
1551 cpl_array_set_double (wave_individual_array, wave, wave_value);
1552 cpl_array_set_double (weight_individual_array, wave, weight_value);
1554 FREE (cpl_matrix_delete, chi2_extract);
1559 cpl_table_new_column_array (wave_individual_table, data_x, CPL_TYPE_DOUBLE, nwave);
1560 cpl_table_set_array (wave_individual_table, data_x, 0, wave_individual_array);
1561 cpl_table_new_column_array (weight_individual_table, data_x, CPL_TYPE_DOUBLE, nwave);
1562 cpl_table_set_array (weight_individual_table, data_x, 0, weight_individual_array);
1563 cpl_table_new_column_array (wave_fitted_table, data_x, CPL_TYPE_DOUBLE, nwave);
1564 cpl_table_set_array (wave_fitted_table, data_x, 0, wave_individual_array);
1567 CPLCHECK_NUL (
"Cannot get individual wavelength for each pixel");
1569 FREE (cpl_array_delete ,wave_individual_array);
1570 FREE (cpl_array_delete ,weight_individual_array);
1571 FREE (cpl_array_delete ,wave_reference_array);
1572 FREE (cpl_matrix_delete ,data_flux_matrix);
1573 FREE (cpl_matrix_delete ,vis_to_flux_matrix);
1574 FREE (cpl_matrix_delete ,signal_matrix);
1575 FREE (cpl_matrix_delete ,residual_matrix);
1577 cpl_msg_info (cpl_func,
"Now fitting polynomials on wavelength channels");
1579 cpl_matrix * coef_to_wave = cpl_matrix_new (n_region / npol,5);
1580 cpl_matrix * coef_to_wave_weight = cpl_matrix_new (n_region / npol,n_region / npol);
1581 cpl_matrix * wavelength = cpl_matrix_new(n_region / npol,1);
1584 for (cpl_size region = 0 ; region < n_region/ npol; region ++)
1586 double mean_region = region - (n_region/npol-1)*0.5;
1587 cpl_matrix_set (coef_to_wave, region, 0, 1);
1588 cpl_matrix_set (coef_to_wave, region, 1, mean_region);
1589 cpl_matrix_set (coef_to_wave, region, 2, mean_region*mean_region);
1590 cpl_matrix_set (coef_to_wave, region, 3, mean_region*mean_region*mean_region);
1591 cpl_matrix_set (coef_to_wave, region, 4, mean_region*mean_region*mean_region*mean_region);
1594 for (
int pol = 0; pol < npol; pol++) {
1596 cpl_msg_info (cpl_func,
"Looping for polyfit now, with pol: %i",(
int) pol);
1598 for (cpl_size wave = 0; wave < nwave; wave ++) {
1601 for (cpl_size region = 0 ; region < n_region/ npol; region ++) {
1607 const cpl_array * wave_array = cpl_table_get_array (wave_individual_table, data_x, 0);
1608 const cpl_array * weight_array = cpl_table_get_array (weight_individual_table, data_x, 0);
1611 cpl_matrix_set (wavelength, region, 0, cpl_array_get(wave_array,wave,NULL));
1612 double weight_value=cpl_array_get(weight_array,wave,NULL);
1613 cpl_matrix_set (coef_to_wave_weight, region, region, weight_value*weight_value);
1618 cpl_matrix * coef_to_wave2 = cpl_matrix_product_create(coef_to_wave_weight,coef_to_wave);
1619 cpl_matrix * wavelength2 = cpl_matrix_product_create(coef_to_wave_weight,wavelength);
1622 cpl_matrix * coeff = cpl_matrix_solve_normal(coef_to_wave2, wavelength2);
1623 cpl_matrix * wavelength_fitted = cpl_matrix_product_create(coef_to_wave, coeff);
1625 CPLCHECK_NUL (
"Cannot do Matrix inversion to calculate optimum polynomial for wavelength");
1628 for (cpl_size region = 0 ; region < n_region/ npol; region ++) {
1632 cpl_array * wave_array = cpl_table_get_data_array (wave_fitted_table, data_x)[0];
1634 cpl_array_set_double(wave_array,wave,cpl_matrix_get(wavelength_fitted,region,0));
1638 FREE (cpl_matrix_delete ,coef_to_wave2);
1639 FREE (cpl_matrix_delete ,wavelength2);
1640 FREE (cpl_matrix_delete ,coeff);
1641 FREE (cpl_matrix_delete ,wavelength_fitted);
1645 FREE (cpl_matrix_delete ,coef_to_wave);
1646 FREE (cpl_matrix_delete ,coef_to_wave_weight);
1647 FREE (cpl_matrix_delete ,wavelength);
1649 CPLCHECK_NUL (
"Cannot fit individual wavelength with 3rd order polynomial");
1651 cpl_msg_info (cpl_func,
"Correcting for wavelength error");
1655 for (cpl_size region = 0 ; region < n_region; region ++)
1658 cpl_array * wavelength_fitted = cpl_table_get_data_array (wave_fitted_table, data_x)[0];
1659 cpl_size nwave_fitted = cpl_array_get_size (wavelength_fitted);
1660 for (cpl_size wave = 0 ; wave < nwave_fitted ; wave ++ ) {
1662 double result = cpl_array_get (wavelength_fitted, wave, NULL);
1664 cpl_array_set (wavelength_fitted, wave, result * (n0 + n1*d_met + n2*d_met*d_met));
1667 for (cpl_size wave = nwave_fitted/2 ; wave < nwave_fitted-1 ; wave ++ ) {
1668 double result = cpl_array_get (wavelength_fitted, wave, NULL);
1669 double result2 = cpl_array_get (wavelength_fitted, wave+1, NULL);
1670 if (result2<result+2e-10) {
1671 result2=result+2e-10;
1672 cpl_array_set (wavelength_fitted, wave+1, result2);
1675 for (cpl_size wave = nwave_fitted/2 ; wave > 0 ; wave -- ) {
1676 double result = cpl_array_get (wavelength_fitted, wave, NULL);
1677 double result2 = cpl_array_get (wavelength_fitted, wave-1, NULL);
1678 if (result2>result-2e-10) {
1679 result2=result-2e-10;
1680 cpl_array_set (wavelength_fitted, wave-1, result2);
1688 return wave_fitted_table;
1802 cpl_table * wavefibre_table,
1803 cpl_table * profile_table,
1804 cpl_table * detector_table)
1807 cpl_ensure (wavedata_table, CPL_ERROR_NULL_INPUT, NULL);
1808 cpl_ensure (wavefibre_table, CPL_ERROR_NULL_INPUT, NULL);
1809 cpl_ensure (detector_table, CPL_ERROR_NULL_INPUT, NULL);
1810 cpl_ensure (profile_table, CPL_ERROR_NULL_INPUT, NULL);
1815 cpl_size n_region = cpl_table_get_nrow (detector_table);
1816 int npol = (n_region > 24 ? 2 : 1);
1821 cpl_size sizex = cpl_table_get_column_dimension (profile_table,
"DATA1", 0);
1822 cpl_size sizey = cpl_table_get_column_dimension (profile_table,
"DATA1", 1);
1824 cpl_image * profilesum_image = cpl_image_new (sizex, sizey, CPL_TYPE_DOUBLE);
1825 cpl_image_fill_window (profilesum_image, 1, 1, sizex, sizey, 0.0);
1827 cpl_image * wave_image = cpl_image_new (sizex, sizey, CPL_TYPE_DOUBLE);
1828 cpl_image_fill_window (wave_image, 1, 1, sizex, sizey, 0.0);
1830 cpl_image * realwave_image = cpl_image_new (sizex, sizey, CPL_TYPE_DOUBLE);
1831 cpl_image_fill_window (realwave_image, 1, 1, sizex, sizey, 0.0);
1836 for (cpl_size region = 0 ; region < n_region; region ++) {
1840 cpl_image * profile_image = cpl_imagelist_get (profile_imglist, 0);
1845 cpl_image_add (profilesum_image, profile_image);
1850 const cpl_array * wavelength;
1851 wavelength = cpl_table_get_array (wavedata_table,
GRAVI_DATA[region], 0);
1854 for (cpl_size x = 0; x < sizex; x ++){
1855 for (cpl_size y = 0; y < sizey; y ++){
1856 if (cpl_image_get (profile_image, x+1, y+1, &nv) > 0.01)
1857 cpl_image_set (wave_image, x+1, y+1,
1858 cpl_array_get (wavelength, x, NULL));
1869 wavelength = cpl_table_get_array (wavefibre_table, name, 0);
1872 for (cpl_size x = 0; x < sizex; x ++){
1873 for (cpl_size y = 0; y < sizey; y ++){
1874 if (cpl_image_get (profile_image, x+1, y+1, &nv) > 0.01)
1875 cpl_image_set (realwave_image, x+1, y+1,
1876 cpl_array_get (wavelength, x, NULL));
1885 cpl_imagelist * testwave_imglist = cpl_imagelist_new ();
1886 cpl_imagelist_set (testwave_imglist, wave_image, 0);
1887 cpl_imagelist_set (testwave_imglist, profilesum_image, 1);
1888 cpl_imagelist_set (testwave_imglist, realwave_image, 2);
1891 return testwave_imglist;
2055 int type_data,
const cpl_parameterlist * parlist,
2059 cpl_ensure_code (wave_map, CPL_ERROR_NULL_INPUT);
2060 cpl_ensure_code (spectrum_data, CPL_ERROR_NULL_INPUT);
2062 CPL_ERROR_ILLEGAL_INPUT);
2070 cpl_propertylist_append (wave_header, raw_header);
2087 cpl_table * wavefibre_table;
2088 wavefibre_table =
gravi_wave_fibre (spectrum_table, detector_table, opd_table);
2097 double n0 = 1.0, n1 = -0.0165448, n2 = 0.00256002;
2098 cpl_msg_info (cpl_func,
"Rescale wavelengths with dispersion (%g,%g,%g)",n0,n1,n2);
2100 cpl_propertylist_update_string (wave_header,
"ESO QC WAVE_CORR",
"lbd*(N0+N1*(lbd-lbd0)/lbd0+N2*(lbd-lbd0)^2/lbd0^2)");
2119 cpl_table * wavedata_table;
2120 int spatial_order=2;
2121 int spectral_order=3;
2122 double rms_residuals;
2125 cpl_msg_info (cpl_func,
"Option force-waveFT-equal applied");
2136 fullstartx, spatial_order, spectral_order, &rms_residuals);
2141 double rms_fit=cpl_propertylist_get_double (raw_header,
QC_PHASECHI2);
2143 cpl_propertylist_set_comment (wave_header,
QC_CHI2WAVE(type_data),
"[nm]rms a.SC-b.FT+c=MET");
2154 cpl_table * wave_individual_table = cpl_table_new (1);
2155 cpl_table * weight_individual_table = cpl_table_new (1);
2156 cpl_table * wave_fitted_table = cpl_table_new (1);
2159 weight_individual_table,
2169 "WAVE_INDIV_SC", wave_individual_table);
2171 "WAVE_WEIGHT_SC", weight_individual_table);
2173 "WAVE_FITTED_SC", wavedata_table);
2183 cpl_msg_info (cpl_func,
"Add WAVE_FIBRE and WAVE_DATA in wave_map");
2199 return CPL_ERROR_NONE;