31#include "moo_params.h"
32#include "moo_single.h"
33#include "moo_badpix.h"
35#include "moo_ext_single.h"
40#include "moo_wavesol.h"
41#include "moo_fibres_table.h"
42#include "moo_line_table.h"
58static moo_tcheby2d_polynomial *
59_moo_wavesol_fit2d(moo_loc_single *loc,
61 moo_spectral_format_info *info,
69 cpl_table *line_table,
71 const char *gfit_colname)
73 moo_tcheby2d_polynomial *result = NULL;
74 cpl_array *seltab = NULL;
75 cpl_vector *vx = NULL;
76 cpl_vector *vy = NULL;
77 cpl_vector *vl = NULL;
79 cpl_ensure(loc != NULL, CPL_ERROR_NULL_INPUT, NULL);
80 cpl_ensure(info != NULL, CPL_ERROR_NULL_INPUT, NULL);
82 cpl_table_select_all(line_table);
83 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_SLITLET, CPL_EQUAL_TO,
85 cpl_size line_table_size =
86 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED,
89 int min_size = (degx + 1) * (degy + 1) + 1;
90 moo_try_assure(line_table_size >= min_size, CPL_ERROR_ILLEGAL_INPUT,
91 "Not enough lines %lld (expected at least %d)",
92 line_table_size, min_size);
94 seltab = cpl_table_where_selected(line_table);
96 double *xpos = cpl_table_get_data_double(line_table, xcolname);
97 double *wave = cpl_table_get_data_double(line_table, MOO_LINE_TABLE_WAVE);
98 double *ypos = cpl_table_get_data_double(line_table, MOO_LINE_TABLE_YLOC);
99 double *fwhm = cpl_table_get_data_double(line_table, MOO_LINE_TABLE_FWHM);
100 int *indexext = cpl_table_get_data_int(line_table, MOO_LINE_TABLE_INDEXEXT);
101 int *fitted = cpl_table_get_data_int(line_table, MOO_LINE_TABLE_MFITTED);
102 int nx = cpl_image_get_size_x(res);
104 cpl_image_reject_value(ycentroids, CPL_VALUE_NAN);
105 double ny = cpl_image_get_max(ycentroids);
106 vx = cpl_vector_new(line_table_size);
107 vl = cpl_vector_new(line_table_size);
108 vy = cpl_vector_new(line_table_size);
110 for (
int i = 0; i < line_table_size; i++) {
111 int idx = cpl_array_get_cplsize(seltab, i, NULL);
112 cpl_vector_set(vx, i, xpos[idx]);
113 cpl_vector_set(vy, i, ypos[idx]);
114 cpl_vector_set(vl, i, wave[idx]);
118 ny, vl, info->wmin, info->wmax);
119 int direction = info->direction;
120 int total_rejected = 0;
121 int size = line_table_size;
123 for (i = 1; i <= niter; i++) {
124 cpl_vector *vdiff = cpl_vector_new(size);
125 for (
int j = 0; j < size; j++) {
126 int idx = cpl_array_get_cplsize(seltab, j, NULL);
127 double x = xpos[idx];
128 double y = ypos[idx];
129 double l = wave[idx];
130 double t = moo_tcheby2d_polynomial_eval(result, x, y);
133 cpl_vector_set(vdiff, j, diff);
136 double stdev = cpl_vector_get_stdev(vdiff);
139 for (
int j = 0; j < size; j++) {
140 double diff = cpl_vector_get(vdiff, j);
141 int idx = cpl_array_get_cplsize(seltab, j, NULL);
142 if (fabs(diff) >= kappa * stdev) {
147 cpl_vector_delete(vdiff);
149 if (nb_rejected == size) {
153 if (nb_rejected == 0) {
158 (double)(nb_rejected + total_rejected) / (double)line_table_size;
160 if (frac > max_frac) {
163 total_rejected += nb_rejected;
164 moo_tcheby2d_polynomial_delete(result);
165 cpl_array_delete(seltab);
167 cpl_table_select_all(line_table);
168 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_SLITLET,
169 CPL_EQUAL_TO, slit_idx);
170 size = cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED,
173 seltab = cpl_table_where_selected(line_table);
174 for (
int j = 0; j < size; j++) {
175 int idx = cpl_array_get_cplsize(seltab, j, NULL);
178 cpl_array_delete(seltab);
180 cpl_table_select_all(line_table);
181 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_SLITLET,
182 CPL_EQUAL_TO, slit_idx);
183 size = cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED,
185 seltab = cpl_table_where_selected(line_table);
187 cpl_vector_delete(vx);
188 cpl_vector_delete(vy);
189 cpl_vector_delete(vl);
191 vx = cpl_vector_new(size);
192 vl = cpl_vector_new(size);
193 vy = cpl_vector_new(size);
195 for (
int j = 0; j < size; j++) {
196 cpl_size idx = cpl_array_get_cplsize(seltab, j, NULL);
197 cpl_vector_set(vx, j, xpos[idx]);
198 cpl_vector_set(vy, j, ypos[idx]);
199 cpl_vector_set(vl, j, wave[idx]);
203 vl, info->wmin, info->wmax);
207 cpl_array_delete(seltab);
208 cpl_msg_debug(__func__,
"Fit2d filtering data from %lld to %d",
209 line_table_size, size);
211 cpl_table_select_all(line_table);
212 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_SLITLET, CPL_EQUAL_TO,
215 cpl_table_and_selected_int(line_table, gfit_colname, CPL_EQUAL_TO, 1);
216 seltab = cpl_table_where_selected(line_table);
218 for (i = 0; i < line_table_size; i++) {
221 int idx = cpl_array_get_cplsize(seltab, i, NULL);
222 double x = xpos[idx];
223 double y = ypos[idx];
224 int iy = indexext[idx];
226 double wavefit = moo_tcheby2d_polynomial_eval(result, x, y);
228 cpl_table_set_double(line_table, MOO_LINE_TABLE_WAVEFIT, idx, wavefit);
230 double fw = fwhm[idx] / 2.;
235 if (x1 >= 1 && x2 >= 1 && x1 <= nx && x2 <= nx) {
239 double wavefit1 = moo_tcheby2d_polynomial_eval(result, x1, y1);
240 double wavefit2 = moo_tcheby2d_polynomial_eval(result, x2, y2);
242 double resolution = wavefit / (wavefit2 - wavefit1) * direction;
244 cpl_table_set_double(line_table, MOO_LINE_TABLE_RESOLUTION, idx,
248 cpl_table_set_double(line_table, MOO_LINE_TABLE_RESOLUTION, idx,
254 cpl_array_delete(seltab);
255 cpl_vector_delete(vx);
256 cpl_vector_delete(vy);
257 cpl_vector_delete(vl);
263_moo_wavesol_fit1d(moo_loc_single *loc,
271 cpl_table *result_table,
274 cpl_table *line_table,
275 const char *xcolname)
277 cpl_table_select_all(line_table);
278 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_INDEXEXT,
279 CPL_EQUAL_TO, numfib);
280 cpl_size line_table_size =
281 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED,
284 if (line_table_size > degree) {
285 int total_rejected = 0;
286 moo_tcheby_polynomial *poly = NULL;
289 cpl_image_reject_value(ycentroids, CPL_VALUE_NAN);
290 int nx = cpl_image_get_size_x(res);
292 cpl_array *seltab = cpl_table_where_selected(line_table);
294 double *xpos = cpl_table_get_data_double(line_table, xcolname);
296 cpl_table_get_data_double(line_table, MOO_LINE_TABLE_WAVE);
298 cpl_table_get_data_double(line_table, MOO_LINE_TABLE_FWHM);
300 cpl_table_get_data_int(line_table, MOO_LINE_TABLE_MFITTED);
302 cpl_bivector *data = cpl_bivector_new(line_table_size);
303 cpl_vector *vx = cpl_bivector_get_x(data);
304 cpl_vector *vy = cpl_bivector_get_y(data);
306 for (
int i = 0; i < line_table_size; i++) {
307 int idx = cpl_array_get_cplsize(seltab, i, NULL);
308 double x = xpos[idx];
309 double w = wave[idx];
310 cpl_vector_set(vx, i, x);
311 cpl_vector_set(vy, i, w);
314 cpl_size size = line_table_size;
316 for (
int i = 1; i <= niter; i++) {
317 cpl_msg_info(__func__,
318 "#%d iter %d / %d with %" CPL_SIZE_FORMAT
319 " data (total rejected %d)",
320 numfib, i, niter, size, total_rejected);
321 cpl_vector *vdiff = cpl_vector_new(size);
323 for (
int j = 0; j < size; j++) {
324 double x = cpl_vector_get(vx, j);
325 double y = cpl_vector_get(vy, j);
326 double t = moo_tcheby_polynomial_eval(poly, x);
328 cpl_vector_set(vdiff, j, diff);
331 double stdev = cpl_vector_get_stdev(vdiff);
334 for (
int j = 0; j < size; j++) {
335 double diff = cpl_vector_get(vdiff, j);
336 if (fabs(diff) >= kappa * stdev) {
337 int idx = cpl_array_get_cplsize(seltab, j, NULL);
342 cpl_vector_delete(vdiff);
344 if (nb_rejected == size) {
345 cpl_msg_info(
"test",
"#%d all rejected", numfib);
349 if (nb_rejected == 0) {
350 cpl_msg_info(
"test",
"#%d no rejected", numfib);
353 double frac = (double)(nb_rejected + total_rejected) /
354 (double)line_table_size;
356 if (frac > max_frac) {
357 cpl_msg_info(__func__,
"max frac reached (%f > %f)", frac,
361 total_rejected += nb_rejected;
362 moo_tcheby_polynomial_delete(poly);
363 cpl_array_delete(seltab);
365 cpl_table_select_all(line_table);
366 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_INDEXEXT,
367 CPL_EQUAL_TO, numfib);
369 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED,
371 seltab = cpl_table_where_selected(line_table);
373 cpl_bivector_delete(data);
374 data = cpl_bivector_new(size);
375 vx = cpl_bivector_get_x(data);
376 vy = cpl_bivector_get_y(data);
377 for (
int j = 0; j < size; j++) {
378 int idx = cpl_array_get_cplsize(seltab, j, NULL);
379 cpl_vector_set(vx, j, xpos[idx]);
380 cpl_vector_set(vy, j, wave[idx]);
384 cpl_array_delete(seltab);
385 cpl_table_select_all(line_table);
386 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_INDEXEXT,
387 CPL_EQUAL_TO, numfib);
388 size = cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED,
391 int nb_points = size;
392 *nb_sigclip += nb_points;
394 cpl_table_select_all(line_table);
396 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_INDEXEXT,
397 CPL_EQUAL_TO, numfib);
398 seltab = cpl_table_where_selected(line_table);
400 for (
int i = 0; i < line_table_size; i++) {
401 int idx = cpl_array_get_cplsize(seltab, i, NULL);
402 double x = xpos[idx];
403 double wavefit = moo_tcheby_polynomial_eval(poly, x);
404 cpl_table_set_double(line_table, MOO_LINE_TABLE_WAVEFIT, idx,
407 double fw = fwhm[idx] / 2.;
411 if (x1 >= 1 && x2 >= 1) {
412 double wavefit1 = moo_tcheby_polynomial_eval(poly, x1);
413 double wavefit2 = moo_tcheby_polynomial_eval(poly, x2);
414 double resolution = wavefit / (wavefit2 - wavefit1);
415 cpl_table_set_double(line_table, MOO_LINE_TABLE_RESOLUTION, idx,
419 cpl_table_set_double(line_table, MOO_LINE_TABLE_RESOLUTION, i,
424 for (
int i = 1; i <= nx; i++) {
427 cpl_image_get(ycentroids, i, numfib, &rej);
430 cpl_image_set(res, i, numfib, NAN);
433 double t = moo_tcheby_polynomial_eval(poly, i);
434 cpl_image_set(res, i, numfib, t);
441 moo_tcheby_polynomial_delete(poly);
442 cpl_bivector_delete(data);
443 cpl_array_delete(seltab);
445 return cpl_error_get_code();
449_compute_slitlet_shift(cpl_table *slitlet_shift,
450 cpl_table *catalog_lines,
453 cpl_vector *vxdiff = NULL;
455 cpl_ensure(catalog_lines != NULL, CPL_ERROR_NULL_INPUT, NULL);
457 const double *waves =
458 cpl_table_get_data_double_const(catalog_lines, MOO_ARCLINE_LIST_WAVE);
459 int nb_catalog_lines = cpl_table_get_nrow(catalog_lines);
461 vxdiff = cpl_vector_new(nb_catalog_lines);
463 if (slitlet_shift != NULL) {
464 int min = cpl_table_get_column_min(slitlet_shift,
465 MOO_SLITLET_SHIFT_TABLE_SLITLET);
466 int max = cpl_table_get_column_max(slitlet_shift,
467 MOO_SLITLET_SHIFT_TABLE_SLITLET);
468 double center = (min + max) / 2.;
469 for (
int i = 0; i < nb_catalog_lines; i++) {
470 double waveref = waves[i];
471 cpl_table_select_all(slitlet_shift);
472 cpl_table_and_selected_int(slitlet_shift,
473 MOO_SLITLET_SHIFT_TABLE_SLITLET,
474 CPL_EQUAL_TO, slitlet_idx);
475 cpl_table_and_selected_double(slitlet_shift,
476 MOO_SLITLET_SHIFT_TABLE_WAVE,
477 CPL_EQUAL_TO, waveref);
478 cpl_array *sel = cpl_table_where_selected(slitlet_shift);
479 int slitletshift_idx = cpl_array_get(sel, 0, NULL);
480 double xdiff = cpl_table_get_double(slitlet_shift,
481 MOO_SLITLET_SHIFT_TABLE_XDIFF,
482 slitletshift_idx, NULL);
483 cpl_array_delete(sel);
486 cpl_table_select_all(slitlet_shift);
487 int next_slit = slitlet_idx + 1;
488 if (slitlet_idx > center) {
489 next_slit = slitlet_idx - 1;
491 cpl_table_and_selected_int(slitlet_shift,
492 MOO_SLITLET_SHIFT_TABLE_SLITLET,
493 CPL_EQUAL_TO, next_slit);
494 cpl_table_and_selected_double(slitlet_shift,
495 MOO_SLITLET_SHIFT_TABLE_WAVE,
496 CPL_EQUAL_TO, waveref);
497 sel = cpl_table_where_selected(slitlet_shift);
498 slitletshift_idx = cpl_array_get(sel, 0, NULL);
499 cpl_array_delete(sel);
500 xdiff = cpl_table_get_double(slitlet_shift,
501 MOO_SLITLET_SHIFT_TABLE_XDIFF,
502 slitletshift_idx, NULL);
507 cpl_vector_set(vxdiff, i, xdiff);
511 for (
int i = 0; i < nb_catalog_lines; i++) {
512 cpl_vector_set(vxdiff, i, 0.0);
519_moo_wavesol_fibre_using_guess(cpl_image *data,
522 cpl_table *slitlet_shift,
524 cpl_table *catalog_lines,
532 cpl_table **lline_table,
537 cpl_table *detected_table = NULL;
538 cpl_table *ref_table = NULL;
539 cpl_vector *sol_w = NULL;
540 cpl_vector *sol_wx = NULL;
541 cpl_bivector *sol = NULL;
543 cpl_ensure(data != NULL, CPL_ERROR_NULL_INPUT, NULL);
545 int nx = cpl_image_get_size_x(data);
546 ref_table = cpl_table_new(nx);
547 cpl_table_new_column(ref_table, MOO_WAVESOL_REFTABLE_WAVE, CPL_TYPE_DOUBLE);
548 cpl_table_new_column(ref_table, MOO_WAVESOL_REFTABLE_X, CPL_TYPE_DOUBLE);
550 cpl_vector *vect = cpl_vector_new_from_image_row(data, numfib);
551 cpl_vector *verr = cpl_vector_new_from_image_row(errs, numfib);
552 cpl_vector *vsol = cpl_vector_new_from_image_row(guess, numfib);
554 for (
int i = 0; i < nx; i++) {
555 double w = (float)cpl_vector_get(vsol, i);
558 cpl_table_set(ref_table, MOO_WAVESOL_REFTABLE_WAVE, i, w);
559 cpl_table_set(ref_table, MOO_WAVESOL_REFTABLE_X, i, x);
562 cpl_table_set_invalid(ref_table, MOO_WAVESOL_REFTABLE_WAVE, i);
565 cpl_vector_delete(vsol);
567 if (!cpl_table_has_valid(ref_table, MOO_WAVESOL_REFTABLE_WAVE)) {
568 cpl_msg_info(
"moo_wavesol",
"#%d invalid guess data", numfib);
569 cpl_vector_delete(verr);
570 cpl_vector_delete(vect);
571 cpl_table_delete(ref_table);
572 return detected_table;
575 cpl_table_erase_invalid(ref_table);
576 int ref_size = cpl_table_get_nrow(ref_table);
578 cpl_table_get_data_double(ref_table, MOO_WAVESOL_REFTABLE_WAVE);
580 cpl_table_get_data_double(ref_table, MOO_WAVESOL_REFTABLE_X);
582 sol_w = cpl_vector_wrap(ref_size, refd_w);
583 sol_wx = cpl_vector_wrap(ref_size, refd_wx);
584 sol = cpl_bivector_wrap_vectors(sol_w, sol_wx);
587 cpl_table_get_column_min(ref_table, MOO_WAVESOL_REFTABLE_WAVE);
589 cpl_table_get_column_max(ref_table, MOO_WAVESOL_REFTABLE_WAVE);
591 cpl_bivector *solx = cpl_bivector_new(ref_size);
592 cpl_vector *solx_x = cpl_bivector_get_x(solx);
593 cpl_vector *solx_y = cpl_bivector_get_y(solx);
595 for (
int i = 0; i < ref_size; i++) {
596 double xv = cpl_vector_get(sol_wx, i);
597 cpl_vector_set(solx_x, i, xv);
598 double yv = cpl_vector_get(sol_w, i);
599 cpl_vector_set(solx_y, i, yv);
602 cpl_bivector_sort(sol, sol, CPL_SORT_ASCENDING, CPL_SORT_BY_X);
604 const double *waves =
605 cpl_table_get_data_double_const(catalog_lines, MOO_ARCLINE_LIST_WAVE);
606 int nb_catalog_lines = cpl_table_get_nrow(catalog_lines);
609 detected_table = moo_detected_table_new(nb_catalog_lines, 0);
611 _compute_slitlet_shift(slitlet_shift, catalog_lines, slitlet_idx);
613 for (
int i = 0; i < nb_catalog_lines; i++) {
614 double waveref = waves[i];
615 cpl_table_set_int(detected_table, MOO_LINE_TABLE_INDEXEXT, i, indexext);
616 cpl_table_set_int(detected_table, MOO_LINE_TABLE_SLITLET, i,
618 cpl_table_set_double(detected_table, MOO_LINE_TABLE_WAVE, i, waveref);
619 double xdiff = cpl_vector_get(vxdiff, i);
621 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XDIFF, i, xdiff);
622 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_NOT_IN_RANGE, i,
624 cpl_table_set_double(detected_table, MOO_LINE_TABLE_INTENSITY, i, NAN);
625 cpl_table_set_int(detected_table, MOO_LINE_TABLE_GFITTED, i, 0);
626 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XGAUSS, i, NAN);
627 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XBARY, i, NAN);
628 cpl_table_set_double(detected_table, MOO_LINE_TABLE_FWHM, i, NAN);
629 cpl_table_set_double(detected_table, MOO_LINE_TABLE_AMPLITUDE, i, NAN);
630 cpl_table_set_double(detected_table, MOO_LINE_TABLE_BACKGROUND, i, NAN);
631 cpl_table_set_double(detected_table, MOO_LINE_TABLE_FIT_FLUX, i, NAN);
632 cpl_table_set_double(detected_table, MOO_LINE_TABLE_FIT_ERR, i, NAN);
633 cpl_table_set_double(detected_table, MOO_LINE_TABLE_FIT_CHI2, i, NAN);
634 cpl_table_set_double(detected_table, MOO_LINE_TABLE_FIT_MSE, i, NAN);
635 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WIN_CEN, i,
637 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WIN_MIN, i,
639 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WIN_MAX, i,
641 cpl_table_set_int(detected_table, MOO_LINE_TABLE_FILTERED, i, -1);
642 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WAVETH, i, NAN);
645 cpl_vector_delete(vxdiff);
647 cpl_table_select_all(detected_table);
648 cpl_table_and_selected_double(detected_table, MOO_LINE_TABLE_WAVE,
649 CPL_NOT_LESS_THAN, wmin);
651 cpl_table_and_selected_double(detected_table, MOO_LINE_TABLE_WAVE,
652 CPL_NOT_GREATER_THAN, wmax);
654 cpl_array *seltab = cpl_table_where_selected(detected_table);
655 nb_failed = nb_catalog_lines - nb_lines;
658 cpl_vector *nwavepos_l = cpl_vector_new(nb_lines);
659 for (
int i = 0; i < nb_lines; i++) {
660 int idx = cpl_array_get_cplsize(seltab, i, NULL);
661 double w = cpl_table_get_double(detected_table, MOO_LINE_TABLE_WAVE,
663 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_NOT_IN_RANGE,
665 cpl_vector_set(nwavepos_l, i, w);
668 cpl_vector_sort(nwavepos_l, CPL_SORT_ASCENDING);
669 cpl_vector *nwavepos_x = cpl_vector_new(nb_lines);
670 cpl_bivector *nwavepos =
671 cpl_bivector_wrap_vectors(nwavepos_l, nwavepos_x);
672 cpl_bivector_interpolate_linear(nwavepos, sol);
674 for (
int i = 0; i < nb_lines; i++) {
675 double xguess = (float)cpl_vector_get(nwavepos_x, i);
677 int idx = cpl_array_get_cplsize(seltab, i, NULL);
680 cpl_table_get_double(detected_table, MOO_LINE_TABLE_XDIFF, idx,
682 double win_cen = round(xguess - xdiff);
683 int size = winhsize * 2 + 1;
684 double win_min = win_cen - winhsize;
685 double win_max = win_cen + winhsize;
692 size = win_max - win_min + 1;
693 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XGUESS, idx,
695 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WIN_MIN,
697 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WIN_MAX,
699 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WIN_CEN,
702 cpl_bivector *points = cpl_bivector_new(size);
703 cpl_vector *x = cpl_bivector_get_x(points);
704 cpl_vector *y = cpl_bivector_get_y(points);
705 cpl_vector *yerr = cpl_vector_new(size);
707 for (
int pos = win_min; pos <= win_max; pos++) {
708 cpl_vector_set(x, pos - win_min, pos);
709 cpl_vector_set(y, pos - win_min,
710 (
float)cpl_vector_get(vect, pos - 1));
711 cpl_vector_set(yerr, pos - win_min,
712 (
float)cpl_vector_get(verr, pos - 1));
714 double intensity = cpl_vector_get_max(y);
715 cpl_table_set_double(detected_table, MOO_LINE_TABLE_INTENSITY, idx,
718 double centroid = NAN, background = NAN, area = NAN, sigma = NAN,
720 cpl_errorstate prev_state = cpl_errorstate_get();
721 cpl_vector_fit_gaussian(x, NULL, y, NULL, CPL_FIT_ALL, ¢roid,
722 &sigma, &area, &background, &mse, NULL,
724 cpl_vector_delete(yerr);
726 if (centroid >= win_min && centroid <= win_max &&
727 cpl_errorstate_is_equal(prev_state)) {
729 cpl_table_set_int(detected_table, MOO_LINE_TABLE_GFITTED, idx,
732 cpl_image_get(data, round(centroid), numfib, &rej);
734 cpl_image_get(errs, round(centroid), numfib, &rej);
736 cpl_table_set_double(detected_table,
737 MOO_DETECTED_TABLE_FIT_FLUX, idx,
739 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_FIT_ERR,
742 cpl_table_set_double(detected_table,
743 MOO_DETECTED_TABLE_FIT_CHI2, idx, chi2);
744 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_FIT_MSE,
747 cpl_bivector *fout = cpl_bivector_new(1);
748 cpl_vector *fout_x = cpl_bivector_get_x(fout);
749 cpl_vector *fout_y = cpl_bivector_get_y(fout);
750 cpl_vector_set(fout_x, 0, centroid);
752 cpl_bivector_interpolate_linear(fout, solx);
753 double waveth = cpl_vector_get(fout_y, 0);
755 cpl_bivector_delete(fout);
756 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XGAUSS, idx,
758 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WAVETH,
761 double amplitude = area / sqrt(CPL_MATH_2PI * sigma * sigma);
762 double fwhm = CPL_MATH_FWHM_SIG * sigma;
763 cpl_table_set_double(detected_table, MOO_LINE_TABLE_FWHM, idx,
765 cpl_table_set_double(detected_table, MOO_LINE_TABLE_AMPLITUDE,
767 cpl_table_set_double(detected_table, MOO_LINE_TABLE_BACKGROUND,
769 double width_bary = 0;
772 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XBARY, idx,
774 if (sigma >= sigma_min && sigma <= sigma_max) {
775 cpl_table_set_int(detected_table, MOO_LINE_TABLE_FILTERED,
778 else if (sigma < sigma_min) {
779 cpl_table_set_int(detected_table, MOO_LINE_TABLE_FILTERED,
783 cpl_table_set_int(detected_table, MOO_LINE_TABLE_FILTERED,
789 cpl_errorstate_set(prev_state);
791 cpl_bivector_delete(points);
793 cpl_array_delete(seltab);
795 cpl_table_select_all(detected_table);
797 cpl_table_and_selected_int(detected_table, MOO_LINE_TABLE_GFITTED,
800 seltab = cpl_table_where_selected(detected_table);
801 *ldetected = nb_detected;
802 *lfailed = nb_failed;
803 *lfitted = nb_fitted;
805 cpl_msg_debug(
"moo_wavesol",
"s%d #%d lines %d fitted %d", slitlet_idx,
806 numfib, nb_catalog_lines, nb_fitted);
809 cpl_table_set_size(*lline_table, nb_fitted);
811 for (
int i = 0; i < nb_fitted; i++) {
812 int idx = cpl_array_get_cplsize(seltab, i, NULL);
814 cpl_table_get_double(detected_table, MOO_LINE_TABLE_WAVE, idx,
817 cpl_table_get_double(detected_table, MOO_LINE_TABLE_XGAUSS, idx,
820 cpl_table_get_double(detected_table, MOO_LINE_TABLE_XBARY, idx,
822 double fwhm = cpl_table_get_double(detected_table,
823 MOO_LINE_TABLE_FWHM, idx, NULL);
825 cpl_table_get_double(detected_table, MOO_LINE_TABLE_INTENSITY,
828 cpl_table_get_double(detected_table, MOO_LINE_TABLE_AMPLITUDE,
831 cpl_table_get_double(detected_table, MOO_LINE_TABLE_BACKGROUND,
834 cpl_table_get_double(detected_table, MOO_LINE_TABLE_FIT_FLUX,
837 cpl_table_get_double(detected_table, MOO_LINE_TABLE_FIT_ERR,
840 cpl_table_get_double(detected_table, MOO_LINE_TABLE_FIT_CHI2,
843 cpl_table_get_double(detected_table, MOO_LINE_TABLE_FIT_MSE,
847 cpl_table_get_double(detected_table, MOO_LINE_TABLE_XGUESS, idx,
850 cpl_table_get_double(detected_table, MOO_DETECTED_TABLE_WAVETH,
852 int detected = cpl_table_get_int(detected_table,
853 MOO_LINE_TABLE_GFITTED, idx, NULL);
855 cpl_table_get_int(detected_table, MOO_LINE_TABLE_FILTERED, idx,
861 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_INDEXEXT, i,
863 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_SLITLET, i,
865 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_WAVE, i,
867 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FLUX, i, NAN);
868 cpl_table_set_string(*lline_table, MOO_LINE_TABLE_NAME, i,
"");
869 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_INDEXRBN, i, -1);
870 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_YLOC, i, NAN);
871 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_GFITTED, i,
873 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_INTENSITY, i,
875 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XGUESS, i,
877 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XGAUSS, i,
879 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XDIFF, i,
881 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_WAVEDIFF, i,
883 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XBARY, i, xbary);
884 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FWHM, i, fwhm);
885 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_AMPLITUDE, i,
887 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_BACKGROUND, i,
889 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_FLUX, i,
891 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_ERR, i,
893 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_CHI2, i,
895 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_MSE, i,
897 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_FILTERED, i,
899 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_MFITTED, i, mfitted);
900 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_WAVEFIT, i, NAN);
901 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_RESOLUTION, i,
903 cpl_table_set_string(*lline_table, MOO_LINE_TABLE_DETECTOR, i,
905 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_SPECTRO, i, spectro);
908 cpl_array_delete(seltab);
909 cpl_bivector_unwrap_vectors(nwavepos);
910 cpl_vector_delete(nwavepos_l);
911 cpl_vector_delete(nwavepos_x);
914 cpl_msg_info(
"moo_wavesol",
"#%d No lines in solution range (%f,%f)",
917 cpl_bivector_delete(solx);
919 cpl_bivector_unwrap_vectors(sol);
920 cpl_vector_unwrap(sol_w);
921 cpl_vector_unwrap(sol_wx);
923 cpl_table_delete(ref_table);
925 cpl_vector_delete(verr);
926 cpl_vector_delete(vect);
927 return detected_table;
931_moo_do_ppm_match(
const double *waves,
933 cpl_table *detected_table,
941 cpl_bivector *res = NULL;
942 cpl_table *ppm_table = NULL;
944 cpl_vector *clines = cpl_vector_new(nb_lines);
945 for (
int i = 0; i < nb_lines; i++) {
946 double wa = waves[i] * direction;
947 cpl_vector_set(clines, i, wa * 10);
949 cpl_table_select_all(detected_table);
951 cpl_table_and_selected_int(detected_table, MOO_LINE_TABLE_FILTERED,
954 cpl_array *seltab = cpl_table_where_selected(detected_table);
955 cpl_vector *npeaks = cpl_vector_new(size);
956 for (
int i = 0; i < size; i++) {
957 int idx = cpl_array_get_cplsize(seltab, i, NULL);
959 cpl_table_get_double(detected_table, MOO_LINE_TABLE_XGAUSS, idx,
961 cpl_vector_set(npeaks, i, xpos);
963 cpl_array_delete(seltab);
965 cpl_vector_sort(npeaks, CPL_SORT_ASCENDING);
966#if MOO_DEBUG_WAVESOL_MATCHING
969 cpl_sprintf(
"%s_ppmmatch_peaks_%d.txt", prefix, numfib);
970 FILE *test = fopen(name,
"w");
971 cpl_vector_dump(npeaks, test);
976 cpl_vector_sort(clines, CPL_SORT_ASCENDING);
978#if MOO_DEBUG_WAVESOL_MATCHING
981 cpl_sprintf(
"%s_ppmmatch_lines_%d.txt", prefix, numfib);
982 FILE *test = fopen(name,
"w");
983 cpl_vector_dump(clines, test);
989 res = cpl_ppm_match_positions(npeaks, clines, min_disp * 10,
990 max_disp * 10, tolerance, NULL, NULL);
992 int rsize = cpl_bivector_get_size(res);
993 ppm_table = cpl_table_new(rsize);
994 cpl_table_new_column(ppm_table, MOO_PPM_TABLE_WAVE,
996 cpl_table_new_column(ppm_table, MOO_PPM_TABLE_X, CPL_TYPE_DOUBLE);
997 cpl_table_new_column(ppm_table, MOO_PPM_TABLE_INDEXEXT,
999 cpl_table_new_column(ppm_table, MOO_PPM_TABLE_DISP,
1002 cpl_vector *x = cpl_bivector_get_x(res);
1003 cpl_vector *w = cpl_bivector_get_y(res);
1005 for (
int i = 0; i < rsize; i++) {
1006 double x1 = cpl_vector_get(x, i);
1007 double w1 = cpl_vector_get(w, i) / 10. * direction;
1008 cpl_table_set(ppm_table, MOO_PPM_TABLE_WAVE, i, w1);
1009 cpl_table_set(ppm_table, MOO_PPM_TABLE_X, i, x1);
1010 cpl_table_set_int(ppm_table, MOO_PPM_TABLE_INDEXEXT, i, numfib);
1012 for (
int i = 0; i < rsize - 1; i++) {
1013 double x1 = cpl_vector_get(x, i);
1014 double x2 = cpl_vector_get(x, i + 1);
1015 double w1 = cpl_vector_get(w, i) / 10 * direction;
1016 double w2 = cpl_vector_get(w, i + 1) / 10 * direction;
1017 double wdiff = (w2 - w1) * direction;
1018 double xdiff = x2 - x1;
1019 cpl_table_unselect_all(ppm_table);
1020 cpl_table_or_selected_double(ppm_table, MOO_PPM_TABLE_WAVE,
1023 cpl_table_or_selected_double(ppm_table, MOO_PPM_TABLE_WAVE,
1025 double disp = wdiff / xdiff;
1026 cpl_array *sel = cpl_table_where_selected(ppm_table);
1027 for (
int j = 0; j < nb; j++) {
1028 int idx = cpl_array_get_cplsize(sel, j, NULL);
1031 cpl_table_get(ppm_table, MOO_PPM_TABLE_DISP, idx, &rej);
1033 disp = (disp + old) / 2.;
1035 cpl_table_set(ppm_table, MOO_PPM_TABLE_DISP, idx, disp);
1037 cpl_array_delete(sel);
1039#if MOO_DEBUG_WAVESOL_MATCHING
1042 cpl_sprintf(
"%s_ppmmatch_res_%d.fits", prefix, numfib);
1043 cpl_table_save(ppm_table, NULL, NULL, name, CPL_IO_CREATE);
1048 cpl_vector_delete(npeaks);
1050 cpl_vector_delete(clines);
1051 cpl_bivector_delete(res);
1056_moo_wavesol_fibre(cpl_image *data,
1064 cpl_table *catalog_lines,
1073 const char *extname,
1075 cpl_table **lline_table,
1081 cpl_table *detected_table = NULL;
1083 cpl_errorstate prestate = cpl_errorstate_get();
1084 cpl_image *idata = NULL;
1085 cpl_image *ierr = NULL;
1087 cpl_ensure(data != NULL, CPL_ERROR_NULL_INPUT, NULL);
1089 int nx = cpl_image_get_size_x(data);
1090 moo_try_check(idata = cpl_image_extract(data, 1, numfib, nx, numfib),
" ");
1091 moo_try_check(ierr = cpl_image_extract(errs, 1, numfib, nx, numfib),
" ");
1092 cpl_mask *imask = cpl_image_get_bpm(idata);
1094 const double *waves =
1095 cpl_table_get_data_double_const(catalog_lines, MOO_ARCLINE_LIST_WAVE);
1096 int nb_catalog_lines = cpl_table_get_nrow(catalog_lines);
1098 int nb_detected = 0;
1102 int current_detected = 0;
1103 detected_table = moo_detected_table_new(current_detected, 1);
1105 while (nb_fitted < nb_peaks_lines) {
1108 int nb_bad = cpl_mask_count(imask);
1112 cpl_table_set_size(detected_table, nb_detected + 1);
1113 cpl_image_get_maxpos(idata, &x, &y);
1114 double intensity = cpl_image_get(idata, x, y, &rej);
1115 cpl_table_set_int(detected_table, MOO_LINE_TABLE_INDEXEXT, nb_detected,
1117 cpl_table_set_int(detected_table, MOO_LINE_TABLE_SLITLET, nb_detected,
1119 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_NGOOD, nb_detected,
1121 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_BADFIT,
1123 cpl_table_set_int(detected_table, MOO_LINE_TABLE_FILTERED, nb_detected,
1125 int min = x - winhsize;
1129 int max = x + winhsize;
1134 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_MIN, nb_detected,
1136 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_MAX, nb_detected,
1138 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_WIN_CEN,
1141 cpl_vector *xv = NULL;
1142 cpl_vector *yv = NULL;
1143 cpl_vector *yerr = NULL;
1144 cpl_matrix *covariance = NULL;
1146 int size = max - min + 1;
1148 xv = cpl_vector_new(size);
1149 yv = cpl_vector_new(size);
1150 yerr = cpl_vector_new(size);
1153 nb_bad = cpl_mask_count(imask);
1155 for (
int i = min; i <= max; i++) {
1156 double flux = cpl_image_get(idata, i, 1, &rej);
1157 if (rej == CPL_BINARY_0) {
1158 double flux_err = cpl_image_get(ierr, i, 1, &rej);
1159 cpl_vector_set(xv, ngood, i);
1160 cpl_vector_set(yv, ngood, (
float)flux);
1161 cpl_vector_set(yerr, ngood, (
float)flux_err);
1166 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_NGOOD, nb_detected,
1170 cpl_vector_set_size(xv, ngood);
1171 cpl_vector_set_size(yv, ngood);
1172 cpl_vector_set_size(yerr, ngood);
1173 cpl_table_set_double(detected_table, MOO_LINE_TABLE_INTENSITY,
1174 nb_detected, intensity);
1175 double centroid = NAN, background = NAN, area = NAN, sigma = NAN,
1176 mse = NAN, chi2 = NAN;
1177 cpl_errorstate prev_state = cpl_errorstate_get();
1179 cpl_vector_fit_gaussian(xv, NULL, yv, yerr, CPL_FIT_ALL, ¢roid,
1180 &sigma, &area, &background, &mse, &chi2,
1183 if (cpl_errorstate_is_equal(prev_state)) {
1185 cpl_image_get(idata, round(centroid), 1, &rej);
1186 double fit_err = cpl_image_get(ierr, round(centroid), 1, &rej);
1188 cpl_table_set_double(detected_table,
1189 MOO_DETECTED_TABLE_FIT_FLUX, nb_detected,
1191 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_FIT_ERR,
1192 nb_detected, fit_err);
1193 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_BADFIT,
1195 cpl_table_set_double(detected_table, MOO_DETECTED_TABLE_FIT_MSE,
1197 cpl_table_set_double(detected_table,
1198 MOO_DETECTED_TABLE_FIT_CHI2, nb_detected,
1200 cpl_table_set_double(detected_table,
1201 MOO_DETECTED_TABLE_FIT_BACKGROUND,
1202 nb_detected, background);
1203 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XGAUSS,
1204 nb_detected, centroid);
1205 double amplitude = area / sqrt(CPL_MATH_2PI * sigma * sigma);
1206 double fwhm = CPL_MATH_FWHM_SIG * sigma;
1207 double fit_snr = amplitude / fit_err;
1208 cpl_table_set_double(detected_table, MOO_LINE_TABLE_FWHM,
1210 cpl_table_set_double(detected_table, MOO_LINE_TABLE_AMPLITUDE,
1211 nb_detected, amplitude);
1212 cpl_table_set_double(detected_table, MOO_LINE_TABLE_BACKGROUND,
1213 nb_detected, background);
1214 double width_bary = 0;
1217 cpl_bivector *fitdata = cpl_bivector_wrap_vectors(xv, yv);
1219 cpl_bivector_unwrap_vectors(fitdata);
1220 cpl_table_set_double(detected_table, MOO_LINE_TABLE_XBARY,
1221 nb_detected, x_bary);
1223 if (sigma >= sigma_min && sigma <= sigma_max) {
1224 if (fit_snr >= ref_snr && fit_flux > 0) {
1225 cpl_table_set_int(detected_table,
1226 MOO_LINE_TABLE_FILTERED, nb_detected,
1231 cpl_table_set_int(detected_table,
1232 MOO_LINE_TABLE_FILTERED, nb_detected,
1236 else if (sigma < sigma_min) {
1237 cpl_table_set_int(detected_table, MOO_LINE_TABLE_FILTERED,
1241 cpl_table_set_int(detected_table, MOO_LINE_TABLE_FILTERED,
1246 cpl_table_set_int(detected_table, MOO_DETECTED_TABLE_BADFIT,
1248 cpl_errorstate_set(prev_state);
1251 cpl_matrix_delete(covariance);
1252 cpl_vector_delete(xv);
1253 cpl_vector_delete(yv);
1254 cpl_vector_delete(yerr);
1256 for (
int i = min; i <= max; i++) {
1257 cpl_mask_set(imask, i, 1, CPL_BINARY_1);
1261 cpl_table *ppm_table =
1262 _moo_do_ppm_match(waves, nb_catalog_lines, detected_table, numfib,
1263 min_disp, max_disp, tolerance, direction, prefix);
1265 int ppm_table_nrow = 0;
1267 if (ppm_table != NULL) {
1268 ppm_table_nrow = cpl_table_get_nrow(ppm_table);
1271 if (ppm_table_nrow <= 1) {
1272 cpl_msg_error(
"moo_wavesol",
1273 "#%d-%d Pattern matching failed with in input %d peaks "
1274 "fitted (%d peaks detected)",
1275 slitlet_idx, numfib, nb_fitted, nb_detected);
1278 nb_matched = ppm_table_nrow;
1280 cpl_table_set_size(*lline_table, nb_catalog_lines);
1282 for (
int i = 0; i < nb_catalog_lines; i++) {
1283 double nm = waves[i];
1284 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_WAVE, i, nm);
1285 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_INDEXEXT, i,
1287 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_SLITLET, i,
1289 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_INDEXRBN, i, -1);
1290 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XGAUSS, i, NAN);
1291 cpl_table_set_string(*lline_table, MOO_LINE_TABLE_DETECTOR, i,
1293 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_SPECTRO, i, spectro);
1294 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_INTENSITY, i,
1296 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XBARY, i, NAN);
1297 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_AMPLITUDE, i,
1299 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_BACKGROUND, i,
1301 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FWHM, i, NAN);
1302 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_MATCHED, i, 0);
1303 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_MFITTED, i, 0);
1304 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_WAVEFIT, i, NAN);
1305 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_RESOLUTION, i,
1307 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_YLOC, i, NAN);
1308 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FLUX, i, NAN);
1309 cpl_table_set_string(*lline_table, MOO_LINE_TABLE_NAME, i,
"");
1312 for (
int i = 0; i < nb_matched; i++) {
1313 double nm = cpl_table_get(ppm_table, MOO_PPM_TABLE_WAVE, i, NULL);
1314 double px = cpl_table_get(ppm_table, MOO_PPM_TABLE_X, i, NULL);
1315 double disp = cpl_table_get(ppm_table, MOO_PPM_TABLE_DISP, i, NULL);
1317 cpl_table_select_all(*lline_table);
1320 cpl_table_and_selected_double(*lline_table, MOO_LINE_TABLE_WAVE,
1321 CPL_LESS_THAN, nm + 1E-5);
1323 cpl_table_and_selected_double(*lline_table, MOO_LINE_TABLE_WAVE,
1324 CPL_GREATER_THAN, nm - 1E-5);
1326 cpl_array *lline_indexes =
1327 cpl_table_where_selected(*lline_table);
1328 cpl_size lline_idx =
1329 cpl_array_get_cplsize(lline_indexes, 0, NULL);
1330 cpl_array_delete(lline_indexes);
1332 cpl_table_or_selected_double(detected_table,
1333 MOO_LINE_TABLE_XGAUSS,
1335 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_INDEXEXT,
1336 lline_idx, slitlet_idx);
1337 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_INDEXEXT,
1338 lline_idx, indexext_idx);
1339 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_INDEXRBN,
1341 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XGAUSS,
1343 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_DISP,
1345 cpl_table_set_string(*lline_table, MOO_LINE_TABLE_DETECTOR,
1346 lline_idx, extname);
1347 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_SPECTRO,
1348 lline_idx, spectro);
1349 cpl_table_unselect_all(detected_table);
1350 cpl_size detected_nb =
1351 cpl_table_or_selected_double(detected_table,
1352 MOO_LINE_TABLE_XGAUSS,
1354 if (detected_nb == 1) {
1355 cpl_array *detected_indexes =
1356 cpl_table_where_selected(detected_table);
1357 cpl_size detected_idx =
1358 cpl_array_get_cplsize(detected_indexes, 0, NULL);
1360 cpl_table_get_double(detected_table,
1361 MOO_LINE_TABLE_INTENSITY,
1362 detected_idx, NULL);
1363 double xbary = cpl_table_get_double(detected_table,
1364 MOO_LINE_TABLE_XBARY,
1365 detected_idx, NULL);
1367 cpl_table_get_double(detected_table,
1368 MOO_LINE_TABLE_AMPLITUDE,
1369 detected_idx, NULL);
1371 cpl_table_get_double(detected_table,
1372 MOO_LINE_TABLE_BACKGROUND,
1373 detected_idx, NULL);
1375 cpl_table_get_double(detected_table,
1376 MOO_LINE_TABLE_FIT_FLUX,
1377 detected_idx, NULL);
1379 cpl_table_get_double(detected_table,
1380 MOO_LINE_TABLE_FIT_ERR,
1381 detected_idx, NULL);
1383 cpl_table_get_double(detected_table,
1384 MOO_LINE_TABLE_FIT_CHI2,
1385 detected_idx, NULL);
1387 cpl_table_get_double(detected_table,
1388 MOO_LINE_TABLE_FIT_MSE,
1389 detected_idx, NULL);
1390 double fwhm = cpl_table_get_double(detected_table,
1391 MOO_LINE_TABLE_FWHM,
1392 detected_idx, NULL);
1393 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_INTENSITY,
1394 lline_idx, intensity);
1395 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_XBARY,
1397 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_AMPLITUDE,
1398 lline_idx, amplitude);
1399 cpl_table_set_double(*lline_table,
1400 MOO_LINE_TABLE_BACKGROUND, lline_idx,
1402 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FWHM,
1405 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_FLUX,
1406 lline_idx, fit_flux);
1407 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_ERR,
1408 lline_idx, fit_err);
1409 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_CHI2,
1410 lline_idx, fit_chi2);
1411 cpl_table_set_double(*lline_table, MOO_LINE_TABLE_FIT_MSE,
1412 lline_idx, fit_mse);
1413 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_MATCHED,
1415 cpl_table_set_int(*lline_table, MOO_LINE_TABLE_MFITTED,
1417 cpl_array_delete(detected_indexes);
1421 cpl_msg_error(
"test",
"the line %f is not find in LINE_TABLE",
1426 if (nb_matched <= degpoly) {
1427 cpl_msg_error(
"moo_wavesol",
1428 "#%d-%d Not enough matched lines (%d) to fit "
1429 "polynomial degree %d",
1430 slitlet_idx, numfib, nb_matched, degpoly);
1433 cpl_msg_debug(
"moo_wavesol",
1434 "#%d-%d, %d peaks detected, %d fitted, %d matched / "
1436 slitlet_idx, numfib, nb_detected, nb_fitted,
1437 nb_matched, nb_catalog_lines);
1440 cpl_table_delete(ppm_table);
1441 *ldetected = nb_detected;
1442 *lfitted = nb_fitted;
1443 *lfailed = nb_failed;
1444 *lmatched = nb_matched;
1447 cpl_image_delete(idata);
1448 cpl_image_delete(ierr);
1451 if (!cpl_errorstate_is_equal(prestate)) {
1452 cpl_msg_error(__func__,
"#%d Error in wavesol pattern matching",
1454 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
1456 cpl_errorstate_set(prestate);
1459 return detected_table;
1462static cpl_error_code
1463_moo_wavecal_qc(cpl_propertylist *header,
int nb_sigclip, cpl_table *line_table)
1465 cpl_table *extract_table = NULL;
1466 cpl_array *sel = NULL;
1467 cpl_vector *waveres = NULL;
1468 cpl_ensure_code(header != NULL, CPL_ERROR_NULL_INPUT);
1469 cpl_ensure_code(line_table != NULL, CPL_ERROR_NULL_INPUT);
1473 cpl_table_select_all(line_table);
1474 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED, CPL_EQUAL_TO,
1476 extract_table = cpl_table_extract_selected(line_table);
1478 cpl_table_get_column_median(extract_table, MOO_LINE_TABLE_RESOLUTION);
1479 cpl_table_delete(extract_table);
1480 extract_table = NULL;
1483 cpl_table_select_all(line_table);
1484 if (cpl_table_has_column(line_table, MOO_LINE_TABLE_FILTERED)) {
1485 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_FILTERED,
1488 sel = cpl_table_where_selected(line_table);
1489 int size = cpl_array_get_size(sel);
1490 waveres = cpl_vector_new(size);
1491 for (
int i = 0; i < size; i++) {
1492 int idx = cpl_array_get_cplsize(sel, i, NULL);
1494 cpl_table_get_double(line_table, MOO_LINE_TABLE_WAVE, idx, NULL);
1496 cpl_table_get_double(line_table, MOO_LINE_TABLE_WAVEFIT, idx, NULL);
1497 double res = wave - wavefit;
1498 cpl_vector_set(waveres, i, res);
1500 double residwave_med = cpl_vector_get_median(waveres);
1501 double residwave_std = cpl_vector_get_stdev(waveres);
1505 cpl_table_delete(extract_table);
1506 cpl_vector_delete(waveres);
1507 cpl_array_delete(sel);
1508 return CPL_ERROR_NONE;
1512_moo_wavesol_single(moo_ext_single *ext,
1513 moo_loc_single *loc,
1516 cpl_table *result_table,
1517 cpl_table *catalog_lines,
1523 cpl_propertylist *guess_header,
1527 int linefit_recentre,
1530 moo_spectral_format_info *info,
1534 cpl_propertylist *header,
1535 moo_wavesol_params *params,
1536 cpl_table **single_line_table)
1539 cpl_image *res = NULL;
1540 cpl_table **all_detected = NULL;
1541 cpl_table **all_fitted = NULL;
1542 cpl_ensure(ext != NULL, CPL_ERROR_NULL_INPUT, NULL);
1543 cpl_ensure(loc != NULL, CPL_ERROR_NULL_INPUT, NULL);
1544 cpl_ensure(health != NULL, CPL_ERROR_NULL_INPUT, NULL);
1545 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
1547 const char *model = params->model;
1548 const char *linefit_method = params->linefit_method;
1549 const char *control = params->control;
1550 int niter = params->clip_niter;
1551 double max_frac = params->clip_frac;
1552 double kappa = params->clip_kappa;
1556 cpl_errorstate prestate = cpl_errorstate_get();
1562 int nb_fibres = cpl_image_get_size_y(data);
1563 cpl_size nb_index = cpl_array_get_size(indexes);
1565 cpl_ensure(nb_index == nb_fibres, CPL_ERROR_ILLEGAL_INPUT, NULL);
1567 int nx = cpl_image_get_size_x(data);
1569 res = cpl_image_new(nx, nb_fibres, CPL_TYPE_DOUBLE);
1571 all_detected = cpl_calloc(nb_fibres,
sizeof(cpl_table *));
1572 all_fitted = cpl_calloc(nb_fibres,
sizeof(cpl_table *));
1574 cpl_propertylist_append_double(header, MOO_PFITS_CRPIX1, MOO_MAP_CRPIX1);
1575 cpl_propertylist_append_double(header, MOO_PFITS_CRPIX2, MOO_MAP_CRPIX2);
1576 cpl_propertylist_append_double(header, MOO_PFITS_CRVAL1, MOO_MAP_CRVAL1);
1577 cpl_propertylist_append_double(header, MOO_PFITS_CRVAL2, MOO_MAP_CRVAL2);
1578 cpl_propertylist_append_double(header, MOO_PFITS_CD1_1, MOO_MAP_CD1_1);
1579 cpl_propertylist_append_double(header, MOO_PFITS_CD1_2, 0.);
1580 cpl_propertylist_append_double(header, MOO_PFITS_CD2_1, 0.);
1581 cpl_propertylist_append_double(header, MOO_PFITS_CD2_2, MOO_MAP_CD2_2);
1582 cpl_propertylist_append_string(header, MOO_PFITS_CTYPE1, MOO_MAP_CTYPE1);
1583 cpl_propertylist_append_string(header, MOO_PFITS_CTYPE2, MOO_MAP_CTYPE2);
1584 cpl_propertylist_append_string(header, MOO_PFITS_BUNIT, MOO_MAP_BUNIT);
1585 int catline = cpl_table_get_nrow(catalog_lines);
1586 const char *extname = ext->extname;
1594 const int *slitlet =
1595 cpl_table_get_data_int_const(result_table, MOO_FIBRES_TABLE_SLITLET);
1596 moo_try_assure(slitlet != NULL, CPL_ERROR_NULL_INPUT,
1597 "No slitlet column in fibre table");
1599 const int *indexext =
1600 cpl_table_get_data_int_const(result_table, MOO_FIBRES_TABLE_INDEXEXT);
1601 if (guess != NULL) {
1602 cpl_msg_info(
"moo_wavesol",
"Fit centroid lines using method %s",
1605#pragma omp parallel default(none) \
1606 shared(nb_fibres, indexes, health, result_table, type, all_detected, \
1607 all_fitted, extname, data, errs, guess, catalog_lines, \
1608 winhsize, degx, sigma_min, sigma_max, linefit_method, \
1609 line_table, indexext, slitlet) firstprivate(spectro) \
1610 reduction(+ : detectline, failedfit, fitline, validfibre)
1614 for (
int i = 1; i <= nb_fibres; i++) {
1616 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
1617 int indexext_idx = indexext[idx];
1618 int slitlet_idx = slitlet[idx];
1619 int h = health[idx];
1624 all_detected[i - 1] = _moo_wavesol_fibre_using_guess(
1625 data, errs, guess, NULL, i, catalog_lines, winhsize,
1626 sigma_min, sigma_max, slitlet_idx, indexext_idx,
1627 extname, spectro, &all_fitted[i - 1], &ldetected,
1628 &lfailed, &lfitted);
1637 detectline += ldetected;
1638 failedfit += lfailed;
1643 all_detected[i - 1] = NULL;
1644 all_fitted[i - 1] = NULL;
1650 matchline = fitline;
1654#pragma omp parallel default(none) \
1655 shared(nb_fibres, indexes, health, result_table, type, all_detected, \
1656 all_fitted, extname, data, errs, catalog_lines, min_disp, \
1657 max_disp, tolerance, direction, nb_peaks_lines, winhsize, ext, \
1658 degx, sigma_min, sigma_max, ref_snr, indexext, slitlet) \
1659 firstprivate(spectro) \
1660 reduction(+ : detectline, failedfit, fitline, matchline, validfibre)
1664 for (
int i = 1; i <= nb_fibres; i++) {
1665 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
1666 int h = health[idx];
1671 int indexext_idx = indexext[idx];
1673 int slitlet_idx = slitlet[idx];
1675 all_detected[i - 1] =
1676 _moo_wavesol_fibre(data, errs, i, nb_peaks_lines,
1677 winhsize, sigma_min, sigma_max,
1678 ref_snr, catalog_lines, min_disp,
1679 max_disp, tolerance, direction,
1680 ext->extname, degx, slitlet_idx,
1681 indexext_idx, extname, spectro,
1682 &all_fitted[i - 1], &ldetected,
1683 &lfailed, &lfitted, &lmatched);
1685 detectline += ldetected;
1686 failedfit += lfailed;
1688 matchline += lmatched;
1692 cpl_msg_info(
"moo_wavesol",
1693 "Broken fibre indexext %d, slitlet %d",
1694 indexext_idx, slitlet_idx);
1696 all_detected[i - 1] = NULL;
1715#if MOO_DEBUG_WAVESOL_DETECTED
1717 cpl_table *test = moo_detected_table_new(0, guess == NULL);
1718 for (
int i = 0; i < nb_fibres; i++) {
1719 cpl_table *t = all_detected[i];
1721 moo_table_append(test, t);
1726 if (guess == NULL) {
1727 name = cpl_sprintf(
"%s_ppm_detected.fits", ext->extname);
1730 name = cpl_sprintf(
"%s_refit_lfwhs%d_detected.fits", ext->extname,
1734 cpl_table_save(test, NULL, NULL, name, CPL_IO_CREATE);
1736 cpl_table_delete(test);
1739 for (
int i = 0; i < nb_fibres; i++) {
1740 cpl_table *t = all_fitted[i];
1743 moo_table_append(line_table, t);
1755 cpl_table_erase_invalid(line_table);
1756 int nb_line_table = cpl_table_get_nrow(line_table);
1757 cpl_msg_info(__func__,
"line table size : %d fitline %d matchline %d",
1758 nb_line_table, fitline, matchline);
1759 const char *line_table_xfit = MOO_LINE_TABLE_XGAUSS;
1760 if (guess != NULL &&
1761 (strcmp(linefit_method, MOO_WAVESOL_LINEFIT_BARYCENTER) == 0)) {
1762 line_table_xfit = MOO_LINE_TABLE_XBARY;
1765 for (
int i = 0; i < nb_line_table; i++) {
1768 double x = cpl_table_get_double(line_table, line_table_xfit, i, NULL);
1771 cpl_table_get_int(line_table, MOO_LINE_TABLE_INDEXEXT, i, NULL);
1777 cpl_table_set_double(line_table, MOO_LINE_TABLE_YLOC, i, yc);
1781 cpl_table_get_double(line_table, MOO_LINE_TABLE_WAVE, i, NULL);
1783 cpl_table_unselect_all(catalog_lines);
1784 cpl_table_or_selected_double(catalog_lines, MOO_LINE_TABLE_WAVE,
1785 CPL_GREATER_THAN, nm - 1E-5);
1787 cpl_table_and_selected_double(catalog_lines, MOO_LINE_TABLE_WAVE,
1788 CPL_LESS_THAN, nm + 1E-5);
1791 cpl_array *cat_indexes = cpl_table_where_selected(catalog_lines);
1792 cpl_size cat_idx = cpl_array_get_cplsize(cat_indexes, 0, NULL);
1793 cpl_array_delete(cat_indexes);
1795 cpl_table_get_double(catalog_lines, MOO_LINE_TABLE_FLUX,
1797 const char *cat_name =
1798 cpl_table_get_string(catalog_lines, MOO_LINE_TABLE_NAME,
1800 cpl_table_set_string(line_table, MOO_LINE_TABLE_NAME, i, cat_name);
1801 cpl_table_set_double(line_table, MOO_LINE_TABLE_FLUX, i, cat_flux);
1805#if MOO_DEBUG_WAVESOL_DETECTED
1808 if (guess == NULL) {
1809 name = cpl_sprintf(
"%s_ppm_lines.fits", ext->extname);
1812 name = cpl_sprintf(
"%s_refit_lfwhs%d_lines.fits", ext->extname,
1815 cpl_table_save(line_table, NULL, NULL, name, CPL_IO_CREATE);
1819 if (cpl_table_has_column(line_table, MOO_LINE_TABLE_DISP)) {
1821 cpl_table_get_column_min(line_table, MOO_LINE_TABLE_DISP);
1823 cpl_table_get_column_max(line_table, MOO_LINE_TABLE_DISP);
1827 else if (guess_header != NULL) {
1828 cpl_propertylist_copy_property(header, guess_header,
1829 MOONS_QC_WAVECAL_DISP_MIN);
1830 cpl_propertylist_copy_property(header, guess_header,
1831 MOONS_QC_WAVECAL_DISP_MAX);
1834 if (guess != NULL && linefit_recentre) {
1835 cpl_msg_info(
"moo_wavesol",
"RECENTRE : compute slitlet shift with %d",
1839 cpl_table *slitlet_table_global = moo_slitlet_shift_table_new(0);
1841 while (i <= nb_fibres) {
1842 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
1844 if (slit_idx != slitlet[idx]) {
1845 cpl_table *slitlet_table = moo_slitlet_shift_table_new(catline);
1846 slit_idx = slitlet[idx];
1848 for (
int j = 0; j < catline; j++) {
1850 cpl_table_get_double(catalog_lines,
1851 MOO_ARCLINE_LIST_WAVE, j, NULL);
1852 cpl_table_set_int(slitlet_table,
1853 MOO_SLITLET_SHIFT_TABLE_SLITLET, j,
1855 cpl_table_set_double(slitlet_table,
1856 MOO_SLITLET_SHIFT_TABLE_WAVE, j, w);
1857 cpl_table_select_all(line_table);
1858 cpl_table_and_selected_int(line_table,
1859 MOO_LINE_TABLE_SLITLET,
1860 CPL_EQUAL_TO, slit_idx);
1861 cpl_table_and_selected_int(line_table,
1862 MOO_LINE_TABLE_FILTERED,
1865 cpl_table_and_selected_double(line_table,
1866 MOO_LINE_TABLE_WAVE,
1868 double median = NAN;
1870 cpl_table *sel = cpl_table_extract_selected(line_table);
1872 cpl_table_get_column_median(sel,
1873 MOO_LINE_TABLE_XDIFF);
1874 cpl_table_delete(sel);
1876 cpl_table_set_double(slitlet_table,
1877 MOO_SLITLET_SHIFT_TABLE_XDIFF, j,
1880 moo_table_append(slitlet_table_global, slitlet_table);
1881 cpl_table_delete(slitlet_table);
1887 cpl_table_get_column_min(slitlet_table_global,
1888 MOO_SLITLET_SHIFT_TABLE_SLITLET);
1890 cpl_table_get_column_max(slitlet_table_global,
1891 MOO_SLITLET_SHIFT_TABLE_SLITLET);
1892 double central_slitlet = (min_slitlet + max_slitlet) / 2.;
1893 int lo_central_slitlet = floor(central_slitlet) - 1;
1894 int up_central_slitlet = ceil(central_slitlet) + 1;
1896 cpl_vector *vx = cpl_vector_new(catline);
1897 cpl_vector *vy = cpl_vector_new(catline);
1900 for (
int j = 0; j < catline; j++) {
1901 double w = cpl_table_get_double(catalog_lines,
1902 MOO_ARCLINE_LIST_WAVE, j, NULL);
1903 cpl_table_select_all(line_table);
1904 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_SLITLET,
1905 CPL_GREATER_THAN, lo_central_slitlet);
1906 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_SLITLET,
1907 CPL_LESS_THAN, up_central_slitlet);
1908 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_FILTERED,
1911 cpl_table_and_selected_double(line_table, MOO_LINE_TABLE_WAVE,
1914 cpl_table *sel = cpl_table_extract_selected(line_table);
1916 cpl_table_get_column_median(sel, MOO_LINE_TABLE_XDIFF);
1917 cpl_table_delete(sel);
1918 cpl_vector_set(vx, vsize, w);
1919 cpl_vector_set(vy, vsize, median);
1923 cpl_vector_set_size(vx, vsize);
1924 cpl_vector_set_size(vy, vsize);
1925 double wmin = cpl_vector_get(vx, 0);
1926 double wmin_xdiff = cpl_vector_get(vy, 0);
1927 double wmax = cpl_vector_get(vx, vsize - 1);
1928 double wmax_xdiff = cpl_vector_get(vy, vsize - 1);
1929 cpl_bivector *fref = cpl_bivector_wrap_vectors(vx, vy);
1930 cpl_bivector *fout = cpl_bivector_new(1);
1931 for (
int j = 0; j < catline; j++) {
1932 double w = cpl_table_get_double(catalog_lines,
1933 MOO_ARCLINE_LIST_WAVE, j, NULL);
1936 median = wmin_xdiff;
1938 else if (w > wmax) {
1939 median = wmax_xdiff;
1942 cpl_vector *fout_x = cpl_bivector_get_x(fout);
1943 cpl_vector_set(fout_x, 0, w);
1944 cpl_vector *fout_y = cpl_bivector_get_y(fout);
1945 cpl_bivector_interpolate_linear(fout, fref);
1946 median = cpl_vector_get(fout_y, 0);
1948 cpl_table_select_all(slitlet_table_global);
1949 cpl_table_and_selected_int(slitlet_table_global,
1950 MOO_SLITLET_SHIFT_TABLE_SLITLET,
1951 CPL_EQUAL_TO, lo_central_slitlet + 1);
1952 cpl_table_and_selected_double(slitlet_table_global,
1953 MOO_LINE_TABLE_WAVE, CPL_EQUAL_TO, w);
1954 cpl_array *sel = cpl_table_where_selected(slitlet_table_global);
1955 int idx = cpl_array_get_cplsize(sel, 0, NULL);
1956 cpl_array_delete(sel);
1957 cpl_table_set_double(slitlet_table_global,
1958 MOO_SLITLET_SHIFT_TABLE_XDIFF, idx, median);
1960 cpl_table_select_all(slitlet_table_global);
1961 cpl_table_and_selected_int(slitlet_table_global,
1962 MOO_SLITLET_SHIFT_TABLE_SLITLET,
1963 CPL_EQUAL_TO, up_central_slitlet - 1);
1964 cpl_table_and_selected_double(slitlet_table_global,
1965 MOO_LINE_TABLE_WAVE, CPL_EQUAL_TO, w);
1966 sel = cpl_table_where_selected(slitlet_table_global);
1967 idx = cpl_array_get_cplsize(sel, 0, NULL);
1968 cpl_array_delete(sel);
1969 cpl_table_set_double(slitlet_table_global,
1970 MOO_SLITLET_SHIFT_TABLE_XDIFF, idx, median);
1972 cpl_bivector_delete(fout);
1973 cpl_bivector_unwrap_vectors(fref);
1974 cpl_vector_delete(vx);
1975 cpl_vector_delete(vy);
1976#if MOO_DEBUG_WAVESOL_DETECTED
1978 char *name = cpl_sprintf(
"%s_refit%d_slitlet.fits", ext->extname,
1980 cpl_table_save(slitlet_table_global, NULL, NULL, name,
1986 cpl_table *detected_global_step2 =
1987 moo_detected_table_new(0, guess == NULL);
1990 for (
int s = lo_central_slitlet + 1; s >= min_slitlet; s--) {
1991 cpl_table_select_all(result_table);
1992 int nb = cpl_table_and_selected_int(result_table,
1993 MOO_FIBRES_TABLE_SLITLET,
1995 nb = cpl_table_and_selected_int(result_table,
1996 MOO_FIBRES_TABLE_HEALTH,
1997 CPL_NOT_EQUAL_TO, 0);
1998 nb = cpl_table_and_selected_int(result_table,
1999 MOO_FIBRES_TABLE_SPECTRO,
2000 CPL_EQUAL_TO, spectro);
2001 cpl_msg_info(
"moo_wavesol",
"do slitlet %d : MOONS%d %d", s,
2003 cpl_array *slitlet_sel = cpl_table_where_selected(result_table);
2004 for (
int isel = 0; isel < nb; isel++) {
2005 int idx = cpl_array_get_cplsize(slitlet_sel, isel, NULL);
2007 cpl_table_get_int(result_table, MOO_FIBRES_TABLE_INDEXEXT,
2010 cpl_table_get_int(result_table, MOO_FIBRES_TABLE_SLITLET,
2016 cpl_table *tfitted = NULL;
2017 cpl_table *tdetected = _moo_wavesol_fibre_using_guess(
2018 data, errs, guess, slitlet_table_global, indexext_idx,
2019 catalog_lines, winhsize, sigma_min, sigma_max, slitlet_idx,
2020 indexext_idx, extname, spectro, &tfitted, &ldetected,
2021 &lfailed, &lfitted);
2022 moo_table_append(detected_global_step2, tdetected);
2023 moo_table_append(lines_global_step2, tfitted);
2024 cpl_table_delete(tdetected);
2025 cpl_table_delete(tfitted);
2036 cpl_array_delete(slitlet_sel);
2038 for (
int j = 0; j < catline; j++) {
2039 double w = cpl_table_get_double(catalog_lines,
2040 MOO_ARCLINE_LIST_WAVE, j, NULL);
2041 cpl_table_select_all(lines_global_step2);
2042 int nblines = cpl_table_and_selected_int(lines_global_step2,
2043 MOO_LINE_TABLE_SLITLET,
2046 nblines = cpl_table_and_selected_int(lines_global_step2,
2047 MOO_LINE_TABLE_FILTERED,
2049 nblines = cpl_table_and_selected_double(lines_global_step2,
2050 MOO_LINE_TABLE_WAVE,
2052 double median = NAN;
2055 cpl_table_extract_selected(lines_global_step2);
2057 cpl_table_get_column_median(sel, MOO_LINE_TABLE_XDIFF);
2058 cpl_table_delete(sel);
2060 cpl_table_select_all(slitlet_table_global);
2061 cpl_table_and_selected_int(slitlet_table_global,
2062 MOO_SLITLET_SHIFT_TABLE_SLITLET,
2064 cpl_table_and_selected_double(slitlet_table_global,
2065 MOO_LINE_TABLE_WAVE, CPL_EQUAL_TO,
2067 cpl_array *sel = cpl_table_where_selected(slitlet_table_global);
2068 int idx = cpl_array_get_cplsize(sel, 0, NULL);
2069 cpl_array_delete(sel);
2070 cpl_table_set_double(slitlet_table_global,
2071 MOO_SLITLET_SHIFT_TABLE_XDIFF, idx,
2075 for (
int s = up_central_slitlet - 1; s <= max_slitlet; s++) {
2076 cpl_table_select_all(result_table);
2077 int nb = cpl_table_and_selected_int(result_table,
2078 MOO_FIBRES_TABLE_SLITLET,
2080 nb = cpl_table_and_selected_int(result_table,
2081 MOO_FIBRES_TABLE_HEALTH,
2082 CPL_NOT_EQUAL_TO, 0);
2083 nb = cpl_table_and_selected_int(result_table,
2084 MOO_FIBRES_TABLE_SPECTRO,
2085 CPL_EQUAL_TO, spectro);
2086 cpl_array *slitlet_sel = cpl_table_where_selected(result_table);
2087 cpl_msg_info(
"moo_wavesol",
"do slitlet %d : MOONS%d %d", s,
2089 for (
int isel = 0; isel < nb; isel++) {
2090 int idx = cpl_array_get_cplsize(slitlet_sel, isel, NULL);
2092 cpl_table_get_int(result_table, MOO_FIBRES_TABLE_INDEXEXT,
2095 cpl_table_get_int(result_table, MOO_FIBRES_TABLE_SLITLET,
2101 cpl_table *tfitted = NULL;
2102 cpl_table *tdetected = _moo_wavesol_fibre_using_guess(
2103 data, errs, guess, slitlet_table_global, indexext_idx,
2104 catalog_lines, winhsize, sigma_min, sigma_max, slitlet_idx,
2105 indexext_idx, extname, spectro, &tfitted, &ldetected,
2106 &lfailed, &lfitted);
2107 moo_table_append(detected_global_step2, tdetected);
2108 moo_table_append(lines_global_step2, tfitted);
2109 cpl_table_delete(tdetected);
2110 cpl_table_delete(tfitted);
2121 cpl_array_delete(slitlet_sel);
2122 for (
int j = 0; j < catline; j++) {
2123 double w = cpl_table_get_double(catalog_lines,
2124 MOO_ARCLINE_LIST_WAVE, j, NULL);
2125 cpl_table_select_all(lines_global_step2);
2126 cpl_table_and_selected_int(lines_global_step2,
2127 MOO_LINE_TABLE_SLITLET, CPL_EQUAL_TO,
2129 cpl_table_and_selected_int(lines_global_step2,
2130 MOO_LINE_TABLE_FILTERED,
2132 int nblines = cpl_table_and_selected_double(lines_global_step2,
2133 MOO_LINE_TABLE_WAVE,
2135 double median = NAN;
2138 cpl_table_extract_selected(lines_global_step2);
2140 cpl_table_get_column_median(sel, MOO_LINE_TABLE_XDIFF);
2141 cpl_table_delete(sel);
2143 cpl_table_select_all(slitlet_table_global);
2144 cpl_table_and_selected_int(slitlet_table_global,
2145 MOO_SLITLET_SHIFT_TABLE_SLITLET,
2147 cpl_table_and_selected_double(slitlet_table_global,
2148 MOO_LINE_TABLE_WAVE, CPL_EQUAL_TO,
2150 cpl_array *sel = cpl_table_where_selected(slitlet_table_global);
2151 int idx = cpl_array_get_cplsize(sel, 0, NULL);
2152 cpl_array_delete(sel);
2153 cpl_table_set_double(slitlet_table_global,
2154 MOO_SLITLET_SHIFT_TABLE_XDIFF, idx,
2158#if MOO_DEBUG_WAVESOL_DETECTED
2160 char *name = cpl_sprintf(
"%s_slitlet_step2.fits", ext->extname);
2161 cpl_table_save(slitlet_table_global, NULL, NULL, name,
2166 char *name = cpl_sprintf(
"%s_refit%d_slitlet_step2.fits",
2167 ext->extname, params->isrefit);
2168 cpl_table_save(detected_global_step2, NULL, NULL, name,
2173 char *name = cpl_sprintf(
"%s_lines_step2.fits", ext->extname);
2174 cpl_table_save(lines_global_step2, NULL, NULL, name, CPL_IO_CREATE);
2178 cpl_table_delete(line_table);
2179 line_table = lines_global_step2;
2180 nb_line_table = cpl_table_get_nrow(line_table);
2182 for (i = 0; i < nb_line_table; i++) {
2185 cpl_table_get_double(line_table, line_table_xfit, i, NULL);
2187 cpl_table_get_int(line_table, MOO_LINE_TABLE_INDEXEXT, i, NULL);
2191 cpl_table_set_double(line_table, MOO_LINE_TABLE_YLOC, i, yc);
2194 cpl_table_get_double(line_table, MOO_LINE_TABLE_WAVE, i, NULL);
2195 cpl_table_unselect_all(catalog_lines);
2196 cpl_table_or_selected_double(catalog_lines, MOO_LINE_TABLE_WAVE,
2197 CPL_GREATER_THAN, nm - 1E-5);
2199 cpl_table_and_selected_double(catalog_lines,
2200 MOO_LINE_TABLE_WAVE,
2201 CPL_LESS_THAN, nm + 1E-5);
2204 cpl_array *cat_indexes =
2205 cpl_table_where_selected(catalog_lines);
2206 cpl_size cat_idx = cpl_array_get_cplsize(cat_indexes, 0, NULL);
2207 cpl_array_delete(cat_indexes);
2209 cpl_table_get_double(catalog_lines, MOO_LINE_TABLE_FLUX,
2211 const char *cat_name =
2212 cpl_table_get_string(catalog_lines, MOO_LINE_TABLE_NAME,
2214 cpl_table_set_string(line_table, MOO_LINE_TABLE_NAME, i,
2216 cpl_table_set_double(line_table, MOO_LINE_TABLE_FLUX, i,
2220 cpl_table_delete(slitlet_table_global);
2221 cpl_table_delete(detected_global_step2);
2223 for (
int f = 1; f <= nb_fibres; f++) {
2224 int idx = cpl_array_get_cplsize(indexes, f - 1, NULL);
2225 int h = health[idx];
2226 int indexext_idx = indexext[idx];
2228 cpl_table_select_all(line_table);
2229 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_INDEXEXT,
2230 CPL_EQUAL_TO, indexext_idx);
2232 cpl_table_and_selected_int(line_table,
2233 MOO_LINE_TABLE_FILTERED,
2236 cpl_table *sel = cpl_table_extract_selected(line_table);
2238 cpl_table_get_column_median(sel, MOO_LINE_TABLE_XDIFF);
2239 cpl_table_delete(sel);
2246 if ((strcmp(control, MOO_WAVESOL_CONTROL_CHECK) == 0) ||
2247 (strcmp(control, MOO_WAVESOL_CONTROL_UPDATE) == 0)) {
2249 if (!cpl_table_has_column(all_guess_line_table, MOO_LINE_TABLE_XDIFF)) {
2250 cpl_table_new_column(all_guess_line_table, MOO_LINE_TABLE_XDIFF,
2253 if (!cpl_table_has_column(all_guess_line_table,
2254 MOO_LINE_TABLE_WAVEDIFF)) {
2255 cpl_table_new_column(all_guess_line_table, MOO_LINE_TABLE_WAVEDIFF,
2258 cpl_table_select_all(all_guess_line_table);
2259 cpl_table_and_selected_string(all_guess_line_table,
2260 MOO_LINE_TABLE_DETECTOR, CPL_EQUAL_TO,
2263 cpl_table *guess_line_table =
2264 cpl_table_extract_selected(all_guess_line_table);
2265 for (
int i = 1; i <= nb_fibres; i++) {
2266 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
2267 int h = health[idx];
2268 int indexext_idx = indexext[idx];
2273 cpl_table_select_all(guess_line_table);
2274 cpl_table_and_selected_int(guess_line_table,
2275 MOO_LINE_TABLE_INDEXEXT,
2276 CPL_EQUAL_TO, indexext_idx);
2278 cpl_table_and_selected_int(guess_line_table,
2279 MOO_LINE_TABLE_FILTERED,
2282 cpl_array *sel = cpl_table_where_selected(guess_line_table);
2283 for (
int j = 0; j < nb; j++) {
2284 int sel_idx = cpl_array_get_cplsize(sel, j, NULL);
2286 cpl_table_get_double(guess_line_table,
2287 MOO_LINE_TABLE_XGAUSS, sel_idx,
2289 cpl_table_set_double(guess_line_table,
2290 MOO_LINE_TABLE_XGAUSS, sel_idx,
2293 cpl_array_delete(sel);
2297 moo_table_append(line_table, guess_line_table);
2298 cpl_table_select_all(line_table);
2299 cpl_size nb = cpl_table_and_selected_int(guess_line_table,
2300 MOO_LINE_TABLE_FILTERED,
2303 cpl_array *sel = cpl_table_where_selected(line_table);
2304 for (
int j = 0; j < nb; j++) {
2305 int sel_idx = cpl_array_get_cplsize(sel, j, NULL);
2306 cpl_table_set_int(line_table, MOO_LINE_TABLE_MFITTED, sel_idx,
2309 cpl_array_delete(sel);
2311 cpl_table_delete(guess_line_table);
2314 const char *line_table_gfit = MOO_LINE_TABLE_MATCHED;
2315 if (guess != NULL) {
2316 line_table_gfit = MOO_LINE_TABLE_GFITTED;
2319 if (strcmp(model, MOO_WAVESOL_MODEL_1D) == 0) {
2320 cpl_msg_info(
"moo_wavesol",
"Do Polynomial %s fit with degree %d",
2322 for (
int i = 1; i <= nb_fibres; i++) {
2323 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
2324 int h = health[idx];
2326 _moo_wavesol_fit1d(loc, degx, i, res, niter, max_frac, kappa,
2327 &nb_sigclip, result_table, idx, ext->type,
2328 line_table, line_table_xfit);
2331 for (
int x = 1; x <= nx; x++) {
2332 cpl_image_set(res, x, i, NAN);
2338 cpl_msg_info(
"moo_wavesol",
2339 "Do Polynomial %s fit with X degree %d and Y degree %d",
2343 moo_tcheby2d_polynomial *sol = NULL;
2344 while (i <= nb_fibres) {
2345 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
2346 int h = health[idx];
2348 if (slit_idx != slitlet[idx]) {
2349 moo_tcheby2d_polynomial_delete(sol);
2350 slit_idx = slitlet[idx];
2351 cpl_msg_debug(
"moo_wavesol",
"Do slitlet %d :", slit_idx);
2352 cpl_errorstate prestate_fit2d = cpl_errorstate_get();
2353 sol = _moo_wavesol_fit2d(loc, res, info, degx, degy, niter,
2354 max_frac, kappa, &nb_sigclip,
2355 slit_idx, line_table,
2356 line_table_xfit, line_table_gfit);
2357 if (!cpl_errorstate_is_equal(prestate_fit2d)) {
2358 moo_tcheby2d_polynomial_delete(sol);
2360 cpl_errorstate_dump(prestate_fit2d, CPL_FALSE,
2361 cpl_errorstate_dump_one);
2362 cpl_errorstate_set(prestate_fit2d);
2367 for (
int x = 1; x <= nx; x++) {
2371 cpl_image_get(ycentroids, x, indexext[idx], &rej);
2374 cpl_image_set(res, x, i, NAN);
2379 v = moo_tcheby2d_polynomial_eval(sol, x, y);
2381 cpl_image_set(res, x, i, v);
2386 for (
int x = 1; x <= nx; x++) {
2387 cpl_image_set(res, x, i, NAN);
2392 moo_tcheby2d_polynomial_delete(sol);
2394 for (i = 1; i < nb_fibres; i++) {
2395 cpl_table_select_all(line_table);
2396 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_MFITTED,
2399 cpl_table_and_selected_int(line_table, MOO_LINE_TABLE_INDEXEXT,
2401 int idx = cpl_array_get_cplsize(indexes, i - 1, NULL);
2406 _moo_wavecal_qc(header, nb_sigclip, line_table);
2408 *single_line_table = line_table;
2411 if (all_detected != NULL) {
2412 for (
int i = 0; i < nb_fibres; i++) {
2413 cpl_table_delete(all_detected[i]);
2415 cpl_free(all_detected);
2417 if (all_fitted != NULL) {
2418 for (
int i = 0; i < nb_fibres; i++) {
2419 cpl_table_delete(all_fitted[i]);
2421 cpl_free(all_fitted);
2423 if (!cpl_errorstate_is_equal(prestate)) {
2424 cpl_image_delete(res);
2426 cpl_msg_error(__func__,
"Error in wavesol for file %s", ext->filename);
2427 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
2429 cpl_errorstate_set(prestate);
2435_arclines_get_caliblines(cpl_table *table,
2440 cpl_table *result = NULL;
2443 cpl_errorstate prestate = cpl_errorstate_get();
2445 cpl_ensure(table != NULL, CPL_ERROR_NULL_INPUT, NULL);
2448 const char *wavecaltype = MOO_ARCLINE_LIST_USEFINAL;
2450 wavecaltype = MOO_ARCLINE_LIST_USEGUESS;
2453 wavecaltype = MOO_ARCLINE_LIST_USEGUESS_REFIT;
2456 cpl_table_select_all(table);
2457 moo_try_check(size = cpl_table_and_selected_string(table,
2458 MOO_ARCLINE_LIST_BAND,
2459 CPL_EQUAL_TO,
typename),
2461 moo_try_check(size = cpl_table_and_selected_int(table, wavecaltype,
2466 cpl_msg_warning(__func__,
"ARC_LINE_LIST %s no arclines found",
2470 result = cpl_table_extract_selected(table);
2473 if (!cpl_errorstate_is_equal(prestate)) {
2474 cpl_table_delete(result);
2504_moo_wavesol_refit(moo_ext *arc_ext,
2505 const char *lineCatname,
2507 moo_spectral_format *sformat,
2510 moo_wavesol_params *params)
2512 moo_map *result = NULL;
2513 cpl_array *indexes = NULL;
2514 int *wavemap_degx = NULL;
2515 int wavemap_degy = 0;
2516 int *line_winhsize = NULL;
2517 cpl_image *guess_tab[6];
2518 cpl_propertylist *guess_headers[6];
2520 cpl_errorstate prestate = cpl_errorstate_get();
2521 cpl_ensure(arc_ext != NULL, CPL_ERROR_NULL_INPUT, NULL);
2522 cpl_ensure(lineCatname != NULL, CPL_ERROR_NULL_INPUT, NULL);
2523 cpl_ensure(sformat != NULL, CPL_ERROR_NULL_INPUT, NULL);
2524 cpl_ensure(loc != NULL, CPL_ERROR_NULL_INPUT, NULL);
2525 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
2527 unsigned int badpix_level =
2531 cpl_ensure(fibres_table != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
2534 result->primary_header = cpl_propertylist_new();
2535 moo_try_check(cpl_propertylist_append_string(result->primary_header,
2536 MOO_PFITS_PRO_WAVESOL_MODEL,
2539 char *degx_tag = NULL;
2540 degx_tag = cpl_sprintf(
"%d,%d,%d", params->wavemap_degx[0],
2541 params->wavemap_degx[1], params->wavemap_degx[2]);
2542 moo_try_check(cpl_propertylist_append_string(result->primary_header,
2543 MOO_PFITS_PRO_WAVESOL_DEGX,
2547 if (strcmp(params->model, MOO_WAVESOL_MODEL_2D) == 0) {
2548 moo_try_check(cpl_propertylist_append_int(result->primary_header,
2549 MOO_PFITS_PRO_WAVESOL_DEGY,
2550 params->wavemap_degy),
2553 cpl_table *result_table = cpl_table_duplicate(fibres_table);
2555 moo_map_set_fibre_table(result, result_table);
2557 int isGuess = (wmap == NULL);
2559 moo_map_set_line_table(result, global_line_table);
2562 if (params->isrefit) {
2564 wavemap_degx = params->wavemap_degx;
2565 wavemap_degy = params->wavemap_degy;
2566 line_winhsize = params->linefit_winhsize;
2567 cpl_errorstate stateA = cpl_errorstate_get();
2568 const char *guess_model =
2570 cpl_errorstate_set(stateA);
2575 if (guess_model != NULL) {
2579 if (strcmp(guess_model, MOO_WAVESOL_MODEL_2D) == 0) {
2581 tag = cpl_sprintf(
"%s_x%s_y%d", guess_model, degx, degy);
2584 tag = cpl_sprintf(
"%s_x%s", guess_model, degx);
2586 cpl_msg_info(__func__,
"Compute wave solution using %s guess", tag);
2587 cpl_propertylist_append_string(result->primary_header,
2588 MOO_PFITS_PRO_WAVEMAP_GUESS, tag);
2592 for (
int i = 0; i < 6; i++) {
2593 guess_tab[i] = wmap->data[i];
2594 guess_headers[i] = wmap->data_header[i];
2599 wavemap_degx = params->ppm_wavemap_degx;
2600 wavemap_degy = params->ppm_wavemap_degy;
2601 line_winhsize = params->linedetect_winhsize;
2604 cpl_msg_info(__func__,
"Compute first wave solution");
2605 for (
int i = 0; i < 6; i++) {
2606 guess_tab[i] = NULL;
2607 guess_headers[i] = NULL;
2611 cpl_msg_indent_more();
2613 for (
int i = 1; i <= 2; i++) {
2614 cpl_table_unselect_all(result_table);
2617 cpl_table_get_data_int_const(result_table, MOO_FIBRES_TABLE_HEALTH);
2619 if (health != NULL) {
2620 for (
int j = 0; j < 3; j++) {
2621 int idx = (i - 1) * 3 + j;
2622 double tolerance = params->tolerance[idx];
2623 int winhsize = line_winhsize[idx];
2624 int degx = wavemap_degx[idx];
2625 int linefit_recentre = params->linefit_recentre[idx];
2627 int linedetect_nlines = params->linedetect_nlines[idx];
2628 double sigma_min = params->fwhm_min[idx] * CPL_MATH_SIG_FWHM;
2629 double sigma_max = params->fwhm_max[idx] * CPL_MATH_SIG_FWHM;
2630 double min_snr = params->min_snr[idx];
2631 cpl_image *guess = guess_tab[(i - 1) * 3 + j];
2632 cpl_propertylist *guess_header = guess_headers[(i - 1) * 3 + j];
2634 moo_ext_single *ext_single =
2637 cpl_image *wave_single = NULL;
2639 if (ext_single != NULL && loc_single != NULL) {
2640 cpl_table *sellines = NULL;
2641 cpl_propertylist *header = NULL;
2644 "Compute wave solution for extension %s, winhsize:%d "
2645 "fwhm:[%f,%f] min_snr:%f recentre:%d",
2647 params->fwhm_min[idx], params->fwhm_max[idx], min_snr,
2649 moo_try_check(sellines =
2650 _arclines_get_caliblines(lines, j,
2653 "Error for Line table %s", lineCatname);
2654 if (sellines != NULL) {
2655 moo_spectral_format_info *info =
2657 header = cpl_propertylist_new();
2658 cpl_table *line_table = NULL;
2661 _moo_wavesol_single(ext_single, loc_single, indexes,
2662 health, result_table, sellines,
2663 info->dispmin, info->dispmax,
2664 tolerance, info->direction,
2665 guess, guess_header, wmap,
2666 linedetect_nlines, winhsize,
2667 linefit_recentre, degx,
2668 wavemap_degy, info, sigma_min,
2669 sigma_max, min_snr, header,
2670 params, &line_table);
2671 moo_table_append(result->line_table, line_table);
2672 cpl_table_delete(line_table);
2674 cpl_table_delete(sellines);
2676 else if (guess != NULL) {
2677 header = cpl_propertylist_new();
2678 wave_single = cpl_image_cast(guess, CPL_TYPE_DOUBLE);
2685 cpl_array_delete(indexes);
2689 cpl_msg_indent_less();
2692 if (!cpl_errorstate_is_equal(prestate)) {
2694 cpl_array_delete(indexes);
2696 cpl_msg_error(__func__,
"Error in wavesolution for EXT %s LOC %s",
2697 arc_ext->filename, loc->filename);
2698 cpl_errorstate_dump(prestate, CPL_FALSE, cpl_errorstate_dump_one);
2700 cpl_errorstate_set(prestate);
2729 const char *lineCatname,
2730 moo_spectral_format *sformat,
2733 moo_wavesol_params *params)
2735 moo_map *result = NULL;
2736 cpl_table *lines = NULL;
2739 cpl_ensure(lineCatname != NULL, CPL_ERROR_NULL_INPUT, NULL);
2740 cpl_ensure(sformat != NULL, CPL_ERROR_NULL_INPUT, NULL);
2741 cpl_ensure(params != NULL, CPL_ERROR_NULL_INPUT, NULL);
2743 if (sformat->mode == MOO_MODE_LR) {
2744 lines = cpl_table_load(lineCatname, 1, 0);
2747 lines = cpl_table_load(lineCatname, 2, 0);
2752 if (params->isrefit > 0) {
2754 const char *refit_colname = MOO_ARCLINE_LIST_USEGUESS;
2756 if (params->isrefit == 1) {
2757 refit_colname = MOO_ARCLINE_LIST_USEGUESS_REFIT;
2759 if (cpl_table_has_column(lines, refit_colname)) {
2760 cpl_table_select_all(lines);
2762 cpl_table_and_selected_int(lines,
2763 MOO_ARCLINE_LIST_USEGUESS_REFIT,
2766 cpl_msg_info(
"moo_wavesol",
"Try doing a refit using %s",
2775 result = _moo_wavesol_refit(arc_ext, lineCatname, lines, sformat, loc,
2781 cpl_table_delete(lines);
#define MOO_BADPIX_OUTSIDE_DATA_RANGE
#define MOO_BADPIX_COSMETIC
const char * moo_detector_get_name(moo_detector_type type)
Get the extension name of a detector.
int moo_detector_get_spectro(int ntas)
Get the spctro name for a ntas.
const char * moo_detector_get_extname(moo_detector_type type, int ntas)
Get the extension name of a detector.
enum _moo_detector_type_ moo_detector_type
The type code type.
cpl_image * moo_ext_single_get_errs(moo_ext_single *self)
Get image of errs.
cpl_image * moo_ext_single_get_data(moo_ext_single *self)
Get image of data.
moo_ext_single * moo_ext_load_single(moo_ext *self, moo_detector_type type, int num, unsigned int level)
Load the type part in EXT and return it.
cpl_table * moo_ext_get_fibre_table(moo_ext *self)
Get the FIBRE TABLE in EXT.
cpl_error_code moo_fibres_table_add_wavecalguess_cols(cpl_table *table)
add wavecal additional columns
cpl_error_code moo_fibres_table_add_wavecal_cols(cpl_table *table, cpl_table *guess, const char *model)
add wavecal additional columns
cpl_error_code moo_fibres_table_set_matchline(cpl_table *table, moo_detector_type type, cpl_size row, int value)
set the number of match lines for the given detector type
cpl_error_code moo_fibres_table_set_failedfit(cpl_table *table, moo_detector_type type, cpl_size row, int value)
set the number od failedfit lines for the given detector type
cpl_array * moo_fibres_table_get_spectro_indexext(cpl_table *table, int num)
get the index of a spectro in the fibre table sort by spetcro,indexext
cpl_error_code moo_fibres_table_set_fitline(cpl_table *table, moo_detector_type type, cpl_size row, int value)
set the number of fit lines for the given detector type
double moo_fibres_table_get_xdiff(cpl_table *table, moo_detector_type type, cpl_size row)
Get xdiff for the given detector type.
cpl_error_code moo_fibres_table_set_xdiff(cpl_table *table, moo_detector_type type, cpl_size row, double value)
set the xdiff for the given fibre and detector type
cpl_error_code moo_fibres_table_set_detectline(cpl_table *table, moo_detector_type type, cpl_size row, int value)
set the number od detectline for the given detector type
cpl_error_code moo_fibres_table_set_rejectline(cpl_table *table, moo_detector_type type, cpl_size row, int value)
set the number of rejected lines for the given detector type
cpl_error_code moo_fibres_table_erase_extract_cols(cpl_table *table)
erase extract additional columns
cpl_table * moo_line_table_new(int isGuess)
create a line table
double moo_loc_single_eval_f_centroids(moo_loc_single *self, double x, int indexext, int *rej)
Get the Y fit centroid for a x value.
cpl_image * moo_loc_single_get_f_centroids(moo_loc_single *self)
Get image of fit centroids.
moo_loc_single * moo_loc_get_single(moo_loc *self, moo_detector_type type, int ntas)
Get the type part in LOC and return it.
cpl_error_code moo_map_check(moo_map *self, moo_spectral_format *sformat)
Save a moo_map to a FITS file.
moo_map * moo_map_new(void)
Create a new moo_map.
cpl_table * moo_map_get_line_table(moo_map *self)
Get the LINE TABLE extension of a map.
cpl_error_code moo_map_set_data(moo_map *self, moo_detector_type type, int ntas, cpl_image *data, cpl_propertylist *header)
set map data for relevant extension
void moo_map_delete(moo_map *self)
Delete a moo_map.
moo_map * moo_wavesol(moo_ext *arc_ext, const char *lineCatname, moo_spectral_format *sformat, moo_loc *loc, moo_map *wmap, moo_wavesol_params *params)
Computes the wavelength solution from 1D extracted arc spectra.
const char * moo_pfits_get_pro_wavesol_degx(const cpl_propertylist *plist)
find out the PRO.WAVESOL.DEGX value
const char * moo_pfits_get_pro_wavesol_model(const cpl_propertylist *plist)
find out the PRO.WAVESOL.MODEL value
int moo_pfits_get_pro_wavesol_degy(const cpl_propertylist *plist)
find out the PRO.WAVESOL.DEGY value
cpl_error_code moo_qc_set_wavecal_residwave_std(cpl_propertylist *plist, double val)
Set the QC.WAVECAL.RESIDWAVE.STD value.
cpl_error_code moo_qc_set_wavecal_validfibre(cpl_propertylist *plist, int val)
Set the QC.WAVECAL.VALIDFIBRE value.
cpl_error_code moo_qc_set_wavecal_catline(cpl_propertylist *plist, int val)
Set the QC.WAVECAL.CATLINE value.
cpl_error_code moo_qc_set_wavecal_disp_max(cpl_propertylist *plist, double val)
Set the QC.WAVECAL.DISP.MAX value.
cpl_error_code moo_qc_set_wavecal_matchline(cpl_propertylist *plist, int val)
Set the QC.WAVECAL.MATCHLINE value.
cpl_error_code moo_qc_set_wavecal_failedfit(cpl_propertylist *plist, int val)
Set the QC.WAVECAL.FAILEDFIT value.
cpl_error_code moo_qc_set_wavecal_clipline(cpl_propertylist *plist, int val)
Set the QC.WAVECAL.CLIPLINE value.
cpl_error_code moo_qc_set_wavecal_residwave_med(cpl_propertylist *plist, double val)
Set the QC.WAVECAL.RESIDWAVE.MED value.
cpl_error_code moo_qc_set_wavecal_disp_min(cpl_propertylist *plist, double val)
Set the QC.WAVECAL.DISP.MIN value.
cpl_error_code moo_qc_set_wavecal_resol_med(cpl_propertylist *plist, double val)
Set the QC.WAVECAL.RESOL.MED value.
cpl_error_code moo_qc_set_wavecal_detectline(cpl_propertylist *plist, int val)
Set the QC.WAVECAL.DETECTLINE value.
cpl_error_code moo_qc_set_wavecal_fitline(cpl_propertylist *plist, int val)
Set the QC.WAVECAL.FITLINE value.
moo_tcheby_polynomial * moo_tcheby_polynomial_fit(cpl_bivector *data, int degree, double xmin, double xmax)
Computes Tchebitchev transformation of data.
moo_tcheby2d_polynomial * moo_tcheby2d_polynomial_fit(cpl_vector *in_x, int xdegree, double xmin, double xmax, cpl_vector *in_y, int ydegree, double ymin, double ymax, cpl_vector *in_l, double lmin, double lmax)
Computes Tchebitchev transformation of data.
cpl_error_code moo_barycenter_fit(cpl_bivector *points, double *center, double *width)
Fit positions using weighted fluxes.