GRAVI Pipeline Reference Manual 1.8.0
Loading...
Searching...
No Matches
gravi_cpl.c
Go to the documentation of this file.
1/* $Id: gravi_cpl.c,v 1.10 2014/11/12 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
31/*-----------------------------------------------------------------------------
32 Includes
33 -----------------------------------------------------------------------------*/
34
35#ifdef HAVE_CONFIG_H
36#include <config.h>
37#endif
38
39#include <cpl.h>
40#include <string.h>
41#include <stdio.h>
42#include <math.h>
43#include <time.h>
44#include <complex.h>
45
46#include "gravi_data.h"
47#include "gravi_dfs.h"
48#include "gravi_pfits.h"
49#include "gravi_cpl.h"
50
51#include "gravi_utils.h"
52
53#include "gravi_calib.h"
54#include "gravi_vis.h"
55#include "gravi_tf.h"
56#include "gravi_eop.h"
57
58/*-----------------------------------------------------------------------------
59 Private prototypes
60 -----------------------------------------------------------------------------*/
61
62double pythag(double , double );
63
64cpl_matrix * svdcmp(cpl_matrix * , cpl_vector * , cpl_matrix * );
65
66/*-----------------------------------------------------------------------------
67 Functions code
68 -----------------------------------------------------------------------------*/
69
70
71int gravi_array_threshold_min (cpl_array * array, double lo_cut)
72{
73 cpl_ensure (array, CPL_ERROR_NULL_INPUT, -1);
74
75 cpl_size size = cpl_array_get_size (array);
76 cpl_size num = 0;
77
78 for (cpl_size s = 0; s < size ; s++) {
79 if (cpl_array_get (array, s, NULL) < lo_cut) {
80 cpl_array_set (array, s, lo_cut);
81 num ++;
82 }
83 }
84
85 return num;
86}
87
88
93cpl_array ** gravi_array_new_list (int n, cpl_type type, int size)
94{
95 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
96 cpl_ensure (size>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
97
98 cpl_array ** output;
99 output = cpl_malloc (n * sizeof(cpl_array *));
100
101 int out1;
102 if ( type == CPL_TYPE_DOUBLE )
103 for ( out1 = 0 ; out1 < n ; out1++ ) {
104 output[out1] = cpl_array_new (size, type);
105 cpl_array_fill_window_double (output[out1], 0, size, 0.0);
106 }
107 else if ( type == CPL_TYPE_DOUBLE_COMPLEX )
108 for ( out1 = 0 ; out1 < n ; out1++ ) {
109 output[out1] = cpl_array_new (size, type);
110 cpl_array_fill_window_double_complex (output[out1], 0, size, 0.0 * I*0.0);
111 }
112 else {
113 cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,"This type is not supported.");
114 FREE (cpl_free, output);
115 return NULL;
116 }
117
118 return output;
119}
120
121cpl_error_code gravi_table_interpolate_column (cpl_table * to_table,
122 const char * to_x,
123 const char * to_y,
124 const cpl_table * from_table,
125 const char * from_x,
126 const char * from_y)
127{
129 cpl_ensure_code (to_table, CPL_ERROR_NULL_INPUT);
130 cpl_ensure_code (to_x, CPL_ERROR_NULL_INPUT);
131 cpl_ensure_code (to_y, CPL_ERROR_NULL_INPUT);
132 cpl_ensure_code (from_table, CPL_ERROR_NULL_INPUT);
133 cpl_ensure_code (from_x, CPL_ERROR_NULL_INPUT);
134 cpl_ensure_code (from_y, CPL_ERROR_NULL_INPUT);
135
136 /* Size */
137 cpl_size nxref = cpl_table_get_nrow (from_table);
138 cpl_size nxout = cpl_table_get_nrow (to_table);
139
140 /* Xref vectors */
141 cpl_vector * xref = cpl_vector_new (nxref);
142 for (cpl_size row = 0; row < nxref; row++) {
143 cpl_vector_set (xref, row, cpl_table_get (from_table, from_x, row, NULL));
144 CPLCHECK_MSG ("Cannot get x data");
145 }
146
147 /* Xout vectors */
148 cpl_vector * xout = cpl_vector_new (nxout);
149 for (cpl_size row = 0; row < nxout; row++) {
150 cpl_vector_set (xout, row, cpl_table_get (to_table, to_x, row, NULL));
151 CPLCHECK_MSG ("Cannot get x data");
152 }
153
154 /* Allocate memory for the interpolation */
155 cpl_vector * yref = cpl_vector_new (nxref);
156 cpl_vector * yout = cpl_vector_new (nxout);
157 cpl_bivector * fref = cpl_bivector_wrap_vectors (xref, yref);
158 cpl_bivector * fout = cpl_bivector_wrap_vectors (xout, yout);
159
160 /* Shall be a column of array */
161 cpl_size depth = cpl_table_get_column_depth (from_table, from_y);
162 if (depth == 0)
163 cpl_error_set_message (cpl_func,CPL_ERROR_INVALID_TYPE ,
164 "Report this error to gravity.drs");
165
166 /* Output is of type DOUBLE */
167 const char * unit = cpl_table_get_column_unit (from_table, from_y);
168 gravi_table_init_column_array (to_table, to_y, unit, CPL_TYPE_DOUBLE, depth);
169
170 /* Loop on column depth */
171 for (cpl_size size = 0; size < depth; size++) {
172
173 /* Yref vector */
174 for (cpl_size row = 0; row < nxref; row++) {
175 double value = gravi_table_get_value (from_table, from_y, row, size);
176 cpl_vector_set (yref, row, value);
177 CPLCHECK_MSG ("Cannot get y data");
178 }
179
180 /* Interpolate linear */
181 cpl_bivector_interpolate_linear (fout, fref);
182 CPLCHECK_MSG ("Cannot interpolate");
183
184 /* fill Yout */
185 for (cpl_size row = 0; row < nxout; row++) {
186 double value = cpl_vector_get (yout, row);
187 gravi_table_set_value (to_table, to_y, row, size, value);
188 CPLCHECK_MSG ("Cannot set y data");
189 }
190
191 } /* End loop on column depth */
192
193 /* Free memory */
194 FREE (cpl_bivector_delete, fref);
195 FREE (cpl_bivector_delete, fout);
196
198 return CPL_ERROR_NONE;
199}
200
217double gravi_table_get_column_flagged_mean (cpl_table * table, const char * name)
218{
219 cpl_ensure (table, CPL_ERROR_NULL_INPUT, 0.0);
220 cpl_ensure (name, CPL_ERROR_NULL_INPUT, 0.0);
221
222 double mean = 0.0;
223 cpl_size valid_elem = 0;
224 int valid;
225 cpl_size nrow = cpl_table_get_nrow (table);
226 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, 0.0);
227
228 cpl_type type = cpl_table_get_column_type (table, name);
229 cpl_size depth = cpl_table_get_column_depth (table, name);
230
231 cpl_array ** flags = cpl_table_get_data_array (table, "FLAG");
232
233 if (depth > 0) {
234 cpl_array ** arrays = cpl_table_get_data_array (table, name);
235 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, 0.0);
236 double sum = 0;
237 cpl_size array_size = cpl_array_get_size(arrays[0]);
238 for (cpl_size r=0; r<nrow;r++)
239 for(cpl_size el=0; el<array_size; el++)
240 if (!cpl_array_get_int(flags[r], el, &valid))
241 {
242 sum += cpl_array_get_double(arrays[r], el, &valid);
243 valid_elem++;
244 }
245 if(valid_elem)
246 mean = sum / valid_elem;
247 }
248 else if (depth == 0 && type == CPL_TYPE_DOUBLE) {
249 double * data = cpl_table_get_data_double (table, name);
250 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
251 cpl_size array_size = cpl_array_get_size(flags[0]);
252 for (cpl_size r=0; r<nrow;r++)
253 {
254 for(cpl_size el=0; el<array_size; el++)
255 {
256 if (!cpl_array_get_int(flags[r], el, &valid))
257 {
258 mean += data[r];
259 valid_elem++;
260 }
261 }
262 }
263 if(valid_elem)
264 mean = mean / valid_elem;
265 }
266
267 else {
268 cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,"unknow type");
269 return 0.0;
270 }
271
272 return mean;
273}
274
275double gravi_table_get_column_mean (cpl_table * table, const char * name, int base, int nbase)
276{
277 cpl_ensure (table, CPL_ERROR_NULL_INPUT, 0.0);
278 cpl_ensure (name, CPL_ERROR_NULL_INPUT, 0.0);
279
280 double mean = 0.0;
281 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
282 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, 0.0);
283
284 cpl_type type = cpl_table_get_column_type (table, name);
285 cpl_size depth = cpl_table_get_column_depth (table, name);
286
287 if (depth == 0 && type == CPL_TYPE_DOUBLE) {
288 double * data = cpl_table_get_data_double (table, name);
289 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
290 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
291 }
292 else if (depth == 0 && type == CPL_TYPE_FLOAT) {
293 float * data = cpl_table_get_data_float (table, name);
294 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
295 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
296 }
297 else if (depth == 0 && type == CPL_TYPE_INT) {
298 int * data = cpl_table_get_data_int (table, name);
299 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
300 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
301 }
302 else if (depth > 0) {
303 cpl_array ** arrays = cpl_table_get_data_array (table, name);
304 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, 0.0);
305 cpl_array * output = cpl_array_duplicate (arrays[base]);
306 cpl_ensure (output, CPL_ERROR_ILLEGAL_INPUT, 0.0);
307 for (cpl_size r=1; r<nrow;r++)
308 cpl_array_add (output, arrays[r*nbase+base]);
309 mean = cpl_array_get_mean (output);
310 FREE (cpl_array_delete, output);
311 }
312 else {
313 cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,"unknow type");
314 return 0.0;
315 }
316
317 return mean / nrow;
318}
319
320double gravi_table_get_column_std (cpl_table * table, const char * name, int base, int nbase)
321{
322 cpl_ensure (table, CPL_ERROR_NULL_INPUT, 0.0);
323 cpl_ensure (name, CPL_ERROR_NULL_INPUT, 0.0);
324
325 double mean = 0.0;
326 double mean2 = 0.0;
327 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
328 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, 0.0);
329
330 cpl_type type = cpl_table_get_column_type (table, name);
331 cpl_size depth = cpl_table_get_column_depth (table, name);
332
333 if (depth == 0 && type == CPL_TYPE_DOUBLE) {
334 double * data = cpl_table_get_data_double (table, name);
335 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
336 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
337 for (cpl_size r=0; r<nrow;r++) mean2 += data[r*nbase+base] * data[r*nbase+base];
338 }
339 else if (depth == 0 && type == CPL_TYPE_FLOAT) {
340 float * data = cpl_table_get_data_float (table, name);
341 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
342 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
343 for (cpl_size r=0; r<nrow;r++) mean2 += data[r*nbase+base] * data[r*nbase+base];
344 }
345 else if (depth == 0 && type == CPL_TYPE_INT) {
346 int * data = cpl_table_get_data_int (table, name);
347 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
348 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
349 for (cpl_size r=0; r<nrow;r++) mean2 += data[r*nbase+base] * data[r*nbase+base];
350 }
351 else {
352 cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,"unknow type");
353 return 0.0;
354 }
355
356 return sqrt (mean2 / nrow - mean*mean / nrow / nrow);
357}
358
359cpl_array * gravi_table_get_column_sum_array (cpl_table * table, const char * name, int base, int nbase)
360{
361 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
362 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
363
364 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
365 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
366
367 /* Get the pointer */
368 cpl_array ** arrays = cpl_table_get_data_array (table, name);
369 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, NULL);
370
371 /* Build the mean (warning that integer will remain an integer) */
372 cpl_array * output = cpl_array_duplicate (arrays[base]);
373
374 /* Coadd all */
375 for (cpl_size r=1; r<nrow;r++)
376 cpl_array_add (output, arrays[r*nbase+base]);
377
378 return output;
379}
380
381cpl_array * gravi_table_get_column_mean_array (cpl_table * table, const char * name, int base, int nbase)
382{
383 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
384 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
385
386 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
387 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
388
389 /* Get the pointer */
390 cpl_array ** arrays = cpl_table_get_data_array (table, name);
391 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, NULL);
392
393 /* Build the mean (warning that integer will remain an integer) */
394 cpl_array * output = cpl_array_duplicate (arrays[base]);
395
396 /* Coadd all */
397 for (cpl_size r=1; r<nrow;r++)
398 cpl_array_add (output, arrays[r*nbase+base]);
399
400 cpl_array_divide_scalar (output, nrow);
401 return output;
402}
403
404
405double ** gravi_table_get_data_array_double(cpl_table * table, const char * name)
406{
407 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
408 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
409
410 cpl_size nrow = cpl_table_get_nrow (table);
411 cpl_array ** pdata = cpl_table_get_data_array (table, name);
412
413 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
414 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
415
416 /* Allocate memory, this will have to be desalocated */
417 double ** data = cpl_malloc (sizeof(double*) * nrow);
418
419 /* Get all the pointers */
420 for (cpl_size row=0; row<nrow; row++) {
421 data[row] = cpl_array_get_data_double (pdata[row]);
422 }
423
424 CPLCHECK_NUL("Cannot load the requested arrays");
425
426 return data;
427}
428
429float ** gravi_table_get_data_array_float(cpl_table * table, const char * name)
430{
431 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
432 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
433
434 cpl_size nrow = cpl_table_get_nrow (table);
435 cpl_array ** pdata = cpl_table_get_data_array (table, name);
436
437 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
438 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
439
440 /* Allocate memory, this will have to be desalocated */
441 float ** data = cpl_malloc (sizeof(float*) * nrow);
442
443 /* Get all the pointers */
444 for (cpl_size row=0; row<nrow; row++) {
445 data[row] = cpl_array_get_data_float (pdata[row]);
446 }
447
448 CPLCHECK_NUL("Cannot load the requested arrays");
449
450 return data;
451}
452
453float complex ** gravi_table_get_data_array_float_complex (cpl_table * table, const char * name)
454{
455 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
456 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
457
458 cpl_size nrow = cpl_table_get_nrow (table);
459 cpl_array ** pdata = cpl_table_get_data_array (table, name);
460
461 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
462 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
463
464 /* Allocate memory, this will have to be desalocated */
465 float complex ** data = cpl_malloc (sizeof(float complex*) * nrow);
466
467 /* Get all the pointers */
468 for (cpl_size row=0; row<nrow; row++) {
469 data[row] = cpl_array_get_data_float_complex (pdata[row]);
470 }
471
472 CPLCHECK_NUL ("Cannot load the requested arrays");
473
474 return data;
475}
476
477
478double complex ** gravi_table_get_data_array_double_complex (cpl_table * table, const char * name)
479{
480 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
481 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
482
483 cpl_size nrow = cpl_table_get_nrow (table);
484 cpl_array ** pdata = cpl_table_get_data_array (table, name);
485
486 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
487 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
488
489 /* Allocate memory, this will have to be desalocated */
490 double complex ** data = cpl_malloc (sizeof(double complex*) * nrow);
491
492 /* Get all the pointers */
493 for (cpl_size row=0; row<nrow; row++) {
494 data[row] = cpl_array_get_data_double_complex (pdata[row]);
495 }
496
497 CPLCHECK_NUL ("Cannot load the requested arrays");
498
499 return data;
500}
501
502int ** gravi_table_get_data_array_int(cpl_table * table, const char * name)
503{
504 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
505 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
506
507 cpl_size nrow = cpl_table_get_nrow (table);
508 cpl_array ** pdata = cpl_table_get_data_array (table, name);
509
510 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
511 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
512
513 /* Allocate memory, this will have to be desalocated */
514 int ** data = cpl_malloc (sizeof(int*) * nrow);
515
516 /* Get all the pointers */
517 for (cpl_size row=0; row<nrow; row++) {
518 data[row] = cpl_array_get_data_int (pdata[row]);
519 }
520
521 CPLCHECK_NUL("Cannot load the requested arrays");
522
523 return data;
524}
525
526/*
527 * Define and init an array of DOUBLE
528 */
529cpl_array * gravi_array_init_double (long n , double value)
530{
531 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
532 cpl_array * output = cpl_array_new (n, CPL_TYPE_DOUBLE);
533 cpl_array_fill_window_double (output, 0, n, value);
534 return output;
535}
536
537/*
538 * Define and init an array of INT
539 */
540cpl_array * gravi_array_init_int (long n, int value)
541{
542 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
543 cpl_array * output = cpl_array_new (n, CPL_TYPE_INT);
544 cpl_array_fill_window_int (output, 0, n, value);
545 return output;
546}
547
548/*
549 * Define and init an array of DOUBLE COMPLEX
550 */
551cpl_array * gravi_array_init_double_complex (long n, double complex value)
552{
553 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
554 cpl_array * output = cpl_array_new (n, CPL_TYPE_DOUBLE_COMPLEX);
555 cpl_array_fill_window_double_complex (output, 0, n, value);
556 return output;
557}
558
559/*
560 * Define and init an array of FLOAT COMPLEX
561 */
562cpl_array * gravi_array_init_float_complex (long n, float complex value)
563{
564 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
565 cpl_array * output = cpl_array_new (n, CPL_TYPE_FLOAT_COMPLEX);
566 cpl_array_fill_window_float_complex (output, 0, n, value);
567 return output;
568}
569
570/*
571 * Compute a new DOUBLE COMPLEX array filled with: input_re + i * input_im
572 */
573cpl_array * gravi_array_wrap_complex (cpl_array * input_re, cpl_array * input_im)
574{
575 cpl_ensure (input_re, CPL_ERROR_NULL_INPUT, NULL);
576 cpl_ensure (input_im, CPL_ERROR_NULL_INPUT, NULL);
577
578 cpl_size size_re = cpl_array_get_size (input_re);
579 cpl_size size_im = cpl_array_get_size (input_im);
580
581 cpl_ensure (size_re == size_im, CPL_ERROR_ILLEGAL_INPUT, NULL);
582
583 cpl_array * output = cpl_array_new (size_re, CPL_TYPE_DOUBLE_COMPLEX);
584
585 for (cpl_size n = 0; n < size_re; n ++) {
586 cpl_array_set_complex (output, n, 1.* I * cpl_array_get (input_im, n, NULL) +
587 cpl_array_get (input_re, n, NULL));
588 }
589
590 return output;
591}
592
593/*
594 * Compute a new FLOAT COMPLEX array filled with: input_re + i * input_im
595 */
596cpl_array * gravi_array_wrap_float_complex (cpl_array * input_re, cpl_array * input_im)
597{
598 cpl_ensure (input_re, CPL_ERROR_NULL_INPUT, NULL);
599 cpl_ensure (input_im, CPL_ERROR_NULL_INPUT, NULL);
600
601 cpl_size size_re = cpl_array_get_size (input_re);
602 cpl_size size_im = cpl_array_get_size (input_im);
603
604 cpl_ensure (size_re == size_im, CPL_ERROR_ILLEGAL_INPUT, NULL);
605
606 cpl_array * output = cpl_array_new (size_re, CPL_TYPE_FLOAT_COMPLEX);
607
608 int nv = 0.0;
609 for (cpl_size n = 0; n < size_re; n ++) {
610 cpl_array_set_float_complex (output, n, 1.* I * cpl_array_get (input_im, n, &nv) +
611 cpl_array_get (input_re, n, &nv));
612 }
613
614 return output;
615}
616
617/*
618 * Compute a new DOUBLE array filled with: input_re^2 + input_im^2
619 */
620cpl_array * gravi_array_compute_norm2 (cpl_array * input_re, cpl_array * input_im)
621{
622 cpl_ensure (input_re, CPL_ERROR_NULL_INPUT, NULL);
623 cpl_ensure (input_im, CPL_ERROR_NULL_INPUT, NULL);
624
625 cpl_size size_re = cpl_array_get_size (input_re);
626 cpl_size size_im = cpl_array_get_size (input_im);
627
628 cpl_ensure (size_re == size_im, CPL_ERROR_ILLEGAL_INPUT, NULL);
629
630 cpl_array * output = cpl_array_new (size_re, CPL_TYPE_DOUBLE);
631 cpl_array_fill_window_double (output, 0, size_re, 0.0);
632
633 int nv = 0.0;
634 for (cpl_size n = 0; n < size_re; n ++) {
635 cpl_array_set_double (output, n, pow(cpl_array_get (input_im, n, &nv),2) +
636 pow(cpl_array_get (input_re, n, &nv),2) );
637 }
638
639 return output;
640}
641
642/*
643 * Set an pair of arrays as the real and imaginary part of
644 * a FLOAT COMPLEX array into the table. Data are copied.
645 */
646cpl_error_code gravi_table_set_array_double_complex (cpl_table * table,
647 const char * name,
648 cpl_size row,
649 cpl_array * visR,
650 cpl_array * visI)
651{
652 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
653 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
654 cpl_ensure_code (visR, CPL_ERROR_NULL_INPUT);
655 cpl_ensure_code (visI, CPL_ERROR_NULL_INPUT);
656
657 cpl_array * tmp_cast = gravi_array_wrap_complex (visR, visI);
658 cpl_table_set_array (table, name, row, tmp_cast);
659 cpl_array_delete (tmp_cast);
660
661 CPLCHECK_MSG("Cannot set float_complex array");
662
663 return CPL_ERROR_NONE;
664}
665
666/*
667 * Set an array in radian into an table and convert it in DOUBLE
668 * with units [deg]
669 */
670cpl_error_code gravi_table_set_array_phase (cpl_table * table, const char * name, cpl_size row, cpl_array * phase)
671{
672 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
673 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
674 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
675
676 cpl_array * tmp_cast;
677 if (cpl_array_get_type (phase) == CPL_TYPE_FLOAT_COMPLEX ||
678 cpl_array_get_type (phase) == CPL_TYPE_DOUBLE_COMPLEX ) {
679 tmp_cast = cpl_array_cast (phase, CPL_TYPE_DOUBLE_COMPLEX);
680 cpl_array_arg (tmp_cast);
681 } else
682 tmp_cast = cpl_array_cast (phase, CPL_TYPE_DOUBLE);
683
684 cpl_array_multiply_scalar (tmp_cast, 180.0/ CPL_MATH_PI);
685 cpl_table_set_array (table, name, row, tmp_cast);
686 cpl_array_delete (tmp_cast);
687
688 CPLCHECK_MSG("Cannot set phase array");
689
690 return CPL_ERROR_NONE;
691}
692
693/*----------------------------------------------------------------------------*/
700/*----------------------------------------------------------------------------*/
701cpl_error_code gravi_table_set_string_fixlen (cpl_table *table, const char *name, int row, const char *value, int len)
702{
704 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
705 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
706 cpl_ensure_code (row>-1, CPL_ERROR_ILLEGAL_INPUT);
707 cpl_ensure_code (len>0, CPL_ERROR_ILLEGAL_INPUT);
708
709 char * str = cpl_sprintf ("%-*.*s", len, len, value);
710 cpl_table_set_string (table, name, row, str);
711
712 FREE (cpl_free, str);
713 CPLCHECK_MSG("Cannot set string");
714
716 return CPL_ERROR_NONE;
717}
718
719/*
720 * Rebin a cpl_array from the SC wavelength table to the FT wavelength table
721 * For each FT bin, average all elements found in lbdEff+/-lbdBand/2
722 * The output array is created, the input array is not modified.
723 */
724cpl_array * gravi_array_rebin (const cpl_array * input, const cpl_array * errs,
725 cpl_table * oi_wave_sc, cpl_table * oi_wave_ft)
726{
728 cpl_ensure (input, CPL_ERROR_NULL_INPUT, NULL);
729 cpl_ensure (errs, CPL_ERROR_NULL_INPUT, NULL);
730 cpl_ensure (oi_wave_sc, CPL_ERROR_NULL_INPUT, NULL);
731 cpl_ensure (oi_wave_ft, CPL_ERROR_NULL_INPUT, NULL);
732
733 /* Get the eff_wave and eff_band of the FT */
734 float *effWave_sc = cpl_table_get_data_float (oi_wave_sc, "EFF_WAVE");
735 float *effWave_ft = cpl_table_get_data_float (oi_wave_ft, "EFF_WAVE");
736 float *effBand_ft = cpl_table_get_data_float (oi_wave_ft, "EFF_BAND");
737 cpl_size nwave_ft = cpl_table_get_nrow (oi_wave_ft);
738 cpl_size nwave_sc = cpl_table_get_nrow (oi_wave_sc);
739
740 CPLCHECK_NUL ("Cannot get data");
741
742 cpl_array * output = cpl_array_new (nwave_ft, CPL_TYPE_DOUBLE);
743 cpl_array * weight = cpl_array_new (nwave_ft, CPL_TYPE_DOUBLE);
744
745 /* Built the SC data at the spectral resolution of the FT (vis2_sc_lr) */
746 for (cpl_size wft = 0; wft < nwave_ft; wft++) {
747 for (cpl_size wsc = 0; wsc < nwave_sc; wsc++)
748 if ( fabs (effWave_sc[wsc] - effWave_ft[wft]) < 0.5 * effBand_ft[wft] ) {
749
750 double v = cpl_array_get (input, wsc, NULL);
751 double w = cpl_array_get (errs, wsc, NULL);
752
753 w = (w!=0?1./w:1.0);
754 cpl_array_set (output, wft, cpl_array_get (output, wft, NULL) + v * w);
755 cpl_array_set (weight, wft, cpl_array_get (weight, wft, NULL) + w);
756
757 CPLCHECK_NUL("Cannot reduce the spectral resolution");
758 }
759 }
760
761 cpl_array_divide (output, weight);
762 cpl_array_delete (weight);
764 return output;
765}
766
767
768/*
769 * Add two columns from differents tables, without duplicating the data.
770 * Use cpl_table_add_columns for columns in the same table.
771 */
772cpl_error_code gravi_table_add_columns (cpl_table * oi_vis1, const char *name1,
773 cpl_table * oi_vis2, const char *name2)
774{
776 cpl_ensure_code (oi_vis1, CPL_ERROR_NULL_INPUT);
777 cpl_ensure_code (oi_vis2, CPL_ERROR_NULL_INPUT);
778 cpl_ensure_code (name1, CPL_ERROR_NULL_INPUT);
779 cpl_ensure_code (name2, CPL_ERROR_NULL_INPUT);
780
781 int row;
782 cpl_msg_debug (cpl_func, "Colname (%s + %s) ",name1,name2);
783
784 cpl_type type1 = cpl_table_get_column_type (oi_vis1, name1);
785 cpl_type type2 = cpl_table_get_column_type (oi_vis2, name2);
786 cpl_size nrow1 = cpl_table_get_nrow (oi_vis1);
787 cpl_size nrow2 = cpl_table_get_nrow (oi_vis2);
788 CPLCHECK_MSG("Cannot get type or nrow");
789
790 if ( type1 != type2 || nrow1 != nrow2) {
791 return cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,
792 "input columns not conformables");
793 }
794
795 if ( type1 == CPL_TYPE_DOUBLE ) {
796 double * data1 = cpl_table_get_data_double (oi_vis1, name1);
797 double * data2 = cpl_table_get_data_double (oi_vis2, name2);
798 CPLCHECK_MSG("Cannot load data");
799
800 for (row=0 ; row<nrow1 ; row++) data1[row] += data2[row];
801 }
802 else if ( type1 == CPL_TYPE_FLOAT_COMPLEX ) {
803 float complex * data1 = cpl_table_get_data_float_complex (oi_vis1, name1);
804 float complex * data2 = cpl_table_get_data_float_complex (oi_vis2, name2);
805 CPLCHECK_MSG("Cannot load data");
806
807 for (row=0 ; row<nrow1; row++) data1[row] += data2[row];
808 }
809 else if ( type1 == CPL_TYPE_DOUBLE_COMPLEX ) {
810 double complex * data1 = cpl_table_get_data_double_complex (oi_vis1, name1);
811 double complex * data2 = cpl_table_get_data_double_complex (oi_vis2, name2);
812 CPLCHECK_MSG("Cannot load data");
813
814 for (row=0 ; row<nrow1; row++) data1[row] += data2[row];
815 }
816 else if ( type1 & CPL_TYPE_POINTER ) {
817 cpl_array ** data1 = cpl_table_get_data_array (oi_vis1, name1);
818 cpl_array ** data2 = cpl_table_get_data_array (oi_vis2, name2);
819 CPLCHECK_MSG("Cannot load data");
820
821 for (row=0 ; row<nrow1; row++) {
822 cpl_array_add (data1[row], data2[row]);
823 CPLCHECK_MSG("Cannot add data");
824 }
825 } else {
826 return cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,
827 "unknow type -- report to DRS team");
828 }
829 /* End case */
830
832 return CPL_ERROR_NONE;
833}
834
835
836
837/*
838 * Smooth column input_name with a box card of length 2*nsmooth+1
839 * Note that this is a running SUM, not a running MEAN.
840 * It integrated 2 x nsmooth + 1 running samples
841 * FIXME: check this running sum near the limits
842 */
843cpl_error_code gravi_table_runint_column (cpl_table * oi_vis,
844 const char *input_name,
845 const char *output_name,
846 int nsmooth, int nbase)
847{
849 cpl_ensure_code (oi_vis, CPL_ERROR_NULL_INPUT);
850 cpl_ensure_code (input_name, CPL_ERROR_NULL_INPUT);
851 cpl_ensure_code (output_name, CPL_ERROR_NULL_INPUT);
852 cpl_ensure_code (nsmooth>=0, CPL_ERROR_ILLEGAL_INPUT);
853 cpl_ensure_code (nbase>0, CPL_ERROR_ILLEGAL_INPUT);
854
855 int row, base;
856 int row_add, row_sub;
857
858 cpl_type type = cpl_table_get_column_type (oi_vis, input_name);
859 cpl_size nrow = cpl_table_get_nrow (oi_vis) / nbase;
860
861 if ( type == CPL_TYPE_DOUBLE ) {
862 double * data = cpl_table_get_data_double (oi_vis, input_name);
863 double * output = cpl_malloc (sizeof(double) * nrow * nbase);
864 double buffer = 0.0;
865
866 CPLCHECK_MSG("Cannot load data");
867
868 /* Loop on base and rows */
869 for ( base=0 ; base<nbase ; base++) {
870 buffer = 0.0;
871
872 for ( row=-nsmooth ; row<nrow ; row++) {
873 row_add = row+nsmooth;
874 row_sub = row-nsmooth-1;
875 if ( row_add < nrow ) buffer += data[row_add * nbase + base];
876 if ( row_sub >= 0 ) buffer -= data[row_sub * nbase + base];
877 if( row>=0 && row<nrow ) output[row * nbase + base] = (double)(buffer);
878 }
879 /* End loop on rows */
880 }
881 /* End loop on base */
882
883 /* Wrap output column */
884 if ( !strcmp (input_name, output_name)) {
885 for (row = 0; row < nrow * nbase; row++) data[row] = output[row];
886 cpl_free (output);
887 } else {
888 if (cpl_table_has_column (oi_vis, output_name))
889 cpl_table_erase_column (oi_vis, output_name);
890 cpl_table_wrap_double (oi_vis, output, output_name);
891 }
892 CPLCHECK_MSG("Cannot Wrap");
893 }
894 else if ( type == CPL_TYPE_DOUBLE_COMPLEX ) {
895 double complex * data = cpl_table_get_data_double_complex (oi_vis, input_name);
896 double complex * output = cpl_malloc (sizeof(double complex) * nrow * nbase);
897 double complex buffer = 0.0;
898
899 CPLCHECK_MSG("Cannot load data");
900
901 /* Loop on rows */
902 for ( base=0 ; base<nbase ; base++) {
903 buffer = 0.0;
904
905 for ( row=-nsmooth ; row<nrow ; row++) {
906 row_add = row+nsmooth;
907 row_sub = row-nsmooth-1;
908 if ( row_add < nrow ) buffer += data[row_add * nbase + base];
909 if ( row_sub >= 0 ) buffer -= data[row_sub * nbase + base];
910 if( row>=0 && row<nrow ) output[row * nbase + base] = (double complex)(buffer);
911 }
912 }
913 /* End loop on base */
914
915 /* Wrap output column */
916 if ( !strcmp (input_name, output_name)) {
917 for (row = 0; row < nrow * nbase; row++) data[row] = output[row];
918 cpl_free (output);
919 } else {
920 if (cpl_table_has_column (oi_vis, output_name))
921 cpl_table_erase_column (oi_vis, output_name);
922 cpl_table_wrap_double_complex (oi_vis, output, output_name);
923 }
924 CPLCHECK_MSG ("Cannot Wrap");
925
926 } else {
927 return cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
928 "This type is not supported..."
929 "report this error to DRS team !!");
930 }
931
933 return CPL_ERROR_NONE;
934}
935
936cpl_error_code gravi_table_smooth_column (cpl_table * oi_vis,
937 const char *input_name,
938 const char *output_name,
939 int nsmooth, int nbase)
940{
942 cpl_ensure_code (oi_vis, CPL_ERROR_NULL_INPUT);
943 cpl_ensure_code (input_name, CPL_ERROR_NULL_INPUT);
944 cpl_ensure_code (output_name, CPL_ERROR_NULL_INPUT);
945 cpl_ensure_code (nsmooth>0, CPL_ERROR_ILLEGAL_INPUT);
946 cpl_ensure_code (nbase>0, CPL_ERROR_ILLEGAL_INPUT);
947
948 /* Performed the running integration and devide */
949 gravi_table_runint_column (oi_vis, input_name, output_name, nsmooth, nbase);
950 cpl_table_divide_scalar (oi_vis, output_name, 2.0*(double)nsmooth+1.0);
951
953 return CPL_ERROR_NONE;
954}
955
956cpl_array * gravi_table_create_sigma_array (cpl_table * oi_wave)
957{
958 int nv = 0;
959 cpl_size size = cpl_table_get_nrow (oi_wave);
960 cpl_array * sigma = cpl_array_new (size, CPL_TYPE_DOUBLE);
961
962 for (cpl_size w = 0; w<size; w++ )
963 cpl_array_set (sigma, w, 1./cpl_table_get (oi_wave, "EFF_WAVE", w, &nv));
964
965 CPLCHECK_NUL("Cannot compute the sigma array from EFF_WAVE");
966 return sigma;
967}
968
969cpl_array * gravi_table_create_wave_array (cpl_table * oi_wave)
970{
971 cpl_ensure (oi_wave, CPL_ERROR_NULL_INPUT, NULL);
972
973 int nv = 0;
974 cpl_size size = cpl_table_get_nrow (oi_wave);
975 cpl_array * wave = cpl_array_new (size, CPL_TYPE_FLOAT);
976
977 for (cpl_size w = 0; w<size; w++ )
978 cpl_array_set (wave, w, cpl_table_get (oi_wave, "EFF_WAVE", w, &nv));
979
980 CPLCHECK_NUL("Cannot compute the wave array from EFF_WAVE");
981 return wave;
982}
983
984
985cpl_error_code gravi_array_normalize_complex (cpl_array * input)
986{
987 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
988
989 int nv = 0;
990 cpl_size size = cpl_array_get_size (input);
991
992 double complex cpx = 0.0 * I + 0.0;
993 for (cpl_size wave = 0; wave<size; wave++ ) {
994 cpx = cpl_array_get_complex (input,wave,&nv);
995 cpl_array_set_complex (input, wave, cpx / cabs (cpx));
996 if (nv) {cpl_array_set_invalid (input, wave); nv=0;}
997 }
998
999 CPLCHECK_MSG("Cannot normalize complex");
1000 return CPL_ERROR_NONE;
1001}
1002
1003cpl_array * gravi_array_create_inverse (cpl_array *input)
1004{
1005 cpl_ensure (input, CPL_ERROR_NULL_INPUT, NULL);
1006
1007 cpl_size size = cpl_array_get_size (input);
1008
1009 cpl_array * inv = cpl_array_new (size, CPL_TYPE_DOUBLE);
1010 cpl_array_fill_window (inv, 0, size, 1.0);
1011 cpl_array_divide (inv, input);
1012
1013 CPLCHECK_NUL("Cannot compute the sigma array from wave");
1014 return inv;
1015}
1016
1017/*
1018 * Unwrap an array of phase (in-place)
1019 */
1020cpl_error_code gravi_array_phase_unwrap (cpl_array * input)
1021{
1022 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1023
1024 cpl_size size_x = cpl_array_get_size (input);
1025 double phi_i, phi_ii, d_phi;
1026 int k_wrap =0;
1027
1028 for (cpl_size i_data = 1; i_data < size_x; i_data++){
1029
1030 /* Evaluation of the phi(i_data) and
1031 * phi(i_data-1) */
1032
1033 phi_i = cpl_array_get(input, i_data, NULL);
1034 phi_ii = cpl_array_get(input, i_data-1, NULL);
1035
1036 d_phi = phi_i + k_wrap * 2 * M_PI - phi_ii;
1037
1038 if (d_phi > M_PI) k_wrap --;
1039 if (d_phi < - M_PI) k_wrap ++;
1040
1041 cpl_array_set(input, i_data, cpl_array_get(input, i_data, NULL) + k_wrap * 2 * M_PI);
1042 }
1043
1044 CPLCHECK_INT("Cannot unwrap the phase array");
1045 return CPL_ERROR_NONE;
1046}
1047
1048/*
1049 * Fill in place the array with carg (cexp (1*I*array))
1050 */
1051cpl_error_code gravi_array_phase_wrap (cpl_array * input)
1052{
1053 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1054
1055 cpl_size size = cpl_array_get_size (input);
1056
1057 for (cpl_size wave = 0; wave<size; wave++ ) {
1058 cpl_array_set (input, wave, carg (cexp ( 1.0 * I * cpl_array_get (input, wave, NULL))));
1059 }
1060
1061 CPLCHECK_MSG("Cannot wrap phase array");
1062 return CPL_ERROR_NONE;
1063}
1064
1069cpl_array * gravi_array_cexp (double complex factor, const cpl_array * input)
1070{
1071 cpl_ensure (input, CPL_ERROR_NULL_INPUT, NULL);
1072
1073 cpl_size size = cpl_array_get_size (input);
1074
1075 cpl_array * output = cpl_array_new (size, CPL_TYPE_DOUBLE_COMPLEX);
1076 cpl_array_fill_window_complex (output, 0, size, (double complex)(0.0 + 0.0 * I));
1077
1078 cpl_size n;
1079 int nv = 0.0;
1080 for (n = 0; n < size; n ++) {
1081 cpl_array_set_complex (output, n, cexp (factor * cpl_array_get (input, n, &nv) ) );
1082 }
1083
1084 return output;
1085}
1086
1091cpl_error_code gravi_array_multiply_phasor (cpl_array * input, double complex factor, cpl_array * phase)
1092{
1093 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1094 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
1095
1096 cpl_size size_in = cpl_array_get_size (input);
1097 cpl_size size_ph = cpl_array_get_size (phase);
1098
1099 cpl_ensure_code (size_in == size_ph, CPL_ERROR_ILLEGAL_INPUT);
1100
1101 cpl_size n;
1102 int nv = 0.0;
1103 for (n = 0; n < size_in; n ++) {
1104 cpl_array_set_complex( input, n,
1105 cpl_array_get_complex( input, n, &nv) *
1106 cexp ( factor * cpl_array_get( phase, n, &nv) ) );
1107 }
1108
1109 CPLCHECK_MSG ("Cannot multiply phasor");
1110 return CPL_ERROR_NONE;
1111}
1112
1117cpl_error_code gravi_array_add_phasor (cpl_array * input, double complex factor, cpl_array * phase)
1118{
1119 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1120 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
1121
1122 cpl_size size_in = cpl_array_get_size (input);
1123 cpl_size size_ph = cpl_array_get_size (phase);
1124
1125 cpl_ensure_code (size_in == size_ph, CPL_ERROR_ILLEGAL_INPUT);
1126
1127 cpl_size n;
1128 int nv = 0.0;
1129 for (n = 0; n < size_in; n ++) {
1130 cpl_array_set_complex( input, n,
1131 cpl_array_get_complex( input, n, &nv) +
1132 cexp ( factor * cpl_array_get( phase, n, &nv) ) );
1133 CPLCHECK_MSG ("Cannot add phasor");
1134 }
1135
1136 return CPL_ERROR_NONE;
1137}
1138
1143cpl_error_code gravi_array_add_phasors (cpl_array * input, cpl_array * add, cpl_array * sub)
1144{
1145 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1146 cpl_ensure_code (add, CPL_ERROR_NULL_INPUT);
1147 cpl_ensure_code (sub, CPL_ERROR_NULL_INPUT);
1148
1149 cpl_size size_in = cpl_array_get_size (input);
1150 cpl_size size_add = cpl_array_get_size (add);
1151 cpl_size size_sub = cpl_array_get_size (sub);
1152
1153 cpl_ensure_code (size_in == size_add, CPL_ERROR_ILLEGAL_INPUT);
1154 cpl_ensure_code (size_in == size_sub, CPL_ERROR_ILLEGAL_INPUT);
1155
1156 cpl_size n;
1157 int nv = 0.0;
1158 for (n = 0; n < size_in; n ++) {
1159 cpl_array_set_complex (input, n,
1160 cpl_array_get_complex (input, n, &nv) +
1161 cpl_array_get_complex (add, n, &nv) *
1162 conj (cpl_array_get_complex (sub, n, &nv)));
1163 CPLCHECK_MSG ("Cannot add phasors");
1164 }
1165
1166 return CPL_ERROR_NONE;
1167}
1168
1173cpl_error_code gravi_array_add_phase (cpl_array * input, double factor, cpl_array * phase)
1174{
1175 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1176 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
1177
1178 cpl_size size_in = cpl_array_get_size (input);
1179 cpl_size size_ph = cpl_array_get_size (phase);
1180
1181 cpl_ensure_code (size_in == size_ph, CPL_ERROR_ILLEGAL_INPUT);
1182
1183 cpl_array * tmp = cpl_array_duplicate (phase);
1184
1185 cpl_array_multiply_scalar (tmp, factor);
1186 cpl_array_add (input, tmp);
1187
1188 cpl_array_delete (tmp);
1189
1190 CPLCHECK_MSG("Cannot add phase");
1191 return CPL_ERROR_NONE;
1192}
1193
1194cpl_error_code gravi_array_multiply_conj (cpl_array * input1, cpl_array * input2)
1195{
1196 cpl_ensure_code (input1, CPL_ERROR_NULL_INPUT);
1197 cpl_ensure_code (input2, CPL_ERROR_NULL_INPUT);
1198
1199 cpl_size size_in1 = cpl_array_get_size (input1);
1200 cpl_size size_in2 = cpl_array_get_size (input2);
1201
1202 cpl_ensure_code (size_in1 == size_in2, CPL_ERROR_ILLEGAL_INPUT);
1203
1204 for (cpl_size w = 0 ; w < size_in1 ; w++)
1205 cpl_array_set_complex (input1, w, cpl_array_get_complex (input1, w, NULL) *
1206 conj(cpl_array_get_complex (input2, w, NULL)));
1207
1208 CPLCHECK_MSG ("Cannot multiply by conj");
1209 return CPL_ERROR_NONE;
1210}
1211
1212
1213/*
1214 * Returned a smoothed version of an array of DOUBLE
1215 * Invalid data are not checked (all considered as valid)
1216 */
1217cpl_array * gravi_array_smooth (cpl_array * input_array, int DIT_smooth)
1218{
1219 cpl_ensure (DIT_smooth>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1220 cpl_ensure (input_array, CPL_ERROR_NULL_INPUT, NULL);
1221
1222 cpl_type type = cpl_array_get_type (input_array);
1223 cpl_size nrow = cpl_array_get_size ( input_array );
1224
1225 /* avoid segmentation fault if nrow < DIT_smooth */
1226 if (nrow-DIT_smooth*2-1<0) DIT_smooth=nrow/2;
1227
1228 /* create output array */
1229 cpl_array * output_smooth_array;
1230
1231 /* create data buffers and data carrier (the smoothed buffer)*/
1232 if ( type == CPL_TYPE_DOUBLE ) {
1233 double* input = cpl_array_get_data_double (input_array);
1234 double* output_smooth = cpl_malloc (nrow * sizeof(double));
1235 double data_carrier = 0.0;
1236
1237 /* smooth data */
1238 int int_carrier = 0;
1239 for (cpl_size row = - DIT_smooth; row < 0; row ++)
1240 {
1241 data_carrier+=input[row+DIT_smooth];
1242 int_carrier+=1;
1243 }
1244 for (cpl_size row = 0; row < DIT_smooth+1; row ++)
1245 {
1246 data_carrier+=input[row+DIT_smooth];
1247 int_carrier+=1;
1248 output_smooth[row]=data_carrier/int_carrier;
1249 }
1250 double inv_int_carrier= 1.0/int_carrier;
1251 for (cpl_size row = DIT_smooth+1; row < nrow-DIT_smooth; row ++)
1252 {
1253 data_carrier-=input[row-DIT_smooth-1];
1254 data_carrier+=input[row+DIT_smooth];
1255 output_smooth[row]=data_carrier*inv_int_carrier;
1256 }
1257 for (cpl_size row = nrow-DIT_smooth; row < nrow; row ++)
1258 {
1259 data_carrier-=input[row-DIT_smooth-1];
1260 int_carrier-=1;
1261 output_smooth[row]=data_carrier/int_carrier;
1262 }
1263
1264 /* wrap data into array */
1265 output_smooth_array=cpl_array_wrap_double (output_smooth, nrow);
1266
1267 } else if ( type == CPL_TYPE_DOUBLE_COMPLEX ){
1268 double complex * input = cpl_array_get_data_double_complex (input_array);
1269 double complex * output_smooth = cpl_malloc (nrow * sizeof(double complex));
1270 double complex data_carrier = 0.0;
1271
1272 /* smooth data */
1273 int int_carrier = 0;
1274 for (cpl_size row = - DIT_smooth; row < 0; row ++)
1275 {
1276 data_carrier+=input[row+DIT_smooth];
1277 int_carrier+=1;
1278 }
1279 for (cpl_size row = 0; row < DIT_smooth+1; row ++)
1280 {
1281 data_carrier+=input[row+DIT_smooth];
1282 int_carrier+=1;
1283 output_smooth[row]=data_carrier/int_carrier;
1284 }
1285 double inv_int_carrier= 1.0/int_carrier;
1286 for (cpl_size row = DIT_smooth+1; row < nrow-DIT_smooth; row ++)
1287 {
1288 data_carrier-=input[row-DIT_smooth-1];
1289 data_carrier+=input[row+DIT_smooth];
1290 output_smooth[row]=data_carrier*inv_int_carrier;
1291 }
1292 for (cpl_size row = nrow-DIT_smooth; row < nrow; row ++)
1293 {
1294 data_carrier-=input[row-DIT_smooth-1];
1295 int_carrier-=1;
1296 output_smooth[row]=data_carrier/int_carrier;
1297 }
1298
1299 /* wrap data into array */
1300 output_smooth_array=cpl_array_wrap_double_complex (output_smooth, nrow);
1301
1302
1303 } else {
1304 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
1305 "This type is not supported... report this error to DRS team !!");
1306 return NULL;
1307 }
1308 return output_smooth_array;
1309}
1310
1311/*----------------------------------------------------------------------------*/
1333/*----------------------------------------------------------------------------*/
1334
1335cpl_error_code gravi_array_get_group_delay_loop (cpl_array ** input,
1336 cpl_array ** flag,
1337 cpl_array * sigma,
1338 double * gd, cpl_size nrow,
1339 double max_width,
1340 int verbose)
1341{
1342 gravi_msg_function_start(verbose);
1343 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1344 cpl_ensure_code (sigma, CPL_ERROR_NULL_INPUT);
1345 cpl_ensure_code (gd, CPL_ERROR_ILLEGAL_OUTPUT);
1346
1347 int nv = 0;
1348 cpl_size nsigma = cpl_array_get_size (sigma);
1349 double width1, step1, width2, step2, width3, step3;
1350 cpl_size w, s, nstep1, nstep2, nstep3;
1351 double x, gd0, gd1, gd2, gd3, current_max = -1.0;
1352 double lbd = 1.0 / cpl_array_get (sigma,nsigma/2,&nv);
1353
1354 /* Width of a single spectral channel in [m] */
1355 double coherence = 0.5 * nsigma / fabs (cpl_array_get (sigma,0,&nv) - cpl_array_get (sigma,nsigma-1,&nv));
1356
1357 /* We never explore more than max_width */
1358 width1 = CPL_MIN (coherence, max_width);
1359 step1 = 2.0 * lbd;
1360 nstep1 = (cpl_size)(width1/step1);
1361
1362 /* Second pass */
1363 width2 = 3.0 * step1;
1364 step2 = 0.1 * lbd;
1365 nstep2 = (cpl_size)(width2/step2);
1366
1367 /* Third pass */
1368 width3 = 3.0 * step2;
1369 step3 = 0.01 * lbd;
1370 nstep3 = (cpl_size)(width3/step3);
1371
1372 /* Allocate memory for the grid search */
1373 double P = 0.0;
1374 double * sigdata = cpl_malloc (sizeof(double complex) * nsigma);
1375 double complex * visdata = cpl_malloc (sizeof(double complex) * nsigma);
1376 double complex * waveform1 = cpl_malloc (sizeof(double complex) * (nstep1+2) * nsigma);
1377 double complex * waveform2 = cpl_malloc (sizeof(double complex) * (nstep2+2) * nsigma);
1378 double complex * waveform3 = cpl_malloc (sizeof(double complex) * (nstep3+2) * nsigma);
1379
1380 /* Copy data as double to secure their type */
1381 for (w=0; w<nsigma; w++) sigdata[w] = cpl_array_get (sigma, w, &nv);
1382
1383 /* Sum of wavenumber differences */
1384 double ds = 0.0;
1385 for (w=1; w<nsigma; w++) ds += sigdata[w] - sigdata[w-1];
1386 ds /= (nsigma-1);
1387
1388 /* Build waveform */
1389 cpl_msg_debug (cpl_func, "Build waveform for 3 pass -- %lli %lli %lli steps", nstep1, nstep2, nstep3);
1390
1391 for (s=0, x = -width1/2.0; x < +width1/2.0; x+=step1)
1392 for (w=0; w<nsigma; w++) { waveform1[s] = cexp (-2.*I*CPL_MATH_PI * x * sigdata[w]); s++;}
1393 for (s=0, x = -width2/2.0; x < +width2/2.0; x+=step2)
1394 for (w=0; w<nsigma; w++) { waveform2[s] = cexp (-2.*I*CPL_MATH_PI * x * sigdata[w]); s++;}
1395 for (s=0, x = -width3/2.0; x < +width3/2.0; x+=step3)
1396 for (w=0; w<nsigma; w++) { waveform3[s] = cexp (-2.*I*CPL_MATH_PI * x * sigdata[w]); s++;}
1397
1398 cpl_msg_debug (cpl_func, "Loop on %lli rows to compute gdelay", nrow);
1399
1400 /* Loop on rows */
1401 for (cpl_size row = 0; row<nrow; row++) {
1402
1403 /* Copy data as double complex to secure their type and allow
1404 * in-place modification between the different grids */
1405 for (w=0; w<nsigma; w++) {
1406 if (flag && cpl_array_get (flag[row], w, &nv)) visdata[w] = 0. + I*0.;
1407 else visdata[w] = cpl_array_get_complex (input[row], w, &nv);
1408 }
1409
1410 /* IOTA method in [m] -- as starting point, with
1411 * equal weight to all channels to avoid badpixels */
1412 double complex is = 0.0 + I * 0.0;
1413 for (w=1; w<nsigma; w++) {
1414 is += visdata[w] * conj(visdata[w-1]) / CPL_MAX(cabs(visdata[w]) * cabs(visdata[w-1]), 1e-15);
1415 }
1416 gd0 = carg (is) / ds / CPL_MATH_2PI;
1417
1418 /* Remove GD */
1419 for (w=0; w<nsigma; w++) visdata[w] *= cexp (-2.*I*CPL_MATH_PI*gd0*sigdata[w]);
1420
1421 /* Loop on x to find the maximum of P(x) = |FT(input(sigma))| */
1422 for (current_max = -1.0, s = 0, x = -width1/2; x < +width1/2; x+=step1) {
1423 double complex tmp = 0.0 * I + 0.0;
1424 for (w=0; w<nsigma; w++) {tmp += visdata[w] * waveform1[s]; s++;}
1425 P = cabs (tmp);
1426 if ( P > current_max) { current_max = P; gd1 = x; }
1427 }
1428
1429 /* Remove GD */
1430 for (w=0; w<nsigma; w++) visdata[w] *= cexp (-2.*I*CPL_MATH_PI*gd1*sigdata[w]);
1431
1432 /* Loop on x to find the maximum of P(x) = |FT(input(sigma))| */
1433 for (current_max = -1.0, s = 0, x = -width2/2; x < +width2/2; x+=step2) {
1434 double complex tmp = 0.0 * I + 0.0;
1435 for (w=0; w<nsigma; w++) {tmp += visdata[w] * waveform2[s]; s++;}
1436 P = cabs (tmp);
1437 if ( P > current_max) { current_max = P; gd2 = x; }
1438 }
1439
1440 /* Remove GD */
1441 for (w=0; w<nsigma; w++) visdata[w] *= cexp (-2.*I*CPL_MATH_PI*gd2*sigdata[w]);
1442
1443 /* Loop on x to find the maximum of P(x) = |FT(input(sigma))| */
1444 for (current_max = -1.0, s = 0, x = -width3/2; x < +width3/2; x+=step3) {
1445 double complex tmp = 0.0 * I + 0.0;
1446 for (w=0; w<nsigma; w++) {tmp += visdata[w] * waveform3[s]; s++;}
1447 P = cabs (tmp);
1448 if ( P > current_max) { current_max = P; gd3 = x; }
1449 }
1450
1451 gd[row] = gd0 + gd1 + gd2 + gd3;
1452
1453 CPLCHECK_MSG("Cannot compute GD");
1454 } /* End loop on rows */
1455
1456 /* Clean memory */
1457 FREE (cpl_free, visdata);
1458 FREE (cpl_free, sigdata);
1459 FREE (cpl_free, waveform1);
1460 FREE (cpl_free, waveform2);
1461 FREE (cpl_free, waveform3);
1462
1463 gravi_msg_function_exit(verbose);
1464 return CPL_ERROR_NONE;
1465}
1466
1467cpl_error_code gravi_table_compute_group_delay (cpl_table * table,
1468 const char *input,
1469 const char *flag,
1470 const char *output, cpl_table * oi_wave)
1471{
1473 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1474 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1475 cpl_ensure_code (flag, CPL_ERROR_NULL_INPUT);
1476 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1477 cpl_ensure_code (oi_wave, CPL_ERROR_NULL_INPUT);
1478
1479 /* Create sigma */
1480 cpl_size nwave = cpl_table_get_nrow (oi_wave);
1481 cpl_array * sigma = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1482 for (cpl_size wave = 0; wave < nwave ; wave ++)
1483 cpl_array_set (sigma, wave, 1./cpl_table_get (oi_wave, "EFF_WAVE", wave, NULL));
1484
1485 /* If output columns doesn't exist, create it */
1486 gravi_table_new_column (table, output, "m", CPL_TYPE_DOUBLE);
1487 double * gdelay = cpl_table_get_data_double (table, output);
1488
1489 /* Get data */
1490 cpl_array ** input_arrays = cpl_table_get_data_array (table, input);
1491 cpl_array ** flag_arrays = cpl_table_get_data_array (table, flag);
1492 cpl_size nrow = cpl_table_get_nrow (table);
1493
1494 CPLCHECK_MSG ("Cannot get data");
1495
1496 /* Run */
1498 flag_arrays,
1499 sigma, gdelay,
1500 nrow, 1.e-3, CPL_TRUE);
1501 FREE (cpl_array_delete, sigma);
1502
1504 return CPL_ERROR_NONE;
1505}
1506
1507
1508
1509/*----------------------------------------------------------------------------*/
1516/*----------------------------------------------------------------------------*/
1517int gravi_table_are_equal (cpl_table * first, cpl_table * second)
1518{
1520 cpl_ensure_code (first, CPL_ERROR_NULL_INPUT);
1521 cpl_ensure_code (second, CPL_ERROR_NULL_INPUT);
1522
1523 cpl_size nrow = cpl_table_get_nrow (first);
1524 cpl_size ncol = cpl_table_get_ncol (first);
1525 int nv = 0;
1526
1527 if (nrow != cpl_table_get_nrow (second)) {cpl_msg_info(cpl_func, "Different rows"); return 0;}
1528 if (ncol != cpl_table_get_ncol (second)) {cpl_msg_info(cpl_func, "Different cols"); return 0;}
1529 if (cpl_table_compare_structure (first, second)) {cpl_msg_info(cpl_func, "Different structure"); return 0;}
1530
1531 /* Create array of names */
1532 cpl_array *names = cpl_table_get_column_names (first);
1533
1534 /* Loop on colums */
1535 for (cpl_size c = 0; c<ncol; c++) {
1536 const char * name = cpl_array_get_string (names, c);
1537 cpl_msg_debug (cpl_func,"Now test %s", name);
1538
1539 /* Cast the type into an int, to avoid warnings */
1540 int type = cpl_table_get_column_type (first, name);
1541
1542 switch (type) {
1543 case CPL_TYPE_STRING:
1544 for (cpl_size r = 0; r<nrow; r++)
1545 if (strcmp (cpl_table_get_string (first, name, r),
1546 cpl_table_get_string (second, name, r) ) )
1547 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1548 break;
1549 case CPL_TYPE_DOUBLE:
1550 case CPL_TYPE_FLOAT:
1551 case CPL_TYPE_INT:
1552 for (cpl_size r = 0; r<nrow; r++)
1553 if (cpl_table_get (first, name, r, &nv) !=
1554 cpl_table_get (second, name, r, &nv) )
1555 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1556 break;
1557 case CPL_TYPE_POINTER|CPL_TYPE_STRING:
1558 for (cpl_size r = 0; r<nrow; r++)
1559 for (cpl_size p = 0; p<cpl_table_get_column_depth (first,name); p++)
1560 if ( strcmp (cpl_array_get_string (cpl_table_get_array (first, name, r), p),
1561 cpl_array_get_string (cpl_table_get_array (second, name, r), p)) )
1562 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1563 break;
1564 case CPL_TYPE_POINTER|CPL_TYPE_DOUBLE:
1565 case CPL_TYPE_POINTER|CPL_TYPE_FLOAT:
1566 case CPL_TYPE_POINTER|CPL_TYPE_INT:
1567 for (cpl_size r = 0; r<nrow; r++)
1568 for (cpl_size p = 0; p<cpl_table_get_column_depth (first,name); p++) {
1569 if (cpl_array_get (cpl_table_get_array (first, name, r), p, NULL) !=
1570 cpl_array_get (cpl_table_get_array (second, name, r), p, NULL) )
1571 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1572 }
1573 break;
1574 default:
1575 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT, "Cannot compare these tables (TBD, FIXME)");
1576 return 0;
1577 }
1578
1579 }/* End loop on columns */
1580
1581 /* Clean memory */
1582 FREE (cpl_array_delete, names);
1583
1585 return 1;
1586}
1587
1588cpl_error_code gravi_table_new_column (cpl_table * table, const char * name, const char * unit, cpl_type type)
1589{
1590 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1591 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1592
1593 if ( cpl_table_has_column (table, name) &&
1594 cpl_table_get_column_type (table, name) == type) {
1595 cpl_msg_info (cpl_func, "Column %s already exists", name);
1596 } else {
1597 cpl_table_new_column (table, name, type);
1598 }
1599
1600 if (type == CPL_TYPE_DOUBLE_COMPLEX || type == CPL_TYPE_FLOAT_COMPLEX)
1601 cpl_table_fill_column_window_complex (table, name, 0, cpl_table_get_nrow (table), 0.0 + I*0.0);
1602 else
1603 cpl_table_fill_column_window (table, name, 0, cpl_table_get_nrow (table), 0.0);
1604
1605 if (unit) cpl_table_set_column_unit (table, name, unit);
1606
1607 return CPL_ERROR_NONE;
1608}
1609
1610cpl_error_code gravi_table_new_column_array (cpl_table * table, const char * name, const char * unit, cpl_type type, cpl_size size)
1611{
1612 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1613 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1614
1615 if ( cpl_table_has_column (table, name) )
1616 cpl_table_erase_column (table, name);
1617
1618 cpl_table_new_column_array (table, name, type, size);
1619 if (unit) cpl_table_set_column_unit (table, name, unit);
1620
1621 return CPL_ERROR_NONE;
1622}
1623
1624cpl_error_code gravi_table_init_column_array (cpl_table * table, const char * name, const char * unit, cpl_type type, cpl_size size)
1625{
1626 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1627 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1628
1629 if ( cpl_table_has_column (table, name) )
1630 cpl_table_erase_column (table, name);
1631
1632 cpl_table_new_column_array (table, name, type, size);
1633 if (unit) cpl_table_set_column_unit (table, name, unit);
1634
1635 cpl_array * array = cpl_array_new (size, type);
1636 cpl_array_fill_window (array, 0, size, 0.0);
1637
1638 cpl_size nrow = cpl_table_get_nrow (table);
1639 for (cpl_size row = 0; row < nrow; row++)
1640 cpl_table_set_array (table, name, row, array);
1641
1642 FREE (cpl_array_delete, array);
1643
1644 return CPL_ERROR_NONE;
1645}
1646
1647/*---------------------------------------------------------------------------*/
1657/*---------------------------------------------------------------------------*/
1658
1659cpl_error_code gravi_imagelist_unwrap_images (cpl_imagelist * imglist)
1660{
1661 cpl_ensure_code (imglist, CPL_ERROR_NULL_INPUT);
1662
1663 cpl_size nrow = cpl_imagelist_get_size (imglist);
1664
1665 for (cpl_size i = nrow-1; i>=0 ; i--) {
1666 cpl_image_unwrap (cpl_imagelist_unset (imglist, i));
1667 CPLCHECK_MSG("Cannot unset image");
1668 }
1669
1670 cpl_imagelist_delete (imglist);
1671 CPLCHECK_MSG("Cannot delete imagelist");
1672
1673 return CPL_ERROR_NONE;
1674}
1675
1676/*---------------------------------------------------------------------------*/
1687/*---------------------------------------------------------------------------*/
1688
1689cpl_imagelist * gravi_imagelist_wrap_column (cpl_table * table_data, const char * data_x)
1690{
1692 cpl_ensure (table_data, CPL_ERROR_NULL_INPUT, NULL);
1693 cpl_ensure (data_x, CPL_ERROR_NULL_INPUT, NULL);
1694
1695 /* Get the type of the column
1696 * Cast into an int to avoid warnings */
1697 int type_column = cpl_table_get_column_type (table_data, data_x);
1698
1699 /* Get pointer to the data */
1700 cpl_size nrow = cpl_table_get_nrow (table_data);
1701 cpl_array ** array = cpl_table_get_data_array (table_data, data_x);
1702 cpl_ensure (array, CPL_ERROR_ILLEGAL_INPUT, NULL);
1703
1704 /* If the column has no-dimension, we fake them */
1705 cpl_size nx, ny;
1706 if (cpl_table_get_column_dimensions (table_data, data_x)<2) {
1707 nx = cpl_table_get_column_depth (table_data, data_x);
1708 ny = 1;
1709 } else {
1710 nx = cpl_table_get_column_dimension (table_data, data_x, 0);
1711 ny = cpl_table_get_column_dimension (table_data, data_x, 1);
1712 }
1713 CPLCHECK_NUL ("Cannot get dimension");
1714
1715 /* Create output */
1716 cpl_image * img;
1717 cpl_imagelist * imglist = cpl_imagelist_new();
1718
1719 /* compute the image list depending of the DATA type */
1720 switch (type_column)
1721 {
1722 case CPL_TYPE_POINTER|CPL_TYPE_DOUBLE :
1723
1724 for (cpl_size j = 0; j < nrow ; j++)
1725 {
1726 img = cpl_image_wrap_double (nx, ny, cpl_array_get_data_double(array[j]));
1727 cpl_imagelist_set (imglist, img, j);
1728 }
1729
1730 break;
1731
1732 case CPL_TYPE_POINTER|CPL_TYPE_INT :
1733
1734 for (cpl_size j = 0; j < nrow ; j++)
1735 {
1736 img = cpl_image_wrap_int (nx, ny, cpl_array_get_data_int(array[j]));
1737 cpl_imagelist_set (imglist, img,j);
1738 }
1739
1740 break;
1741
1742 case CPL_TYPE_POINTER|CPL_TYPE_FLOAT :
1743 for (cpl_size j = 0; j < nrow ; j++)
1744 {
1745 img = cpl_image_wrap_float (nx, ny, cpl_array_get_data_float(array[j]));
1746 cpl_imagelist_set (imglist, img, j);
1747 }
1748
1749 break;
1750
1751 default:
1752
1753 cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
1754 "invalid type of image coming from %s", data_x);
1755 cpl_imagelist_delete (imglist);
1756 return NULL;
1757 break;
1758 }
1759
1761 return imglist;
1762}
1763
1764/*----------------------------------------------------------------------------*/
1769/*----------------------------------------------------------------------------*/
1770
1771double gravi_image_get_noise_window (cpl_image *img,
1772 cpl_size llx, cpl_size lly,
1773 cpl_size urx, cpl_size ury)
1774{
1776 cpl_ensure (img, CPL_ERROR_NULL_INPUT, -1);
1777 int nv;
1778
1779 /* Extract values in vector */
1780 cpl_vector * flux = cpl_vector_new ((urx-llx+1)*(ury-lly+1));
1781
1782 for (cpl_size v = 0, x = llx; x <= urx; x++) {
1783 for (cpl_size y = lly; y <= ury; y++) {
1784 cpl_vector_set (flux, v, cpl_image_get (img, x, y, &nv));
1785 v++;
1786 CPLCHECK_MSG ("Cannot fill vector");
1787 }
1788 }
1789
1790 /* FIXME: remove the median before square */
1791
1792 /* Compute typical error as the
1793 * median of spatial variation */
1794 cpl_vector_multiply (flux, flux);
1795
1796 double RMS = sqrt (cpl_vector_get_median (flux));
1797 FREE (cpl_vector_delete, flux);
1798
1800 return RMS;
1801}
1802
1803/*----------------------------------------------------------------------------*/
1814/*----------------------------------------------------------------------------*/
1815
1816cpl_image * gravi_image_collapse_median_x (cpl_image * img, cpl_size drop_from, cpl_size drop_to)
1817{
1819 cpl_ensure (img, CPL_ERROR_NULL_INPUT, NULL);
1820 cpl_ensure (drop_from < drop_to, CPL_ERROR_ILLEGAL_INPUT, NULL);
1821
1822 /* Get size */
1823 cpl_size nx = cpl_image_get_size_x (img);
1824 cpl_size ny = cpl_image_get_size_y (img);
1825
1826 /* Check */
1827 cpl_ensure (drop_from >0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1828 cpl_ensure (drop_to <=nx, CPL_ERROR_ILLEGAL_INPUT, NULL);
1829
1830 /* Fill mask */
1831 cpl_mask * mask = cpl_mask_new (nx, ny);
1832 for (cpl_size y = 1; y <= ny; y++)
1833 for (cpl_size x = drop_from; x <= drop_to ; x++)
1834 cpl_mask_set (mask, x, y, CPL_BINARY_1);
1835
1836 /* Set BPM */
1837 cpl_mask * bpm = cpl_image_set_bpm (img, mask);
1838
1839 /* Collapse in the x direction */
1840 cpl_image * collapse = cpl_image_collapse_median_create (img, 1, 0, 0);
1841
1842 /* Set back current BPM */
1843 mask = cpl_image_set_bpm (img, bpm);
1844 FREE (cpl_mask_delete, mask);
1845
1846 /* Return collapse */
1848 return collapse;
1849}
1850
1851/*----------------------------------------------------------------------------*/
1852
1853cpl_error_code gravi_image_subtract_collapse (cpl_image * img,
1854 const cpl_image * collapse,
1855 int direction)
1856{
1858 cpl_ensure_code (img, CPL_ERROR_NULL_INPUT);
1859 cpl_ensure_code (collapse, CPL_ERROR_NULL_INPUT);
1860 cpl_ensure_code (direction==0 || direction==1, CPL_ERROR_ILLEGAL_INPUT);
1861
1862 int nv;
1863
1864 /* Get size */
1865 cpl_size nx = cpl_image_get_size_x (img);
1866 cpl_size ny = cpl_image_get_size_y (img);
1867
1868 if (direction == 0) {
1869 /* Collapse was done along the y direction */
1870 cpl_ensure_code (cpl_image_get_size_x (collapse) == nx &&
1871 cpl_image_get_size_y (collapse) == 1,
1872 CPL_ERROR_ILLEGAL_INPUT);
1873
1874 for (cpl_size x = 0; x < nx ; x++) {
1875 double value = cpl_image_get (collapse, x+1, 1, &nv);
1876 for (cpl_size y = 0; y < ny ; y++) {
1877 cpl_image_set (img, x+1, y+1, cpl_image_get (img, x+1, y+1, &nv) - value);
1878 CPLCHECK_MSG ("Cannot remove collapse y");
1879 }
1880 }
1881
1882 } else {
1883 /* Collapse was done along the x direction */
1884 cpl_ensure_code (cpl_image_get_size_x (collapse) == 1 &&
1885 cpl_image_get_size_y (collapse) == ny,
1886 CPL_ERROR_ILLEGAL_INPUT);
1887
1888 for (cpl_size y = 0; y < ny ; y++) {
1889 double value = cpl_image_get (collapse, 1, y+1, &nv);
1890 for (cpl_size x = 0; x < nx ; x++) {
1891 cpl_image_set (img, x+1, y+1, cpl_image_get (img, x+1, y+1, &nv) - value);
1892 CPLCHECK_MSG ("Cannot remove collapse x");
1893 }
1894 }
1895 }
1896
1898 return CPL_ERROR_NONE;
1899}
1900
1901/*----------------------------------------------------------------------------*/
1902
1903cpl_error_code gravi_image_subtract_window (cpl_image * img1, const cpl_image * img2,
1904 cpl_size llx, cpl_size lly,
1905 cpl_size urx, cpl_size ury,
1906 cpl_size llx2, cpl_size lly2)
1907{
1909 cpl_ensure_code (img1, CPL_ERROR_NULL_INPUT);
1910 cpl_ensure_code (img2, CPL_ERROR_NULL_INPUT);
1911
1912 /* Ensure size */
1913 cpl_size nx = cpl_image_get_size_x (img1);
1914 cpl_size ny = cpl_image_get_size_y (img1);
1915
1916 urx = CPL_MIN (urx, nx);
1917 ury = CPL_MIN (ury, ny);
1918 llx2 -= llx;
1919 lly2 -= lly;
1920
1921 int nv;
1922 for (cpl_size x=llx; x<=urx; x++) {
1923 for (cpl_size y=lly; y<=ury; y++) {
1924 cpl_image_set (img1, x, y,
1925 cpl_image_get (img1,x,y,&nv) -
1926 cpl_image_get (img2,x+llx2,y+lly2,&nv));
1927 }
1928 }
1929
1931 return CPL_ERROR_NONE;
1932}
1933
1934/*----------------------------------------------------------------------------*/
1935
1936cpl_error_code gravi_image_replace_window (cpl_image * img1, const cpl_image * img2,
1937 cpl_size llx, cpl_size lly,
1938 cpl_size urx, cpl_size ury,
1939 cpl_size llx2, cpl_size lly2)
1940{
1942 cpl_ensure_code (img1, CPL_ERROR_NULL_INPUT);
1943 cpl_ensure_code (img2, CPL_ERROR_NULL_INPUT);
1944
1945 /* Ensure size */
1946 cpl_size nx = cpl_image_get_size_x (img1);
1947 cpl_size ny = cpl_image_get_size_y (img1);
1948 cpl_size nx2 = cpl_image_get_size_x (img2);
1949 cpl_size ny2 = cpl_image_get_size_y (img2);
1950 cpl_msg_info(cpl_func, "Size image 1 %lli/%lli, Size window %lli/%lli" , nx,ny,nx2,ny2);
1951
1952 urx = CPL_MIN (urx, nx);
1953 ury = CPL_MIN (ury, ny);
1954 llx2 -= llx;
1955 lly2 -= lly;
1956
1957 int nv;
1958 for (cpl_size x=llx; x<=urx; x++) {
1959 for (cpl_size y=lly; y<=ury; y++) {
1960 cpl_image_set (img1, x, y,
1961 cpl_image_get (img2,x+llx2,y+lly2,&nv));
1962 }
1963 }
1964
1966 return CPL_ERROR_NONE;
1967}
1968
1969/*---------------------------------------------------------------------------*/
1982/*---------------------------------------------------------------------------*/
1983
1984cpl_image * gravi_image_from_column (cpl_table * table_data, const char * data_x, cpl_size row)
1985{
1987 cpl_ensure (table_data, CPL_ERROR_NULL_INPUT, NULL);
1988 cpl_ensure (data_x, CPL_ERROR_NULL_INPUT, NULL);
1989 cpl_ensure (row < cpl_table_get_nrow (table_data), CPL_ERROR_ILLEGAL_INPUT, NULL);
1990
1991 cpl_imagelist * wrap_imglist = gravi_imagelist_wrap_column (table_data, data_x);
1992 cpl_ensure (wrap_imglist, CPL_ERROR_ILLEGAL_INPUT, NULL);
1993
1994 cpl_image * out_img = cpl_image_duplicate (cpl_imagelist_get (wrap_imglist, row));
1995 gravi_imagelist_unwrap_images (wrap_imglist);
1996
1998 return out_img;
1999}
2000
2001/*---------------------------------------------------------------------------*/
2014/*---------------------------------------------------------------------------*/
2015
2016cpl_imagelist * gravi_imagelist_from_column (cpl_table * table_data, const char * data_x)
2017{
2019 cpl_ensure (table_data, CPL_ERROR_NULL_INPUT, NULL);
2020 cpl_ensure (data_x, CPL_ERROR_NULL_INPUT, NULL);
2021
2022 cpl_imagelist * wrap_imglist = gravi_imagelist_wrap_column (table_data, data_x);
2023 cpl_ensure (wrap_imglist, CPL_ERROR_ILLEGAL_INPUT, NULL);
2024
2025 cpl_imagelist * out_imglist = cpl_imagelist_duplicate (wrap_imglist);
2026 gravi_imagelist_unwrap_images (wrap_imglist);
2027
2029 return out_imglist;
2030}
2031
2032
2033/*---------------------------------------------------------------------------*/
2044/*---------------------------------------------------------------------------*/
2045
2046cpl_array * gravi_table_get_column_dimension (const cpl_table * table, const char * name)
2047{
2048 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
2049 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
2050
2051 cpl_size ndim = cpl_table_get_column_dimensions (table, name);
2052 cpl_array * dimension = cpl_array_new (ndim, CPL_TYPE_INT);
2053 for (cpl_size dim = 0; dim < ndim; dim++) {
2054 int value = cpl_table_get_column_dimension (table, name, dim);
2055 cpl_array_set (dimension, dim, value);
2056 }
2057
2058 return dimension;
2059}
2060
2061/*---------------------------------------------------------------------------*/
2071/*---------------------------------------------------------------------------*/
2072
2073cpl_array * gravi_array_wrap_image (cpl_image * img)
2074{
2075 cpl_ensure (img, CPL_ERROR_NULL_INPUT, NULL);
2076
2077 cpl_type type_img = cpl_image_get_type (img);
2078 int x = cpl_image_get_size_x (img);
2079 int y = cpl_image_get_size_y (img);
2080
2081 CPLCHECK_NUL ("Cannot get data");
2082
2083 cpl_array * array = NULL;
2084 switch (type_img){
2085 case CPL_TYPE_FLOAT :
2086 array = cpl_array_wrap_float (cpl_image_get_data_float(img), x*y);
2087 break;
2088 case CPL_TYPE_DOUBLE :
2089 array = cpl_array_wrap_double (cpl_image_get_data_double(img), x*y);
2090 break;
2091 case CPL_TYPE_INT :
2092 array = cpl_array_wrap_int (cpl_image_get_data_int(img), x*y);
2093 break;
2094 default :
2095 cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
2096 "invalid type of image");
2097 return NULL;
2098 }
2099
2100 return array;
2101}
2102
2103
2104/*---------------------------------------------------------------------------*/
2115/*---------------------------------------------------------------------------*/
2116
2117cpl_matrix * get_matrix_from_vector(cpl_vector * vector1,
2118 cpl_vector * vector2)
2119{
2120 cpl_ensure (vector1, CPL_ERROR_NULL_INPUT, NULL);
2121
2122 cpl_matrix * matrix, * matrix_wrap;
2123 int size = cpl_vector_get_size(vector1);
2124 double * data1, * data2;
2125
2126 if( vector2 != NULL ){
2127 int size2 = cpl_vector_get_size(vector2);
2128 cpl_ensure (size == size2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2129
2130 data1 = cpl_malloc(2 * size * sizeof(double));
2131 memcpy(data1, cpl_vector_get_data(vector1), size * sizeof(double));
2132
2133 data2 = cpl_vector_get_data(vector2);
2134 memcpy(data1 + size, data2, size * sizeof(double));
2135
2136 matrix_wrap = cpl_matrix_wrap(2, size, data1);
2137 matrix = cpl_matrix_transpose_create(matrix_wrap);
2138
2139 cpl_matrix_unwrap(matrix_wrap);
2140 }
2141 else{
2142 data1 = cpl_malloc(size * sizeof(double));
2143 memcpy(data1, cpl_vector_get_data(vector1), size * sizeof(double));
2144
2145 matrix = cpl_matrix_wrap(size, 1, data1);
2146 }
2147 cpl_free(data1);
2148
2149 return matrix;
2150}
2151
2152/*---------------------------------------------------------------------------*/
2165/*---------------------------------------------------------------------------*/
2166
2167cpl_vector * gravi_table_get_vector (cpl_table * spectrum_data,
2168 cpl_size index,
2169 const char * regname)
2170{
2171 /* Check the inputs */
2172 cpl_ensure (spectrum_data, CPL_ERROR_NULL_INPUT, NULL);
2173 cpl_ensure (regname, CPL_ERROR_NULL_INPUT, NULL);
2174 cpl_ensure (index>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2175
2176 /* Get the array size */
2177 cpl_size size = cpl_table_get_column_depth (spectrum_data, regname);
2178 cpl_ensure (index<size, CPL_ERROR_ILLEGAL_INPUT, NULL);
2179
2180 /* allocate the vector */
2181 cpl_size nrow = cpl_table_get_nrow (spectrum_data);
2182 cpl_vector * data_value = cpl_vector_new (nrow);
2183
2184 if (size > 0) {
2185
2186 /* Extract the data from the column region */
2187 cpl_array ** column_array = cpl_table_get_data_array (spectrum_data, regname);
2188 cpl_ensure (column_array, CPL_ERROR_ILLEGAL_INPUT, NULL);
2189
2190 /* Loop on row */
2191 double value;
2192 for (cpl_size row = 0; row < nrow; row ++){
2193 value = cpl_array_get (column_array[row], index, NULL);
2194 cpl_vector_set (data_value, row, value);
2195 }
2196 } else if (cpl_table_get_column_type (spectrum_data, regname)
2197 == CPL_TYPE_DOUBLE) {
2198
2199 double * data = cpl_table_get_data_double (spectrum_data, regname);
2200 for (cpl_size row = 0; row < nrow; row++) {
2201 cpl_vector_set (data_value, row, data[row]);
2202 }
2203
2204 } else if (cpl_table_get_column_type (spectrum_data, regname)
2205 == CPL_TYPE_INT) {
2206
2207 int * data = cpl_table_get_data_int (spectrum_data, regname);
2208 for (cpl_size row = 0; row < nrow; row++) {
2209 cpl_vector_set (data_value, row, data[row]);
2210 }
2211
2212 } else {
2213 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2214 "This type is not supported"
2215 "(report to DRS team).");
2216 FREE (cpl_vector_delete, data_value);
2217 return NULL;
2218 }
2219
2220 return (data_value);
2221}
2222
2223cpl_vector * gravi_table_get_vector_scalar (cpl_table * table,
2224 const char * name,
2225 cpl_size base,
2226 cpl_size nbase)
2227{
2228 /* Check the inputs */
2229 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
2230 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
2231 cpl_ensure (base>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2232 cpl_ensure (nbase>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2233
2234 /* Ensure it is scalar */
2235 cpl_size size = cpl_table_get_column_depth (table, name);
2236 cpl_ensure (size==0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2237
2238 /* Allocate the vector */
2239 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
2240 cpl_vector * vector = cpl_vector_new (nrow);
2241
2242 /* Get the type */
2243 cpl_type type = cpl_table_get_column_type (table, name);
2244
2245 if (type == CPL_TYPE_DOUBLE) {
2246 double * data = cpl_table_get_data_double (table, name);
2247 for (cpl_size row = 0; row < nrow; row++)
2248 cpl_vector_set (vector, row, data[row*nbase+base]);
2249 }
2250 else if (type == CPL_TYPE_FLOAT) {
2251 float * data = cpl_table_get_data_float (table, name);
2252 for (cpl_size row = 0; row < nrow; row++)
2253 cpl_vector_set (vector, row, data[row*nbase+base]);
2254 }
2255 else if (type == CPL_TYPE_INT) {
2256 int * data = cpl_table_get_data_int (table, name);
2257 for (cpl_size row = 0; row < nrow; row++)
2258 cpl_vector_set (vector, row, data[row*nbase+base]);
2259 }
2260 else {
2261 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2262 "This type is not supported"
2263 "(report to DRS team).");
2264 FREE (cpl_vector_delete, vector);
2265 return NULL;
2266 }
2267
2268 return vector;
2269}
2270
2271/*---------------------------------------------------------------------------*/
2286/*---------------------------------------------------------------------------*/
2287
2288cpl_vector * gravi_table_get_vector_diff (cpl_table * spectrum_data, int index,
2289 const char * regname1,
2290 const char * regname2)
2291{
2292 /* Check the inputs */
2293 cpl_ensure (spectrum_data, CPL_ERROR_NULL_INPUT, NULL);
2294 cpl_ensure (regname1, CPL_ERROR_NULL_INPUT, NULL);
2295 cpl_ensure (regname2, CPL_ERROR_NULL_INPUT, NULL);
2296 cpl_ensure (index>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2297
2298 /* Get the array size */
2299 cpl_size size1 = cpl_table_get_column_depth (spectrum_data, regname1);
2300 cpl_size size2 = cpl_table_get_column_depth (spectrum_data, regname2);
2301 cpl_ensure (index<size1, CPL_ERROR_ILLEGAL_INPUT, NULL);
2302 cpl_ensure (index<size2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2303
2304 /* Extract the data from the column region */
2305 cpl_array ** column_array1 = cpl_table_get_data_array (spectrum_data, regname1);
2306 cpl_array ** column_array2 = cpl_table_get_data_array (spectrum_data, regname2);
2307 cpl_ensure (column_array1, CPL_ERROR_ILLEGAL_INPUT, NULL);
2308 cpl_ensure (column_array2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2309
2310 /* allocate the vector */
2311 cpl_size nrow = cpl_table_get_nrow (spectrum_data);
2312 cpl_vector * data_value = cpl_vector_new (nrow);
2313
2314 /* Loop on row */
2315 double value;
2316 for (cpl_size row = 0; row < nrow; row++){
2317 value = cpl_array_get (column_array1[row], index, NULL) - cpl_array_get (column_array2[row], index, NULL);
2318 cpl_vector_set (data_value, row, value);
2319 }
2320
2321 return (data_value);
2322}
2323
2324/*---------------------------------------------------------------------------*/
2328/*---------------------------------------------------------------------------*/
2329
2330cpl_error_code gravi_image_fill (cpl_image * img, double value)
2331{
2332 cpl_ensure_code (img, CPL_ERROR_NULL_INPUT);
2333
2334 cpl_size nx = cpl_image_get_size_x (img);
2335 cpl_size ny = cpl_image_get_size_y (img);
2336 cpl_image_fill_window (img, 1,1,nx,ny, value);
2337
2338 return CPL_ERROR_NONE;
2339}
2340
2341/*---------------------------------------------------------------------------*/
2345/*---------------------------------------------------------------------------*/
2346
2347cpl_image * gravi_image_wrap_matrix (cpl_matrix * matrix)
2348{
2349 cpl_ensure (matrix, CPL_ERROR_NULL_INPUT, NULL);
2350 cpl_size nx = cpl_matrix_get_ncol (matrix);
2351 cpl_size ny = cpl_matrix_get_nrow (matrix);
2352 return cpl_image_wrap_double (nx, ny, cpl_matrix_get_data (matrix));
2353}
2354
2355cpl_image * gravi_image_from_matrix (cpl_matrix * matrix)
2356{
2357 cpl_ensure (matrix, CPL_ERROR_NULL_INPUT, NULL);
2358 cpl_size nx = cpl_matrix_get_ncol (matrix);
2359 cpl_size ny = cpl_matrix_get_nrow (matrix);
2360
2361 cpl_image * image = cpl_image_new (nx,ny,CPL_TYPE_DOUBLE);
2362 for (cpl_size i = 0; i < nx; i++)
2363 for (cpl_size j = 0; j < ny; j++)
2364 cpl_image_set (image, i+1, j+1, cpl_matrix_get (matrix,j,i));
2365
2366 return image;
2367}
2368
2369/*---------------------------------------------------------------------------*/
2373/*---------------------------------------------------------------------------*/
2374
2375cpl_image * gravi_image_wrap_vector (cpl_vector * vector)
2376{
2377 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, NULL);
2378 cpl_size nx = cpl_vector_get_size (vector);
2379 cpl_size ny = 1;
2380 return cpl_image_wrap_double (nx, ny, cpl_vector_get_data (vector));
2381}
2382
2383cpl_image * gravi_image_from_vector (cpl_vector * vector)
2384{
2385 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, NULL);
2386 cpl_size nx = cpl_vector_get_size (vector);
2387 cpl_size ny = 1;
2388
2389 cpl_image * image = cpl_image_new (nx,ny,CPL_TYPE_DOUBLE);
2390 for (cpl_size i = 0; i < nx; i++)
2391 cpl_image_set (image, i+1, 1, cpl_vector_get (vector,i));
2392
2393 return image;
2394}
2395
2396/*---------------------------------------------------------------------------*/
2407/*---------------------------------------------------------------------------*/
2408
2409double gravi_image_get_quantile (const cpl_image * img, double thr)
2410{
2411 cpl_ensure (img, CPL_ERROR_NULL_INPUT, -1);
2412 cpl_ensure (thr>0 && thr<1, CPL_ERROR_ILLEGAL_INPUT, -1);
2413
2414 cpl_size nx = cpl_image_get_size_x (img);
2415 cpl_size ny = cpl_image_get_size_y (img);
2416 cpl_size nq = (cpl_size)(thr * nx * ny);
2417
2418 cpl_ensure (nq>=0 && nq<=nx*ny, CPL_ERROR_ILLEGAL_INPUT, -1);
2419
2420 /* Create vector and fill */
2421 int nv;
2422 cpl_vector * vect = cpl_vector_new (nx*ny);
2423 for (cpl_size ix = 0; ix < nx ; ix++)
2424 for (cpl_size iy = 0; iy < ny ; iy++)
2425 cpl_vector_set (vect, ix * ny + iy, cpl_image_get (img, ix+1, iy+1, &nv));
2426
2427 /* Sort and get quartil */
2428 cpl_vector_sort (vect, CPL_SORT_ASCENDING);
2429 double value = cpl_vector_get (vect, nq);
2430 cpl_vector_delete (vect);
2431
2432 return value;
2433}
2434
2435/*---------------------------------------------------------------------------*/
2441/*---------------------------------------------------------------------------*/
2442
2443double gravi_array_get_quantile (cpl_array * arr, double thr)
2444{
2445 cpl_ensure (arr, CPL_ERROR_NULL_INPUT, -1);
2446 cpl_ensure (thr>0 && thr<1, CPL_ERROR_ILLEGAL_INPUT, -1);
2447
2448 cpl_size nx = cpl_array_get_size (arr);
2449 cpl_size nq = (cpl_size)(thr * nx);
2450
2451 cpl_ensure (nq>=0 && nq<=nx, CPL_ERROR_ILLEGAL_INPUT, -1);
2452
2453 /* Create vector and fill */
2454 int nv;
2455 cpl_vector * vect = cpl_vector_new (nx);
2456 for (cpl_size ix = 0; ix < nx ; ix++)
2457 cpl_vector_set (vect, ix, cpl_array_get (arr, ix, &nv));
2458
2459 /* Sort and get quartil */
2460 cpl_vector_sort (vect, CPL_SORT_ASCENDING);
2461 double value = cpl_vector_get (vect, nq);
2462 cpl_vector_delete (vect);
2463
2464 return value;
2465}
2466
2467/*---------------------------------------------------------------------------*/
2477/*---------------------------------------------------------------------------*/
2478
2479cpl_vector * gravi_vector_median (const cpl_vector * vector, cpl_size hw)
2480{
2481 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, NULL);
2482 cpl_ensure (hw>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2483
2484 cpl_size size = cpl_vector_get_size (vector);
2485 cpl_vector * median = NULL;
2486
2487 /* Case the vector is shorter than the the box */
2488 if (size < hw*2+3)
2489 {
2490 median = cpl_vector_new (size);
2491 cpl_vector_fill (median, cpl_vector_get_median_const (vector));
2492 }
2493 /* case longer than the box */
2494 else
2495 {
2496 median = cpl_vector_filter_median_create (vector, hw);
2497 cpl_ensure (median, CPL_ERROR_DATA_NOT_FOUND, NULL);
2498
2499 double * data = cpl_vector_get_data (median);
2500 cpl_ensure (data, CPL_ERROR_DATA_NOT_FOUND, NULL);
2501
2502 for (int i = 0; i < hw; i++) data[i] = data[hw];
2503 for (int i = size-hw; i < size; i++) data[i] = data[size-hw-1];
2504 }
2505
2506 return median;
2507}
2508/*---------------------------------------------------------------------------*/
2518/*---------------------------------------------------------------------------*/
2519
2520cpl_error_code gravi_vector_abs (cpl_vector * vector)
2521{
2522 cpl_ensure_code (vector, CPL_ERROR_NULL_INPUT);
2523
2524 /* Get data */
2525 cpl_size size = cpl_vector_get_size (vector);
2526 cpl_ensure_code (size > 0, CPL_ERROR_ILLEGAL_INPUT);
2527
2528 double * data = cpl_vector_get_data (vector);
2529 cpl_ensure_code (data, CPL_ERROR_ILLEGAL_INPUT);
2530
2531 /* Take abs */
2532 for (int i = 0; i < size; i++) data[i] = fabs (data[i]);
2533
2534 return CPL_ERROR_NONE;
2535}
2536
2537/*---------------------------------------------------------------------------*/
2544/*---------------------------------------------------------------------------*/
2545
2546cpl_size gravi_vector_get_maxpos (cpl_vector * vector)
2547{
2548 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, -1);
2549 cpl_size size = cpl_vector_get_size (vector);
2550
2551 cpl_size pos = 0;
2552 double value = cpl_vector_get (vector, 0);
2553 for (int s = 1; s < size; s++) {
2554 if (cpl_vector_get (vector, s) > value) {
2555 pos = s;
2556 value = cpl_vector_get (vector, s);
2557 }
2558 }
2559
2560 return pos;
2561}
2562
2563/*---------------------------------------------------------------------------*/
2573/*---------------------------------------------------------------------------*/
2574double gravi_vector_get_mean_clip (cpl_vector * vector_in,
2575 double percent,
2576 double nsigma)
2577{
2578 cpl_ensure (vector_in, CPL_ERROR_NULL_INPUT, 0.0);
2579 cpl_ensure (percent > 0, CPL_ERROR_ILLEGAL_INPUT, 0.0);
2580 cpl_ensure (percent < 0.5, CPL_ERROR_ILLEGAL_INPUT, 0.0);
2581 cpl_ensure (nsigma > 0, CPL_ERROR_ILLEGAL_INPUT, 0.0);
2582
2583 /* Sort */
2584 cpl_vector * sort_vector = cpl_vector_duplicate (vector_in);
2585 cpl_vector_sort (sort_vector, CPL_SORT_ASCENDING);
2586
2587 /* Clip extrems values */
2588 cpl_size size = cpl_vector_get_size (vector_in);
2589 cpl_size sizeout = size*(1-percent*2);
2590 cpl_size start = (size-sizeout)/2;
2591
2592 cpl_vector * vector = cpl_vector_new (sizeout);
2593 for (cpl_size i = 0 ; i < sizeout ; i++)
2594 cpl_vector_set (vector, i, cpl_vector_get (sort_vector, i+start));
2595
2596 /* Clip above several sigmas */
2597 cpl_vector * vector_med = cpl_vector_new (sizeout);
2598 double med = cpl_vector_get_median (vector);
2599 double rms = nsigma * cpl_vector_get_stdev (vector);
2600
2601 cpl_size size_med = 0;
2602 for (cpl_size i = 0 ; i < cpl_vector_get_size (vector) ; i++)
2603 if ( (cpl_vector_get (vector, i) > med-rms) &&
2604 (cpl_vector_get (vector, i) < med+rms) ) {
2605 cpl_vector_set (vector_med, size_med, cpl_vector_get (vector, i));
2606 size_med++;
2607 }
2608 cpl_vector_set_size (vector_med, size_med);
2609
2610 /* Compute mean of accepted values */
2611 double output = cpl_vector_get_mean (vector_med);
2612
2613 FREE (cpl_vector_delete, vector_med);
2614 FREE (cpl_vector_delete, sort_vector);
2615 return output;
2616}
2617
2618/*---------------------------------------------------------------------------*/
2626/*---------------------------------------------------------------------------*/
2627
2628cpl_vector * gravi_vector_extract (const cpl_vector * vector, int start, int step)
2629{
2630 cpl_size size = cpl_vector_get_size (vector);
2631 cpl_size newsize = size / step;
2632 cpl_vector * out = cpl_vector_new (newsize);
2633
2634 for (int s = 0; s < newsize; s++)
2635 cpl_vector_set (out, s, cpl_vector_get (vector, s*step+start));
2636
2637 return out;
2638}
2639
2640/*---------------------------------------------------------------------------*/
2649/*---------------------------------------------------------------------------*/
2650
2651cpl_error_code gravi_vector_unwrap_with_guess (cpl_vector * vector, cpl_vector * ref, double ref_to_phase)
2652{
2653 cpl_ensure_code (vector, CPL_ERROR_NULL_INPUT);
2654 cpl_ensure_code (ref, CPL_ERROR_NULL_INPUT);
2655
2656 cpl_size nrow = cpl_vector_get_size (vector);
2657
2658 double referenced, referenced_prev = 0.0;
2659 cpl_size wrap = 0;
2660
2661 for (cpl_size row = 0 ; row < nrow; row ++) {
2662 double phase_ref = ref_to_phase * cpl_vector_get (ref, row);
2663
2664 /* Referenced phase in radian in [0,2pi] */
2665 referenced = (cpl_vector_get (vector, row) - phase_ref);
2666 referenced = fmod (referenced, CPL_MATH_2PI);
2667 if (referenced < 0) referenced += CPL_MATH_2PI;
2668
2669 /* Check if referenced_phase is wrapp */
2670 if ( referenced - referenced_prev > CPL_MATH_PI ) wrap --;
2671 if ( referenced - referenced_prev < -CPL_MATH_PI ) wrap ++;
2672 referenced_prev = referenced;
2673
2674 /* Set back in-place */
2675 cpl_vector_set (vector, row, phase_ref + referenced + wrap * CPL_MATH_2PI);
2676 }
2677
2678 CPLCHECK_MSG ("Cannot unwrap with guess");
2679
2680 return CPL_ERROR_NONE;
2681}
2682
2683/*---------------------------------------------------------------------------*/
2696/*---------------------------------------------------------------------------*/
2697
2698cpl_error_code gravi_table_multiply_scalar (cpl_table * table, const char * name,
2699 int base, int nbase, double value)
2700{
2701 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
2702 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
2703 cpl_ensure_code (nbase==1 || nbase==4 || nbase==6, CPL_ERROR_ILLEGAL_INPUT);
2704 cpl_ensure_code (base>=0 && base <nbase, CPL_ERROR_ILLEGAL_INPUT);
2705
2706 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
2707
2708 if (cpl_table_get_column_depth (table, name) > 0) {
2709 cpl_array ** array = cpl_table_get_data_array (table, name);
2710 for (cpl_size row = 0 ; row < nrow ; row ++) {
2711 cpl_array_multiply_scalar (array[row*nbase+base], value);
2712 CPLCHECK_MSG ("Cannot multiply (array may not be numerical)");
2713 }
2714 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_DOUBLE) {
2715 double * array = cpl_table_get_data_double (table, name);
2716 for (cpl_size row = 0 ; row < nrow ; row ++) {
2717 array[row*nbase+base] *= value;
2718 }
2719 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_INT) {
2720 int * array = cpl_table_get_data_int (table, name);
2721 for (cpl_size row = 0 ; row < nrow ; row ++) {
2722 array[row*nbase+base] *= value;
2723 }
2724 } else {
2725 return cpl_error_set_message (cpl_func, CPL_ERROR_INVALID_TYPE,
2726 "Column type is not supported");
2727 }
2728
2729 CPLCHECK_MSG ("Cannot multiply");
2730 return CPL_ERROR_NONE;
2731}
2732
2733/*---------------------------------------------------------------------------*/
2746/*---------------------------------------------------------------------------*/
2747
2748cpl_error_code gravi_table_add_scalar (cpl_table * table, const char * name,
2749 int base, int nbase, double value)
2750{
2751 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
2752 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
2753 cpl_ensure_code (nbase==1 || nbase==4 || nbase==6, CPL_ERROR_ILLEGAL_INPUT);
2754 cpl_ensure_code (base>=0 && base <nbase, CPL_ERROR_ILLEGAL_INPUT);
2755
2756 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
2757
2758 if (cpl_table_get_column_depth (table, name) > 0) {
2759 cpl_array ** array = cpl_table_get_data_array (table, name);
2760 for (cpl_size row = 0 ; row < nrow ; row ++) {
2761 cpl_array_add_scalar (array[row*nbase+base], value);
2762 CPLCHECK_MSG ("Cannot multiply (array may not be numerical)");
2763 }
2764 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_DOUBLE) {
2765 double * array = cpl_table_get_data_double (table, name);
2766 for (cpl_size row = 0 ; row < nrow ; row ++) {
2767 array[row*nbase+base] += value;
2768 }
2769 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_INT) {
2770 int * array = cpl_table_get_data_int (table, name);
2771 for (cpl_size row = 0 ; row < nrow ; row ++) {
2772 array[row*nbase+base] += value;
2773 }
2774 } else {
2775 return cpl_error_set_message (cpl_func, CPL_ERROR_INVALID_TYPE,
2776 "Column type is not supported");
2777 }
2778
2779 CPLCHECK_MSG ("Cannot multiply");
2780 return CPL_ERROR_NONE;
2781}
2782
2783
2784/*---------------------------------------------------------------------------*/
2797/*---------------------------------------------------------------------------*/
2798
2799cpl_matrix * gravi_matrix_interpolate_col (cpl_matrix * matrix,
2800 cpl_vector * xref,
2801 cpl_vector * xout)
2802{
2804
2805 cpl_ensure (matrix, CPL_ERROR_NULL_INPUT, NULL);
2806 cpl_ensure (xref, CPL_ERROR_NULL_INPUT, NULL);
2807 cpl_ensure (xout, CPL_ERROR_NULL_INPUT, NULL);
2808
2809 cpl_size nrow = cpl_matrix_get_nrow (matrix);
2810 cpl_size ncol = cpl_matrix_get_ncol (matrix);
2811 cpl_size nxref = cpl_vector_get_size (xref);
2812 cpl_size nxout = cpl_vector_get_size (xout);
2813
2814 cpl_ensure (ncol == nxref, CPL_ERROR_ILLEGAL_INPUT, NULL);
2815 cpl_ensure (nxout > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2816
2817 /* Allocate memory */
2818 cpl_matrix * outmatrix = cpl_matrix_new (nrow, nxout);
2819 cpl_vector * yref = cpl_vector_new (nxref);
2820 cpl_vector * yout = cpl_vector_new (nxout);
2821 cpl_bivector * fref = cpl_bivector_wrap_vectors (xref, yref);
2822 cpl_bivector * fout = cpl_bivector_wrap_vectors (xout, yout);
2823
2824 /* Loop on rows */
2825 for (cpl_size row = 0; row < nrow; row++) {
2826 for (cpl_size x = 0; x < nxref; x++)
2827 cpl_vector_set (yref, x, cpl_matrix_get (matrix, row, x));
2828 cpl_bivector_interpolate_linear (fout, fref);
2829 for (cpl_size x = 0; x < nxout; x++)
2830 cpl_matrix_set (outmatrix, row, x, cpl_vector_get (yout, x));
2831 CPLCHECK_NUL ("Cannot interpolate matrix");
2832 }
2833
2834 FREE (cpl_bivector_unwrap_vectors, fref);
2835 FREE (cpl_bivector_unwrap_vectors, fout);
2836 FREE (cpl_vector_delete, yref);
2837 FREE (cpl_vector_delete, yout);
2838
2840 return outmatrix;
2841}
2842
2843/*---------------------------------------------------------------------------*/
2851/*---------------------------------------------------------------------------*/
2852
2853cpl_matrix * gravi_matrix_invertSV_create (cpl_matrix *a_in)
2854{
2856
2857 cpl_ensure (a_in, CPL_ERROR_NULL_INPUT, NULL);
2858
2859 cpl_size m = cpl_matrix_get_nrow (a_in);
2860 cpl_size n = cpl_matrix_get_ncol (a_in);
2861
2862 cpl_vector * w = cpl_vector_new (n);
2863 cpl_matrix * v = cpl_matrix_new (n, n);
2864
2865 /*
2866 * fill nr matrix with data
2867 * w are the singular values of the matrix
2868 */
2869 cpl_matrix * a_out = svdcmp (a_in, w, v);
2870 CPLCHECK_NUL ("Error in inverse SV");
2871
2872 /* Check the singular values */
2873 for (cpl_size ii = 0; ii < n; ii++) {
2874 if (cpl_vector_get (w, ii) < 0.1)
2875 cpl_msg_warning (cpl_func, "Singular Value %lld = %e",
2876 ii, cpl_vector_get (w, ii));
2877 }
2878
2879 /*
2880 * Compute inverse (vt*1/w*at)
2881 */
2882 cpl_matrix * a_inv = cpl_matrix_new (n,m);
2883 double * a_inv_data = cpl_matrix_get_data (a_inv);
2884
2885 for (cpl_size j = 0; j < m; j++) {
2886 for (cpl_size i = 0; i < n; i++){
2887 double wv_at = 0;
2888
2889 for (cpl_size ii = 0; ii < n; ii++)
2890 if (cpl_vector_get (w, ii) > 1e-15)
2891 wv_at += cpl_matrix_get (v, i, ii) /
2892 cpl_vector_get (w, ii) *
2893 cpl_matrix_get (a_out, j, ii);
2894
2895 a_inv_data[j + i * m] = wv_at;
2896 }
2897 }
2898
2899 /* Delete intermediate matrix */
2900 cpl_vector_delete (w);
2901 cpl_matrix_delete (v);
2902 cpl_matrix_delete (a_out);
2903
2905 return a_inv;
2906}
2907
2908/*
2909 * pythag fonction from numerical recipe in C,
2910 * necessary for gravi_matrix_invertSV_create
2911 */
2912double pythag(double a, double b)
2913{
2914 double absa=fabs(a);
2915 double absb=fabs(b);
2916 if (absa > absb)
2917 return absa*sqrt(1.0+pow(absb/absa, 2));
2918 else
2919 return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+pow(absa/absb, 2)));
2920}
2921
2922/*
2923 * svdcmp fonction from numerical recipe in C
2924 * w and v are pre-allocated results,
2925 * necessary for gravi_matrix_invertSV_create
2926 */
2927cpl_matrix * svdcmp (cpl_matrix * a_in, cpl_vector * w, cpl_matrix * v)
2928{
2930 cpl_ensure (a_in, CPL_ERROR_NULL_INPUT, NULL);
2931
2932 int flag, i, its, j, jj, k, l, nm, n, m;
2933 double anorm, c, f, g, h, s, scale, x, y, z;
2934 cpl_vector * rv1;
2935 cpl_matrix * a;
2936
2937 a = cpl_matrix_duplicate(a_in);
2938 m = cpl_matrix_get_nrow (a_in);
2939 n = cpl_matrix_get_ncol (a_in);
2940 rv1 = cpl_vector_new(n);
2941
2942 g = scale = anorm = 0.0;
2943 for (i = 0; i < n; i++) {
2944 l = i + 1;
2945 cpl_vector_set(rv1, i, scale*g);
2946 g = s = scale = 0.0;
2947 if (i < m) {
2948 for (k = i; k < m; k++)
2949 scale += fabs(cpl_matrix_get(a, k, i));
2950 if (scale) {
2951
2952 for (k = i; k < m; k++) {
2953
2954 cpl_matrix_set (a, k, i, cpl_matrix_get(a, k, i)/scale);
2955 s += cpl_matrix_get(a, k, i) * cpl_matrix_get(a, k, i);
2956 }
2957 f = cpl_matrix_get(a, i, i);
2958 g = -SIGN(sqrt(s),f);
2959 h = f * g - s;
2960 cpl_matrix_set (a, i, i, f - g);
2961 for (j = l; j < n; j++) {
2962 for (s = 0.0, k = i; k < m; k++)
2963 s += cpl_matrix_get(a, k, i) * cpl_matrix_get(a, k, j);
2964
2965 f = s / h;
2966 for (k = i; k < m; k++)
2967 cpl_matrix_set (a, k, j, cpl_matrix_get(a, k, j) +
2968 f * cpl_matrix_get(a, k, i));
2969
2970 }
2971 for (k = i; k < m; k++)
2972 cpl_matrix_set (a, k, i, cpl_matrix_get(a, k, i) * scale);
2973
2974 }
2975 }
2976
2977 cpl_vector_set(w, i, scale *g);
2978
2979 g = s = scale = 0.0;
2980 if (i < m && i != (n - 1)) {
2981 for (k = l; k < n; k++)
2982 scale += fabs(cpl_matrix_get(a, i, k));;
2983 if (scale) {
2984 for (k = l; k < n; k++) {
2985 cpl_matrix_set (a, i, k, cpl_matrix_get(a, i, k) / scale);
2986 s += cpl_matrix_get(a, i, k) * cpl_matrix_get(a, i, k);
2987 }
2988 f = cpl_matrix_get(a, i, l);
2989 g = -SIGN(sqrt(s),f);
2990 h = f * g - s;
2991 cpl_matrix_set (a, i, l, f - g);
2992 for (k = l; k < n; k++)
2993 cpl_vector_set(rv1, k, cpl_matrix_get(a, i, k)/h);
2994 for (j = l; j < m; j++) {
2995 for (s = 0.0, k = l; k < n; k++)
2996 s += cpl_matrix_get(a, j, k) * cpl_matrix_get(a, i, k);
2997 for (k = l; k < n; k++)
2998 cpl_matrix_set (a, j, k, cpl_matrix_get(a, j, k) + s * cpl_vector_get(rv1, k));
2999 }
3000 for (k = l; k < n; k++)
3001 cpl_matrix_set (a, i, k, cpl_matrix_get(a, i, k) * scale);
3002 }
3003 }
3004
3005 anorm = fmax(anorm,(fabs(cpl_vector_get(w, i)) +
3006 fabs(cpl_vector_get(rv1, i))));
3007
3008 }
3009
3010 for (i = (n - 1); i >= 0; i--) {
3011 if (i < n) {
3012 if (g) {
3013 for (j = l; j < n; j++)
3014 cpl_matrix_set(v, j, i, (cpl_matrix_get(a, i, j) /
3015 cpl_matrix_get(a, i, l)) / g);
3016
3017 for (j = l;j < n; j++) {
3018 for (s = 0.0, k = l; k < n; k++)
3019 s += cpl_matrix_get(a, i, k) * cpl_matrix_get(v, k, j);
3020
3021 for (k = l; k < n; k++)
3022 cpl_matrix_set(v, k, j, cpl_matrix_get(v, k, j) + s *
3023 cpl_matrix_get(v, k, i));
3024
3025 }
3026 }
3027 for (j = l; j < n; j++) {
3028 cpl_matrix_set(v, i, j, 0.0);
3029 cpl_matrix_set(v, j, i, 0.0);
3030 }
3031 }
3032 cpl_matrix_set(v, i, i, 1.0);
3033
3034 g = cpl_vector_get(rv1, i);
3035 l = i;
3036 }
3037
3038 for (i = (IMIN(m,n) - 1); i >= 0; i--) {
3039 l = i + 1;
3040 g = cpl_vector_get(w, i);
3041 for (j = l; j < n; j++)
3042 cpl_matrix_set(a, i, j, 0.0);
3043
3044 if (g) {
3045 g = 1.0/g;
3046 for (j = l; j < n; j++) {
3047 for (s = 0.0, k = l; k < m; k++)
3048 s += cpl_matrix_get(a, k, i) * cpl_matrix_get(a, k, j);
3049
3050 f = (s / cpl_matrix_get(a, i, i)) * g;
3051
3052 for (k = i; k < m; k++)
3053 cpl_matrix_set(a, k, j, cpl_matrix_get(a, k, j) + f *
3054 cpl_matrix_get(a, k, i));
3055
3056 }
3057 for (j = i; j < m; j++)
3058 cpl_matrix_set(a, j, i, cpl_matrix_get(a, j, i) * g);
3059
3060 }
3061 else
3062 for (j = i; j < m; j++)
3063 cpl_matrix_set(a, j, i, 0.0);
3064
3065 cpl_matrix_set(a, i, i, cpl_matrix_get(a, i, i) + 1);
3066
3067 }
3068
3069 for (k = (n - 1); k >= 0; k--) {
3070 for (its = 1; its <= 60; its ++) {
3071 flag = 1;
3072
3073 for (l = k; l >= 0; l--) {
3074 nm = l;
3075 if ((fabs(cpl_vector_get(rv1, l)) + anorm) == anorm) {
3076 flag = 0;
3077 break;
3078 }
3079 if ((fabs(cpl_vector_get(w, nm)) + anorm) == anorm)
3080 break;
3081 }
3082
3083 if (flag) {
3084 c = 0.0;
3085 s = 1.0;
3086 for (i = l; i <= k; i++) {
3087 f = s * cpl_vector_get(rv1, i);
3088 cpl_vector_set(rv1, i, c * cpl_vector_get(rv1, i));
3089 if ((fabs(f) + anorm) == anorm)
3090 break;
3091 g = cpl_vector_get(w, i);
3092 h = pythag(f,g);
3093 cpl_vector_set(w, i, h);
3094 h = 1.0 / h;
3095 c = g * h;
3096 s = -f * h;
3097 for (j = 0; j < m; j++) {
3098 y = cpl_matrix_get(a, j, nm);
3099 z = cpl_matrix_get(a, j, i);
3100 cpl_matrix_set(a, j, nm, y*c+z*s);
3101 cpl_matrix_set(a, j, i, z*c-y*s);
3102 }
3103 }
3104 }
3105 z = cpl_vector_get(w, k);
3106 if (l == k) {
3107 if (z < 0.0) {
3108 cpl_vector_set(w, k, -z);
3109 for (j = 0; j < n; j++)
3110 cpl_matrix_set(v, j, k, -cpl_matrix_get(v, j, k));
3111
3112 }
3113 break;
3114 }
3115
3116 if (its == 120) {
3117 cpl_error_set_message(cpl_func,
3118 CPL_ERROR_ILLEGAL_INPUT,
3119 "no convergence in 120 svdcmp iterations");
3120 cpl_vector_delete(rv1);
3121 cpl_matrix_delete(a);
3122 return NULL;
3123 }
3124 x = cpl_vector_get(w, l);
3125 nm = k ;//- 1;
3126 y = cpl_vector_get(w, nm); ;
3127 g = cpl_vector_get(rv1, nm);
3128 h = cpl_vector_get(rv1, k);
3129 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
3130 g = pythag(f,1.0);
3131 f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
3132 c = s = 1.0;
3133 for (j = l; j < nm; j++) {
3134 i = j+1;
3135 g = cpl_vector_get(rv1, i);
3136 y = cpl_vector_get(w, i);
3137 h = s * g;
3138 g = c * g;
3139 z = pythag(f, h);
3140 cpl_vector_set(rv1, j, z);
3141 c = f / z;
3142 s = h / z;
3143 f = x * c + g * s;
3144 g = g * c - x * s;
3145 h = y * s;
3146 y *= c;
3147 for (jj = 0; jj < n; jj++) {
3148 x = cpl_matrix_get(v, jj, j);
3149 z=cpl_matrix_get(v, jj, i);
3150 cpl_matrix_set(v, jj, j, x*c+z*s);
3151 cpl_matrix_set(v, jj, i, z*c-x*s);
3152 }
3153 z = pythag(f, h);
3154 cpl_vector_set(w, j, z);
3155
3156 if (z) {
3157 z = 1.0 / z;
3158 c = f * z;
3159 s = h * z;
3160 }
3161 f = c * g + s * y;
3162 x = c * y - s * g;
3163 for (jj = 0; jj < m; jj++) {
3164 y = cpl_matrix_get(a, jj, j);
3165 z = cpl_matrix_get(a, jj, i);
3166 cpl_matrix_set(a, jj, j, y*c+z*s);
3167 cpl_matrix_set(a, jj, i, z*c-y*s);
3168 }
3169 }
3170 cpl_vector_set(rv1, l, 0.0);
3171 cpl_vector_set(rv1, k, f);
3172 cpl_vector_set(w, k, x);
3173 }
3174
3175 }
3176 cpl_vector_delete(rv1);
3177
3179 return a;
3180}
3181
3182
3183/*----------------------------------------------------------------------------*/
3192/*----------------------------------------------------------------------------*/
3193cpl_table * gravi_table_extract_time_interval (cpl_table *table, double start, double end)
3194{
3196 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
3197
3198 /* Select only interested */
3199 cpl_table_select_all (table);
3200 cpl_table_and_selected_double (table, "TIME", CPL_NOT_LESS_THAN, start);
3201 cpl_table_and_selected_double (table, "TIME", CPL_LESS_THAN, end);
3202 cpl_table * out = cpl_table_extract_selected (table);
3203
3205 return out;
3206}
3207
#define gravi_table_set_value(table, name, row, value, val)
Definition: gravi_cpl.h:49
#define gravi_table_get_value(table, name, row, value)
Definition: gravi_cpl.h:48
cpl_msg_debug(cpl_func, "Spectra has <50 pixels -> don't flat")
cpl_msg_info(cpl_func, "Compute WAVE_SCAN for %s", GRAVI_TYPE(type_data))
#define IMIN(a, b)
Definition: gravi_utils.h:154
#define CPLCHECK_INT(msg)
Definition: gravi_utils.h:51
#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
#define SIGN(a, b)
Definition: gravi_utils.h:153
cpl_array * gravi_array_init_int(long n, int value)
Definition: gravi_cpl.c:540
double pythag(double, double)
Definition: gravi_cpl.c:2912
cpl_error_code gravi_table_set_array_double_complex(cpl_table *table, const char *name, cpl_size row, cpl_array *visR, cpl_array *visI)
Definition: gravi_cpl.c:646
cpl_array * gravi_array_smooth(cpl_array *input_array, int DIT_smooth)
Definition: gravi_cpl.c:1217
cpl_table * gravi_table_extract_time_interval(cpl_table *table, double start, double end)
Extract rows from table based on the TIME column.
Definition: gravi_cpl.c:3193
cpl_error_code gravi_table_smooth_column(cpl_table *oi_vis, const char *input_name, const char *output_name, int nsmooth, int nbase)
Definition: gravi_cpl.c:936
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:772
float complex ** gravi_table_get_data_array_float_complex(cpl_table *table, const char *name)
Definition: gravi_cpl.c:453
cpl_error_code gravi_table_runint_column(cpl_table *oi_vis, const char *input_name, const char *output_name, int nsmooth, int nbase)
Definition: gravi_cpl.c:843
cpl_vector * gravi_vector_extract(const cpl_vector *vector, int start, int step)
Extract part of a vector.
Definition: gravi_cpl.c:2628
double gravi_table_get_column_flagged_mean(cpl_table *table, const char *name)
Function to compute the mean of a column table with arrays.
Definition: gravi_cpl.c:217
double gravi_image_get_noise_window(cpl_image *img, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury)
Estimate the median noise in a window. This noise is estimated as the median{img**2}**0....
Definition: gravi_cpl.c:1771
cpl_array * gravi_array_create_inverse(cpl_array *input)
Definition: gravi_cpl.c:1003
cpl_array * gravi_table_get_column_dimension(const cpl_table *table, const char *name)
Return an array ready for cpl_table_set_column_dimension.
Definition: gravi_cpl.c:2046
double gravi_table_get_column_mean(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:275
cpl_image * gravi_image_wrap_matrix(cpl_matrix *matrix)
Wrap matrix into an image (data not duplicated)
Definition: gravi_cpl.c:2347
cpl_error_code gravi_table_new_column(cpl_table *table, const char *name, const char *unit, cpl_type type)
Definition: gravi_cpl.c:1588
double complex ** gravi_table_get_data_array_double_complex(cpl_table *table, const char *name)
Definition: gravi_cpl.c:478
cpl_image * gravi_image_from_vector(cpl_vector *vector)
Definition: gravi_cpl.c:2383
cpl_array * gravi_array_cexp(double complex factor, const cpl_array *input)
Compute the complex exponention of an array: cexp (factor * input)
Definition: gravi_cpl.c:1069
cpl_vector * gravi_table_get_vector_scalar(cpl_table *table, const char *name, cpl_size base, cpl_size nbase)
Definition: gravi_cpl.c:2223
cpl_vector * gravi_table_get_vector_diff(cpl_table *spectrum_data, int index, const char *regname1, const char *regname2)
Create a vector from the row index of the column regname.
Definition: gravi_cpl.c:2288
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:1467
cpl_array * gravi_array_init_float_complex(long n, float complex value)
Definition: gravi_cpl.c:562
cpl_image * gravi_image_from_column(cpl_table *table_data, const char *data_x, cpl_size row)
Create an image from a column array in table.
Definition: gravi_cpl.c:1984
cpl_error_code gravi_image_fill(cpl_image *img, double value)
Fill entire image with value.
Definition: gravi_cpl.c:2330
cpl_matrix * gravi_matrix_invertSV_create(cpl_matrix *a_in)
Invers a matrix with singular value decomposition.
Definition: gravi_cpl.c:2853
cpl_imagelist * gravi_imagelist_from_column(cpl_table *table_data, const char *data_x)
Create an imagelist from a column array in table.
Definition: gravi_cpl.c:2016
cpl_error_code gravi_array_phase_unwrap(cpl_array *input)
Definition: gravi_cpl.c:1020
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:1624
cpl_error_code gravi_array_add_phase(cpl_array *input, double factor, cpl_array *phase)
Add a REAL phase to a REAL phase array, in-place: input = input + factor * phase.
Definition: gravi_cpl.c:1173
cpl_error_code gravi_vector_abs(cpl_vector *vector)
Return the running median of a vector, with special care for the boundaray, that are filled with the ...
Definition: gravi_cpl.c:2520
double gravi_image_get_quantile(const cpl_image *img, double thr)
Compute the quantile of an image.
Definition: gravi_cpl.c:2409
cpl_error_code gravi_vector_unwrap_with_guess(cpl_vector *vector, cpl_vector *ref, double ref_to_phase)
Unwrap a phase vector following a guess vector. The difference is actually unwrap and shall thus be s...
Definition: gravi_cpl.c:2651
cpl_array * gravi_table_create_wave_array(cpl_table *oi_wave)
Definition: gravi_cpl.c:969
cpl_array * gravi_array_wrap_image(cpl_image *img)
Wrap the data of na image into an array.
Definition: gravi_cpl.c:2073
cpl_error_code gravi_table_set_array_phase(cpl_table *table, const char *name, cpl_size row, cpl_array *phase)
Definition: gravi_cpl.c:670
cpl_array * gravi_array_init_double(long n, double value)
Definition: gravi_cpl.c:529
double ** gravi_table_get_data_array_double(cpl_table *table, const char *name)
Definition: gravi_cpl.c:405
cpl_error_code gravi_array_normalize_complex(cpl_array *input)
Definition: gravi_cpl.c:985
cpl_imagelist * gravi_imagelist_wrap_column(cpl_table *table_data, const char *data_x)
Wrap a column array of a table into an imagelist.
Definition: gravi_cpl.c:1689
cpl_vector * gravi_vector_median(const cpl_vector *vector, cpl_size hw)
Return the running median of a vector, with special care for the boundaray, that are filled with the ...
Definition: gravi_cpl.c:2479
cpl_error_code gravi_image_subtract_window(cpl_image *img1, const cpl_image *img2, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury, cpl_size llx2, cpl_size lly2)
Definition: gravi_cpl.c:1903
double gravi_array_get_quantile(cpl_array *arr, double thr)
Compute the value of the vector corresponding to the quantile 'thr' (0 < thr < 1)
Definition: gravi_cpl.c:2443
cpl_error_code gravi_imagelist_unwrap_images(cpl_imagelist *imglist)
Unwrap an imagelist an all its images.
Definition: gravi_cpl.c:1659
cpl_error_code gravi_array_get_group_delay_loop(cpl_array **input, cpl_array **flag, cpl_array *sigma, double *gd, cpl_size nrow, double max_width, int verbose)
Optimized computation of GDELAY for a list of arrays.
Definition: gravi_cpl.c:1335
cpl_array * gravi_table_get_column_sum_array(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:359
cpl_image * gravi_image_from_matrix(cpl_matrix *matrix)
Definition: gravi_cpl.c:2355
cpl_error_code gravi_array_add_phasor(cpl_array *input, double complex factor, cpl_array *phase)
Add a REAL phase to a COMPLEX array, in-place: input = input + cexp (factor * phase)
Definition: gravi_cpl.c:1117
cpl_matrix * gravi_matrix_interpolate_col(cpl_matrix *matrix, cpl_vector *xref, cpl_vector *xout)
Linear interpolation of matrix column.
Definition: gravi_cpl.c:2799
cpl_vector * gravi_table_get_vector(cpl_table *spectrum_data, cpl_size index, const char *regname)
Create a vector from the row index of the column regname.
Definition: gravi_cpl.c:2167
cpl_error_code gravi_table_set_string_fixlen(cpl_table *table, const char *name, int row, const char *value, int len)
Set string in table, ensuring fixed length (right space padding). see cpl_table_set_string.
Definition: gravi_cpl.c:701
cpl_array * gravi_array_wrap_float_complex(cpl_array *input_re, cpl_array *input_im)
Definition: gravi_cpl.c:596
cpl_array * gravi_array_compute_norm2(cpl_array *input_re, cpl_array *input_im)
Definition: gravi_cpl.c:620
int gravi_array_threshold_min(cpl_array *array, double lo_cut)
Definition: gravi_cpl.c:71
cpl_error_code gravi_image_replace_window(cpl_image *img1, const cpl_image *img2, cpl_size llx, cpl_size lly, cpl_size urx, cpl_size ury, cpl_size llx2, cpl_size lly2)
Definition: gravi_cpl.c:1936
cpl_matrix * svdcmp(cpl_matrix *, cpl_vector *, cpl_matrix *)
Definition: gravi_cpl.c:2927
double gravi_table_get_column_std(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:320
cpl_array * gravi_table_get_column_mean_array(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:381
cpl_error_code gravi_image_subtract_collapse(cpl_image *img, const cpl_image *collapse, int direction)
Definition: gravi_cpl.c:1853
cpl_image * gravi_image_wrap_vector(cpl_vector *vector)
Wrap vector into an image (data not duplicated)
Definition: gravi_cpl.c:2375
cpl_array * gravi_array_rebin(const cpl_array *input, const cpl_array *errs, cpl_table *oi_wave_sc, cpl_table *oi_wave_ft)
Definition: gravi_cpl.c:724
cpl_array * gravi_table_create_sigma_array(cpl_table *oi_wave)
Definition: gravi_cpl.c:956
double gravi_vector_get_mean_clip(cpl_vector *vector_in, double percent, double nsigma)
Return the mean of a vector after extrema and RMS clipping.
Definition: gravi_cpl.c:2574
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:2698
cpl_matrix * get_matrix_from_vector(cpl_vector *vector1, cpl_vector *vector2)
Copy the content of two vector into a newly allocated 2D matrix.
Definition: gravi_cpl.c:2117
cpl_error_code gravi_array_phase_wrap(cpl_array *input)
Definition: gravi_cpl.c:1051
cpl_array * gravi_array_init_double_complex(long n, double complex value)
Definition: gravi_cpl.c:551
int ** gravi_table_get_data_array_int(cpl_table *table, const char *name)
Definition: gravi_cpl.c:502
cpl_array ** gravi_array_new_list(int n, cpl_type type, int size)
Allocate a list of arrays, pre-filled with 0.0.
Definition: gravi_cpl.c:93
cpl_error_code gravi_array_multiply_phasor(cpl_array *input, double complex factor, cpl_array *phase)
Multiply a REAL phase to a COMPLEX array, in-place: input = input * cexp (factor * phase)
Definition: gravi_cpl.c:1091
cpl_size gravi_vector_get_maxpos(cpl_vector *vector)
Return the index of maximum in a vector. If several indexes exists with the maximum value,...
Definition: gravi_cpl.c:2546
cpl_error_code gravi_table_add_scalar(cpl_table *table, const char *name, int base, int nbase, double value)
Multply scalar or array column by scalar.
Definition: gravi_cpl.c:2748
cpl_error_code gravi_array_add_phasors(cpl_array *input, cpl_array *add, cpl_array *sub)
Add a pair of COMPLEX arrays to a COMPLEX array, in-place: input = input + add*conj(sub)
Definition: gravi_cpl.c:1143
float ** gravi_table_get_data_array_float(cpl_table *table, const char *name)
Definition: gravi_cpl.c:429
cpl_array * gravi_array_wrap_complex(cpl_array *input_re, cpl_array *input_im)
Definition: gravi_cpl.c:573
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:1610
int gravi_table_are_equal(cpl_table *first, cpl_table *second)
Check if two tables have the same content.
Definition: gravi_cpl.c:1517
cpl_error_code gravi_array_multiply_conj(cpl_array *input1, cpl_array *input2)
Definition: gravi_cpl.c:1194
cpl_image * gravi_image_collapse_median_x(cpl_image *img, cpl_size drop_from, cpl_size drop_to)
collapse image along the x direction, droping a part of the image
Definition: gravi_cpl.c:1816