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