GRAVI Pipeline Reference Manual 1.11.0
Loading...
Searching...
No Matches
gravi_disp.c
Go to the documentation of this file.
1/* $Id: gravi_disp.c,v 1.10 2012/03/23 15:10:40 nazouaoui Exp $
2 *
3 * This file is part of the GRAVI Pipeline
4 * Copyright (C) 2002,2003 European Southern Observatory
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
35
36/*
37 * History
38 * 07/12/208 add wave_param to gravi_compute_argon_pos
39 */
40/*----------------------------------------------------------------------------
41 DEBUG
42 -----------------------------------------------------------------------------*/
43
44#define INFO_DEBUG 0
45#define GRAVI_ACOEFF_RANGE 0.02
46
47/*-----------------------------------------------------------------------------
48 Includes
49 -----------------------------------------------------------------------------*/
50
51#ifdef HAVE_CONFIG_H
52#include <config.h>
53#endif
54
55#include <cpl.h>
56#include <string.h>
57#include <stdio.h>
58#include <time.h>
59#include <math.h>
60#include <complex.h>
61
62#include "gravi_data.h"
63#include "gravi_dfs.h"
64#include "gravi_pfits.h"
65#include "gravi_cpl.h"
66
67#include "gravi_utils.h"
68#include "gravi_signal.h"
69
70#include "gravi_vis.h"
71#include "gravi_disp.h"
72
73/*-----------------------------------------------------------------------------
74 Private prototypes
75 -----------------------------------------------------------------------------*/
76
77cpl_table * gravi_fit_fddl_lin (cpl_table * oiflux_table);
78
79cpl_table * gravi_fit_dispersion (cpl_table * oiflux_table,
80 cpl_table * oivis_table,
81 cpl_table * oiwave_table,
82 double * GDrms,
83 double * Amin,
84 double * Amax);
85
86/*-----------------------------------------------------------------------------
87 Functions code
88 -----------------------------------------------------------------------------*/
89
90/*----------------------------------------------------------------------------*/
111/*----------------------------------------------------------------------------*/
112
114{
116 cpl_ensure (vis_data, CPL_ERROR_NULL_INPUT, NULL);
117
118 /* Get data */
119 cpl_size ntel = 4;
120 cpl_propertylist * vis_header = gravi_data_get_header (vis_data);
121 cpl_propertylist * vis_header_extra = gravi_data_get_extra_primary_header (vis_data);
122 cpl_size npol = gravi_pfits_get_pola_num (vis_header, GRAVI_SC);
123 cpl_table * oiflux_table = gravi_data_get_oi_flux (vis_data, GRAVI_SC, 0, npol);
124 CPLCHECK_NUL ("Cannot get data");
125
126 /* Get the number of observations */
127 cpl_size nrow = cpl_table_get_nrow (oiflux_table) / ntel;
128 cpl_msg_info (cpl_func,"Input vis_data has %lld observation",nrow);
129
130 /* Check the number of observation */
131 if (nrow < 10) {
132 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
133 "Not enough observations to compute"
134 "a dispersion model. Check input SOF");
135 return NULL;
136 }
137
138 /*
139 * Create output data
140 */
141 gravi_data * disp_map = gravi_data_new (0);
142
143 /* Set the input header */
144 cpl_propertylist * disp_header = gravi_data_get_header (disp_map);
145 cpl_propertylist_append (disp_header, vis_header);
146
147 cpl_propertylist *disp_header_extra = gravi_data_get_extra_primary_header (disp_map);
148 cpl_propertylist_append (disp_header_extra, vis_header_extra);
149
150 /* Set a QC parameter with the number of observations */
151 const char * qc_name = "ESO QC DISP NEXP";
152 cpl_propertylist_update_int (disp_header, qc_name, nrow);
153 cpl_propertylist_set_comment (disp_header, qc_name, "Number of exposures used");
154
155
156 /*
157 * Compute the coefficient of FDDL linearity
158 */
159
160 cpl_table * linearity_table;
161 linearity_table = gravi_fit_fddl_lin (oiflux_table);
162 CPLCHECK_NUL ("Cannot compute the FDDL linearity");
163
164
165 /*
166 * Compute the coefficients for FDDL index dispersion
167 */
168
169 cpl_table * dispwave_table;
170 double GDrms = 0.0, Amin = 1e4, Amax = -1e4;
171
172 /* Loop on polarisations */
173 for (int pol = 0; pol < npol; pol++) {
174
175 /* Get table for this polarisation */
176 cpl_table * oiflux_table = gravi_data_get_oi_flux (vis_data, GRAVI_SC, pol, npol);
177 cpl_table * oivis_table = gravi_data_get_oi_vis (vis_data, GRAVI_SC, pol, npol);
178 cpl_table * oiwave_table = gravi_data_get_oi_wave (vis_data, GRAVI_SC, pol, npol);
179
180 /* (Re) create the column FDDLi = (FDDL_FTi + FDDL_SCi)/2 */
181 gravi_flux_create_fddllin_sc (oiflux_table, linearity_table);
182
183 /* Compute the BETA and GAMMA for each wavelength */
184 cpl_table * dispwave_table0;
185 dispwave_table0 = gravi_fit_dispersion (oiflux_table, oivis_table,
186 oiwave_table, &GDrms,
187 &Amin, &Amax);
188 CPLCHECK_NUL ("Cannot compute dispersion");
189
190 /* Co-add the two polarisation. So here we assume the wavelength
191 * table are the same for the two polarisation */
192 if (pol == 0) {
193 dispwave_table = dispwave_table0;
194 } else {
195 gravi_msg_warning ("FIXME", "Assumes same OI_WAVE for both polar of SC");
196 gravi_table_add_columns (dispwave_table, "BETA", dispwave_table0, "BETA");
197 gravi_table_multiply_scalar (dispwave_table, "BETA", 0, 1, 0.5);
198 gravi_table_add_columns (dispwave_table, "GAMMA", dispwave_table0, "GAMMA");
199 gravi_table_multiply_scalar (dispwave_table, "GAMMA", 0, 1, 0.5);
200 cpl_table_delete (dispwave_table0);
201 }
202 } /* End loop on polarisations */
203
204
205 /* Set a QC parameters */
206 qc_name = "ESO QC DISP GDELAY_RMS";
207 cpl_propertylist_update_double (disp_header, qc_name, GDrms);
208 cpl_propertylist_set_comment (disp_header, qc_name, "[m] GDELAY rms over files");
209
210 qc_name = "ESO QC DISP BETA_CORRECTION MIN";
211 cpl_propertylist_update_double (disp_header, qc_name, Amin);
212 cpl_propertylist_set_comment (disp_header, qc_name, "Fine correction");
213
214 qc_name = "ESO QC DISP BETA_CORRECTION MAX";
215 cpl_propertylist_update_double (disp_header, qc_name, Amax);
216 cpl_propertylist_set_comment (disp_header, qc_name, "Fine correction");
217
218 qc_name = "ESO QC DISP BETA_CORRECTION RANGE";
220 cpl_propertylist_set_comment (disp_header, qc_name, "Fine correction");
221
222
223 /*
224 * Interpolate BETA and GAMMA at known Argon wavelength
225 * WAVE is the position of the argon line on the current OI_WAVE
226 * WAVE_TH is the true, vaccum line wavelength
227 */
228
229 cpl_table * pos_table = gravi_data_get_table (vis_data, "POS_ARGON");
230 cpl_table * dispth_table = cpl_table_duplicate (pos_table);
231 cpl_size nline = cpl_table_get_nrow (dispth_table);
232
233 gravi_table_interpolate_column (dispth_table, "WAVE", "BETA",
234 dispwave_table, "EFF_WAVE", "BETA");
235
236 gravi_table_interpolate_column (dispth_table, "WAVE", "GAMMA",
237 dispwave_table, "EFF_WAVE", "GAMMA");
238
239 CPLCHECK_NUL ("Cannot interpolate into argon lines");
240
241 /*
242 * Compute the optical index N_MEAN and N_DIFF from BETA and GAMMA
243 * N_MEAN = BETA * WAVE_TH / LAMBDA_MET
244 * N_DIFF = GAMMA * WAVE_TH / LAMBDA_MET
245 */
246
247 cpl_table_duplicate_column (dispth_table, "N_MEAN", dispth_table, "BETA");
248 cpl_table_duplicate_column (dispth_table, "N_DIFF", dispth_table, "GAMMA");
249
250 for (cpl_size line = 0; line < nline; line++) {
251 double value = cpl_table_get (dispth_table, "WAVE_TH", line, NULL) / LAMBDA_MET;
252 cpl_array_multiply_scalar (cpl_table_get_data_array (dispth_table, "N_MEAN")[line], value);
253 cpl_array_multiply_scalar (cpl_table_get_data_array (dispth_table, "N_DIFF")[line], value);
254 }
255
256
257 /*
258 * Create the output table from the linearity table
259 */
260 cpl_table * disp_table = linearity_table;
261
262
263 /*
264 * Fit dispersion by a polynomial of order 3 and fill
265 * the output table
266 * SG 2019-08-02: increased order from 2 to 3
267 */
268
269 cpl_size mindeg = 0, maxdeg = 3;
270 gravi_table_new_column_array (disp_table, "N_MEAN", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
271 gravi_table_new_column_array (disp_table, "N_DIFF", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
272 gravi_table_new_column (disp_table, "WAVE0", "m", CPL_TYPE_DOUBLE);
273 gravi_table_new_column_array (disp_table, "BETA", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
274 gravi_table_new_column_array (disp_table, "GAMMA", NULL, CPL_TYPE_DOUBLE, maxdeg+1);
275
276 /* Allocation of the fit */
277 cpl_matrix * matrix = cpl_matrix_new (1, nline);
278 cpl_vector * vector = cpl_vector_new (nline);
279 cpl_polynomial * poly = cpl_polynomial_new (1);
280 cpl_array * coeff = cpl_array_new (maxdeg+1, CPL_TYPE_DOUBLE);
281
282 /* The axis for the 2.2e-6/wave_th - 1 */
283 double wave0 = 2.2e-6;
284 for (cpl_size line = 0; line < nline; line++) {
285 double wave_th = cpl_table_get (dispth_table, "WAVE_TH", line, NULL);
286 cpl_matrix_set (matrix, 0, line, wave0/wave_th - 1.);
287 }
288
289 for (cpl_size tel = 0; tel < ntel; tel++) {
290 cpl_table_set (disp_table, "WAVE0", tel, wave0);
291
292 /* Fit the BETA */
293 for (cpl_size line = 0; line < nline; line++)
294 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table, "BETA", line, tel));
295 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
296 for (cpl_size order = 0; order <= maxdeg; order ++)
297 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
298 cpl_table_set_array (disp_table, "BETA", tel, coeff);
299
300 /* Fit the GAMMA */
301 for (cpl_size line = 0; line < nline; line++)
302 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table, "GAMMA", line, tel));
303 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
304 for (cpl_size order = 0; order <= maxdeg; order ++)
305 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
306 cpl_table_set_array (disp_table, "GAMMA", tel, coeff);
307
308 /* Fit the N_MEAN */
309 for (cpl_size line = 0; line < nline; line++)
310 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table, "N_MEAN", line, tel));
311 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
312 for (cpl_size order = 0; order <= maxdeg; order ++)
313 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
314 cpl_table_set_array (disp_table, "N_MEAN", tel, coeff);
315
316 /* Fit the N_DIFF */
317 for (cpl_size line = 0; line < nline; line++)
318 cpl_vector_set (vector, line, gravi_table_get_value (dispth_table, "N_DIFF", line, tel));
319 cpl_polynomial_fit (poly, matrix, NULL, vector, NULL, CPL_FALSE, &mindeg, &maxdeg);
320 for (cpl_size order = 0; order <= maxdeg; order ++)
321 cpl_array_set (coeff, order, cpl_polynomial_get_coeff (poly, &order));
322 cpl_table_set_array (disp_table, "N_DIFF", tel, coeff);
323 }
324 CPLCHECK_NUL ("Cannot fit the dispersion coefficients");
325
326 FREE (cpl_vector_delete, vector);
327 FREE (cpl_matrix_delete, matrix);
328 FREE (cpl_polynomial_delete, poly);
329 FREE (cpl_array_delete, coeff);
330
331
332 /*
333 * Output data
334 */
335
336 /* Add the DISP_MODEL in the output gravi_data */
337 gravi_data_add_table (disp_map, NULL, "DISP_MODEL", disp_table);
338
339 /* Add the DISP_WAVE in the output gravi_data */
340 gravi_data_add_table (disp_map, NULL, "DISP_WAVE", dispwave_table);
341
342 /* Add the DISP_WAVETH in the output gravi_data */
343 gravi_data_add_table (disp_map, NULL, "DISP_WAVETH", dispth_table);
344
345
347 return disp_map;
348}
349
350/*----------------------------------------------------------------------------*/
362/*----------------------------------------------------------------------------*/
363
364cpl_error_code gravi_disp_cleanup (gravi_data * vis_data)
365{
367 cpl_ensure_code (vis_data, CPL_ERROR_NULL_INPUT);
368
369 cpl_size nbase = 6, ntel = 4, nclo = 4;
370
371 cpl_propertylist * header = gravi_data_get_header (vis_data);
372 cpl_size npol_sc = gravi_pfits_get_pola_num (header, GRAVI_SC);
373 cpl_size npol_ft = gravi_pfits_get_pola_num (header, GRAVI_FT);
374
375 /* Get one FT OI_VIS table */
376 cpl_table * oivis_table = gravi_data_get_oi_vis (vis_data, GRAVI_FT, 0, npol_ft);
377 cpl_table * oiflux_table = gravi_data_get_oi_flux (vis_data, GRAVI_SC, 0, npol_sc);
378 cpl_size nrow = cpl_table_get_nrow (oivis_table) / nbase;
379
380 /* Rejection flag (1 = rejected) */
381 cpl_array * flag_array = cpl_array_new (nrow, CPL_TYPE_INT);
382 cpl_array_fill_window (flag_array, 0, nrow, 0);
383
384 /*
385 * Verify the visibility amplitude
386 */
387
388 for (cpl_size row = 0; row < nrow; row++) {
389 for (cpl_size base = 0; base < nbase; base++) {
390 cpl_size id = row * nbase + base;
391 double vis = cpl_array_get_median (cpl_table_get_array (oivis_table, "VISAMP", id));
392 cpl_msg_debug ("TEST", "vis = %g", vis);
393 if ( vis < 0.35) cpl_array_set (flag_array, row, 1);
394 }
395 }
396 CPLCHECK_MSG ("Cannot compute flag_array");
397
398 /*
399 * Flag on lockdate LKDT
400 */
401
402 /* Get longuest sequence */
403 cpl_size first = 0, nobs = 0;
404 gravi_lkdt_get_sequence (oiflux_table, 4, &first, &nobs);
405
406 /* Flag all observations outside this sequence */
407 for (cpl_size row = 0; row < nrow; row++) {
408 if (row < first || row >= first+nobs)
409 cpl_array_set (flag_array, row, 1);
410 }
411
412 if (nobs != nrow) {
413 cpl_msg_warning (cpl_func, "LKDT not stable over all files "
414 "(keep %lld over %lld)", nobs, nrow);
415 } else {
416 cpl_msg_info (cpl_func, "LKDT stable over all files");
417 }
418
419 /*
420 * Cleanup all tables with this flag_array (rejection flag)
421 */
422
423 for (int type_data = 0; type_data < 2; type_data ++) {
424 cpl_size npol = gravi_pfits_get_pola_num (header, type_data);
425 for (int pol = 0; pol < npol; pol ++) {
426 gravi_vis_erase_obs (gravi_data_get_oi_flux (vis_data, type_data, pol, npol), flag_array, ntel);
427 gravi_vis_erase_obs (gravi_data_get_oi_vis (vis_data, type_data, pol, npol), flag_array, nbase);
428 gravi_vis_erase_obs (gravi_data_get_oi_vis2 (vis_data, type_data, pol, npol), flag_array, nbase);
429 gravi_vis_erase_obs (gravi_data_get_oi_t3 (vis_data, type_data, pol, npol), flag_array, nclo);
430 CPLCHECK_MSG ("Cannot erase flagged observations");
431 }
432 }
433 FREE (cpl_array_delete, flag_array);
434
435 /* Verbose */
436 cpl_size nrow_new = cpl_table_get_nrow (oivis_table) / nbase;
437 cpl_msg_info (cpl_func, "Initial data had %lld obs, now %lld", nrow, nrow_new);
438
440 return CPL_ERROR_NONE;
441}
442
443/*----------------------------------------------------------------------------*/
466/*----------------------------------------------------------------------------*/
467
468cpl_table * gravi_fit_fddl_lin (cpl_table * oiflux_table)
469{
471 cpl_ensure (oiflux_table, CPL_ERROR_NULL_INPUT, NULL);
472
473 cpl_size ntel = 4, nbase = 6;
474 cpl_size nrow = cpl_table_get_nrow (oiflux_table) / ntel;
475
476 /* Model and right-hand-side for the lineary system */
477 cpl_matrix * rhs_matrix = cpl_matrix_new (nrow * nbase, 1);
478 cpl_matrix * model_matrix = cpl_matrix_new (nrow * nbase, nbase + 4 * ntel);
479
480 for (int base = 0; base < nbase; base++) {
481 int i = GRAVI_BASE_TEL[base][0];
482 int j = GRAVI_BASE_TEL[base][1];
483
484 for (cpl_size row=0; row<nrow; row++) {
485 int id = row * nbase + base;
486 int idi = row * ntel + i;
487 int idj = row * ntel + j;
488
489 /* Fill the MET [um] */
490 double meti = cpl_table_get (oiflux_table, "OPD_MET_FC", idi, NULL);
491 double metj = cpl_table_get (oiflux_table, "OPD_MET_FC", idj, NULL);
492 cpl_matrix_set (rhs_matrix, id, 0, (meti - metj)*1e6);
493
494 /* Fill the model Aij (unfilled matrix are 0.0) */
495 cpl_matrix_set (model_matrix, id, base, 1.0);
496
497 /* Fill the model Bi, Bj, Ci, Cj */
498 double ft_posi = cpl_table_get (oiflux_table, "FT_POS", idi, NULL);
499 double ft_posj = cpl_table_get (oiflux_table, "FT_POS", idj, NULL);
500 cpl_matrix_set (model_matrix, id, 6 +i, ft_posi);
501 cpl_matrix_set (model_matrix, id, 6 +j, -1*ft_posj);
502 cpl_matrix_set (model_matrix, id, 10+i, ft_posi*ft_posi);
503 cpl_matrix_set (model_matrix, id, 10+j, -1*ft_posj*ft_posj);
504
505 /* Fill the model Di, Dj, Ei, Ej */
506 double sc_posi = cpl_table_get (oiflux_table, "SC_POS", idi, NULL);
507 double sc_posj = cpl_table_get (oiflux_table, "SC_POS", idj, NULL);
508 cpl_matrix_set (model_matrix, id, 14+i, -1*sc_posi);
509 cpl_matrix_set (model_matrix, id, 14+j, sc_posj);
510 cpl_matrix_set (model_matrix, id, 18+i, -1*sc_posi*sc_posi);
511 cpl_matrix_set (model_matrix, id, 18+j, sc_posj*sc_posj);
512 } /* End loop on rows */
513 } /* End loop on bases */
514
515 /* Solve the system */
516 cpl_matrix * res_matrix = cpl_matrix_solve_normal (model_matrix, rhs_matrix);
517 FREE (cpl_matrix_delete, model_matrix);
518 FREE (cpl_matrix_delete, rhs_matrix);
519
520
521 /*
522 * Fill the linearity coefficients in the output table
523 */
524 cpl_table * lin_table = cpl_table_new (ntel);
525 gravi_table_new_column_array (lin_table, "LIN_FDDL_SC", "um/V^i", CPL_TYPE_DOUBLE, 3);
526 gravi_table_new_column_array (lin_table, "LIN_FDDL_FT", "um/V^i", CPL_TYPE_DOUBLE, 3);
527
528 cpl_array * coeff = cpl_array_new (3, CPL_TYPE_DOUBLE);
529 for (cpl_size tel = 0; tel < ntel; tel++) {
530 cpl_array_set (coeff, 0, 0);
531 cpl_array_set (coeff, 1, cpl_matrix_get (res_matrix, 6 +tel, 0));
532 cpl_array_set (coeff, 2, cpl_matrix_get (res_matrix, 10+tel, 0));
533 cpl_table_set_array (lin_table, "LIN_FDDL_FT", tel, coeff);
534 cpl_array_set (coeff, 0, 0);
535 cpl_array_set (coeff, 1, cpl_matrix_get (res_matrix, 14+tel, 0));
536 cpl_array_set (coeff, 2, cpl_matrix_get (res_matrix, 18+tel, 0));
537 cpl_table_set_array (lin_table, "LIN_FDDL_SC", tel, coeff);
538 CPLCHECK_NUL ("Cannot set dispersion coeff");
539 }
540
541 /* Free results */
542 FREE (cpl_matrix_delete, res_matrix);
543 FREE (cpl_array_delete, coeff);
544
546 return lin_table;
547}
548
549/*----------------------------------------------------------------------------*/
587/*----------------------------------------------------------------------------*/
588
589cpl_table * gravi_fit_dispersion (cpl_table * oiflux_table,
590 cpl_table * oivis_table,
591 cpl_table * oiwave_table,
592 double * GDrms,
593 double * Amin,
594 double * Amax)
595{
597 cpl_ensure (oiflux_table, CPL_ERROR_NULL_INPUT, NULL);
598 cpl_ensure (oivis_table, CPL_ERROR_NULL_INPUT, NULL);
599 cpl_ensure (oiwave_table, CPL_ERROR_NULL_INPUT, NULL);
600
601 cpl_size nbase = 6, ntel = 4;
602 cpl_size nrow = cpl_table_get_nrow (oiflux_table) / 4;
603 cpl_size nwave = cpl_table_get_column_depth (oiflux_table, "FLUXDATA");
604 CPLCHECK_NUL ("Cannot get data");
605
606 /*
607 * Compute a guess of the BETA dispersion coefficient
608 */
609 double beta0 = 0.8651, beta1 = 0.8814;
610
611 cpl_table_new_column (oiwave_table, "BETA", CPL_TYPE_DOUBLE);
612 for (cpl_size wave = 0; wave < nwave; wave ++) {
613 double lbd = cpl_table_get (oiwave_table, "EFF_WAVE", wave, NULL);
614 double beta = beta0 + beta1 * (2.2e-6/lbd - 1.0);
615 cpl_table_set (oiwave_table, "BETA", wave, beta);
616 }
617 CPLCHECK_NUL ("Cannot create BETA column");
618
619 /* Get direct pointer to data */
620 double * metdata = cpl_table_get_data_double (oivis_table, "OPD_MET_FC");
621 double complex ** visdata = gravi_table_get_data_array_double_complex (oivis_table, "VISDATA");
622 double * beta = cpl_table_get_data_double (oiwave_table, "BETA");
623 float * effwave = cpl_table_get_data_float (oiwave_table, "EFF_WAVE");
624 CPLCHECK_NUL ("Cannot get data");
625
626
627 /*
628 * Correction par la metrologie (Correction # 1)
629 * VIS_ijlt *= exp (-2ipi * BETA_l * METC_ijt / LAMBDA_MET)
630 */
631 cpl_msg_info (cpl_func, "Correction #1");
632
633 /* Loop on base, rows and wave */
634 for (cpl_size base = 0; base < nbase ; base ++) {
635 for (cpl_size row = 0; row < nrow ; row ++) {
636 int id = row * nbase + base;
637 for (cpl_size wave = 0; wave < nwave; wave ++) {
638 visdata[id][wave] *= cexp (- 2*I*CPL_MATH_PI * beta[wave] * metdata[id] / LAMBDA_MET);
639 }
640 }
641 }
642
643
644 /*
645 * Correction par le groupe delay (Correction # 2)
646 * VIS_ijlt *= exp (-2ipi * GD_ij / LBD_l)
647 * with GD_ij = <GD_ijt>
648 */
649 cpl_msg_info (cpl_func, "Correction #2");
650
651 /* Compute the GD of all base and rows (with wavelength in glass) */
652 gravi_table_compute_group_delay (oivis_table, "VISDATA", "FLAG", "GDELAY", oiwave_table);
653
654 /* Allocate memory for result */
655 cpl_vector * GDb = cpl_vector_new (nbase);
656
657 for (cpl_size base = 0; base < nbase ; base ++) {
658 double mean = gravi_table_get_column_mean (oivis_table, "GDELAY", base, nbase);
659 double std = gravi_table_get_column_std (oivis_table, "GDELAY", base, nbase);
660 cpl_vector_set (GDb, base, mean);
661
662 /* Correct from the mean group-delay */
663 for (cpl_size row = 0; row < nrow ; row ++) {
664 int id = row * nbase + base;
665 for (cpl_size wave = 0; wave < nwave; wave ++) {
666 visdata[id][wave] *= cexp (-2*I*CPL_MATH_PI * mean / effwave[wave]);
667 }
668 }
669
670 cpl_msg_info (cpl_func, "GD mean = %g [um]", mean*1e6);
671 cpl_msg_info (cpl_func, "GD std = %g [um]", std*1e6);
672
673 /* Save the overall worst value of GD rms */
674 *GDrms = CPL_MAX (std, *GDrms);
675 }
676
677
678 /*
679 * Correction from the residual slope versus met (Correction # 3)
680 * VIS_ijlt *= exp (-2ipi * A_bl * METC_ijt / LAMBDA_MET)
681 *
682 * Where A_bl is computed such that the following is maximum:
683 * | Sum_t[ VIS_ijlt * exp (-2ipi * A_bl * METC_ijt / LAMBDA_MET) ] |
684 *
685 * Hence the A value is a BETA coefficient fine correction.
686 */
687 cpl_msg_info (cpl_func, "Correction #3");
688
689 /* Allocate memory for force-brut exploration of A values */
690 cpl_size nA = 1000;
691 double complex * phasor = cpl_calloc (nrow * nA, sizeof (double complex));
692 // cpl_vector * plot_vector = cpl_vector_new (nA);
693
694 /* Allocate memory for results */
695 cpl_matrix * Abl = cpl_matrix_new (nbase, nwave);
696
697 /* Loop on base and wave */
698 for (cpl_size base = 0; base < nbase ; base ++) {
699 for (cpl_size wave = 0; wave < nwave ; wave ++) {
700
701 /* Test various possible A value */
702 cpl_size iAmax;
703 double maxV = 0.0;
704 for (cpl_size iA = 0; iA < nA; iA++) {
705 double A = GRAVI_ACOEFF_RANGE * (2.* iA / nA - 1.0);
706
707 /* Accumulate the re-phased complex Note that we
708 * compute the exp(i.a.METbm) only if needed */
709 double complex currentV = 0.0;
710 for (cpl_size row = 0; row < nrow; row++) {
711 if (wave==0) phasor[row*nA+iA] = cexp (-2.* CPL_MATH_PI * I * A *
712 metdata[row*nbase+base] /
713 LAMBDA_MET);
714 currentV += phasor[row*nA+iA] * visdata[row*nbase+base][wave];
715 }
716
717 // if (base == 0 && wave == 1700) cpl_vector_set (plot_vector, iA, cabs (currentV));
718
719 /* Check if better fit */
720 if (cabs (currentV) > maxV) {
721 cpl_matrix_set (Abl, base, wave, A);
722 iAmax = iA;
723 maxV = cabs (currentV);
724 }
725 }/* End exploration in A values */
726
727 /* Correct the visdata of this base and wave
728 * from the best-fit A value */
729 for (cpl_size row = 0; row < nrow; row++) {
730 visdata[row*nbase+base][wave] *= phasor[row*nA+iAmax];
731 }
732
733 }
734 } /* End loop on base and wave */
735 FREE (cpl_free, phasor);
736
737 /* Some verbose */
738 cpl_msg_info (cpl_func, "Abl range = %g (beta correction)",
740 cpl_msg_info (cpl_func, "Abl mean = %g (beta correction)",
741 cpl_matrix_get_mean (Abl));
742 cpl_msg_info (cpl_func, "Abl std = %g (beta correction)",
743 cpl_matrix_get_stdev (Abl));
744
745 *Amax = CPL_MAX (*Amax, cpl_matrix_get_max (Abl));
746 *Amin = CPL_MIN (*Amin, cpl_matrix_get_min (Abl));
747
748
749 // cpl_plot_vector (NULL, NULL, NULL, plot_vector);
750 // FREE (cpl_vector_delete, plot_vector);
751
752
753 /*
754 * Remove the mean phase over the rows (Correction # 4)
755 * VIS_ijlt *= exp (-i*O_ijl)
756 * with O_ijl = arg (<VIS_ijlt>)
757 */
758 cpl_msg_info (cpl_func, "Correction #4");
759
760 /* Allocate memory for results */
761 cpl_matrix * Obl = cpl_matrix_new (nbase, nwave);
762
763 /* Loop on base and wave */
764 for (cpl_size base = 0; base < nbase ; base ++) {
765 for (cpl_size wave = 0; wave < nwave ; wave ++) {
766
767 /* Compute the mean phase */
768 double complex currentV = 0.0;
769 for (cpl_size row = 0; row < nrow; row++) {
770 currentV += visdata[row*nbase+base][wave];
771 }
772 cpl_matrix_set (Obl, base, wave, carg (currentV));
773
774 /* Correct the visdata of this base and wave
775 * from this mean phase */
776 for (cpl_size row = 0; row < nrow; row++) {
777 visdata[row*nbase+base][wave] *= conj (currentV);
778 }
779 }
780 } /* End loop on base and wave */
781
782
783
784 /*
785 * Search for 6Aij + 4Bi + 4Ci solving the linear system:
786 * PHASEijt * LAMBDA_MET / 2pi = Aij + Ci (FDDL_FTit + FDDL_SCit)/2
787 * - Cj (FDDL_FTjt + FDDL_SCjt)/2
788 * + Bi METit - Bj METjt
789 * for all wavelength and both polaristions
790 */
791 cpl_msg_info (cpl_func, "Fit dispersion model");
792
793 /* Output of all wavelenths */
794 cpl_matrix * disp_fits = cpl_matrix_new (nbase + ntel * 2, nwave);
795 cpl_matrix * residuals_fits = cpl_matrix_new (nrow*nbase, nwave);
796
797 /* Model and right-hand-side for the lineary system (unfilled matrix are 0.0) */
798 cpl_matrix * rhs_matrix = cpl_matrix_new (nrow * nbase, 1);
799 cpl_matrix * model_matrix = cpl_matrix_new (nrow * nbase, nbase + ntel * 2);
800
801 for (cpl_size wave = 0; wave < nwave; wave ++) {
802
803 for (int base = 0; base < nbase; base++) {
804 int i = GRAVI_BASE_TEL[base][0];
805 int j = GRAVI_BASE_TEL[base][1];
806
807 for (cpl_size row=0; row<nrow; row++) {
808 int id = row * nbase + base;
809 int idi = row * ntel + i;
810 int idj = row * ntel + j;
811
812 /* Fill with unwrap phases from all the corrections
813 * PHIblt = angle(visdata) + Obl + 2pi*Abl*METbt*Abl/LBD_l
814 * 2pi*GDb/LBD_l + 2pi*beta_l*METbt/LAMBDA_MET */
815 double phi = carg (visdata[id][wave]);
816 phi += cpl_matrix_get (Obl, base, wave);
817 phi += CPL_MATH_2PI * cpl_matrix_get (Abl, base, wave) * metdata[id] / LAMBDA_MET;
818 phi += CPL_MATH_2PI * cpl_vector_get (GDb, base) / effwave[wave];
819 phi += CPL_MATH_2PI * beta[wave] * metdata[id] / LAMBDA_MET;
820 cpl_matrix_set (rhs_matrix, id, 0, phi * LAMBDA_MET / CPL_MATH_2PI);
821
822 /* Fill the model Aij (unfilled matrix are 0.0) */
823 cpl_matrix_set (model_matrix, id, base, 1);
824
825 /* Fill the model GAMMAi, GAMMAj */
826 double fddli = cpl_table_get (oiflux_table, "FDDL", idi, NULL);
827 double fddlj = cpl_table_get (oiflux_table, "FDDL", idj, NULL);
828 cpl_matrix_set (model_matrix, id, 6+i, fddli);
829 cpl_matrix_set (model_matrix, id, 6+j, -1*fddlj);
830
831 /* Fill the model BETAi, BETAj */
832 double meti = cpl_table_get (oiflux_table, "OPD_MET_FC", idi, NULL);
833 double metj = cpl_table_get (oiflux_table, "OPD_MET_FC", idj, NULL);
834 cpl_matrix_set (model_matrix, id, 10+i, meti);
835 cpl_matrix_set (model_matrix, id, 10+j, -1*metj);
836 } /* End loop on rows */
837 } /* End loop on bases */
838
839 /* Solve the system */
840 cpl_matrix * res_matrix = cpl_matrix_solve_normal (model_matrix, rhs_matrix);
841
842 /* Compute the residuals */
843 cpl_matrix * residual_matrix = cpl_matrix_product_create ( model_matrix, res_matrix);
844 cpl_matrix_subtract(residual_matrix, rhs_matrix);
845
846 /* Save result in disp_fits */
847 for (cpl_size param = 0; param < nbase + ntel * 2; param++)
848 cpl_matrix_set (disp_fits, param, wave, cpl_matrix_get (res_matrix,param,0));
849 for (cpl_size param = 0; param < nrow * nbase; param++)
850 cpl_matrix_set (residuals_fits, param, wave, cpl_matrix_get (residual_matrix,param,0));
851 FREE (cpl_matrix_delete, res_matrix);
852 FREE (cpl_matrix_delete, residual_matrix);
853
854 } /* End loop on waves */
855 FREE (cpl_matrix_delete, model_matrix);
856 FREE (cpl_matrix_delete, rhs_matrix);
857
858 /* Delete pointer to data */
859 FREE (cpl_free, visdata);
860 // FREE (cpl_table_delete, oiwavefb_table);
861
862 /* Delete corrections */
863 FREE (cpl_vector_delete, GDb);
864 FREE (cpl_matrix_delete, Abl);
865 FREE (cpl_matrix_delete, Obl);
866
867
868 /* Convert the result into DISP_WAVE table,
869 * inspired from OI_WAVE */
870 cpl_table * dispwave_table = cpl_table_duplicate (oiwave_table);
871
872 /* Add the BETA and GAMMA columns */
873 gravi_table_init_column_array (dispwave_table, "BETA", NULL, CPL_TYPE_DOUBLE, ntel);
874 gravi_table_init_column_array (dispwave_table, "GAMMA", NULL, CPL_TYPE_DOUBLE, ntel);
875 gravi_table_init_column_array (dispwave_table, "RESIDUALS", NULL, CPL_TYPE_DOUBLE, nbase*nrow);
876
877 /* Fill the BETA and GAMMA columns */
878 for (cpl_size tel = 0; tel < ntel; tel++) {
879 for (cpl_size wave = 0; wave < nwave; wave ++) {
880 gravi_table_set_value (dispwave_table,"BETA",wave,tel,
881 cpl_matrix_get (disp_fits, 10+tel, wave));
882 gravi_table_set_value (dispwave_table,"GAMMA",wave,tel,
883 cpl_matrix_get (disp_fits, 6+tel, wave));
884 CPLCHECK_NUL ("Cannot fill the dispwave_table");
885 }
886 }
887
888 /* Fill the RESIDUALS columns */
889 for (cpl_size tel = 0; tel < nrow * nbase; tel++) {
890 for (cpl_size wave = 0; wave < nwave; wave ++) {
891 gravi_table_set_value (dispwave_table,"RESIDUALS",wave,tel,
892 cpl_matrix_get (residuals_fits, tel, wave));
893 CPLCHECK_NUL ("Cannot fill the dispwave_table");
894 }
895 }
896
897 /* Delete the matrix */
898 FREE (cpl_matrix_delete, disp_fits);
899 FREE (cpl_matrix_delete, residuals_fits);
900
902 return dispwave_table;
903}
904
905/*----------------------------------------------------------------------------*/
920/*----------------------------------------------------------------------------*/
921
922cpl_error_code gravi_compute_argon_pos (gravi_data * preproc_data, gravi_data *wave_param)
923{
925 cpl_ensure_code (preproc_data, CPL_ERROR_NULL_INPUT);
926
927 /* Get data */
928 cpl_table * spectrum_table = gravi_data_get_spectrum_data (preproc_data, GRAVI_SC);
929 cpl_size n_region = gravi_spectrum_get_nregion (spectrum_table);
930 cpl_size npol = gravi_spectrum_get_npol (spectrum_table);
931 cpl_size nwave = gravi_spectrum_get_nwave (spectrum_table);
932 CPLCHECK_MSG ("Cannot get data");
933
934 /* Get the OI_WAVE */
935 gravi_msg_warning ("FIXME", "Assumes same OI_WAVE for both polar of SC");
936 cpl_table * oi_wave = gravi_data_get_oi_wave (preproc_data, GRAVI_SC, 0, npol);
937
938 /* Ensure */
939 cpl_ensure_code (spectrum_table, CPL_ERROR_ILLEGAL_INPUT);
940 cpl_ensure_code (oi_wave, CPL_ERROR_ILLEGAL_INPUT);
941
942 /*
943 * Compute the mean of all the spectra of the argon
944 */
945
946 const cpl_array * array_data;
947 cpl_array * argon = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
948 cpl_array_fill_window (argon, 0, nwave, 0.0);
949
950 /* Loop region */
951 for (cpl_size region = 0; region < n_region; region ++) {
952 array_data = cpl_table_get_array (spectrum_table, GRAVI_DATA[region], 0);
953 cpl_array_add (argon, array_data);
954 }
955
956 cpl_array_divide_scalar (argon, n_region);
957
958 /*
959 * Wavelengths of the argon emission lines [m]
960 */
961 double *line_wave;
962 int nlines;
963
964 cpl_table * line_wave_table = gravi_data_get_table (wave_param, "ARGON_TAB");
965 if ( cpl_table_has_column (line_wave_table , "ARGON_LINES") ) {
966
967 line_wave = cpl_table_get_data_double (line_wave_table, "ARGON_LINES");
968 nlines = cpl_table_get_nrow (line_wave_table);
969
970 cpl_msg_info (cpl_func,"line_wave [0] : %e", line_wave[0]);
971 cpl_msg_info (cpl_func,"line_wave [1] : %e", line_wave[1]);
972 cpl_msg_info (cpl_func,"line_wave [2] : %e", line_wave[2]);
973 cpl_msg_info (cpl_func,"line_wave [3] : %e", line_wave[3]);
974 cpl_msg_info (cpl_func,"line_wave [4] : %e", line_wave[4]);
975 cpl_msg_info (cpl_func,"line_wave [5] : %e", line_wave[5]);
976 cpl_msg_info (cpl_func,"line_wave [6] : %e", line_wave[6]);
977 cpl_msg_info (cpl_func,"line_wave [7] : %e", line_wave[7]);
978 cpl_msg_info (cpl_func,"line_wave [8] : %e", line_wave[8]);
979 cpl_msg_info (cpl_func,"line_wave [9] : %e", line_wave[9]);
980 cpl_msg_info (cpl_func,"nlines : %d", nlines);
981 }
982 else {
983 /* We cannot continue without line information */
984 cpl_msg_error(cpl_func,"Cannot get the default values for Argon line_wave");
985 return CPL_ERROR_ILLEGAL_INPUT;
986 }
987
988 /*
989 * Fit the position of each emission line
990 */
991
992 /* Number of pixels to fit around the line */
993 int fitwidth = nwave > 500 ? 10 : 3;
994 int nfitwidth = fitwidth * 2;
995
996 /* Create output tables */
997 cpl_table * outTable = cpl_table_new (nlines);
998 gravi_table_new_column (outTable, "WAVE_TH", "m", CPL_TYPE_DOUBLE);
999 gravi_table_new_column (outTable, "WAVE", "m", CPL_TYPE_DOUBLE);
1000 gravi_table_new_column (outTable, "SIGMA", "m", CPL_TYPE_DOUBLE);
1001 gravi_table_new_column (outTable, "DIFF", "m", CPL_TYPE_DOUBLE);
1002 gravi_table_new_column (outTable, "DIFF_PIX", "pix", CPL_TYPE_DOUBLE);
1003 gravi_table_new_column_array (outTable, "DATA_MEAN", "adu", CPL_TYPE_DOUBLE, nfitwidth);
1004
1005 /* Allocate vector to extract only sub-part of spectrum */
1006 cpl_vector * vector_x = cpl_vector_new (nfitwidth);
1007 cpl_vector * vector_y = cpl_vector_new (nfitwidth);
1008
1009 for (cpl_size list = 0; list < nlines; list ++) {
1010
1011 /* Expected position */
1012 double waveI = line_wave[list];
1013
1014 /* Expected position in integer [pix] */
1015 cpl_size pixI = 0;
1016 while ( cpl_table_get (oi_wave, "EFF_WAVE", pixI, NULL) < waveI) {
1017 CPLCHECK_MSG ("Cannot get the expected position");
1018 pixI++;
1019 }
1020
1021 /* Fill the extracted sub-vector */
1022 for (cpl_size i = 0; i < nfitwidth; i++) {
1023 cpl_size w = pixI - fitwidth + i;
1024 cpl_vector_set (vector_x, i, cpl_table_get (oi_wave, "EFF_WAVE", w, NULL));
1025 cpl_vector_set (vector_y, i, cpl_array_get (argon, w, NULL));
1026 }
1027
1028 /* Fit Gaussian */
1029 cpl_errorstate prestate = cpl_errorstate_get();
1030 double w0 = waveI, sigma, area, offset, mse;
1031 cpl_vector_fit_gaussian (vector_x, NULL, vector_y, NULL,
1032 CPL_FIT_ALL, &w0, &sigma, &area,
1033 &offset, &mse, NULL, NULL);
1034
1035 if (cpl_error_get_code() == CPL_ERROR_CONTINUE){
1036 cpl_errorstate_set (prestate);
1037 cpl_msg_warning(cpl_func, "The gaussian fit did not converge");
1038 cpl_vector_multiply (vector_x, vector_y);
1039 w0 = cpl_vector_get_mean (vector_x) /
1040 cpl_vector_get_mean (vector_y);
1041 sigma = 100.0;
1042 }
1043
1044 /* compute difference in [m] and [pix] */
1045 double diff = w0 - waveI;
1046 double scale = (cpl_vector_get_max (vector_x) - cpl_vector_get_min (vector_x)) / (nfitwidth - 1);
1047 double diff_pix = diff / scale;
1048
1049 /* Print results */
1050 cpl_msg_info (cpl_func,"Argon line %lld: %.3g [nm] %.3g [pix] (over %i)",
1051 list, 1e9*diff, diff_pix, fitwidth);
1052
1053 /* Set the result */
1054 cpl_table_set (outTable, "WAVE_TH", list, waveI);
1055 cpl_table_set (outTable, "WAVE", list, w0);
1056 cpl_table_set (outTable, "SIGMA", list, sigma);
1057 cpl_table_set (outTable, "DIFF", list, diff);
1058 cpl_table_set (outTable, "DIFF_PIX", list, diff_pix);
1059
1060 /* Set the extracted part of spectrum for this line */
1061 cpl_array * tmp_array = cpl_array_wrap_double (cpl_vector_get_data (vector_y), nfitwidth);
1062 cpl_table_set_array (outTable, "DATA_MEAN", list, tmp_array);
1063 FREE (cpl_array_unwrap, tmp_array);
1064
1065 CPLCHECK_MSG ("Error during the computation");
1066 } /* End loop on list of lines */
1067
1068 /* Delete vector extraction */
1069 FREE (cpl_vector_delete, vector_y);
1070 FREE (cpl_vector_delete, vector_x);
1071 FREE (cpl_array_delete, argon);
1072
1073 /*
1074 * Compute RMS of difference
1075 */
1076 cpl_msg_info (cpl_func, "MIN=%e MAX=%e RMS=%e [nm]",
1077 cpl_table_get_column_min (outTable, "DIFF") * 1e9,
1078 cpl_table_get_column_max (outTable, "DIFF") * 1e9,
1079 cpl_table_get_column_stdev (outTable, "DIFF") * 1e9);
1080
1081 /* Set the table in gravi_data */
1082 gravi_data_add_table (preproc_data, NULL, "POS_ARGON", outTable);
1083
1085 return CPL_ERROR_NONE;
1086}
1087
1088
1089/*----------------------------------------------------------------------------*/
1090
1091
#define gravi_table_set_value(table, name, row, value, val)
Definition gravi_cpl.h:50
#define gravi_table_get_value(table, name, row, value)
Definition gravi_cpl.h:49
typedefCPL_BEGIN_DECLS struct _gravi_data_ gravi_data
Definition gravi_data.h:39
#define gravi_data_get_spectrum_data(data, type)
Definition gravi_data.h:63
#define gravi_data_get_oi_t3(data, type, pol, npol)
Definition gravi_data.h:48
#define gravi_data_get_oi_flux(data, type, pol, npol)
Definition gravi_data.h:49
#define gravi_data_get_header(data)
Definition gravi_data.h:75
#define gravi_data_get_oi_vis2(data, type, pol, npol)
Definition gravi_data.h:47
#define gravi_data_get_oi_wave(data, type, pol, npol)
Definition gravi_data.h:45
#define gravi_data_get_oi_vis(data, type, pol, npol)
Definition gravi_data.h:46
const cpl_size ntel
cpl_msg_debug(cpl_func, "Spectra has <50 pixels -> don't flat")
cpl_propertylist * header
Definition gravi_old.c:2004
cpl_msg_info(cpl_func, "Compute WAVE_SCAN for %s", GRAVI_TYPE(type_data))
cpl_propertylist_update_double(header, "ESO QC MINWAVE SC", cpl_propertylist_get_double(plist, "ESO QC MINWAVE SC"))
#define GRAVI_SC
#define LAMBDA_MET
#define GRAVI_FT
#define gravi_spectrum_get_npol(table)
Definition gravi_utils.h:92
#define gravi_msg_function_exit(flag)
Definition gravi_utils.h:85
#define FREE(function, variable)
Definition gravi_utils.h:69
#define CPLCHECK_NUL(msg)
Definition gravi_utils.h:48
#define gravi_msg_function_start(flag)
Definition gravi_utils.h:84
#define CPLCHECK_MSG(msg)
Definition gravi_utils.h:45
cpl_error_code gravi_table_add_columns(cpl_table *oi_vis1, const char *name1, cpl_table *oi_vis2, const char *name2)
Definition gravi_cpl.c:839
double gravi_table_get_column_mean(cpl_table *table, const char *name, int base, int nbase)
Definition gravi_cpl.c:342
cpl_error_code gravi_table_new_column(cpl_table *table, const char *name, const char *unit, cpl_type type)
Definition gravi_cpl.c:1655
double complex ** gravi_table_get_data_array_double_complex(cpl_table *table, const char *name)
Definition gravi_cpl.c:545
cpl_error_code gravi_table_compute_group_delay(cpl_table *table, const char *input, const char *flag, const char *output, cpl_table *oi_wave)
Definition gravi_cpl.c:1534
cpl_error_code gravi_table_init_column_array(cpl_table *table, const char *name, const char *unit, cpl_type type, cpl_size size)
Definition gravi_cpl.c:1691
double gravi_table_get_column_std(cpl_table *table, const char *name, int base, int nbase)
Definition gravi_cpl.c:387
cpl_error_code gravi_table_multiply_scalar(cpl_table *table, const char *name, int base, int nbase, double value)
Multiply scalar or array column by scalar.
Definition gravi_cpl.c:2765
cpl_error_code gravi_table_interpolate_column(cpl_table *to_table, const char *to_x, const char *to_y, const cpl_table *from_table, const char *from_x, const char *from_y)
Definition gravi_cpl.c:121
cpl_error_code gravi_table_new_column_array(cpl_table *table, const char *name, const char *unit, cpl_type type, cpl_size size)
Definition gravi_cpl.c:1677
cpl_propertylist * gravi_data_get_extra_primary_header(gravi_data *self)
Get the propertylist for additional keywords to the primary header.
gravi_data * gravi_data_new(int nb_ext)
Create an empty gravi_data.
Definition gravi_data.c:110
cpl_error_code gravi_data_add_table(gravi_data *self, cpl_propertylist *plist, const char *extname, cpl_table *table)
Add a BINTABLE extension in gravi_data.
cpl_table * gravi_data_get_table(gravi_data *self, const char *extname)
Return a pointer on a table extension by its EXTNAME.
gravi_data * gravi_compute_disp(gravi_data *vis_data)
Compute the DISP_MODEL calibration map.
Definition gravi_disp.c:113
cpl_error_code gravi_disp_cleanup(gravi_data *vis_data)
Cleanup a VIS gravi_data before calibrating the dispersion.
Definition gravi_disp.c:364
cpl_table * gravi_fit_fddl_lin(cpl_table *oiflux_table)
Compute the linearity coefficient of FDDLs.
Definition gravi_disp.c:468
cpl_table * gravi_fit_dispersion(cpl_table *oiflux_table, cpl_table *oivis_table, cpl_table *oiwave_table, double *GDrms, double *Amin, double *Amax)
Compute the dispersion coefficient of FDDLs.
Definition gravi_disp.c:589
cpl_error_code gravi_compute_argon_pos(gravi_data *preproc_data, gravi_data *wave_param)
Compute position of argon lines in SC spectrum.
Definition gravi_disp.c:922
#define GRAVI_ACOEFF_RANGE
Definition gravi_disp.c:45
int gravi_pfits_get_pola_num(const cpl_propertylist *plist, int type_data)
cpl_error_code gravi_flux_create_fddllin_sc(cpl_table *flux_SC, cpl_table *disp_table)
Compute the (FDDL_SC + FDDL_FT)/2 position in [m].
cpl_error_code gravi_msg_warning(const char *component, const char *msg)
cpl_size gravi_spectrum_get_nwave(const cpl_table *table)
char GRAVI_DATA[50][7]
Definition gravi_utils.c:71
cpl_error_code gravi_lkdt_get_sequence(cpl_table *oi_table, cpl_size ntel, cpl_size *first, cpl_size *nobs)
Return the longuest sequence with constant LKDT.
cpl_size gravi_spectrum_get_nregion(const cpl_table *table)
int GRAVI_BASE_TEL[GRAVI_NBASE][2]
Definition gravi_utils.c:56
cpl_error_code gravi_vis_erase_obs(cpl_table *oi_table, cpl_array *flag_array, cpl_size ntel)
Erase observation from an OIFITS table.
Definition gravi_vis.c:4015