GRAVI Pipeline Reference Manual 1.9.4
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
290double gravi_table_get_column_flagged_max (cpl_table * table, const char * name)
291{
292 cpl_ensure (table, CPL_ERROR_NULL_INPUT, 0.0);
293 cpl_ensure (name, CPL_ERROR_NULL_INPUT, 0.0);
294
295 double max = 0.0;
296 cpl_size valid_elem = 0;
297 int valid;
298 cpl_size nrow = cpl_table_get_nrow (table);
299 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, 0.0);
300
301 cpl_type type = cpl_table_get_column_type (table, name);
302 cpl_size depth = cpl_table_get_column_depth (table, name);
303
304 cpl_array ** flags = cpl_table_get_data_array (table, "FLAG");
305
306 if (depth > 0) {
307 cpl_array ** arrays = cpl_table_get_data_array (table, name);
308 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, 0.0);
309 cpl_size array_size = cpl_array_get_size(arrays[0]);
310 for (cpl_size r=0; r<nrow;r++)
311 for(cpl_size el=0; el<array_size; el++)
312 if (!cpl_array_get_int(flags[r], el, &valid))
313 {
314 if(cpl_array_get_double(arrays[r], el, &valid) > max)
315 max = cpl_array_get_double(arrays[r], el, &valid);
316 }
317 }
318 else if (depth == 0 && type == CPL_TYPE_DOUBLE) {
319 double * data = cpl_table_get_data_double (table, name);
320 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
321 cpl_size array_size = cpl_array_get_size(flags[0]);
322 for (cpl_size r=0; r<nrow;r++)
323 {
324 for(cpl_size el=0; el<array_size; el++)
325 {
326 if (!cpl_array_get_int(flags[r], el, &valid))
327 {
328 if(data[r] > max)
329 max = data[r];
330 }
331 }
332 }
333 }
334
335 else {
336 cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,"unknow type");
337 return 0.0;
338 }
339
340 return max;
341}
342
343double gravi_table_get_column_mean (cpl_table * table, const char * name, int base, int nbase)
344{
345 cpl_ensure (table, CPL_ERROR_NULL_INPUT, 0.0);
346 cpl_ensure (name, CPL_ERROR_NULL_INPUT, 0.0);
347
348 double mean = 0.0;
349 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
350 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, 0.0);
351
352 cpl_type type = cpl_table_get_column_type (table, name);
353 cpl_size depth = cpl_table_get_column_depth (table, name);
354
355 if (depth == 0 && type == CPL_TYPE_DOUBLE) {
356 double * data = cpl_table_get_data_double (table, name);
357 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
358 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
359 }
360 else if (depth == 0 && type == CPL_TYPE_FLOAT) {
361 float * data = cpl_table_get_data_float (table, name);
362 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
363 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
364 }
365 else if (depth == 0 && type == CPL_TYPE_INT) {
366 int * data = cpl_table_get_data_int (table, name);
367 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
368 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
369 }
370 else if (depth > 0) {
371 cpl_array ** arrays = cpl_table_get_data_array (table, name);
372 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, 0.0);
373 cpl_array * output = cpl_array_duplicate (arrays[base]);
374 cpl_ensure (output, CPL_ERROR_ILLEGAL_INPUT, 0.0);
375 for (cpl_size r=1; r<nrow;r++)
376 cpl_array_add (output, arrays[r*nbase+base]);
377 mean = cpl_array_get_mean (output);
378 FREE (cpl_array_delete, output);
379 }
380 else {
381 cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,"unknow type");
382 return 0.0;
383 }
384
385 return mean / nrow;
386}
387
388double gravi_table_get_column_std (cpl_table * table, const char * name, int base, int nbase)
389{
390 cpl_ensure (table, CPL_ERROR_NULL_INPUT, 0.0);
391 cpl_ensure (name, CPL_ERROR_NULL_INPUT, 0.0);
392
393 double mean = 0.0;
394 double mean2 = 0.0;
395 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
396 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, 0.0);
397
398 cpl_type type = cpl_table_get_column_type (table, name);
399 cpl_size depth = cpl_table_get_column_depth (table, name);
400
401 if (depth == 0 && type == CPL_TYPE_DOUBLE) {
402 double * data = cpl_table_get_data_double (table, name);
403 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
404 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
405 for (cpl_size r=0; r<nrow;r++) mean2 += data[r*nbase+base] * data[r*nbase+base];
406 }
407 else if (depth == 0 && type == CPL_TYPE_FLOAT) {
408 float * data = cpl_table_get_data_float (table, name);
409 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
410 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
411 for (cpl_size r=0; r<nrow;r++) mean2 += data[r*nbase+base] * data[r*nbase+base];
412 }
413 else if (depth == 0 && type == CPL_TYPE_INT) {
414 int * data = cpl_table_get_data_int (table, name);
415 cpl_ensure (data, CPL_ERROR_ILLEGAL_INPUT, 0.0);
416 for (cpl_size r=0; r<nrow;r++) mean += data[r*nbase+base];
417 for (cpl_size r=0; r<nrow;r++) mean2 += data[r*nbase+base] * data[r*nbase+base];
418 }
419 else {
420 cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,"unknow type");
421 return 0.0;
422 }
423
424 return sqrt (mean2 / nrow - mean*mean / nrow / nrow);
425}
426
427cpl_array * gravi_table_get_column_sum_array (cpl_table * table, const char * name, int base, int nbase)
428{
429 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
430 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
431
432 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
433 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
434
435 /* Get the pointer */
436 cpl_array ** arrays = cpl_table_get_data_array (table, name);
437 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, NULL);
438
439 /* Build the mean (warning that integer will remain an integer) */
440 cpl_array * output = cpl_array_duplicate (arrays[base]);
441
442 /* Coadd all */
443 for (cpl_size r=1; r<nrow;r++)
444 cpl_array_add (output, arrays[r*nbase+base]);
445
446 return output;
447}
448
449cpl_array * gravi_table_get_column_mean_array (cpl_table * table, const char * name, int base, int nbase)
450{
451 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
452 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
453
454 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
455 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
456
457 /* Get the pointer */
458 cpl_array ** arrays = cpl_table_get_data_array (table, name);
459 cpl_ensure (arrays, CPL_ERROR_ILLEGAL_INPUT, NULL);
460
461 /* Build the mean (warning that integer will remain an integer) */
462 cpl_array * output = cpl_array_duplicate (arrays[base]);
463
464 /* Coadd all */
465 for (cpl_size r=1; r<nrow;r++)
466 cpl_array_add (output, arrays[r*nbase+base]);
467
468 cpl_array_divide_scalar (output, nrow);
469 return output;
470}
471
472
473double ** gravi_table_get_data_array_double(cpl_table * table, const char * name)
474{
475 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
476 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
477
478 cpl_size nrow = cpl_table_get_nrow (table);
479 cpl_array ** pdata = cpl_table_get_data_array (table, name);
480
481 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
482 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
483
484 /* Allocate memory, this will have to be desalocated */
485 double ** data = cpl_malloc (sizeof(double*) * nrow);
486
487 /* Get all the pointers */
488 for (cpl_size row=0; row<nrow; row++) {
489 data[row] = cpl_array_get_data_double (pdata[row]);
490 }
491
492 CPLCHECK_NUL("Cannot load the requested arrays");
493
494 return data;
495}
496
497float ** gravi_table_get_data_array_float(cpl_table * table, const char * name)
498{
499 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
500 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
501
502 cpl_size nrow = cpl_table_get_nrow (table);
503 cpl_array ** pdata = cpl_table_get_data_array (table, name);
504
505 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
506 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
507
508 /* Allocate memory, this will have to be desalocated */
509 float ** data = cpl_malloc (sizeof(float*) * nrow);
510
511 /* Get all the pointers */
512 for (cpl_size row=0; row<nrow; row++) {
513 data[row] = cpl_array_get_data_float (pdata[row]);
514 }
515
516 CPLCHECK_NUL("Cannot load the requested arrays");
517
518 return data;
519}
520
521float complex ** gravi_table_get_data_array_float_complex (cpl_table * table, const char * name)
522{
523 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
524 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
525
526 cpl_size nrow = cpl_table_get_nrow (table);
527 cpl_array ** pdata = cpl_table_get_data_array (table, name);
528
529 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
530 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
531
532 /* Allocate memory, this will have to be desalocated */
533 float complex ** data = cpl_malloc (sizeof(float complex*) * nrow);
534
535 /* Get all the pointers */
536 for (cpl_size row=0; row<nrow; row++) {
537 data[row] = cpl_array_get_data_float_complex (pdata[row]);
538 }
539
540 CPLCHECK_NUL ("Cannot load the requested arrays");
541
542 return data;
543}
544
545
546double complex ** gravi_table_get_data_array_double_complex (cpl_table * table, const char * name)
547{
548 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
549 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
550
551 cpl_size nrow = cpl_table_get_nrow (table);
552 cpl_array ** pdata = cpl_table_get_data_array (table, name);
553
554 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
555 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
556
557 /* Allocate memory, this will have to be desalocated */
558 double complex ** data = cpl_malloc (sizeof(double complex*) * nrow);
559
560 /* Get all the pointers */
561 for (cpl_size row=0; row<nrow; row++) {
562 data[row] = cpl_array_get_data_double_complex (pdata[row]);
563 }
564
565 CPLCHECK_NUL ("Cannot load the requested arrays");
566
567 return data;
568}
569
570int ** gravi_table_get_data_array_int(cpl_table * table, const char * name)
571{
572 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
573 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
574
575 cpl_size nrow = cpl_table_get_nrow (table);
576 cpl_array ** pdata = cpl_table_get_data_array (table, name);
577
578 cpl_ensure (nrow, CPL_ERROR_ILLEGAL_INPUT, NULL);
579 cpl_ensure (pdata, CPL_ERROR_ILLEGAL_INPUT, NULL);
580
581 /* Allocate memory, this will have to be desalocated */
582 int ** data = cpl_malloc (sizeof(int*) * nrow);
583
584 /* Get all the pointers */
585 for (cpl_size row=0; row<nrow; row++) {
586 data[row] = cpl_array_get_data_int (pdata[row]);
587 }
588
589 CPLCHECK_NUL("Cannot load the requested arrays");
590
591 return data;
592}
593
594/*
595 * Define and init an array of DOUBLE
596 */
597cpl_array * gravi_array_init_double (long n , double value)
598{
599 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
600 cpl_array * output = cpl_array_new (n, CPL_TYPE_DOUBLE);
601 cpl_array_fill_window_double (output, 0, n, value);
602 return output;
603}
604
605/*
606 * Define and init an array of INT
607 */
608cpl_array * gravi_array_init_int (long n, int value)
609{
610 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
611 cpl_array * output = cpl_array_new (n, CPL_TYPE_INT);
612 cpl_array_fill_window_int (output, 0, n, value);
613 return output;
614}
615
616/*
617 * Define and init an array of DOUBLE COMPLEX
618 */
619cpl_array * gravi_array_init_double_complex (long n, double complex value)
620{
621 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
622 cpl_array * output = cpl_array_new (n, CPL_TYPE_DOUBLE_COMPLEX);
623 cpl_array_fill_window_double_complex (output, 0, n, value);
624 return output;
625}
626
627/*
628 * Define and init an array of FLOAT COMPLEX
629 */
630cpl_array * gravi_array_init_float_complex (long n, float complex value)
631{
632 cpl_ensure (n>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
633 cpl_array * output = cpl_array_new (n, CPL_TYPE_FLOAT_COMPLEX);
634 cpl_array_fill_window_float_complex (output, 0, n, value);
635 return output;
636}
637
638/*
639 * Compute a new DOUBLE COMPLEX array filled with: input_re + i * input_im
640 */
641cpl_array * gravi_array_wrap_complex (cpl_array * input_re, cpl_array * input_im)
642{
643 cpl_ensure (input_re, CPL_ERROR_NULL_INPUT, NULL);
644 cpl_ensure (input_im, CPL_ERROR_NULL_INPUT, NULL);
645
646 cpl_size size_re = cpl_array_get_size (input_re);
647 cpl_size size_im = cpl_array_get_size (input_im);
648
649 cpl_ensure (size_re == size_im, CPL_ERROR_ILLEGAL_INPUT, NULL);
650
651 cpl_array * output = cpl_array_new (size_re, CPL_TYPE_DOUBLE_COMPLEX);
652
653 for (cpl_size n = 0; n < size_re; n ++) {
654 cpl_array_set_complex (output, n, 1.* I * cpl_array_get (input_im, n, NULL) +
655 cpl_array_get (input_re, n, NULL));
656 }
657
658 return output;
659}
660
661/*
662 * Compute a new FLOAT COMPLEX array filled with: input_re + i * input_im
663 */
664cpl_array * gravi_array_wrap_float_complex (cpl_array * input_re, cpl_array * input_im)
665{
666 cpl_ensure (input_re, CPL_ERROR_NULL_INPUT, NULL);
667 cpl_ensure (input_im, CPL_ERROR_NULL_INPUT, NULL);
668
669 cpl_size size_re = cpl_array_get_size (input_re);
670 cpl_size size_im = cpl_array_get_size (input_im);
671
672 cpl_ensure (size_re == size_im, CPL_ERROR_ILLEGAL_INPUT, NULL);
673
674 cpl_array * output = cpl_array_new (size_re, CPL_TYPE_FLOAT_COMPLEX);
675
676 int nv = 0.0;
677 for (cpl_size n = 0; n < size_re; n ++) {
678 cpl_array_set_float_complex (output, n, 1.* I * cpl_array_get (input_im, n, &nv) +
679 cpl_array_get (input_re, n, &nv));
680 }
681
682 return output;
683}
684
685/*
686 * Compute a new DOUBLE array filled with: input_re^2 + input_im^2
687 */
688cpl_array * gravi_array_compute_norm2 (cpl_array * input_re, cpl_array * input_im)
689{
690 cpl_ensure (input_re, CPL_ERROR_NULL_INPUT, NULL);
691 cpl_ensure (input_im, CPL_ERROR_NULL_INPUT, NULL);
692
693 cpl_size size_re = cpl_array_get_size (input_re);
694 cpl_size size_im = cpl_array_get_size (input_im);
695
696 cpl_ensure (size_re == size_im, CPL_ERROR_ILLEGAL_INPUT, NULL);
697
698 cpl_array * output = cpl_array_new (size_re, CPL_TYPE_DOUBLE);
699 cpl_array_fill_window_double (output, 0, size_re, 0.0);
700
701 int nv = 0.0;
702 for (cpl_size n = 0; n < size_re; n ++) {
703 cpl_array_set_double (output, n, pow(cpl_array_get (input_im, n, &nv),2) +
704 pow(cpl_array_get (input_re, n, &nv),2) );
705 }
706
707 return output;
708}
709
710/*
711 * Set an pair of arrays as the real and imaginary part of
712 * a FLOAT COMPLEX array into the table. Data are copied.
713 */
714cpl_error_code gravi_table_set_array_double_complex (cpl_table * table,
715 const char * name,
716 cpl_size row,
717 cpl_array * visR,
718 cpl_array * visI)
719{
720 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
721 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
722 cpl_ensure_code (visR, CPL_ERROR_NULL_INPUT);
723 cpl_ensure_code (visI, CPL_ERROR_NULL_INPUT);
724
725 cpl_array * tmp_cast = gravi_array_wrap_complex (visR, visI);
726 cpl_table_set_array (table, name, row, tmp_cast);
727 cpl_array_delete (tmp_cast);
728
729 CPLCHECK_MSG("Cannot set float_complex array");
730
731 return CPL_ERROR_NONE;
732}
733
734/*
735 * Set an array in radian into an table and convert it in DOUBLE
736 * with units [deg]
737 */
738cpl_error_code gravi_table_set_array_phase (cpl_table * table, const char * name, cpl_size row, cpl_array * phase)
739{
740 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
741 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
742 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
743
744 cpl_array * tmp_cast;
745 if (cpl_array_get_type (phase) == CPL_TYPE_FLOAT_COMPLEX ||
746 cpl_array_get_type (phase) == CPL_TYPE_DOUBLE_COMPLEX ) {
747 tmp_cast = cpl_array_cast (phase, CPL_TYPE_DOUBLE_COMPLEX);
748 cpl_array_arg (tmp_cast);
749 } else
750 tmp_cast = cpl_array_cast (phase, CPL_TYPE_DOUBLE);
751
752 cpl_array_multiply_scalar (tmp_cast, 180.0/ CPL_MATH_PI);
753 cpl_table_set_array (table, name, row, tmp_cast);
754 cpl_array_delete (tmp_cast);
755
756 CPLCHECK_MSG("Cannot set phase array");
757
758 return CPL_ERROR_NONE;
759}
760
761/*----------------------------------------------------------------------------*/
768/*----------------------------------------------------------------------------*/
769cpl_error_code gravi_table_set_string_fixlen (cpl_table *table, const char *name, int row, const char *value, int len)
770{
772 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
773 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
774 cpl_ensure_code (row>-1, CPL_ERROR_ILLEGAL_INPUT);
775 cpl_ensure_code (len>0, CPL_ERROR_ILLEGAL_INPUT);
776
777 char * str = cpl_sprintf ("%-*.*s", len, len, value);
778 cpl_table_set_string (table, name, row, str);
779
780 FREE (cpl_free, str);
781 CPLCHECK_MSG("Cannot set string");
782
784 return CPL_ERROR_NONE;
785}
786
787/*
788 * Rebin a cpl_array from the SC wavelength table to the FT wavelength table
789 * For each FT bin, average all elements found in lbdEff+/-lbdBand/2
790 * The output array is created, the input array is not modified.
791 */
792cpl_array * gravi_array_rebin (const cpl_array * input, const cpl_array * errs,
793 cpl_table * oi_wave_sc, cpl_table * oi_wave_ft)
794{
796 cpl_ensure (input, CPL_ERROR_NULL_INPUT, NULL);
797 cpl_ensure (errs, CPL_ERROR_NULL_INPUT, NULL);
798 cpl_ensure (oi_wave_sc, CPL_ERROR_NULL_INPUT, NULL);
799 cpl_ensure (oi_wave_ft, CPL_ERROR_NULL_INPUT, NULL);
800
801 /* Get the eff_wave and eff_band of the FT */
802 float *effWave_sc = cpl_table_get_data_float (oi_wave_sc, "EFF_WAVE");
803 float *effWave_ft = cpl_table_get_data_float (oi_wave_ft, "EFF_WAVE");
804 float *effBand_ft = cpl_table_get_data_float (oi_wave_ft, "EFF_BAND");
805 cpl_size nwave_ft = cpl_table_get_nrow (oi_wave_ft);
806 cpl_size nwave_sc = cpl_table_get_nrow (oi_wave_sc);
807
808 CPLCHECK_NUL ("Cannot get data");
809
810 cpl_array * output = cpl_array_new (nwave_ft, CPL_TYPE_DOUBLE);
811 cpl_array * weight = cpl_array_new (nwave_ft, CPL_TYPE_DOUBLE);
812
813 /* Built the SC data at the spectral resolution of the FT (vis2_sc_lr) */
814 for (cpl_size wft = 0; wft < nwave_ft; wft++) {
815 for (cpl_size wsc = 0; wsc < nwave_sc; wsc++)
816 if ( fabs (effWave_sc[wsc] - effWave_ft[wft]) < 0.5 * effBand_ft[wft] ) {
817
818 double v = cpl_array_get (input, wsc, NULL);
819 double w = cpl_array_get (errs, wsc, NULL);
820
821 w = (w!=0?1./w:1.0);
822 cpl_array_set (output, wft, cpl_array_get (output, wft, NULL) + v * w);
823 cpl_array_set (weight, wft, cpl_array_get (weight, wft, NULL) + w);
824
825 CPLCHECK_NUL("Cannot reduce the spectral resolution");
826 }
827 }
828
829 cpl_array_divide (output, weight);
830 cpl_array_delete (weight);
832 return output;
833}
834
835
836/*
837 * Add two columns from differents tables, without duplicating the data.
838 * Use cpl_table_add_columns for columns in the same table.
839 */
840cpl_error_code gravi_table_add_columns (cpl_table * oi_vis1, const char *name1,
841 cpl_table * oi_vis2, const char *name2)
842{
844 cpl_ensure_code (oi_vis1, CPL_ERROR_NULL_INPUT);
845 cpl_ensure_code (oi_vis2, CPL_ERROR_NULL_INPUT);
846 cpl_ensure_code (name1, CPL_ERROR_NULL_INPUT);
847 cpl_ensure_code (name2, CPL_ERROR_NULL_INPUT);
848
849 int row;
850 cpl_msg_debug (cpl_func, "Colname (%s + %s) ",name1,name2);
851
852 cpl_type type1 = cpl_table_get_column_type (oi_vis1, name1);
853 cpl_type type2 = cpl_table_get_column_type (oi_vis2, name2);
854 cpl_size nrow1 = cpl_table_get_nrow (oi_vis1);
855 cpl_size nrow2 = cpl_table_get_nrow (oi_vis2);
856 CPLCHECK_MSG("Cannot get type or nrow");
857
858 if ( type1 != type2 || nrow1 != nrow2) {
859 return cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,
860 "input columns not conformables");
861 }
862
863 if ( type1 == CPL_TYPE_DOUBLE ) {
864 double * data1 = cpl_table_get_data_double (oi_vis1, name1);
865 double * data2 = cpl_table_get_data_double (oi_vis2, name2);
866 CPLCHECK_MSG("Cannot load data");
867
868 for (row=0 ; row<nrow1 ; row++) data1[row] += data2[row];
869 }
870 else if ( type1 == CPL_TYPE_FLOAT_COMPLEX ) {
871 float complex * data1 = cpl_table_get_data_float_complex (oi_vis1, name1);
872 float complex * data2 = cpl_table_get_data_float_complex (oi_vis2, name2);
873 CPLCHECK_MSG("Cannot load data");
874
875 for (row=0 ; row<nrow1; row++) data1[row] += data2[row];
876 }
877 else if ( type1 == CPL_TYPE_DOUBLE_COMPLEX ) {
878 double complex * data1 = cpl_table_get_data_double_complex (oi_vis1, name1);
879 double complex * data2 = cpl_table_get_data_double_complex (oi_vis2, name2);
880 CPLCHECK_MSG("Cannot load data");
881
882 for (row=0 ; row<nrow1; row++) data1[row] += data2[row];
883 }
884 else if ( type1 & CPL_TYPE_POINTER ) {
885 cpl_array ** data1 = cpl_table_get_data_array (oi_vis1, name1);
886 cpl_array ** data2 = cpl_table_get_data_array (oi_vis2, name2);
887 CPLCHECK_MSG("Cannot load data");
888
889 for (row=0 ; row<nrow1; row++) {
890 cpl_array_add (data1[row], data2[row]);
891 CPLCHECK_MSG("Cannot add data");
892 }
893 } else {
894 return cpl_error_set_message (cpl_func,CPL_ERROR_ILLEGAL_INPUT,
895 "unknow type -- report to DRS team");
896 }
897 /* End case */
898
900 return CPL_ERROR_NONE;
901}
902
903
904
905/*
906 * Smooth column input_name with a box card of length 2*nsmooth+1
907 * Note that this is a running SUM, not a running MEAN.
908 * It integrated 2 x nsmooth + 1 running samples
909 * FIXME: check this running sum near the limits
910 */
911cpl_error_code gravi_table_runint_column (cpl_table * oi_vis,
912 const char *input_name,
913 const char *output_name,
914 int nsmooth, int nbase)
915{
917 cpl_ensure_code (oi_vis, CPL_ERROR_NULL_INPUT);
918 cpl_ensure_code (input_name, CPL_ERROR_NULL_INPUT);
919 cpl_ensure_code (output_name, CPL_ERROR_NULL_INPUT);
920 cpl_ensure_code (nsmooth>=0, CPL_ERROR_ILLEGAL_INPUT);
921 cpl_ensure_code (nbase>0, CPL_ERROR_ILLEGAL_INPUT);
922
923 int row, base;
924 int row_add, row_sub;
925
926 cpl_type type = cpl_table_get_column_type (oi_vis, input_name);
927 cpl_size nrow = cpl_table_get_nrow (oi_vis) / nbase;
928
929 if ( type == CPL_TYPE_DOUBLE ) {
930 double * data = cpl_table_get_data_double (oi_vis, input_name);
931 double * output = cpl_malloc (sizeof(double) * nrow * nbase);
932 double buffer = 0.0;
933
934 CPLCHECK_MSG("Cannot load data");
935
936 /* Loop on base and rows */
937 for ( base=0 ; base<nbase ; base++) {
938 buffer = 0.0;
939
940 for ( row=-nsmooth ; row<nrow ; row++) {
941 row_add = row+nsmooth;
942 row_sub = row-nsmooth-1;
943 if ( row_add < nrow ) buffer += data[row_add * nbase + base];
944 if ( row_sub >= 0 ) buffer -= data[row_sub * nbase + base];
945 if( row>=0 && row<nrow ) output[row * nbase + base] = (double)(buffer);
946 }
947 /* End loop on rows */
948 }
949 /* End loop on base */
950
951 /* Wrap output column */
952 if ( !strcmp (input_name, output_name)) {
953 for (row = 0; row < nrow * nbase; row++) data[row] = output[row];
954 cpl_free (output);
955 } else {
956 if (cpl_table_has_column (oi_vis, output_name))
957 cpl_table_erase_column (oi_vis, output_name);
958 cpl_table_wrap_double (oi_vis, output, output_name);
959 }
960 CPLCHECK_MSG("Cannot Wrap");
961 }
962 else if ( type == CPL_TYPE_DOUBLE_COMPLEX ) {
963 double complex * data = cpl_table_get_data_double_complex (oi_vis, input_name);
964 double complex * output = cpl_malloc (sizeof(double complex) * nrow * nbase);
965 double complex buffer = 0.0;
966
967 CPLCHECK_MSG("Cannot load data");
968
969 /* Loop on rows */
970 for ( base=0 ; base<nbase ; base++) {
971 buffer = 0.0;
972
973 for ( row=-nsmooth ; row<nrow ; row++) {
974 row_add = row+nsmooth;
975 row_sub = row-nsmooth-1;
976 if ( row_add < nrow ) buffer += data[row_add * nbase + base];
977 if ( row_sub >= 0 ) buffer -= data[row_sub * nbase + base];
978 if( row>=0 && row<nrow ) output[row * nbase + base] = (double complex)(buffer);
979 }
980 }
981 /* End loop on base */
982
983 /* Wrap output column */
984 if ( !strcmp (input_name, output_name)) {
985 for (row = 0; row < nrow * nbase; row++) data[row] = output[row];
986 cpl_free (output);
987 } else {
988 if (cpl_table_has_column (oi_vis, output_name))
989 cpl_table_erase_column (oi_vis, output_name);
990 cpl_table_wrap_double_complex (oi_vis, output, output_name);
991 }
992 CPLCHECK_MSG ("Cannot Wrap");
993
994 } else {
995 return cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
996 "This type is not supported..."
997 "report this error to DRS team !!");
998 }
999
1001 return CPL_ERROR_NONE;
1002}
1003
1004cpl_error_code gravi_table_smooth_column (cpl_table * oi_vis,
1005 const char *input_name,
1006 const char *output_name,
1007 int nsmooth, int nbase)
1008{
1010 cpl_ensure_code (oi_vis, CPL_ERROR_NULL_INPUT);
1011 cpl_ensure_code (input_name, CPL_ERROR_NULL_INPUT);
1012 cpl_ensure_code (output_name, CPL_ERROR_NULL_INPUT);
1013 cpl_ensure_code (nsmooth>0, CPL_ERROR_ILLEGAL_INPUT);
1014 cpl_ensure_code (nbase>0, CPL_ERROR_ILLEGAL_INPUT);
1015
1016 /* Performed the running integration and devide */
1017 gravi_table_runint_column (oi_vis, input_name, output_name, nsmooth, nbase);
1018 cpl_table_divide_scalar (oi_vis, output_name, 2.0*(double)nsmooth+1.0);
1019
1021 return CPL_ERROR_NONE;
1022}
1023
1024cpl_array * gravi_table_create_sigma_array (cpl_table * oi_wave)
1025{
1026 int nv = 0;
1027 cpl_size size = cpl_table_get_nrow (oi_wave);
1028 cpl_array * sigma = cpl_array_new (size, CPL_TYPE_DOUBLE);
1029
1030 for (cpl_size w = 0; w<size; w++ )
1031 cpl_array_set (sigma, w, 1./cpl_table_get (oi_wave, "EFF_WAVE", w, &nv));
1032
1033 CPLCHECK_NUL("Cannot compute the sigma array from EFF_WAVE");
1034 return sigma;
1035}
1036
1037cpl_array * gravi_table_create_wave_array (cpl_table * oi_wave)
1038{
1039 cpl_ensure (oi_wave, CPL_ERROR_NULL_INPUT, NULL);
1040
1041 int nv = 0;
1042 cpl_size size = cpl_table_get_nrow (oi_wave);
1043 cpl_array * wave = cpl_array_new (size, CPL_TYPE_FLOAT);
1044
1045 for (cpl_size w = 0; w<size; w++ )
1046 cpl_array_set (wave, w, cpl_table_get (oi_wave, "EFF_WAVE", w, &nv));
1047
1048 CPLCHECK_NUL("Cannot compute the wave array from EFF_WAVE");
1049 return wave;
1050}
1051
1052
1053cpl_error_code gravi_array_normalize_complex (cpl_array * input)
1054{
1055 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1056
1057 int nv = 0;
1058 cpl_size size = cpl_array_get_size (input);
1059
1060 double complex cpx = 0.0 * I + 0.0;
1061 for (cpl_size wave = 0; wave<size; wave++ ) {
1062 cpx = cpl_array_get_complex (input,wave,&nv);
1063 cpl_array_set_complex (input, wave, cpx / cabs (cpx));
1064 if (nv) {cpl_array_set_invalid (input, wave); nv=0;}
1065 }
1066
1067 CPLCHECK_MSG("Cannot normalize complex");
1068 return CPL_ERROR_NONE;
1069}
1070
1071cpl_array * gravi_array_create_inverse (cpl_array *input)
1072{
1073 cpl_ensure (input, CPL_ERROR_NULL_INPUT, NULL);
1074
1075 cpl_size size = cpl_array_get_size (input);
1076
1077 cpl_array * inv = cpl_array_new (size, CPL_TYPE_DOUBLE);
1078 cpl_array_fill_window (inv, 0, size, 1.0);
1079 cpl_array_divide (inv, input);
1080
1081 CPLCHECK_NUL("Cannot compute the sigma array from wave");
1082 return inv;
1083}
1084
1085/*
1086 * Unwrap an array of phase (in-place)
1087 */
1088cpl_error_code gravi_array_phase_unwrap (cpl_array * input)
1089{
1090 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1091
1092 cpl_size size_x = cpl_array_get_size (input);
1093 double phi_i, phi_ii, d_phi;
1094 int k_wrap =0;
1095
1096 for (cpl_size i_data = 1; i_data < size_x; i_data++){
1097
1098 /* Evaluation of the phi(i_data) and
1099 * phi(i_data-1) */
1100
1101 phi_i = cpl_array_get(input, i_data, NULL);
1102 phi_ii = cpl_array_get(input, i_data-1, NULL);
1103
1104 d_phi = phi_i + k_wrap * 2 * M_PI - phi_ii;
1105
1106 if (d_phi > M_PI) k_wrap --;
1107 if (d_phi < - M_PI) k_wrap ++;
1108
1109 cpl_array_set(input, i_data, cpl_array_get(input, i_data, NULL) + k_wrap * 2 * M_PI);
1110 }
1111
1112 CPLCHECK_INT("Cannot unwrap the phase array");
1113 return CPL_ERROR_NONE;
1114}
1115
1116/*
1117 * Fill in place the array with carg (cexp (1*I*array))
1118 */
1119cpl_error_code gravi_array_phase_wrap (cpl_array * input)
1120{
1121 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1122
1123 cpl_size size = cpl_array_get_size (input);
1124
1125 for (cpl_size wave = 0; wave<size; wave++ ) {
1126 cpl_array_set (input, wave, carg (cexp ( 1.0 * I * cpl_array_get (input, wave, NULL))));
1127 }
1128
1129 CPLCHECK_MSG("Cannot wrap phase array");
1130 return CPL_ERROR_NONE;
1131}
1132
1137cpl_array * gravi_array_cexp (double complex factor, const cpl_array * input)
1138{
1139 cpl_ensure (input, CPL_ERROR_NULL_INPUT, NULL);
1140
1141 cpl_size size = cpl_array_get_size (input);
1142
1143 cpl_array * output = cpl_array_new (size, CPL_TYPE_DOUBLE_COMPLEX);
1144 cpl_array_fill_window_complex (output, 0, size, (double complex)(0.0 + 0.0 * I));
1145
1146 cpl_size n;
1147 int nv = 0.0;
1148 for (n = 0; n < size; n ++) {
1149 cpl_array_set_complex (output, n, cexp (factor * cpl_array_get (input, n, &nv) ) );
1150 }
1151
1152 return output;
1153}
1154
1159cpl_error_code gravi_array_multiply_phasor (cpl_array * input, double complex factor, cpl_array * phase)
1160{
1161 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1162 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
1163
1164 cpl_size size_in = cpl_array_get_size (input);
1165 cpl_size size_ph = cpl_array_get_size (phase);
1166
1167 cpl_ensure_code (size_in == size_ph, CPL_ERROR_ILLEGAL_INPUT);
1168
1169 cpl_size n;
1170 int nv = 0.0;
1171 for (n = 0; n < size_in; n ++) {
1172 cpl_array_set_complex( input, n,
1173 cpl_array_get_complex( input, n, &nv) *
1174 cexp ( factor * cpl_array_get( phase, n, &nv) ) );
1175 }
1176
1177 CPLCHECK_MSG ("Cannot multiply phasor");
1178 return CPL_ERROR_NONE;
1179}
1180
1185cpl_error_code gravi_array_add_phasor (cpl_array * input, double complex factor, cpl_array * phase)
1186{
1187 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1188 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
1189
1190 cpl_size size_in = cpl_array_get_size (input);
1191 cpl_size size_ph = cpl_array_get_size (phase);
1192
1193 cpl_ensure_code (size_in == size_ph, CPL_ERROR_ILLEGAL_INPUT);
1194
1195 cpl_size n;
1196 int nv = 0.0;
1197 for (n = 0; n < size_in; n ++) {
1198 cpl_array_set_complex( input, n,
1199 cpl_array_get_complex( input, n, &nv) +
1200 cexp ( factor * cpl_array_get( phase, n, &nv) ) );
1201 CPLCHECK_MSG ("Cannot add phasor");
1202 }
1203
1204 return CPL_ERROR_NONE;
1205}
1206
1211cpl_error_code gravi_array_add_phasors (cpl_array * input, cpl_array * add, cpl_array * sub)
1212{
1213 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1214 cpl_ensure_code (add, CPL_ERROR_NULL_INPUT);
1215 cpl_ensure_code (sub, CPL_ERROR_NULL_INPUT);
1216
1217 cpl_size size_in = cpl_array_get_size (input);
1218 cpl_size size_add = cpl_array_get_size (add);
1219 cpl_size size_sub = cpl_array_get_size (sub);
1220
1221 cpl_ensure_code (size_in == size_add, CPL_ERROR_ILLEGAL_INPUT);
1222 cpl_ensure_code (size_in == size_sub, CPL_ERROR_ILLEGAL_INPUT);
1223
1224 cpl_size n;
1225 int nv = 0.0;
1226 for (n = 0; n < size_in; n ++) {
1227 cpl_array_set_complex (input, n,
1228 cpl_array_get_complex (input, n, &nv) +
1229 cpl_array_get_complex (add, n, &nv) *
1230 conj (cpl_array_get_complex (sub, n, &nv)));
1231 CPLCHECK_MSG ("Cannot add phasors");
1232 }
1233
1234 return CPL_ERROR_NONE;
1235}
1236
1241cpl_error_code gravi_array_add_phase (cpl_array * input, double factor, cpl_array * phase)
1242{
1243 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1244 cpl_ensure_code (phase, CPL_ERROR_NULL_INPUT);
1245
1246 cpl_size size_in = cpl_array_get_size (input);
1247 cpl_size size_ph = cpl_array_get_size (phase);
1248
1249 cpl_ensure_code (size_in == size_ph, CPL_ERROR_ILLEGAL_INPUT);
1250
1251 cpl_array * tmp = cpl_array_duplicate (phase);
1252
1253 cpl_array_multiply_scalar (tmp, factor);
1254 cpl_array_add (input, tmp);
1255
1256 cpl_array_delete (tmp);
1257
1258 CPLCHECK_MSG("Cannot add phase");
1259 return CPL_ERROR_NONE;
1260}
1261
1262cpl_error_code gravi_array_multiply_conj (cpl_array * input1, cpl_array * input2)
1263{
1264 cpl_ensure_code (input1, CPL_ERROR_NULL_INPUT);
1265 cpl_ensure_code (input2, CPL_ERROR_NULL_INPUT);
1266
1267 cpl_size size_in1 = cpl_array_get_size (input1);
1268 cpl_size size_in2 = cpl_array_get_size (input2);
1269
1270 cpl_ensure_code (size_in1 == size_in2, CPL_ERROR_ILLEGAL_INPUT);
1271
1272 for (cpl_size w = 0 ; w < size_in1 ; w++)
1273 cpl_array_set_complex (input1, w, cpl_array_get_complex (input1, w, NULL) *
1274 conj(cpl_array_get_complex (input2, w, NULL)));
1275
1276 CPLCHECK_MSG ("Cannot multiply by conj");
1277 return CPL_ERROR_NONE;
1278}
1279
1280
1281/*
1282 * Returned a smoothed version of an array of DOUBLE
1283 * Invalid data are not checked (all considered as valid)
1284 */
1285cpl_array * gravi_array_smooth (cpl_array * input_array, int DIT_smooth)
1286{
1287 cpl_ensure (DIT_smooth>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1288 cpl_ensure (input_array, CPL_ERROR_NULL_INPUT, NULL);
1289
1290 cpl_type type = cpl_array_get_type (input_array);
1291 cpl_size nrow = cpl_array_get_size ( input_array );
1292
1293 /* avoid segmentation fault if nrow < DIT_smooth */
1294 if (nrow-DIT_smooth*2-1<0) DIT_smooth=nrow/2;
1295
1296 /* create output array */
1297 cpl_array * output_smooth_array;
1298
1299 /* create data buffers and data carrier (the smoothed buffer)*/
1300 if ( type == CPL_TYPE_DOUBLE ) {
1301 double* input = cpl_array_get_data_double (input_array);
1302 double* output_smooth = cpl_malloc (nrow * sizeof(double));
1303 double data_carrier = 0.0;
1304
1305 /* smooth data */
1306 int int_carrier = 0;
1307 for (cpl_size row = - DIT_smooth; row < 0; row ++)
1308 {
1309 data_carrier+=input[row+DIT_smooth];
1310 int_carrier+=1;
1311 }
1312 for (cpl_size row = 0; row < DIT_smooth+1; row ++)
1313 {
1314 data_carrier+=input[row+DIT_smooth];
1315 int_carrier+=1;
1316 output_smooth[row]=data_carrier/int_carrier;
1317 }
1318 double inv_int_carrier= 1.0/int_carrier;
1319 for (cpl_size row = DIT_smooth+1; row < nrow-DIT_smooth; row ++)
1320 {
1321 data_carrier-=input[row-DIT_smooth-1];
1322 data_carrier+=input[row+DIT_smooth];
1323 output_smooth[row]=data_carrier*inv_int_carrier;
1324 }
1325 for (cpl_size row = nrow-DIT_smooth; row < nrow; row ++)
1326 {
1327 data_carrier-=input[row-DIT_smooth-1];
1328 int_carrier-=1;
1329 output_smooth[row]=data_carrier/int_carrier;
1330 }
1331
1332 /* wrap data into array */
1333 output_smooth_array=cpl_array_wrap_double (output_smooth, nrow);
1334
1335 } else if ( type == CPL_TYPE_DOUBLE_COMPLEX ){
1336 double complex * input = cpl_array_get_data_double_complex (input_array);
1337 double complex * output_smooth = cpl_malloc (nrow * sizeof(double complex));
1338 double complex data_carrier = 0.0;
1339
1340 /* smooth data */
1341 int int_carrier = 0;
1342 for (cpl_size row = - DIT_smooth; row < 0; row ++)
1343 {
1344 data_carrier+=input[row+DIT_smooth];
1345 int_carrier+=1;
1346 }
1347 for (cpl_size row = 0; row < DIT_smooth+1; row ++)
1348 {
1349 data_carrier+=input[row+DIT_smooth];
1350 int_carrier+=1;
1351 output_smooth[row]=data_carrier/int_carrier;
1352 }
1353 double inv_int_carrier= 1.0/int_carrier;
1354 for (cpl_size row = DIT_smooth+1; row < nrow-DIT_smooth; row ++)
1355 {
1356 data_carrier-=input[row-DIT_smooth-1];
1357 data_carrier+=input[row+DIT_smooth];
1358 output_smooth[row]=data_carrier*inv_int_carrier;
1359 }
1360 for (cpl_size row = nrow-DIT_smooth; row < nrow; row ++)
1361 {
1362 data_carrier-=input[row-DIT_smooth-1];
1363 int_carrier-=1;
1364 output_smooth[row]=data_carrier/int_carrier;
1365 }
1366
1367 /* wrap data into array */
1368 output_smooth_array=cpl_array_wrap_double_complex (output_smooth, nrow);
1369
1370
1371 } else {
1372 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
1373 "This type is not supported... report this error to DRS team !!");
1374 return NULL;
1375 }
1376 return output_smooth_array;
1377}
1378
1379/*----------------------------------------------------------------------------*/
1401/*----------------------------------------------------------------------------*/
1402
1403cpl_error_code gravi_array_get_group_delay_loop (cpl_array ** input,
1404 cpl_array ** flag,
1405 cpl_array * sigma,
1406 double * gd, cpl_size nrow,
1407 double max_width,
1408 int verbose)
1409{
1410 gravi_msg_function_start(verbose);
1411 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1412 cpl_ensure_code (sigma, CPL_ERROR_NULL_INPUT);
1413 cpl_ensure_code (gd, CPL_ERROR_ILLEGAL_OUTPUT);
1414
1415 int nv = 0;
1416 cpl_size nsigma = cpl_array_get_size (sigma);
1417 double width1, step1, width2, step2, width3, step3;
1418 cpl_size w, s, nstep1, nstep2, nstep3;
1419 double x, gd0, gd1, gd2, gd3, current_max = -1.0;
1420 double lbd = 1.0 / cpl_array_get (sigma,nsigma/2,&nv);
1421
1422 /* Width of a single spectral channel in [m] */
1423 double coherence = 0.5 * nsigma / fabs (cpl_array_get (sigma,0,&nv) - cpl_array_get (sigma,nsigma-1,&nv));
1424
1425 /* We never explore more than max_width */
1426 width1 = CPL_MIN (coherence, max_width);
1427 step1 = 2.0 * lbd;
1428 nstep1 = (cpl_size)(width1/step1);
1429
1430 /* Second pass */
1431 width2 = 3.0 * step1;
1432 step2 = 0.1 * lbd;
1433 nstep2 = (cpl_size)(width2/step2);
1434
1435 /* Third pass */
1436 width3 = 3.0 * step2;
1437 step3 = 0.01 * lbd;
1438 nstep3 = (cpl_size)(width3/step3);
1439
1440 /* Allocate memory for the grid search */
1441 double P = 0.0;
1442 double * sigdata = cpl_malloc (sizeof(double complex) * nsigma);
1443 double complex * visdata = cpl_malloc (sizeof(double complex) * nsigma);
1444 double complex * waveform1 = cpl_malloc (sizeof(double complex) * (nstep1+2) * nsigma);
1445 double complex * waveform2 = cpl_malloc (sizeof(double complex) * (nstep2+2) * nsigma);
1446 double complex * waveform3 = cpl_malloc (sizeof(double complex) * (nstep3+2) * nsigma);
1447
1448 /* Copy data as double to secure their type */
1449 for (w=0; w<nsigma; w++) sigdata[w] = cpl_array_get (sigma, w, &nv);
1450
1451 /* Sum of wavenumber differences */
1452 double ds = 0.0;
1453 for (w=1; w<nsigma; w++) ds += sigdata[w] - sigdata[w-1];
1454 ds /= (nsigma-1);
1455
1456 /* Build waveform */
1457 cpl_msg_debug (cpl_func, "Build waveform for 3 pass -- %lli %lli %lli steps", nstep1, nstep2, nstep3);
1458
1459 for (s=0, x = -width1/2.0; x < +width1/2.0; x+=step1)
1460 for (w=0; w<nsigma; w++) { waveform1[s] = cexp (-2.*I*CPL_MATH_PI * x * sigdata[w]); s++;}
1461 for (s=0, x = -width2/2.0; x < +width2/2.0; x+=step2)
1462 for (w=0; w<nsigma; w++) { waveform2[s] = cexp (-2.*I*CPL_MATH_PI * x * sigdata[w]); s++;}
1463 for (s=0, x = -width3/2.0; x < +width3/2.0; x+=step3)
1464 for (w=0; w<nsigma; w++) { waveform3[s] = cexp (-2.*I*CPL_MATH_PI * x * sigdata[w]); s++;}
1465
1466 cpl_msg_debug (cpl_func, "Loop on %lli rows to compute gdelay", nrow);
1467
1468 /* Loop on rows */
1469 for (cpl_size row = 0; row<nrow; row++) {
1470
1471 /* Copy data as double complex to secure their type and allow
1472 * in-place modification between the different grids */
1473 for (w=0; w<nsigma; w++) {
1474 if (flag && cpl_array_get (flag[row], w, &nv)) visdata[w] = 0. + I*0.;
1475 else visdata[w] = cpl_array_get_complex (input[row], w, &nv);
1476 }
1477
1478 /* IOTA method in [m] -- as starting point, with
1479 * equal weight to all channels to avoid badpixels */
1480 double complex is = 0.0 + I * 0.0;
1481 for (w=1; w<nsigma; w++) {
1482 is += visdata[w] * conj(visdata[w-1]) / CPL_MAX(cabs(visdata[w]) * cabs(visdata[w-1]), 1e-15);
1483 }
1484 gd0 = carg (is) / ds / CPL_MATH_2PI;
1485
1486 /* Remove GD */
1487 for (w=0; w<nsigma; w++) visdata[w] *= cexp (-2.*I*CPL_MATH_PI*gd0*sigdata[w]);
1488
1489 /* Loop on x to find the maximum of P(x) = |FT(input(sigma))| */
1490 for (current_max = -1.0, s = 0, x = -width1/2; x < +width1/2; x+=step1) {
1491 double complex tmp = 0.0 * I + 0.0;
1492 for (w=0; w<nsigma; w++) {tmp += visdata[w] * waveform1[s]; s++;}
1493 P = cabs (tmp);
1494 if ( P > current_max) { current_max = P; gd1 = x; }
1495 }
1496
1497 /* Remove GD */
1498 for (w=0; w<nsigma; w++) visdata[w] *= cexp (-2.*I*CPL_MATH_PI*gd1*sigdata[w]);
1499
1500 /* Loop on x to find the maximum of P(x) = |FT(input(sigma))| */
1501 for (current_max = -1.0, s = 0, x = -width2/2; x < +width2/2; x+=step2) {
1502 double complex tmp = 0.0 * I + 0.0;
1503 for (w=0; w<nsigma; w++) {tmp += visdata[w] * waveform2[s]; s++;}
1504 P = cabs (tmp);
1505 if ( P > current_max) { current_max = P; gd2 = x; }
1506 }
1507
1508 /* Remove GD */
1509 for (w=0; w<nsigma; w++) visdata[w] *= cexp (-2.*I*CPL_MATH_PI*gd2*sigdata[w]);
1510
1511 /* Loop on x to find the maximum of P(x) = |FT(input(sigma))| */
1512 for (current_max = -1.0, s = 0, x = -width3/2; x < +width3/2; x+=step3) {
1513 double complex tmp = 0.0 * I + 0.0;
1514 for (w=0; w<nsigma; w++) {tmp += visdata[w] * waveform3[s]; s++;}
1515 P = cabs (tmp);
1516 if ( P > current_max) { current_max = P; gd3 = x; }
1517 }
1518
1519 gd[row] = gd0 + gd1 + gd2 + gd3;
1520
1521 CPLCHECK_MSG("Cannot compute GD");
1522 } /* End loop on rows */
1523
1524 /* Clean memory */
1525 FREE (cpl_free, visdata);
1526 FREE (cpl_free, sigdata);
1527 FREE (cpl_free, waveform1);
1528 FREE (cpl_free, waveform2);
1529 FREE (cpl_free, waveform3);
1530
1531 gravi_msg_function_exit(verbose);
1532 return CPL_ERROR_NONE;
1533}
1534
1535cpl_error_code gravi_table_compute_group_delay (cpl_table * table,
1536 const char *input,
1537 const char *flag,
1538 const char *output, cpl_table * oi_wave)
1539{
1541 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1542 cpl_ensure_code (input, CPL_ERROR_NULL_INPUT);
1543 cpl_ensure_code (flag, CPL_ERROR_NULL_INPUT);
1544 cpl_ensure_code (output, CPL_ERROR_NULL_INPUT);
1545 cpl_ensure_code (oi_wave, CPL_ERROR_NULL_INPUT);
1546
1547 /* Create sigma */
1548 cpl_size nwave = cpl_table_get_nrow (oi_wave);
1549 cpl_array * sigma = cpl_array_new (nwave, CPL_TYPE_DOUBLE);
1550 for (cpl_size wave = 0; wave < nwave ; wave ++)
1551 cpl_array_set (sigma, wave, 1./cpl_table_get (oi_wave, "EFF_WAVE", wave, NULL));
1552
1553 /* If output columns doesn't exist, create it */
1554 gravi_table_new_column (table, output, "m", CPL_TYPE_DOUBLE);
1555 double * gdelay = cpl_table_get_data_double (table, output);
1556
1557 /* Get data */
1558 cpl_array ** input_arrays = cpl_table_get_data_array (table, input);
1559 cpl_array ** flag_arrays = cpl_table_get_data_array (table, flag);
1560 cpl_size nrow = cpl_table_get_nrow (table);
1561
1562 CPLCHECK_MSG ("Cannot get data");
1563
1564 /* Run */
1566 flag_arrays,
1567 sigma, gdelay,
1568 nrow, 1.e-3, CPL_TRUE);
1569 FREE (cpl_array_delete, sigma);
1570
1572 return CPL_ERROR_NONE;
1573}
1574
1575
1576
1577/*----------------------------------------------------------------------------*/
1584/*----------------------------------------------------------------------------*/
1585int gravi_table_are_equal (cpl_table * first, cpl_table * second)
1586{
1588 cpl_ensure_code (first, CPL_ERROR_NULL_INPUT);
1589 cpl_ensure_code (second, CPL_ERROR_NULL_INPUT);
1590
1591 cpl_size nrow = cpl_table_get_nrow (first);
1592 cpl_size ncol = cpl_table_get_ncol (first);
1593 int nv = 0;
1594
1595 if (nrow != cpl_table_get_nrow (second)) {cpl_msg_info(cpl_func, "Different rows"); return 0;}
1596 if (ncol != cpl_table_get_ncol (second)) {cpl_msg_info(cpl_func, "Different cols"); return 0;}
1597 if (cpl_table_compare_structure (first, second)) {cpl_msg_info(cpl_func, "Different structure"); return 0;}
1598
1599 /* Create array of names */
1600 cpl_array *names = cpl_table_get_column_names (first);
1601
1602 /* Loop on colums */
1603 for (cpl_size c = 0; c<ncol; c++) {
1604 const char * name = cpl_array_get_string (names, c);
1605 cpl_msg_debug (cpl_func,"Now test %s", name);
1606
1607 /* Cast the type into an int, to avoid warnings */
1608 int type = cpl_table_get_column_type (first, name);
1609
1610 switch (type) {
1611 case CPL_TYPE_STRING:
1612 for (cpl_size r = 0; r<nrow; r++)
1613 if (strcmp (cpl_table_get_string (first, name, r),
1614 cpl_table_get_string (second, name, r) ) )
1615 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1616 break;
1617 case CPL_TYPE_DOUBLE:
1618 case CPL_TYPE_FLOAT:
1619 case CPL_TYPE_INT:
1620 for (cpl_size r = 0; r<nrow; r++)
1621 if (cpl_table_get (first, name, r, &nv) !=
1622 cpl_table_get (second, name, r, &nv) )
1623 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1624 break;
1625 case CPL_TYPE_POINTER|CPL_TYPE_STRING:
1626 for (cpl_size r = 0; r<nrow; r++)
1627 for (cpl_size p = 0; p<cpl_table_get_column_depth (first,name); p++)
1628 if ( strcmp (cpl_array_get_string (cpl_table_get_array (first, name, r), p),
1629 cpl_array_get_string (cpl_table_get_array (second, name, r), p)) )
1630 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1631 break;
1632 case CPL_TYPE_POINTER|CPL_TYPE_DOUBLE:
1633 case CPL_TYPE_POINTER|CPL_TYPE_FLOAT:
1634 case CPL_TYPE_POINTER|CPL_TYPE_INT:
1635 for (cpl_size r = 0; r<nrow; r++)
1636 for (cpl_size p = 0; p<cpl_table_get_column_depth (first,name); p++) {
1637 if (cpl_array_get (cpl_table_get_array (first, name, r), p, NULL) !=
1638 cpl_array_get (cpl_table_get_array (second, name, r), p, NULL) )
1639 {cpl_msg_info (cpl_func,"Different values in column %s, row %lli", name,r); return 0;}
1640 }
1641 break;
1642 default:
1643 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT, "Cannot compare these tables (TBD, FIXME)");
1644 return 0;
1645 }
1646
1647 }/* End loop on columns */
1648
1649 /* Clean memory */
1650 FREE (cpl_array_delete, names);
1651
1653 return 1;
1654}
1655
1656cpl_error_code gravi_table_new_column (cpl_table * table, const char * name, const char * unit, cpl_type type)
1657{
1658 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1659 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1660
1661 if ( cpl_table_has_column (table, name) &&
1662 cpl_table_get_column_type (table, name) == type) {
1663 cpl_msg_info (cpl_func, "Column %s already exists", name);
1664 } else {
1665 cpl_table_new_column (table, name, type);
1666 }
1667
1668 if (type == CPL_TYPE_DOUBLE_COMPLEX || type == CPL_TYPE_FLOAT_COMPLEX)
1669 cpl_table_fill_column_window_complex (table, name, 0, cpl_table_get_nrow (table), 0.0 + I*0.0);
1670 else
1671 cpl_table_fill_column_window (table, name, 0, cpl_table_get_nrow (table), 0.0);
1672
1673 if (unit) cpl_table_set_column_unit (table, name, unit);
1674
1675 return CPL_ERROR_NONE;
1676}
1677
1678cpl_error_code gravi_table_new_column_array (cpl_table * table, const char * name, const char * unit, cpl_type type, cpl_size size)
1679{
1680 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1681 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1682
1683 if ( cpl_table_has_column (table, name) )
1684 cpl_table_erase_column (table, name);
1685
1686 cpl_table_new_column_array (table, name, type, size);
1687 if (unit) cpl_table_set_column_unit (table, name, unit);
1688
1689 return CPL_ERROR_NONE;
1690}
1691
1692cpl_error_code gravi_table_init_column_array (cpl_table * table, const char * name, const char * unit, cpl_type type, cpl_size size)
1693{
1694 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
1695 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
1696
1697 if ( cpl_table_has_column (table, name) )
1698 cpl_table_erase_column (table, name);
1699
1700 cpl_table_new_column_array (table, name, type, size);
1701 if (unit) cpl_table_set_column_unit (table, name, unit);
1702
1703 cpl_array * array = cpl_array_new (size, type);
1704 cpl_array_fill_window (array, 0, size, 0.0);
1705
1706 cpl_size nrow = cpl_table_get_nrow (table);
1707 for (cpl_size row = 0; row < nrow; row++)
1708 cpl_table_set_array (table, name, row, array);
1709
1710 FREE (cpl_array_delete, array);
1711
1712 return CPL_ERROR_NONE;
1713}
1714
1715/*---------------------------------------------------------------------------*/
1725/*---------------------------------------------------------------------------*/
1726
1727cpl_error_code gravi_imagelist_unwrap_images (cpl_imagelist * imglist)
1728{
1729 cpl_ensure_code (imglist, CPL_ERROR_NULL_INPUT);
1730
1731 cpl_size nrow = cpl_imagelist_get_size (imglist);
1732
1733 for (cpl_size i = nrow-1; i>=0 ; i--) {
1734 cpl_image_unwrap (cpl_imagelist_unset (imglist, i));
1735 CPLCHECK_MSG("Cannot unset image");
1736 }
1737
1738 cpl_imagelist_delete (imglist);
1739 CPLCHECK_MSG("Cannot delete imagelist");
1740
1741 return CPL_ERROR_NONE;
1742}
1743
1744/*---------------------------------------------------------------------------*/
1755/*---------------------------------------------------------------------------*/
1756
1757cpl_imagelist * gravi_imagelist_wrap_column (cpl_table * table_data, const char * data_x)
1758{
1760 cpl_ensure (table_data, CPL_ERROR_NULL_INPUT, NULL);
1761 cpl_ensure (data_x, CPL_ERROR_NULL_INPUT, NULL);
1762
1763 /* Get the type of the column
1764 * Cast into an int to avoid warnings */
1765 int type_column = cpl_table_get_column_type (table_data, data_x);
1766
1767 /* Get pointer to the data */
1768 cpl_size nrow = cpl_table_get_nrow (table_data);
1769 cpl_array ** array = cpl_table_get_data_array (table_data, data_x);
1770 cpl_ensure (array, CPL_ERROR_ILLEGAL_INPUT, NULL);
1771
1772 /* If the column has no-dimension, we fake them */
1773 cpl_size nx, ny;
1774 if (cpl_table_get_column_dimensions (table_data, data_x)<2) {
1775 nx = cpl_table_get_column_depth (table_data, data_x);
1776 ny = 1;
1777 } else {
1778 nx = cpl_table_get_column_dimension (table_data, data_x, 0);
1779 ny = cpl_table_get_column_dimension (table_data, data_x, 1);
1780 }
1781 CPLCHECK_NUL ("Cannot get dimension");
1782
1783 /* Create output */
1784 cpl_image * img;
1785 cpl_imagelist * imglist = cpl_imagelist_new();
1786
1787 /* compute the image list depending of the DATA type */
1788 switch (type_column)
1789 {
1790 case CPL_TYPE_POINTER|CPL_TYPE_DOUBLE :
1791
1792 for (cpl_size j = 0; j < nrow ; j++)
1793 {
1794 img = cpl_image_wrap_double (nx, ny, cpl_array_get_data_double(array[j]));
1795 cpl_imagelist_set (imglist, img, j);
1796 }
1797
1798 break;
1799
1800 case CPL_TYPE_POINTER|CPL_TYPE_INT :
1801
1802 for (cpl_size j = 0; j < nrow ; j++)
1803 {
1804 img = cpl_image_wrap_int (nx, ny, cpl_array_get_data_int(array[j]));
1805 cpl_imagelist_set (imglist, img,j);
1806 }
1807
1808 break;
1809
1810 case CPL_TYPE_POINTER|CPL_TYPE_FLOAT :
1811 for (cpl_size j = 0; j < nrow ; j++)
1812 {
1813 img = cpl_image_wrap_float (nx, ny, cpl_array_get_data_float(array[j]));
1814 cpl_imagelist_set (imglist, img, j);
1815 }
1816
1817 break;
1818
1819 default:
1820
1821 cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
1822 "invalid type of image coming from %s", data_x);
1823 cpl_imagelist_delete (imglist);
1824 return NULL;
1825 break;
1826 }
1827
1829 return imglist;
1830}
1831
1832/*----------------------------------------------------------------------------*/
1837/*----------------------------------------------------------------------------*/
1838
1839double gravi_image_get_noise_window (cpl_image *img,
1840 cpl_size llx, cpl_size lly,
1841 cpl_size urx, cpl_size ury)
1842{
1844 cpl_ensure (img, CPL_ERROR_NULL_INPUT, -1);
1845 int nv;
1846
1847 /* Extract values in vector */
1848 cpl_vector * flux = cpl_vector_new ((urx-llx+1)*(ury-lly+1));
1849
1850 for (cpl_size v = 0, x = llx; x <= urx; x++) {
1851 for (cpl_size y = lly; y <= ury; y++) {
1852 cpl_vector_set (flux, v, cpl_image_get (img, x, y, &nv));
1853 v++;
1854 CPLCHECK_MSG ("Cannot fill vector");
1855 }
1856 }
1857
1858 /* FIXME: remove the median before square */
1859
1860 /* Compute typical error as the
1861 * median of spatial variation */
1862 cpl_vector_multiply (flux, flux);
1863
1864 double RMS = sqrt (cpl_vector_get_median (flux));
1865 FREE (cpl_vector_delete, flux);
1866
1868 return RMS;
1869}
1870
1871/*----------------------------------------------------------------------------*/
1882/*----------------------------------------------------------------------------*/
1883
1884cpl_image * gravi_image_collapse_median_x (cpl_image * img, cpl_size drop_from, cpl_size drop_to)
1885{
1887 cpl_ensure (img, CPL_ERROR_NULL_INPUT, NULL);
1888 cpl_ensure (drop_from < drop_to, CPL_ERROR_ILLEGAL_INPUT, NULL);
1889
1890 /* Get size */
1891 cpl_size nx = cpl_image_get_size_x (img);
1892 cpl_size ny = cpl_image_get_size_y (img);
1893
1894 /* Check */
1895 cpl_ensure (drop_from >0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1896 cpl_ensure (drop_to <=nx, CPL_ERROR_ILLEGAL_INPUT, NULL);
1897
1898 /* Fill mask */
1899 cpl_mask * mask = cpl_mask_new (nx, ny);
1900 for (cpl_size y = 1; y <= ny; y++)
1901 for (cpl_size x = drop_from; x <= drop_to ; x++)
1902 cpl_mask_set (mask, x, y, CPL_BINARY_1);
1903
1904 /* Set BPM */
1905 cpl_mask * bpm = cpl_image_set_bpm (img, mask);
1906
1907 /* Collapse in the x direction */
1908 cpl_image * collapse = cpl_image_collapse_median_create (img, 1, 0, 0);
1909
1910 /* Set back current BPM */
1911 mask = cpl_image_set_bpm (img, bpm);
1912 FREE (cpl_mask_delete, mask);
1913
1914 /* Return collapse */
1916 return collapse;
1917}
1918
1919/*----------------------------------------------------------------------------*/
1920
1921cpl_error_code gravi_image_subtract_collapse (cpl_image * img,
1922 const cpl_image * collapse,
1923 int direction)
1924{
1926 cpl_ensure_code (img, CPL_ERROR_NULL_INPUT);
1927 cpl_ensure_code (collapse, CPL_ERROR_NULL_INPUT);
1928 cpl_ensure_code (direction==0 || direction==1, CPL_ERROR_ILLEGAL_INPUT);
1929
1930 int nv;
1931
1932 /* Get size */
1933 cpl_size nx = cpl_image_get_size_x (img);
1934 cpl_size ny = cpl_image_get_size_y (img);
1935
1936 if (direction == 0) {
1937 /* Collapse was done along the y direction */
1938 cpl_ensure_code (cpl_image_get_size_x (collapse) == nx &&
1939 cpl_image_get_size_y (collapse) == 1,
1940 CPL_ERROR_ILLEGAL_INPUT);
1941
1942 for (cpl_size x = 0; x < nx ; x++) {
1943 double value = cpl_image_get (collapse, x+1, 1, &nv);
1944 for (cpl_size y = 0; y < ny ; y++) {
1945 cpl_image_set (img, x+1, y+1, cpl_image_get (img, x+1, y+1, &nv) - value);
1946 CPLCHECK_MSG ("Cannot remove collapse y");
1947 }
1948 }
1949
1950 } else {
1951 /* Collapse was done along the x direction */
1952 cpl_ensure_code (cpl_image_get_size_x (collapse) == 1 &&
1953 cpl_image_get_size_y (collapse) == ny,
1954 CPL_ERROR_ILLEGAL_INPUT);
1955
1956 for (cpl_size y = 0; y < ny ; y++) {
1957 double value = cpl_image_get (collapse, 1, y+1, &nv);
1958 for (cpl_size x = 0; x < nx ; x++) {
1959 cpl_image_set (img, x+1, y+1, cpl_image_get (img, x+1, y+1, &nv) - value);
1960 CPLCHECK_MSG ("Cannot remove collapse x");
1961 }
1962 }
1963 }
1964
1966 return CPL_ERROR_NONE;
1967}
1968
1969/*----------------------------------------------------------------------------*/
1970
1971cpl_error_code gravi_image_subtract_window (cpl_image * img1, const cpl_image * img2,
1972 cpl_size llx, cpl_size lly,
1973 cpl_size urx, cpl_size ury,
1974 cpl_size llx2, cpl_size lly2)
1975{
1977 cpl_ensure_code (img1, CPL_ERROR_NULL_INPUT);
1978 cpl_ensure_code (img2, CPL_ERROR_NULL_INPUT);
1979
1980 /* Ensure size */
1981 cpl_size nx = cpl_image_get_size_x (img1);
1982 cpl_size ny = cpl_image_get_size_y (img1);
1983
1984 urx = CPL_MIN (urx, nx);
1985 ury = CPL_MIN (ury, ny);
1986 llx2 -= llx;
1987 lly2 -= lly;
1988
1989 int nv;
1990 for (cpl_size x=llx; x<=urx; x++) {
1991 for (cpl_size y=lly; y<=ury; y++) {
1992 cpl_image_set (img1, x, y,
1993 cpl_image_get (img1,x,y,&nv) -
1994 cpl_image_get (img2,x+llx2,y+lly2,&nv));
1995 }
1996 }
1997
1999 return CPL_ERROR_NONE;
2000}
2001
2002/*----------------------------------------------------------------------------*/
2003
2004cpl_error_code gravi_image_replace_window (cpl_image * img1, const cpl_image * img2,
2005 cpl_size llx, cpl_size lly,
2006 cpl_size urx, cpl_size ury,
2007 cpl_size llx2, cpl_size lly2)
2008{
2010 cpl_ensure_code (img1, CPL_ERROR_NULL_INPUT);
2011 cpl_ensure_code (img2, CPL_ERROR_NULL_INPUT);
2012
2013 /* Ensure size */
2014 cpl_size nx = cpl_image_get_size_x (img1);
2015 cpl_size ny = cpl_image_get_size_y (img1);
2016 cpl_size nx2 = cpl_image_get_size_x (img2);
2017 cpl_size ny2 = cpl_image_get_size_y (img2);
2018 cpl_msg_info(cpl_func, "Size image 1 %lli/%lli, Size window %lli/%lli" , nx,ny,nx2,ny2);
2019
2020 urx = CPL_MIN (urx, nx);
2021 ury = CPL_MIN (ury, ny);
2022 llx2 -= llx;
2023 lly2 -= lly;
2024
2025 int nv;
2026 for (cpl_size x=llx; x<=urx; x++) {
2027 for (cpl_size y=lly; y<=ury; y++) {
2028 cpl_image_set (img1, x, y,
2029 cpl_image_get (img2,x+llx2,y+lly2,&nv));
2030 }
2031 }
2032
2034 return CPL_ERROR_NONE;
2035}
2036
2037/*---------------------------------------------------------------------------*/
2050/*---------------------------------------------------------------------------*/
2051
2052cpl_image * gravi_image_from_column (cpl_table * table_data, const char * data_x, cpl_size row)
2053{
2055 cpl_ensure (table_data, CPL_ERROR_NULL_INPUT, NULL);
2056 cpl_ensure (data_x, CPL_ERROR_NULL_INPUT, NULL);
2057 cpl_ensure (row < cpl_table_get_nrow (table_data), CPL_ERROR_ILLEGAL_INPUT, NULL);
2058
2059 cpl_imagelist * wrap_imglist = gravi_imagelist_wrap_column (table_data, data_x);
2060 cpl_ensure (wrap_imglist, CPL_ERROR_ILLEGAL_INPUT, NULL);
2061
2062 cpl_image * out_img = cpl_image_duplicate (cpl_imagelist_get (wrap_imglist, row));
2063 gravi_imagelist_unwrap_images (wrap_imglist);
2064
2066 return out_img;
2067}
2068
2069/*---------------------------------------------------------------------------*/
2082/*---------------------------------------------------------------------------*/
2083
2084cpl_imagelist * gravi_imagelist_from_column (cpl_table * table_data, const char * data_x)
2085{
2087 cpl_ensure (table_data, CPL_ERROR_NULL_INPUT, NULL);
2088 cpl_ensure (data_x, CPL_ERROR_NULL_INPUT, NULL);
2089
2090 cpl_imagelist * wrap_imglist = gravi_imagelist_wrap_column (table_data, data_x);
2091 cpl_ensure (wrap_imglist, CPL_ERROR_ILLEGAL_INPUT, NULL);
2092
2093 cpl_imagelist * out_imglist = cpl_imagelist_duplicate (wrap_imglist);
2094 gravi_imagelist_unwrap_images (wrap_imglist);
2095
2097 return out_imglist;
2098}
2099
2100
2101/*---------------------------------------------------------------------------*/
2112/*---------------------------------------------------------------------------*/
2113
2114cpl_array * gravi_table_get_column_dimension (const cpl_table * table, const char * name)
2115{
2116 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
2117 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
2118
2119 cpl_size ndim = cpl_table_get_column_dimensions (table, name);
2120 cpl_array * dimension = cpl_array_new (ndim, CPL_TYPE_INT);
2121 for (cpl_size dim = 0; dim < ndim; dim++) {
2122 int value = cpl_table_get_column_dimension (table, name, dim);
2123 cpl_array_set (dimension, dim, value);
2124 }
2125
2126 return dimension;
2127}
2128
2129/*---------------------------------------------------------------------------*/
2139/*---------------------------------------------------------------------------*/
2140
2141cpl_array * gravi_array_wrap_image (cpl_image * img)
2142{
2143 cpl_ensure (img, CPL_ERROR_NULL_INPUT, NULL);
2144
2145 cpl_type type_img = cpl_image_get_type (img);
2146 int x = cpl_image_get_size_x (img);
2147 int y = cpl_image_get_size_y (img);
2148
2149 CPLCHECK_NUL ("Cannot get data");
2150
2151 cpl_array * array = NULL;
2152 switch (type_img){
2153 case CPL_TYPE_FLOAT :
2154 array = cpl_array_wrap_float (cpl_image_get_data_float(img), x*y);
2155 break;
2156 case CPL_TYPE_DOUBLE :
2157 array = cpl_array_wrap_double (cpl_image_get_data_double(img), x*y);
2158 break;
2159 case CPL_TYPE_INT :
2160 array = cpl_array_wrap_int (cpl_image_get_data_int(img), x*y);
2161 break;
2162 default :
2163 cpl_error_set_message(cpl_func, CPL_ERROR_INVALID_TYPE,
2164 "invalid type of image");
2165 return NULL;
2166 }
2167
2168 return array;
2169}
2170
2171
2172/*---------------------------------------------------------------------------*/
2183/*---------------------------------------------------------------------------*/
2184
2185cpl_matrix * get_matrix_from_vector(cpl_vector * vector1,
2186 cpl_vector * vector2)
2187{
2188 cpl_ensure (vector1, CPL_ERROR_NULL_INPUT, NULL);
2189
2190 cpl_matrix * matrix, * matrix_wrap;
2191 int size = cpl_vector_get_size(vector1);
2192 double * data1, * data2;
2193
2194 if( vector2 != NULL ){
2195 int size2 = cpl_vector_get_size(vector2);
2196 cpl_ensure (size == size2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2197
2198 data1 = cpl_malloc(2 * size * sizeof(double));
2199 memcpy(data1, cpl_vector_get_data(vector1), size * sizeof(double));
2200
2201 data2 = cpl_vector_get_data(vector2);
2202 memcpy(data1 + size, data2, size * sizeof(double));
2203
2204 matrix_wrap = cpl_matrix_wrap(2, size, data1);
2205 matrix = cpl_matrix_transpose_create(matrix_wrap);
2206
2207 cpl_matrix_unwrap(matrix_wrap);
2208 }
2209 else{
2210 data1 = cpl_malloc(size * sizeof(double));
2211 memcpy(data1, cpl_vector_get_data(vector1), size * sizeof(double));
2212
2213 matrix = cpl_matrix_wrap(size, 1, data1);
2214 }
2215 cpl_free(data1);
2216
2217 return matrix;
2218}
2219
2220/*---------------------------------------------------------------------------*/
2233/*---------------------------------------------------------------------------*/
2234
2235cpl_vector * gravi_table_get_vector (cpl_table * spectrum_data,
2236 cpl_size index,
2237 const char * regname)
2238{
2239 /* Check the inputs */
2240 cpl_ensure (spectrum_data, CPL_ERROR_NULL_INPUT, NULL);
2241 cpl_ensure (regname, CPL_ERROR_NULL_INPUT, NULL);
2242 cpl_ensure (index>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2243
2244 /* Get the array size */
2245 cpl_size size = cpl_table_get_column_depth (spectrum_data, regname);
2246 cpl_ensure (index<size, CPL_ERROR_ILLEGAL_INPUT, NULL);
2247
2248 /* allocate the vector */
2249 cpl_size nrow = cpl_table_get_nrow (spectrum_data);
2250 cpl_vector * data_value = cpl_vector_new (nrow);
2251
2252 if (size > 0) {
2253
2254 /* Extract the data from the column region */
2255 cpl_array ** column_array = cpl_table_get_data_array (spectrum_data, regname);
2256 cpl_ensure (column_array, CPL_ERROR_ILLEGAL_INPUT, NULL);
2257
2258 /* Loop on row */
2259 double value;
2260 for (cpl_size row = 0; row < nrow; row ++){
2261 value = cpl_array_get (column_array[row], index, NULL);
2262 cpl_vector_set (data_value, row, value);
2263 }
2264 } else if (cpl_table_get_column_type (spectrum_data, regname)
2265 == CPL_TYPE_DOUBLE) {
2266
2267 double * data = cpl_table_get_data_double (spectrum_data, regname);
2268 for (cpl_size row = 0; row < nrow; row++) {
2269 cpl_vector_set (data_value, row, data[row]);
2270 }
2271
2272 } else if (cpl_table_get_column_type (spectrum_data, regname)
2273 == CPL_TYPE_INT) {
2274
2275 int * data = cpl_table_get_data_int (spectrum_data, regname);
2276 for (cpl_size row = 0; row < nrow; row++) {
2277 cpl_vector_set (data_value, row, data[row]);
2278 }
2279
2280 } else {
2281 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2282 "This type is not supported"
2283 "(report to DRS team).");
2284 FREE (cpl_vector_delete, data_value);
2285 return NULL;
2286 }
2287
2288 return (data_value);
2289}
2290
2291cpl_vector * gravi_table_get_vector_scalar (cpl_table * table,
2292 const char * name,
2293 cpl_size base,
2294 cpl_size nbase)
2295{
2296 /* Check the inputs */
2297 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
2298 cpl_ensure (name, CPL_ERROR_NULL_INPUT, NULL);
2299 cpl_ensure (base>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2300 cpl_ensure (nbase>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2301
2302 /* Ensure it is scalar */
2303 cpl_size size = cpl_table_get_column_depth (table, name);
2304 cpl_ensure (size==0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2305
2306 /* Allocate the vector */
2307 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
2308 cpl_vector * vector = cpl_vector_new (nrow);
2309
2310 /* Get the type */
2311 cpl_type type = cpl_table_get_column_type (table, name);
2312
2313 if (type == CPL_TYPE_DOUBLE) {
2314 double * data = cpl_table_get_data_double (table, name);
2315 for (cpl_size row = 0; row < nrow; row++)
2316 cpl_vector_set (vector, row, data[row*nbase+base]);
2317 }
2318 else if (type == CPL_TYPE_FLOAT) {
2319 float * data = cpl_table_get_data_float (table, name);
2320 for (cpl_size row = 0; row < nrow; row++)
2321 cpl_vector_set (vector, row, data[row*nbase+base]);
2322 }
2323 else if (type == CPL_TYPE_INT) {
2324 int * data = cpl_table_get_data_int (table, name);
2325 for (cpl_size row = 0; row < nrow; row++)
2326 cpl_vector_set (vector, row, data[row*nbase+base]);
2327 }
2328 else {
2329 cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
2330 "This type is not supported"
2331 "(report to DRS team).");
2332 FREE (cpl_vector_delete, vector);
2333 return NULL;
2334 }
2335
2336 return vector;
2337}
2338
2339/*---------------------------------------------------------------------------*/
2354/*---------------------------------------------------------------------------*/
2355
2356cpl_vector * gravi_table_get_vector_diff (cpl_table * spectrum_data, int index,
2357 const char * regname1,
2358 const char * regname2)
2359{
2360 /* Check the inputs */
2361 cpl_ensure (spectrum_data, CPL_ERROR_NULL_INPUT, NULL);
2362 cpl_ensure (regname1, CPL_ERROR_NULL_INPUT, NULL);
2363 cpl_ensure (regname2, CPL_ERROR_NULL_INPUT, NULL);
2364 cpl_ensure (index>=0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2365
2366 /* Get the array size */
2367 cpl_size size1 = cpl_table_get_column_depth (spectrum_data, regname1);
2368 cpl_size size2 = cpl_table_get_column_depth (spectrum_data, regname2);
2369 cpl_ensure (index<size1, CPL_ERROR_ILLEGAL_INPUT, NULL);
2370 cpl_ensure (index<size2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2371
2372 /* Extract the data from the column region */
2373 cpl_array ** column_array1 = cpl_table_get_data_array (spectrum_data, regname1);
2374 cpl_array ** column_array2 = cpl_table_get_data_array (spectrum_data, regname2);
2375 cpl_ensure (column_array1, CPL_ERROR_ILLEGAL_INPUT, NULL);
2376 cpl_ensure (column_array2, CPL_ERROR_ILLEGAL_INPUT, NULL);
2377
2378 /* allocate the vector */
2379 cpl_size nrow = cpl_table_get_nrow (spectrum_data);
2380 cpl_vector * data_value = cpl_vector_new (nrow);
2381
2382 /* Loop on row */
2383 double value;
2384 for (cpl_size row = 0; row < nrow; row++){
2385 value = cpl_array_get (column_array1[row], index, NULL) - cpl_array_get (column_array2[row], index, NULL);
2386 cpl_vector_set (data_value, row, value);
2387 }
2388
2389 return (data_value);
2390}
2391
2392/*---------------------------------------------------------------------------*/
2396/*---------------------------------------------------------------------------*/
2397
2398cpl_error_code gravi_image_fill (cpl_image * img, double value)
2399{
2400 cpl_ensure_code (img, CPL_ERROR_NULL_INPUT);
2401
2402 cpl_size nx = cpl_image_get_size_x (img);
2403 cpl_size ny = cpl_image_get_size_y (img);
2404 cpl_image_fill_window (img, 1,1,nx,ny, value);
2405
2406 return CPL_ERROR_NONE;
2407}
2408
2409/*---------------------------------------------------------------------------*/
2413/*---------------------------------------------------------------------------*/
2414
2415cpl_image * gravi_image_wrap_matrix (cpl_matrix * matrix)
2416{
2417 cpl_ensure (matrix, CPL_ERROR_NULL_INPUT, NULL);
2418 cpl_size nx = cpl_matrix_get_ncol (matrix);
2419 cpl_size ny = cpl_matrix_get_nrow (matrix);
2420 return cpl_image_wrap_double (nx, ny, cpl_matrix_get_data (matrix));
2421}
2422
2423cpl_image * gravi_image_from_matrix (cpl_matrix * matrix)
2424{
2425 cpl_ensure (matrix, CPL_ERROR_NULL_INPUT, NULL);
2426 cpl_size nx = cpl_matrix_get_ncol (matrix);
2427 cpl_size ny = cpl_matrix_get_nrow (matrix);
2428
2429 cpl_image * image = cpl_image_new (nx,ny,CPL_TYPE_DOUBLE);
2430 for (cpl_size i = 0; i < nx; i++)
2431 for (cpl_size j = 0; j < ny; j++)
2432 cpl_image_set (image, i+1, j+1, cpl_matrix_get (matrix,j,i));
2433
2434 return image;
2435}
2436
2437/*---------------------------------------------------------------------------*/
2441/*---------------------------------------------------------------------------*/
2442
2443cpl_image * gravi_image_wrap_vector (cpl_vector * vector)
2444{
2445 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, NULL);
2446 cpl_size nx = cpl_vector_get_size (vector);
2447 cpl_size ny = 1;
2448 return cpl_image_wrap_double (nx, ny, cpl_vector_get_data (vector));
2449}
2450
2451cpl_image * gravi_image_from_vector (cpl_vector * vector)
2452{
2453 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, NULL);
2454 cpl_size nx = cpl_vector_get_size (vector);
2455 cpl_size ny = 1;
2456
2457 cpl_image * image = cpl_image_new (nx,ny,CPL_TYPE_DOUBLE);
2458 for (cpl_size i = 0; i < nx; i++)
2459 cpl_image_set (image, i+1, 1, cpl_vector_get (vector,i));
2460
2461 return image;
2462}
2463
2464/*---------------------------------------------------------------------------*/
2475/*---------------------------------------------------------------------------*/
2476
2477double gravi_image_get_quantile (const cpl_image * img, double thr)
2478{
2479 cpl_ensure (img, CPL_ERROR_NULL_INPUT, -1);
2480 cpl_ensure (thr>0 && thr<1, CPL_ERROR_ILLEGAL_INPUT, -1);
2481
2482 cpl_size nx = cpl_image_get_size_x (img);
2483 cpl_size ny = cpl_image_get_size_y (img);
2484 cpl_size nq = (cpl_size)(thr * nx * ny);
2485
2486 cpl_ensure (nq>=0 && nq<=nx*ny, CPL_ERROR_ILLEGAL_INPUT, -1);
2487
2488 /* Create vector and fill */
2489 int nv;
2490 cpl_vector * vect = cpl_vector_new (nx*ny);
2491 for (cpl_size ix = 0; ix < nx ; ix++)
2492 for (cpl_size iy = 0; iy < ny ; iy++)
2493 cpl_vector_set (vect, ix * ny + iy, cpl_image_get (img, ix+1, iy+1, &nv));
2494
2495 /* Sort and get quartil */
2496 cpl_vector_sort (vect, CPL_SORT_ASCENDING);
2497 double value = cpl_vector_get (vect, nq);
2498 cpl_vector_delete (vect);
2499
2500 return value;
2501}
2502
2503/*---------------------------------------------------------------------------*/
2509/*---------------------------------------------------------------------------*/
2510
2511double gravi_array_get_quantile (cpl_array * arr, double thr)
2512{
2513 cpl_ensure (arr, CPL_ERROR_NULL_INPUT, -1);
2514 cpl_ensure (thr>0 && thr<1, CPL_ERROR_ILLEGAL_INPUT, -1);
2515
2516 cpl_size nx = cpl_array_get_size (arr);
2517 cpl_size nq = (cpl_size)(thr * nx);
2518
2519 cpl_ensure (nq>=0 && nq<=nx, CPL_ERROR_ILLEGAL_INPUT, -1);
2520
2521 /* Create vector and fill */
2522 int nv;
2523 cpl_vector * vect = cpl_vector_new (nx);
2524 for (cpl_size ix = 0; ix < nx ; ix++)
2525 cpl_vector_set (vect, ix, cpl_array_get (arr, ix, &nv));
2526
2527 /* Sort and get quartil */
2528 cpl_vector_sort (vect, CPL_SORT_ASCENDING);
2529 double value = cpl_vector_get (vect, nq);
2530 cpl_vector_delete (vect);
2531
2532 return value;
2533}
2534
2535/*---------------------------------------------------------------------------*/
2545/*---------------------------------------------------------------------------*/
2546
2547cpl_vector * gravi_vector_median (const cpl_vector * vector, cpl_size hw)
2548{
2549 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, NULL);
2550 cpl_ensure (hw>0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2551
2552 cpl_size size = cpl_vector_get_size (vector);
2553 cpl_vector * median = NULL;
2554
2555 /* Case the vector is shorter than the the box */
2556 if (size < hw*2+3)
2557 {
2558 median = cpl_vector_new (size);
2559 cpl_vector_fill (median, cpl_vector_get_median_const (vector));
2560 }
2561 /* case longer than the box */
2562 else
2563 {
2564 median = cpl_vector_filter_median_create (vector, hw);
2565 cpl_ensure (median, CPL_ERROR_DATA_NOT_FOUND, NULL);
2566
2567 double * data = cpl_vector_get_data (median);
2568 cpl_ensure (data, CPL_ERROR_DATA_NOT_FOUND, NULL);
2569
2570 for (int i = 0; i < hw; i++) data[i] = data[hw];
2571 for (int i = size-hw; i < size; i++) data[i] = data[size-hw-1];
2572 }
2573
2574 return median;
2575}
2576/*---------------------------------------------------------------------------*/
2586/*---------------------------------------------------------------------------*/
2587
2588cpl_error_code gravi_vector_abs (cpl_vector * vector)
2589{
2590 cpl_ensure_code (vector, CPL_ERROR_NULL_INPUT);
2591
2592 /* Get data */
2593 cpl_size size = cpl_vector_get_size (vector);
2594 cpl_ensure_code (size > 0, CPL_ERROR_ILLEGAL_INPUT);
2595
2596 double * data = cpl_vector_get_data (vector);
2597 cpl_ensure_code (data, CPL_ERROR_ILLEGAL_INPUT);
2598
2599 /* Take abs */
2600 for (int i = 0; i < size; i++) data[i] = fabs (data[i]);
2601
2602 return CPL_ERROR_NONE;
2603}
2604
2605/*---------------------------------------------------------------------------*/
2612/*---------------------------------------------------------------------------*/
2613
2614cpl_size gravi_vector_get_maxpos (cpl_vector * vector)
2615{
2616 cpl_ensure (vector, CPL_ERROR_NULL_INPUT, -1);
2617 cpl_size size = cpl_vector_get_size (vector);
2618
2619 cpl_size pos = 0;
2620 double value = cpl_vector_get (vector, 0);
2621 for (int s = 1; s < size; s++) {
2622 if (cpl_vector_get (vector, s) > value) {
2623 pos = s;
2624 value = cpl_vector_get (vector, s);
2625 }
2626 }
2627
2628 return pos;
2629}
2630
2631/*---------------------------------------------------------------------------*/
2641/*---------------------------------------------------------------------------*/
2642double gravi_vector_get_mean_clip (cpl_vector * vector_in,
2643 double percent,
2644 double nsigma)
2645{
2646 cpl_ensure (vector_in, CPL_ERROR_NULL_INPUT, 0.0);
2647 cpl_ensure (percent > 0, CPL_ERROR_ILLEGAL_INPUT, 0.0);
2648 cpl_ensure (percent < 0.5, CPL_ERROR_ILLEGAL_INPUT, 0.0);
2649 cpl_ensure (nsigma > 0, CPL_ERROR_ILLEGAL_INPUT, 0.0);
2650
2651 /* Sort */
2652 cpl_vector * sort_vector = cpl_vector_duplicate (vector_in);
2653 cpl_vector_sort (sort_vector, CPL_SORT_ASCENDING);
2654
2655 /* Clip extrems values */
2656 cpl_size size = cpl_vector_get_size (vector_in);
2657 cpl_size sizeout = size*(1-percent*2);
2658 cpl_size start = (size-sizeout)/2;
2659
2660 cpl_vector * vector = cpl_vector_new (sizeout);
2661 for (cpl_size i = 0 ; i < sizeout ; i++)
2662 cpl_vector_set (vector, i, cpl_vector_get (sort_vector, i+start));
2663
2664 /* Clip above several sigmas */
2665 cpl_vector * vector_med = cpl_vector_new (sizeout);
2666 double med = cpl_vector_get_median (vector);
2667 double rms = nsigma * cpl_vector_get_stdev (vector);
2668
2669 cpl_size size_med = 0;
2670 for (cpl_size i = 0 ; i < cpl_vector_get_size (vector) ; i++)
2671 if ( (cpl_vector_get (vector, i) > med-rms) &&
2672 (cpl_vector_get (vector, i) < med+rms) ) {
2673 cpl_vector_set (vector_med, size_med, cpl_vector_get (vector, i));
2674 size_med++;
2675 }
2676 cpl_vector_set_size (vector_med, size_med);
2677
2678 /* Compute mean of accepted values */
2679 double output = cpl_vector_get_mean (vector_med);
2680
2681 FREE (cpl_vector_delete, vector_med);
2682 FREE (cpl_vector_delete, sort_vector);
2683 return output;
2684}
2685
2686/*---------------------------------------------------------------------------*/
2694/*---------------------------------------------------------------------------*/
2695
2696cpl_vector * gravi_vector_extract (const cpl_vector * vector, int start, int step)
2697{
2698 cpl_size size = cpl_vector_get_size (vector);
2699 cpl_size newsize = size / step;
2700 cpl_vector * out = cpl_vector_new (newsize);
2701
2702 for (int s = 0; s < newsize; s++)
2703 cpl_vector_set (out, s, cpl_vector_get (vector, s*step+start));
2704
2705 return out;
2706}
2707
2708/*---------------------------------------------------------------------------*/
2717/*---------------------------------------------------------------------------*/
2718
2719cpl_error_code gravi_vector_unwrap_with_guess (cpl_vector * vector, cpl_vector * ref, double ref_to_phase)
2720{
2721 cpl_ensure_code (vector, CPL_ERROR_NULL_INPUT);
2722 cpl_ensure_code (ref, CPL_ERROR_NULL_INPUT);
2723
2724 cpl_size nrow = cpl_vector_get_size (vector);
2725
2726 double referenced, referenced_prev = 0.0;
2727 cpl_size wrap = 0;
2728
2729 for (cpl_size row = 0 ; row < nrow; row ++) {
2730 double phase_ref = ref_to_phase * cpl_vector_get (ref, row);
2731
2732 /* Referenced phase in radian in [0,2pi] */
2733 referenced = (cpl_vector_get (vector, row) - phase_ref);
2734 referenced = fmod (referenced, CPL_MATH_2PI);
2735 if (referenced < 0) referenced += CPL_MATH_2PI;
2736
2737 /* Check if referenced_phase is wrapp */
2738 if ( referenced - referenced_prev > CPL_MATH_PI ) wrap --;
2739 if ( referenced - referenced_prev < -CPL_MATH_PI ) wrap ++;
2740 referenced_prev = referenced;
2741
2742 /* Set back in-place */
2743 cpl_vector_set (vector, row, phase_ref + referenced + wrap * CPL_MATH_2PI);
2744 }
2745
2746 CPLCHECK_MSG ("Cannot unwrap with guess");
2747
2748 return CPL_ERROR_NONE;
2749}
2750
2751/*---------------------------------------------------------------------------*/
2764/*---------------------------------------------------------------------------*/
2765
2766cpl_error_code gravi_table_multiply_scalar (cpl_table * table, const char * name,
2767 int base, int nbase, double value)
2768{
2769 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
2770 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
2771 cpl_ensure_code (nbase==1 || nbase==4 || nbase==6, CPL_ERROR_ILLEGAL_INPUT);
2772 cpl_ensure_code (base>=0 && base <nbase, CPL_ERROR_ILLEGAL_INPUT);
2773
2774 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
2775
2776 if (cpl_table_get_column_depth (table, name) > 0) {
2777 cpl_array ** array = cpl_table_get_data_array (table, name);
2778 for (cpl_size row = 0 ; row < nrow ; row ++) {
2779 cpl_array_multiply_scalar (array[row*nbase+base], value);
2780 CPLCHECK_MSG ("Cannot multiply (array may not be numerical)");
2781 }
2782 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_DOUBLE) {
2783 double * array = cpl_table_get_data_double (table, name);
2784 for (cpl_size row = 0 ; row < nrow ; row ++) {
2785 array[row*nbase+base] *= value;
2786 }
2787 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_INT) {
2788 int * array = cpl_table_get_data_int (table, name);
2789 for (cpl_size row = 0 ; row < nrow ; row ++) {
2790 array[row*nbase+base] *= value;
2791 }
2792 } else {
2793 return cpl_error_set_message (cpl_func, CPL_ERROR_INVALID_TYPE,
2794 "Column type is not supported");
2795 }
2796
2797 CPLCHECK_MSG ("Cannot multiply");
2798 return CPL_ERROR_NONE;
2799}
2800
2801/*---------------------------------------------------------------------------*/
2814/*---------------------------------------------------------------------------*/
2815
2816cpl_error_code gravi_table_add_scalar (cpl_table * table, const char * name,
2817 int base, int nbase, double value)
2818{
2819 cpl_ensure_code (table, CPL_ERROR_NULL_INPUT);
2820 cpl_ensure_code (name, CPL_ERROR_NULL_INPUT);
2821 cpl_ensure_code (nbase==1 || nbase==4 || nbase==6, CPL_ERROR_ILLEGAL_INPUT);
2822 cpl_ensure_code (base>=0 && base <nbase, CPL_ERROR_ILLEGAL_INPUT);
2823
2824 cpl_size nrow = cpl_table_get_nrow (table) / nbase;
2825
2826 if (cpl_table_get_column_depth (table, name) > 0) {
2827 cpl_array ** array = cpl_table_get_data_array (table, name);
2828 for (cpl_size row = 0 ; row < nrow ; row ++) {
2829 cpl_array_add_scalar (array[row*nbase+base], value);
2830 CPLCHECK_MSG ("Cannot multiply (array may not be numerical)");
2831 }
2832 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_DOUBLE) {
2833 double * array = cpl_table_get_data_double (table, name);
2834 for (cpl_size row = 0 ; row < nrow ; row ++) {
2835 array[row*nbase+base] += value;
2836 }
2837 } else if(cpl_table_get_column_type (table, name) == CPL_TYPE_INT) {
2838 int * array = cpl_table_get_data_int (table, name);
2839 for (cpl_size row = 0 ; row < nrow ; row ++) {
2840 array[row*nbase+base] += value;
2841 }
2842 } else {
2843 return cpl_error_set_message (cpl_func, CPL_ERROR_INVALID_TYPE,
2844 "Column type is not supported");
2845 }
2846
2847 CPLCHECK_MSG ("Cannot multiply");
2848 return CPL_ERROR_NONE;
2849}
2850
2851
2852/*---------------------------------------------------------------------------*/
2865/*---------------------------------------------------------------------------*/
2866
2867cpl_matrix * gravi_matrix_interpolate_col (cpl_matrix * matrix,
2868 cpl_vector * xref,
2869 cpl_vector * xout)
2870{
2872
2873 cpl_ensure (matrix, CPL_ERROR_NULL_INPUT, NULL);
2874 cpl_ensure (xref, CPL_ERROR_NULL_INPUT, NULL);
2875 cpl_ensure (xout, CPL_ERROR_NULL_INPUT, NULL);
2876
2877 cpl_size nrow = cpl_matrix_get_nrow (matrix);
2878 cpl_size ncol = cpl_matrix_get_ncol (matrix);
2879 cpl_size nxref = cpl_vector_get_size (xref);
2880 cpl_size nxout = cpl_vector_get_size (xout);
2881
2882 cpl_ensure (ncol == nxref, CPL_ERROR_ILLEGAL_INPUT, NULL);
2883 cpl_ensure (nxout > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
2884
2885 /* Allocate memory */
2886 cpl_matrix * outmatrix = cpl_matrix_new (nrow, nxout);
2887 cpl_vector * yref = cpl_vector_new (nxref);
2888 cpl_vector * yout = cpl_vector_new (nxout);
2889 cpl_bivector * fref = cpl_bivector_wrap_vectors (xref, yref);
2890 cpl_bivector * fout = cpl_bivector_wrap_vectors (xout, yout);
2891
2892 /* Loop on rows */
2893 for (cpl_size row = 0; row < nrow; row++) {
2894 for (cpl_size x = 0; x < nxref; x++)
2895 cpl_vector_set (yref, x, cpl_matrix_get (matrix, row, x));
2896 cpl_bivector_interpolate_linear (fout, fref);
2897 for (cpl_size x = 0; x < nxout; x++)
2898 cpl_matrix_set (outmatrix, row, x, cpl_vector_get (yout, x));
2899 CPLCHECK_NUL ("Cannot interpolate matrix");
2900 }
2901
2902 FREE (cpl_bivector_unwrap_vectors, fref);
2903 FREE (cpl_bivector_unwrap_vectors, fout);
2904 FREE (cpl_vector_delete, yref);
2905 FREE (cpl_vector_delete, yout);
2906
2908 return outmatrix;
2909}
2910
2911/*---------------------------------------------------------------------------*/
2919/*---------------------------------------------------------------------------*/
2920
2921cpl_matrix * gravi_matrix_invertSV_create (cpl_matrix *a_in)
2922{
2924
2925 cpl_ensure (a_in, CPL_ERROR_NULL_INPUT, NULL);
2926
2927 cpl_size m = cpl_matrix_get_nrow (a_in);
2928 cpl_size n = cpl_matrix_get_ncol (a_in);
2929
2930 cpl_vector * w = cpl_vector_new (n);
2931 cpl_matrix * v = cpl_matrix_new (n, n);
2932
2933 /*
2934 * fill nr matrix with data
2935 * w are the singular values of the matrix
2936 */
2937 cpl_matrix * a_out = svdcmp (a_in, w, v);
2938 CPLCHECK_NUL ("Error in inverse SV");
2939
2940 /* Check the singular values */
2941 for (cpl_size ii = 0; ii < n; ii++) {
2942 if (cpl_vector_get (w, ii) < 0.1)
2943 cpl_msg_warning (cpl_func, "Singular Value %lld = %e",
2944 ii, cpl_vector_get (w, ii));
2945 }
2946
2947 /*
2948 * Compute inverse (vt*1/w*at)
2949 */
2950 cpl_matrix * a_inv = cpl_matrix_new (n,m);
2951 double * a_inv_data = cpl_matrix_get_data (a_inv);
2952
2953 for (cpl_size j = 0; j < m; j++) {
2954 for (cpl_size i = 0; i < n; i++){
2955 double wv_at = 0;
2956
2957 for (cpl_size ii = 0; ii < n; ii++)
2958 if (cpl_vector_get (w, ii) > 1e-15)
2959 wv_at += cpl_matrix_get (v, i, ii) /
2960 cpl_vector_get (w, ii) *
2961 cpl_matrix_get (a_out, j, ii);
2962
2963 a_inv_data[j + i * m] = wv_at;
2964 }
2965 }
2966
2967 /* Delete intermediate matrix */
2968 cpl_vector_delete (w);
2969 cpl_matrix_delete (v);
2970 cpl_matrix_delete (a_out);
2971
2973 return a_inv;
2974}
2975
2976/*
2977 * pythag fonction from numerical recipe in C,
2978 * necessary for gravi_matrix_invertSV_create
2979 */
2980double pythag(double a, double b)
2981{
2982 double absa=fabs(a);
2983 double absb=fabs(b);
2984 if (absa > absb)
2985 return absa*sqrt(1.0+pow(absb/absa, 2));
2986 else
2987 return (absb == 0.0 ? 0.0 : absb*sqrt(1.0+pow(absa/absb, 2)));
2988}
2989
2990/*
2991 * svdcmp fonction from numerical recipe in C
2992 * w and v are pre-allocated results,
2993 * necessary for gravi_matrix_invertSV_create
2994 */
2995cpl_matrix * svdcmp (cpl_matrix * a_in, cpl_vector * w, cpl_matrix * v)
2996{
2998 cpl_ensure (a_in, CPL_ERROR_NULL_INPUT, NULL);
2999
3000 int flag, i, its, j, jj, k, l, nm, n, m;
3001 double anorm, c, f, g, h, s, scale, x, y, z;
3002 cpl_vector * rv1;
3003 cpl_matrix * a;
3004
3005 a = cpl_matrix_duplicate(a_in);
3006 m = cpl_matrix_get_nrow (a_in);
3007 n = cpl_matrix_get_ncol (a_in);
3008 rv1 = cpl_vector_new(n);
3009
3010 g = scale = anorm = 0.0;
3011 for (i = 0; i < n; i++) {
3012 l = i + 1;
3013 cpl_vector_set(rv1, i, scale*g);
3014 g = s = scale = 0.0;
3015 if (i < m) {
3016 for (k = i; k < m; k++)
3017 scale += fabs(cpl_matrix_get(a, k, i));
3018 if (scale) {
3019
3020 for (k = i; k < m; k++) {
3021
3022 cpl_matrix_set (a, k, i, cpl_matrix_get(a, k, i)/scale);
3023 s += cpl_matrix_get(a, k, i) * cpl_matrix_get(a, k, i);
3024 }
3025 f = cpl_matrix_get(a, i, i);
3026 g = -SIGN(sqrt(s),f);
3027 h = f * g - s;
3028 cpl_matrix_set (a, i, i, f - g);
3029 for (j = l; j < n; j++) {
3030 for (s = 0.0, k = i; k < m; k++)
3031 s += cpl_matrix_get(a, k, i) * cpl_matrix_get(a, k, j);
3032
3033 f = s / h;
3034 for (k = i; k < m; k++)
3035 cpl_matrix_set (a, k, j, cpl_matrix_get(a, k, j) +
3036 f * cpl_matrix_get(a, k, i));
3037
3038 }
3039 for (k = i; k < m; k++)
3040 cpl_matrix_set (a, k, i, cpl_matrix_get(a, k, i) * scale);
3041
3042 }
3043 }
3044
3045 cpl_vector_set(w, i, scale *g);
3046
3047 g = s = scale = 0.0;
3048 if (i < m && i != (n - 1)) {
3049 for (k = l; k < n; k++)
3050 scale += fabs(cpl_matrix_get(a, i, k));;
3051 if (scale) {
3052 for (k = l; k < n; k++) {
3053 cpl_matrix_set (a, i, k, cpl_matrix_get(a, i, k) / scale);
3054 s += cpl_matrix_get(a, i, k) * cpl_matrix_get(a, i, k);
3055 }
3056 f = cpl_matrix_get(a, i, l);
3057 g = -SIGN(sqrt(s),f);
3058 h = f * g - s;
3059 cpl_matrix_set (a, i, l, f - g);
3060 for (k = l; k < n; k++)
3061 cpl_vector_set(rv1, k, cpl_matrix_get(a, i, k)/h);
3062 for (j = l; j < m; j++) {
3063 for (s = 0.0, k = l; k < n; k++)
3064 s += cpl_matrix_get(a, j, k) * cpl_matrix_get(a, i, k);
3065 for (k = l; k < n; k++)
3066 cpl_matrix_set (a, j, k, cpl_matrix_get(a, j, k) + s * cpl_vector_get(rv1, k));
3067 }
3068 for (k = l; k < n; k++)
3069 cpl_matrix_set (a, i, k, cpl_matrix_get(a, i, k) * scale);
3070 }
3071 }
3072
3073 anorm = fmax(anorm,(fabs(cpl_vector_get(w, i)) +
3074 fabs(cpl_vector_get(rv1, i))));
3075
3076 }
3077
3078 for (i = (n - 1); i >= 0; i--) {
3079 if (i < n) {
3080 if (g) {
3081 for (j = l; j < n; j++)
3082 cpl_matrix_set(v, j, i, (cpl_matrix_get(a, i, j) /
3083 cpl_matrix_get(a, i, l)) / g);
3084
3085 for (j = l;j < n; j++) {
3086 for (s = 0.0, k = l; k < n; k++)
3087 s += cpl_matrix_get(a, i, k) * cpl_matrix_get(v, k, j);
3088
3089 for (k = l; k < n; k++)
3090 cpl_matrix_set(v, k, j, cpl_matrix_get(v, k, j) + s *
3091 cpl_matrix_get(v, k, i));
3092
3093 }
3094 }
3095 for (j = l; j < n; j++) {
3096 cpl_matrix_set(v, i, j, 0.0);
3097 cpl_matrix_set(v, j, i, 0.0);
3098 }
3099 }
3100 cpl_matrix_set(v, i, i, 1.0);
3101
3102 g = cpl_vector_get(rv1, i);
3103 l = i;
3104 }
3105
3106 for (i = (IMIN(m,n) - 1); i >= 0; i--) {
3107 l = i + 1;
3108 g = cpl_vector_get(w, i);
3109 for (j = l; j < n; j++)
3110 cpl_matrix_set(a, i, j, 0.0);
3111
3112 if (g) {
3113 g = 1.0/g;
3114 for (j = l; j < n; j++) {
3115 for (s = 0.0, k = l; k < m; k++)
3116 s += cpl_matrix_get(a, k, i) * cpl_matrix_get(a, k, j);
3117
3118 f = (s / cpl_matrix_get(a, i, i)) * g;
3119
3120 for (k = i; k < m; k++)
3121 cpl_matrix_set(a, k, j, cpl_matrix_get(a, k, j) + f *
3122 cpl_matrix_get(a, k, i));
3123
3124 }
3125 for (j = i; j < m; j++)
3126 cpl_matrix_set(a, j, i, cpl_matrix_get(a, j, i) * g);
3127
3128 }
3129 else
3130 for (j = i; j < m; j++)
3131 cpl_matrix_set(a, j, i, 0.0);
3132
3133 cpl_matrix_set(a, i, i, cpl_matrix_get(a, i, i) + 1);
3134
3135 }
3136
3137 for (k = (n - 1); k >= 0; k--) {
3138 for (its = 1; its <= 60; its ++) {
3139 flag = 1;
3140
3141 for (l = k; l >= 0; l--) {
3142 nm = l;
3143 if ((fabs(cpl_vector_get(rv1, l)) + anorm) == anorm) {
3144 flag = 0;
3145 break;
3146 }
3147 if ((fabs(cpl_vector_get(w, nm)) + anorm) == anorm)
3148 break;
3149 }
3150
3151 if (flag) {
3152 c = 0.0;
3153 s = 1.0;
3154 for (i = l; i <= k; i++) {
3155 f = s * cpl_vector_get(rv1, i);
3156 cpl_vector_set(rv1, i, c * cpl_vector_get(rv1, i));
3157 if ((fabs(f) + anorm) == anorm)
3158 break;
3159 g = cpl_vector_get(w, i);
3160 h = pythag(f,g);
3161 cpl_vector_set(w, i, h);
3162 h = 1.0 / h;
3163 c = g * h;
3164 s = -f * h;
3165 for (j = 0; j < m; j++) {
3166 y = cpl_matrix_get(a, j, nm);
3167 z = cpl_matrix_get(a, j, i);
3168 cpl_matrix_set(a, j, nm, y*c+z*s);
3169 cpl_matrix_set(a, j, i, z*c-y*s);
3170 }
3171 }
3172 }
3173 z = cpl_vector_get(w, k);
3174 if (l == k) {
3175 if (z < 0.0) {
3176 cpl_vector_set(w, k, -z);
3177 for (j = 0; j < n; j++)
3178 cpl_matrix_set(v, j, k, -cpl_matrix_get(v, j, k));
3179
3180 }
3181 break;
3182 }
3183
3184 if (its == 120) {
3185 cpl_error_set_message(cpl_func,
3186 CPL_ERROR_ILLEGAL_INPUT,
3187 "no convergence in 120 svdcmp iterations");
3188 cpl_vector_delete(rv1);
3189 cpl_matrix_delete(a);
3190 return NULL;
3191 }
3192 x = cpl_vector_get(w, l);
3193 nm = k ;//- 1;
3194 y = cpl_vector_get(w, nm); ;
3195 g = cpl_vector_get(rv1, nm);
3196 h = cpl_vector_get(rv1, k);
3197 f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y);
3198 g = pythag(f,1.0);
3199 f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
3200 c = s = 1.0;
3201 for (j = l; j < nm; j++) {
3202 i = j+1;
3203 g = cpl_vector_get(rv1, i);
3204 y = cpl_vector_get(w, i);
3205 h = s * g;
3206 g = c * g;
3207 z = pythag(f, h);
3208 cpl_vector_set(rv1, j, z);
3209 c = f / z;
3210 s = h / z;
3211 f = x * c + g * s;
3212 g = g * c - x * s;
3213 h = y * s;
3214 y *= c;
3215 for (jj = 0; jj < n; jj++) {
3216 x = cpl_matrix_get(v, jj, j);
3217 z=cpl_matrix_get(v, jj, i);
3218 cpl_matrix_set(v, jj, j, x*c+z*s);
3219 cpl_matrix_set(v, jj, i, z*c-x*s);
3220 }
3221 z = pythag(f, h);
3222 cpl_vector_set(w, j, z);
3223
3224 if (z) {
3225 z = 1.0 / z;
3226 c = f * z;
3227 s = h * z;
3228 }
3229 f = c * g + s * y;
3230 x = c * y - s * g;
3231 for (jj = 0; jj < m; jj++) {
3232 y = cpl_matrix_get(a, jj, j);
3233 z = cpl_matrix_get(a, jj, i);
3234 cpl_matrix_set(a, jj, j, y*c+z*s);
3235 cpl_matrix_set(a, jj, i, z*c-y*s);
3236 }
3237 }
3238 cpl_vector_set(rv1, l, 0.0);
3239 cpl_vector_set(rv1, k, f);
3240 cpl_vector_set(w, k, x);
3241 }
3242
3243 }
3244 cpl_vector_delete(rv1);
3245
3247 return a;
3248}
3249
3250
3251/*----------------------------------------------------------------------------*/
3260/*----------------------------------------------------------------------------*/
3261cpl_table * gravi_table_extract_time_interval (cpl_table *table, double start, double end)
3262{
3264 cpl_ensure (table, CPL_ERROR_NULL_INPUT, NULL);
3265
3266 /* Select only interested */
3267 cpl_table_select_all (table);
3268 cpl_table_and_selected_double (table, "TIME", CPL_NOT_LESS_THAN, start);
3269 cpl_table_and_selected_double (table, "TIME", CPL_LESS_THAN, end);
3270 cpl_table * out = cpl_table_extract_selected (table);
3271
3273 return out;
3274}
3275
#define gravi_table_set_value(table, name, row, value, val)
Definition: gravi_cpl.h:50
#define gravi_table_get_value(table, name, row, value)
Definition: gravi_cpl.h:49
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:155
#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:154
cpl_array * gravi_array_init_int(long n, int value)
Definition: gravi_cpl.c:608
double pythag(double, double)
Definition: gravi_cpl.c:2980
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:714
cpl_array * gravi_array_smooth(cpl_array *input_array, int DIT_smooth)
Definition: gravi_cpl.c:1285
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:3261
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:1004
cpl_error_code gravi_table_add_columns(cpl_table *oi_vis1, const char *name1, cpl_table *oi_vis2, const char *name2)
Definition: gravi_cpl.c:840
float complex ** gravi_table_get_data_array_float_complex(cpl_table *table, const char *name)
Definition: gravi_cpl.c:521
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:911
cpl_vector * gravi_vector_extract(const cpl_vector *vector, int start, int step)
Extract part of a vector.
Definition: gravi_cpl.c:2696
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:1839
cpl_array * gravi_array_create_inverse(cpl_array *input)
Definition: gravi_cpl.c:1071
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:2114
double gravi_table_get_column_mean(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:343
cpl_image * gravi_image_wrap_matrix(cpl_matrix *matrix)
Wrap matrix into an image (data not duplicated)
Definition: gravi_cpl.c:2415
cpl_error_code gravi_table_new_column(cpl_table *table, const char *name, const char *unit, cpl_type type)
Definition: gravi_cpl.c:1656
double complex ** gravi_table_get_data_array_double_complex(cpl_table *table, const char *name)
Definition: gravi_cpl.c:546
cpl_image * gravi_image_from_vector(cpl_vector *vector)
Definition: gravi_cpl.c:2451
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:1137
cpl_vector * gravi_table_get_vector_scalar(cpl_table *table, const char *name, cpl_size base, cpl_size nbase)
Definition: gravi_cpl.c:2291
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:2356
cpl_error_code gravi_table_compute_group_delay(cpl_table *table, const char *input, const char *flag, const char *output, cpl_table *oi_wave)
Definition: gravi_cpl.c:1535
cpl_array * gravi_array_init_float_complex(long n, float complex value)
Definition: gravi_cpl.c:630
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:2052
cpl_error_code gravi_image_fill(cpl_image *img, double value)
Fill entire image with value.
Definition: gravi_cpl.c:2398
cpl_matrix * gravi_matrix_invertSV_create(cpl_matrix *a_in)
Invers a matrix with singular value decomposition.
Definition: gravi_cpl.c:2921
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:2084
cpl_error_code gravi_array_phase_unwrap(cpl_array *input)
Definition: gravi_cpl.c:1088
cpl_error_code gravi_table_init_column_array(cpl_table *table, const char *name, const char *unit, cpl_type type, cpl_size size)
Definition: gravi_cpl.c:1692
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:1241
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:2588
double gravi_image_get_quantile(const cpl_image *img, double thr)
Compute the quantile of an image.
Definition: gravi_cpl.c:2477
double gravi_table_get_column_flagged_max(cpl_table *table, const char *name)
Function to compute the maximum of a column table with arrays.
Definition: gravi_cpl.c:290
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:2719
cpl_array * gravi_table_create_wave_array(cpl_table *oi_wave)
Definition: gravi_cpl.c:1037
cpl_array * gravi_array_wrap_image(cpl_image *img)
Wrap the data of na image into an array.
Definition: gravi_cpl.c:2141
cpl_error_code gravi_table_set_array_phase(cpl_table *table, const char *name, cpl_size row, cpl_array *phase)
Definition: gravi_cpl.c:738
cpl_array * gravi_array_init_double(long n, double value)
Definition: gravi_cpl.c:597
double ** gravi_table_get_data_array_double(cpl_table *table, const char *name)
Definition: gravi_cpl.c:473
cpl_error_code gravi_array_normalize_complex(cpl_array *input)
Definition: gravi_cpl.c:1053
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:1757
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:2547
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:1971
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:2511
cpl_error_code gravi_imagelist_unwrap_images(cpl_imagelist *imglist)
Unwrap an imagelist an all its images.
Definition: gravi_cpl.c:1727
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:1403
cpl_array * gravi_table_get_column_sum_array(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:427
cpl_image * gravi_image_from_matrix(cpl_matrix *matrix)
Definition: gravi_cpl.c:2423
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:1185
cpl_matrix * gravi_matrix_interpolate_col(cpl_matrix *matrix, cpl_vector *xref, cpl_vector *xout)
Linear interpolation of matrix column.
Definition: gravi_cpl.c:2867
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:2235
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:769
cpl_array * gravi_array_wrap_float_complex(cpl_array *input_re, cpl_array *input_im)
Definition: gravi_cpl.c:664
cpl_array * gravi_array_compute_norm2(cpl_array *input_re, cpl_array *input_im)
Definition: gravi_cpl.c:688
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:2004
cpl_matrix * svdcmp(cpl_matrix *, cpl_vector *, cpl_matrix *)
Definition: gravi_cpl.c:2995
double gravi_table_get_column_std(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:388
cpl_array * gravi_table_get_column_mean_array(cpl_table *table, const char *name, int base, int nbase)
Definition: gravi_cpl.c:449
cpl_error_code gravi_image_subtract_collapse(cpl_image *img, const cpl_image *collapse, int direction)
Definition: gravi_cpl.c:1921
cpl_image * gravi_image_wrap_vector(cpl_vector *vector)
Wrap vector into an image (data not duplicated)
Definition: gravi_cpl.c:2443
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:792
cpl_array * gravi_table_create_sigma_array(cpl_table *oi_wave)
Definition: gravi_cpl.c:1024
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:2642
cpl_error_code gravi_table_multiply_scalar(cpl_table *table, const char *name, int base, int nbase, double value)
Multiply scalar or array column by scalar.
Definition: gravi_cpl.c:2766
cpl_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:2185
cpl_error_code gravi_array_phase_wrap(cpl_array *input)
Definition: gravi_cpl.c:1119
cpl_array * gravi_array_init_double_complex(long n, double complex value)
Definition: gravi_cpl.c:619
int ** gravi_table_get_data_array_int(cpl_table *table, const char *name)
Definition: gravi_cpl.c:570
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:1159
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:2614
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:2816
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:1211
float ** gravi_table_get_data_array_float(cpl_table *table, const char *name)
Definition: gravi_cpl.c:497
cpl_array * gravi_array_wrap_complex(cpl_array *input_re, cpl_array *input_im)
Definition: gravi_cpl.c:641
cpl_error_code gravi_table_interpolate_column(cpl_table *to_table, const char *to_x, const char *to_y, const cpl_table *from_table, const char *from_x, const char *from_y)
Definition: gravi_cpl.c:121
cpl_error_code gravi_table_new_column_array(cpl_table *table, const char *name, const char *unit, cpl_type type, cpl_size size)
Definition: gravi_cpl.c:1678
int gravi_table_are_equal(cpl_table *first, cpl_table *second)
Check if two tables have the same content.
Definition: gravi_cpl.c:1585
cpl_error_code gravi_array_multiply_conj(cpl_array *input1, cpl_array *input2)
Definition: gravi_cpl.c:1262
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:1884