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