37#include "irplib_utils.h"
39#include "cr2res_dfs.h"
40#include "cr2res_trace.h"
41#include "cr2res_extract.h"
42#include "cr2res_wave.h"
43#include "cr2res_bpm.h"
49typedef unsigned char byte;
50#define min(a,b) (((a)<(b))?(a):(b))
51#define max(a,b) (((a)>(b))?(a):(b))
52#define signum(a) (((a)>0)?1:((a)<0)?-1:0)
53#define zeta_index(x, y, z) (z * ncols * nrows) + (y * ncols) + x
54#define mzeta_index(x, y) (y * ncols) + x
55#define xi_index(x, y, z) (z * ncols * ny) + (y * ncols) + x
79static int cr2res_extract_slit_func_curved(
91 cpl_polynomial ** slitcurves,
102 const double * slit_func_in,
113static int cr2res_extract_xi_zeta_tensors(
118 const int * ycen_offset,
121 cpl_polynomial ** slitcurves,
126static int cr2res_extract_slitdec_adjust_swath(
133 cpl_vector ** bins_begin,
134 cpl_vector ** bins_end) ;
136static int debug_output(
int ncols,
145 cpl_polynomial ** slitcurves);
184 const hdrl_image * img,
185 const cpl_table * traces,
186 const cpl_table * slit_func_in,
187 const cpl_table * blaze_table_in,
191 cr2res_extr_method extr_method,
203 cpl_table ** extracted,
204 cpl_table ** slit_func,
205 hdrl_image ** model_master)
207 cpl_bivector ** spectrum ;
210 cpl_bivector * blaze_biv ;
211 cpl_bivector * blaze_err_biv ;
213 double * pblaze_err ;
214 cpl_vector * tmp_vec ;
215 cpl_vector * slit_func_in_vec ;
216 cpl_vector ** slit_func_vec ;
217 cpl_table * slit_func_loc ;
218 cpl_table * extract_loc ;
219 hdrl_image * model_loc ;
220 hdrl_image * model_loc_one ;
221 double first_nonzero_value, first_nonzero_error,
222 norm_factor, val, err ;
229 if (img == NULL || traces == NULL)
return -1 ;
232 nb_traces = cpl_table_get_nrow(traces) ;
235 spectrum = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
236 slit_func_vec = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
241 for (i=0 ; i<nb_traces ; i++) {
245 slit_func_vec[i] = NULL ;
247 model_loc_one = NULL ;
250 order = cpl_table_get(traces, CR2RES_COL_ORDER, i, NULL) ;
251 trace_id = cpl_table_get(traces, CR2RES_COL_TRACENB, i, NULL) ;
254 if (reduce_order > -1 && order != reduce_order) continue ;
257 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
259 cpl_msg_info(__func__,
"Process Order %d/Trace %d",order,trace_id) ;
260 cpl_msg_indent_more() ;
263 if (slit_func_in != NULL) {
266 trace_id, &slit_func_in_vec) ;
268 slit_func_in_vec = NULL ;
272 if (extr_method == CR2RES_EXTR_SUM) {
274 trace_id, extr_height, &(slit_func_vec[i]),
275 &(spectrum[i]), &model_loc_one) != 0) {
276 cpl_msg_error(__func__,
"Cannot (sum-)extract the trace") ;
277 if (slit_func_in_vec != NULL)
278 cpl_vector_delete(slit_func_in_vec) ;
279 slit_func_vec[i] = NULL ;
281 model_loc_one = NULL ;
283 cpl_msg_indent_less() ;
286 }
else if (extr_method == CR2RES_EXTR_MEDIAN) {
288 trace_id, extr_height, &(slit_func_vec[i]),
289 &(spectrum[i]), &model_loc_one) != 0) {
290 cpl_msg_error(__func__,
"Cannot (median-)extract the trace") ;
291 if (slit_func_in_vec != NULL)
292 cpl_vector_delete(slit_func_in_vec) ;
293 slit_func_vec[i] = NULL ;
295 model_loc_one = NULL ;
297 cpl_msg_indent_less() ;
300 }
else if (extr_method == CR2RES_EXTR_TILTSUM) {
302 trace_id, extr_height, &(slit_func_vec[i]),
303 &(spectrum[i]), &model_loc_one) != 0) {
304 cpl_msg_error(__func__,
"Cannot (tiltsum-)extract the trace") ;
305 if (slit_func_in_vec != NULL)
306 cpl_vector_delete(slit_func_in_vec) ;
307 slit_func_vec[i] = NULL ;
309 model_loc_one = NULL ;
311 cpl_msg_indent_less() ;
314 }
else if (extr_method == CR2RES_EXTR_OPT_CURV) {
316 order, trace_id, extr_height, swath_width,
317 oversample, smooth_slit, smooth_spec,
318 niter, kappa, error_factor,
320 &(spectrum[i]), &model_loc_one) != 0) {
321 cpl_msg_error(__func__,
322 "Cannot extract order %d, trace %d", order, trace_id) ;
323 if (slit_func_in_vec != NULL)
324 cpl_vector_delete(slit_func_in_vec) ;
325 slit_func_vec[i] = NULL ;
327 model_loc_one = NULL ;
329 cpl_msg_indent_less() ;
333 if (slit_func_in_vec != NULL) cpl_vector_delete(slit_func_in_vec) ;
336 if (blaze_table_in != NULL) {
338 trace_id, &blaze_biv, &blaze_err_biv)) {
339 cpl_msg_warning(__func__,
340 "Cannot Get the Blaze for order/trace:%d/%d - skip",
345 cpl_vector_get_data(cpl_bivector_get_y(blaze_biv)) ;
347 cpl_vector_get_data(cpl_bivector_get_y(blaze_err_biv)) ;
348 first_nonzero_value = first_nonzero_error = 0.0 ;
349 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
350 if (fabs(pblaze[j])>1e-3) {
351 first_nonzero_value = pblaze[j] ;
352 first_nonzero_error = pblaze_err[j] ;
356 if (fabs(first_nonzero_value)<1e-3) {
357 cpl_msg_warning(__func__,
"Blaze filled with zeros - skip");
359 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
360 if (fabs(pblaze[j])<1e-3) {
361 pblaze[j] = first_nonzero_value ;
362 pblaze_err[j] = first_nonzero_error ;
372 norm_factor = blaze_norm;
374 tmp_vec=cpl_vector_duplicate(cpl_bivector_get_y(blaze_biv));
375 kth = (cpl_size)(cpl_bivector_get_size(blaze_biv)*0.95) ;
376 irplib_vector_get_kth(tmp_vec, kth) ;
377 norm_factor = cpl_vector_get(tmp_vec, kth) ;
378 cpl_vector_delete(tmp_vec) ;
382 pspec = cpl_bivector_get_x_data(spectrum[i]) ;
383 pspec_err = cpl_bivector_get_y_data(spectrum[i]);
384 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
385 if (fabs(pspec[j]) > 1e-3) {
387 val = pspec[j] / (pblaze[j]/norm_factor) ;
391 err = val * sqrt(((pspec_err[j]*pspec_err[j])/
392 (pspec[j]*pspec[j]))+
393 ((pblaze_err[j]*pblaze_err[j])/
394 (pblaze[j]*pblaze[j])));
403 if (cpl_error_get_code()) {
405 cpl_msg_warning(__func__,
406 "Cannot Correct Blaze for order/trace:%d/%d - skip",
410 cpl_bivector_delete(blaze_biv) ;
411 cpl_bivector_delete(blaze_err_biv) ;
416 if (model_loc_one != NULL) {
422 if (pixval.data != 0 && badpix == 0){
431 if (display && disp_order_idx==order && disp_trace==trace_id) {
433 "set grid;set xlabel 'pixels';set ylabel 'Flux (ADU)';",
434 "t 'Extracted Spectrum' w lines",
"",
435 cpl_bivector_get_x_const(spectrum[i])) ;
437 cpl_msg_indent_less() ;
443 cpl_msg_error(__func__,
"Cannot compute the slit function") ;
444 for (i=0 ; i<nb_traces ; i++) {
445 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
446 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
449 cpl_free(slit_func_vec) ;
457 for (i=0 ; i<nb_traces ; i++) {
458 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
459 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
462 cpl_free(slit_func_vec) ;
464 cpl_table_delete(slit_func_loc);
469 for (i=0 ; i<nb_traces ; i++) {
470 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
471 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
474 cpl_free(slit_func_vec) ;
477 *extracted = extract_loc ;
478 *slit_func = slit_func_loc ;
479 *model_master = model_loc;
508 const hdrl_image * hdrl_in,
509 const cpl_table * trace_tab,
513 cpl_vector ** slit_func,
514 cpl_bivector ** spec,
521 const cpl_image * img_in;
522 const cpl_image * err_in;
528 double trace_cen, trace_height ;
532 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
538 imtyp = cpl_image_get_type(img_in);
539 lenx = cpl_image_get_size_x(img_in);
540 leny = cpl_image_get_size_y(img_in);
546 cpl_msg_error(__func__,
"Cannot compute height");
552 trace_id, lenx)) == NULL) {
553 cpl_msg_error(__func__,
"Cannot get ycen");
556 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
558 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
559 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
562 if (img_tmp == NULL) {
563 cpl_msg_error(__func__,
"Cannot rectify order");
564 cpl_vector_delete(ycen);
568 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
569 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
570 NULL, CPL_IO_CREATE);
572 img_1d = cpl_image_collapse_create(img_tmp, 0);
573 spc = cpl_vector_new_from_image_row(img_1d, 1);
574 cpl_image_delete(img_1d);
576 img_1d = cpl_image_collapse_create(img_tmp, 1);
577 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
578 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
579 cpl_image_delete(img_1d);
580 cpl_image_delete(img_tmp);
583 if (img_tmp == NULL) {
584 cpl_msg_error(__func__,
"Cannot rectify error");
585 cpl_vector_delete(ycen);
588 cpl_image_multiply(img_tmp, img_tmp);
589 img_1d = cpl_image_collapse_create(img_tmp, 0);
590 sigma = cpl_vector_new_from_image_row(img_1d, 1);
591 cpl_vector_sqrt(sigma);
592 cpl_image_delete(img_tmp);
593 cpl_image_delete(img_1d);
596 img_tmp = cpl_image_new(lenx, leny, imtyp);
598 for (i=1;i<=lenx;i++){
599 for (j=1;j<=height;j++){
600 y = ycen_int[i-1]-(height/2)+j;
601 if ((y <=0) || (y > leny)){
continue; }
602 cpl_image_set(img_tmp, i, y,
603 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
606 cpl_vector_delete(ycen);
609 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
610 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
611 NULL, CPL_IO_CREATE);
616 *spec = cpl_bivector_wrap_vectors(spc, sigma);
618 cpl_image_delete(img_tmp);
620 if (cpl_error_get_code() != CPL_ERROR_NONE){
621 cpl_msg_error(__func__,
"Error in the vertical sum extraction %s",
622 cpl_error_get_where());
656 const hdrl_image * hdrl_in,
657 const cpl_table * trace_tab,
661 cpl_vector ** slit_func,
662 cpl_bivector ** spec,
669 const cpl_image * img_in;
670 const cpl_image * err_in;
676 double trace_cen, trace_height ;
680 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
686 imtyp = cpl_image_get_type(img_in);
687 lenx = cpl_image_get_size_x(img_in);
688 leny = cpl_image_get_size_y(img_in);
694 cpl_msg_error(__func__,
"Cannot compute height");
700 trace_id, lenx)) == NULL) {
701 cpl_msg_error(__func__,
"Cannot get ycen");
704 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
706 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
707 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
710 if (img_tmp == NULL) {
711 cpl_msg_error(__func__,
"Cannot rectify order");
712 cpl_vector_delete(ycen);
716 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
717 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
718 NULL, CPL_IO_CREATE);
720 img_1d = cpl_image_collapse_median_create(img_tmp, 0, 0, 0);
721 spc = cpl_vector_new_from_image_row(img_1d, 1);
724 cpl_vector_multiply_scalar(spc,(
double)height);
725 cpl_image_delete(img_1d);
727 img_1d = cpl_image_collapse_median_create(img_tmp, 1, 0, 0);
728 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
729 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
730 cpl_image_delete(img_1d);
731 cpl_image_delete(img_tmp);
736 cpl_msg_error(__func__,
"Cannot rectify error");
737 cpl_vector_delete(ycen);
740 cpl_image_multiply(img_tmp, img_tmp);
741 img_1d = cpl_image_collapse_create(img_tmp, 0);
742 sigma = cpl_vector_new_from_image_row(img_1d, 1);
743 cpl_vector_sqrt(sigma);
744 cpl_image_delete(img_tmp);
745 cpl_image_delete(img_1d);
748 img_tmp = cpl_image_new(lenx, leny, imtyp);
750 for (i=1;i<=lenx;i++){
751 for (j=1;j<=height;j++){
752 cpl_image_set(img_tmp, i, ycen_int[i-1]-(height/2)+j,
753 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
756 cpl_vector_delete(ycen);
759 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
760 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
761 NULL, CPL_IO_CREATE);
766 *spec = cpl_bivector_wrap_vectors(spc, sigma);
768 cpl_image_delete(img_tmp);
799 const hdrl_image * hdrl_in,
800 const cpl_table * trace_tab,
804 cpl_vector ** slit_func,
805 cpl_bivector ** spec,
812 const cpl_image * img_in;
813 const cpl_image * err_in;
819 double trace_cen, trace_height ;
823 double a, b, c, value;
824 cpl_polynomial * slitcurve_A, * slitcurve_B, *slitcurve_C;
825 cpl_bivector * xi, *xt;
828 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
834 imtyp = cpl_image_get_type(img_in);
835 lenx = cpl_image_get_size_x(img_in);
836 leny = cpl_image_get_size_y(img_in);
842 cpl_msg_error(__func__,
"Cannot compute height");
848 trace_id, lenx)) == NULL) {
849 cpl_msg_error(__func__,
"Cannot get ycen");
852 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
854 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
855 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
858 if (img_tmp == NULL) {
859 cpl_msg_error(__func__,
"Cannot rectify order");
860 cpl_vector_delete(ycen);
864 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
865 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
866 NULL, CPL_IO_CREATE);
886 if ((slitcurve_A == NULL) || (slitcurve_B == NULL) || (slitcurve_C == NULL))
888 cpl_msg_error(__func__,
889 "No (or incomplete) slitcurve data found in trace table");
890 cpl_vector_delete(ycen);
891 cpl_polynomial_delete(slitcurve_A);
892 cpl_polynomial_delete(slitcurve_B);
893 cpl_polynomial_delete(slitcurve_C);
900 xi = cpl_bivector_new(lenx);
901 xt = cpl_bivector_new(lenx);
902 for (i = 0; i < lenx; i++){
903 cpl_vector_set(cpl_bivector_get_x(xi), i, i);
904 cpl_vector_set(cpl_bivector_get_x(xt), i, i);
905 cpl_vector_set(cpl_bivector_get_y(xi), i, 0);
906 cpl_vector_set(cpl_bivector_get_y(xt), i, 0);
909 for (i = 0; i < height; i++){
910 int yt = i - height / 2 + 0.5;
911 int yc = cpl_vector_get(ycen, i);
913 for (j = 1; j < lenx - 1; j++){
915 b = cpl_polynomial_eval_1d(slitcurve_B, j, NULL);
916 c = cpl_polynomial_eval_1d(slitcurve_C, j, NULL);
923 value = j - a - yt * b - yt * yt * c;
924 value = max(min(value, lenx-1), 0);
925 cpl_vector_set(cpl_bivector_get_x(xt), j, value);
926 value = cpl_image_get(img_tmp, j + 1, i + 1, &badpix);
927 if (badpix) value = NAN;
928 cpl_vector_set(cpl_bivector_get_y(xt), j, value);
931 cpl_bivector_interpolate_linear(xi, xt);
933 for (j = 0; j < lenx; j++){
934 value = cpl_vector_get(cpl_bivector_get_y(xi), j);
935 cpl_image_set(img_tmp, j+1, i+1, value);
937 cpl_image_set(img_tmp, j+1, i+1, 0);
938 cpl_image_reject(img_tmp, j+1, i+1);
943 cpl_bivector_delete(xi);
944 cpl_bivector_delete(xt);
945 cpl_polynomial_delete(slitcurve_A);
946 cpl_polynomial_delete(slitcurve_B);
947 cpl_polynomial_delete(slitcurve_C);
949 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
950 cpl_image_save(img_tmp,
"debug_img_shifted.fits", imtyp,
951 NULL, CPL_IO_CREATE);
957 xi = cpl_bivector_new(height);
958 xt = cpl_bivector_new(height);
960 for (j = 0; j < lenx; j++){
962 cpl_vector_set(cpl_bivector_get_x(xi), 0, 0);
963 cpl_vector_set(cpl_bivector_get_y(xi), 0, 0);
964 cpl_vector_set(cpl_bivector_get_x(xi), height-1, height-1);
965 cpl_vector_set(cpl_bivector_get_y(xi), height-1, 0);
966 for (i = 0; i < height; i++){
967 cpl_vector_set(cpl_bivector_get_x(xt), i, i);
968 cpl_vector_set(cpl_bivector_get_y(xt), i, 0);
970 value = cpl_image_get(img_tmp, j+1, i+1, &badpix);
972 cpl_vector_set(cpl_bivector_get_x(xi), i, i);
973 cpl_vector_set(cpl_bivector_get_y(xi), i, value);
976 cpl_bivector_interpolate_linear(xt, xi);
977 for (i = 0; i < height; i++){
978 value = cpl_vector_get(cpl_bivector_get_y(xt), i);
979 cpl_image_set(img_tmp, j+1, i+1, value);
983 cpl_bivector_delete(xi);
984 cpl_bivector_delete(xt);
986 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
987 cpl_image_save(img_tmp,
"debug_img_shifted_corrected.fits", imtyp,
988 NULL, CPL_IO_CREATE);
991 img_1d = cpl_image_collapse_create(img_tmp, 0);
992 spc = cpl_vector_new_from_image_row(img_1d, 1);
993 cpl_image_delete(img_1d);
995 img_1d = cpl_image_collapse_create(img_tmp, 1);
996 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
997 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
998 cpl_image_delete(img_1d);
999 cpl_image_delete(img_tmp);
1002 if (img_tmp == NULL)
1004 cpl_msg_error(__func__,
"Cannot rectify error");
1005 cpl_vector_delete(ycen);
1008 cpl_image_multiply(img_tmp, img_tmp);
1009 img_1d = cpl_image_collapse_create(img_tmp, 0);
1010 sigma = cpl_vector_new_from_image_row(img_1d, 1);
1011 cpl_vector_sqrt(sigma);
1012 cpl_image_delete(img_tmp);
1013 cpl_image_delete(img_1d);
1016 img_tmp = cpl_image_new(lenx, leny, imtyp);
1018 for (i=1;i<=lenx;i++){
1019 for (j=1;j<=height;j++){
1020 cpl_image_set(img_tmp, i, ycen_int[i-1]-(height/2)+j,
1021 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
1024 cpl_vector_delete(ycen);
1027 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1028 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
1029 NULL, CPL_IO_CREATE);
1033 *slit_func = slitfu;
1034 *spec = cpl_bivector_wrap_vectors(spc, sigma);
1036 cpl_image_delete(img_tmp);
1050 cpl_bivector ** spectrum,
1051 const cpl_table * trace_table)
1055 const double * pspec ;
1056 const double * perr ;
1057 cpl_vector * wave_vec ;
1058 const double * pwl ;
1059 int nrows, all_null, i, order, trace_id, nb_traces ;
1062 if (spectrum == NULL || trace_table == NULL)
return NULL ;
1065 nb_traces = cpl_table_get_nrow(trace_table) ;
1069 for (i=0 ; i<nb_traces ; i++)
1070 if (spectrum[i] != NULL) {
1071 nrows = cpl_bivector_get_size(spectrum[i]) ;
1074 if (all_null == 1)
return NULL ;
1077 for (i=0 ; i<nb_traces ; i++)
1078 if (spectrum[i] != NULL && cpl_bivector_get_size(spectrum[i]) != nrows)
1082 out = cpl_table_new(nrows);
1083 for (i=0 ; i<nb_traces ; i++) {
1084 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1085 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1088 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1089 cpl_free(col_name) ;
1092 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1093 cpl_free(col_name) ;
1096 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1097 cpl_free(col_name) ;
1101 for (i=0 ; i<nb_traces ; i++) {
1102 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1103 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1104 if (spectrum[i] != NULL) {
1105 pspec = cpl_bivector_get_x_data_const(spectrum[i]) ;
1106 perr = cpl_bivector_get_y_data_const(spectrum[i]);
1109 cpl_table_copy_data_double(out, col_name, pspec) ;
1110 cpl_free(col_name) ;
1113 cpl_table_copy_data_double(out, col_name, perr) ;
1114 cpl_free(col_name) ;
1118 CR2RES_DETECTOR_SIZE);
1119 if (wave_vec == NULL) {
1120 wave_vec = cpl_vector_new(CR2RES_DETECTOR_SIZE) ;
1121 cpl_vector_fill(wave_vec, 0.0) ;
1123 pwl = cpl_vector_get_data(wave_vec) ;
1127 cpl_table_copy_data_double(out, col_name, pwl) ;
1128 cpl_free(col_name) ;
1129 cpl_vector_delete(wave_vec) ;
1133 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1134 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1135 cpl_free(col_name) ;
1138 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1139 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1140 cpl_free(col_name) ;
1143 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1144 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1145 cpl_free(col_name) ;
1160 cpl_vector ** slit_func,
1161 const cpl_table * trace_table)
1165 const double * pslit ;
1166 int nrows, nrows_max, all_null, i, order, trace_id,
1170 if (slit_func == NULL || trace_table == NULL)
return NULL ;
1174 nb_traces = cpl_table_get_nrow(trace_table) ;
1178 for (i=0 ; i<nb_traces ; i++)
1179 if (slit_func[i] != NULL) {
1180 nrows = cpl_vector_get_size(slit_func[i]) ;
1181 if (nrows > nrows_max) nrows_max = nrows ;
1184 if (all_null == 1)
return NULL ;
1187 out = cpl_table_new(nrows_max);
1188 for (i=0 ; i<nb_traces ; i++) {
1189 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1190 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1192 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1193 cpl_free(col_name) ;
1197 for (i=0 ; i<nb_traces ; i++) {
1198 if (slit_func[i] != NULL) {
1199 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1200 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1201 pslit = cpl_vector_get_data_const(slit_func[i]) ;
1203 cpl_table_copy_data_double(out, col_name, pslit) ;
1204 cpl_free(col_name) ;
1222 const cpl_table * tab,
1225 cpl_bivector ** spec,
1226 cpl_bivector ** spec_err)
1230 char * spec_err_name ;
1231 const double * pspec ;
1232 const double * pwave ;
1233 const double * pspec_err ;
1236 double * pxspec_err ;
1237 double * pyspec_err ;
1241 if (tab == NULL || spec == NULL || spec_err == NULL)
return -1 ;
1245 if ((pspec = cpl_table_get_data_double_const(tab, spec_name)) == NULL) {
1246 cpl_msg_error(__func__,
"Cannot find the spectrum") ;
1247 cpl_free(spec_name) ;
1250 cpl_free(spec_name) ;
1254 if ((pwave = cpl_table_get_data_double_const(tab, wave_name)) == NULL) {
1255 cpl_msg_error(__func__,
"Cannot find the wavelength") ;
1256 cpl_free(wave_name) ;
1259 cpl_free(wave_name) ;
1263 if ((pspec_err = cpl_table_get_data_double_const(tab, spec_err_name))
1265 cpl_msg_error(__func__,
"Cannot find the spectrum error") ;
1266 cpl_free(spec_err_name) ;
1269 cpl_free(spec_err_name) ;
1272 tab_size = cpl_table_get_nrow(tab) ;
1273 *spec = cpl_bivector_new(tab_size) ;
1274 *spec_err = cpl_bivector_new(tab_size) ;
1275 pxspec = cpl_bivector_get_x_data(*spec) ;
1276 pyspec = cpl_bivector_get_y_data(*spec) ;
1277 pxspec_err = cpl_bivector_get_x_data(*spec_err) ;
1278 pyspec_err = cpl_bivector_get_y_data(*spec_err) ;
1279 for (i=0 ; i<tab_size ; i++) {
1280 pxspec[i] = pwave[i] ;
1281 pyspec[i] = pspec[i] ;
1282 pxspec_err[i] = pwave[i] ;
1283 pyspec_err[i] = pspec_err[i] ;
1299 const cpl_table * tab,
1305 const double * ptab ;
1310 if (tab == NULL || vec == NULL)
return -1 ;
1314 if ((ptab = cpl_table_get_data_double_const(tab, vec_name)) == NULL) {
1315 cpl_msg_error(__func__,
"Cannot find the slit_func") ;
1316 cpl_free(vec_name) ;
1321 cpl_free(vec_name) ;
1324 tab_size = cpl_table_get_nrow(tab) ;
1325 *vec = cpl_vector_new(tab_size) ;
1326 pvec = cpl_vector_get_data(*vec) ;
1327 for (i=0 ; i<tab_size ; i++) pvec[i] = ptab[i] ;
1371 const hdrl_image * img_hdrl,
1372 const cpl_table * trace_tab,
1373 const cpl_vector * slit_func_vec_in,
1383 double error_factor,
1384 cpl_vector ** slit_func,
1385 cpl_bivector ** spec,
1386 hdrl_image ** model)
1390 int * ycen_offset_sw;
1391 double * slitfu_sw_data;
1393 const double * slit_func_in;
1395 const cpl_image * img_in;
1396 const cpl_image * err_in;
1399 cpl_image * img_rect;
1400 cpl_image * err_rect;
1401 cpl_image * model_rect;
1403 cpl_image * img_out;
1404 cpl_vector * slitfu_sw;
1405 cpl_vector * unc_sw;
1407 cpl_vector * slitfu;
1408 cpl_vector * weights_sw;
1409 cpl_vector * tmp_vec;
1410 cpl_vector * bins_begin;
1411 cpl_vector * bins_end;
1412 cpl_vector * unc_decomposition;
1413 cpl_size lenx, leny, pow;
1415 cpl_polynomial *slitcurve_A, *slitcurve_B, *slitcurve_C;
1416 cpl_polynomial ** slitcurves_sw;
1417 hdrl_image * model_out;
1418 cpl_bivector * spectrum_loc;
1424 cpl_image * img_mad;
1429 double pixval, errval;
1430 double trace_cen, trace_height;
1431 int i, j, k, nswaths, col, x, y, ny_os,
1437 if (img_hdrl == NULL || trace_tab == NULL)
return -1 ;
1439 if (smooth_slit == 0.0) {
1440 cpl_msg_error(__func__,
"Slit-smoothing cannot be 0.0");
1442 }
else if (smooth_slit < 0.1) {
1443 cpl_msg_warning(__func__,
"Slit-smoothing unreasonably small");
1444 }
else if (smooth_slit > 100.0) {
1445 cpl_msg_warning(__func__,
"Slit-smoothing unreasonably big");
1447 if (oversample < 3){
1448 cpl_msg_error(__func__,
"Oversampling too small");
1450 }
else if (oversample > 15) {
1451 cpl_msg_warning(__func__,
"Large oversampling, runtime will be long");
1454 cpl_msg_warning(__func__,
1455 "Allowing at least 5 iterations is recommended.");
1458 cpl_msg_warning(__func__,
1459 "Rejecting outliers < 4 sigma risks making good data.");
1465 imtyp = cpl_image_get_type(img_in);
1466 lenx = cpl_image_get_size_x(img_in);
1467 leny = cpl_image_get_size_y(img_in);
1473 cpl_msg_error(__func__,
"Cannot compute height");
1479 cpl_msg_warning(__func__,
1480 "Given height larger than image, clipping height");
1485 trace_id, lenx)) == NULL) {
1486 cpl_msg_error(__func__,
"Cannot get ycen");
1489 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
1491 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
1492 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
1493 if (trace_cen-(height/2) < 0.0 ||
1494 trace_cen+(height/2) > CR2RES_DETECTOR_SIZE) {
1495 cpl_msg_error(__func__,
"Extraction outside detector edges impossible");
1496 cpl_vector_delete(ycen);
1502 if (img_rect == NULL){
1503 cpl_msg_error(__func__,
"Cannot rectify order");
1504 cpl_vector_delete(ycen);
1507 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1508 cpl_image_save(img_rect,
"debug_rectorder_curved.fits", imtyp,
1509 NULL, CPL_IO_CREATE);
1521 if ((slitcurve_A == NULL) || (slitcurve_B == NULL) || (slitcurve_C == NULL))
1523 cpl_msg_error(__func__,
1524 "No (or incomplete) slitcurve data found in trace table");
1525 cpl_vector_delete(ycen);
1526 cpl_free(ycen_rest) ;
1527 cpl_image_delete(err_rect) ;
1528 cpl_image_delete(img_rect) ;
1529 cpl_polynomial_delete(slitcurve_A);
1530 cpl_polynomial_delete(slitcurve_B);
1531 cpl_polynomial_delete(slitcurve_C);
1537 for (i=1; i<=lenx; i+=swath/2){
1538 double delta_tmp, a, b, c, yc;
1544 b = cpl_polynomial_eval_1d(slitcurve_B, i, NULL);
1545 c = cpl_polynomial_eval_1d(slitcurve_C, i, NULL);
1546 yc = cpl_vector_get(ycen, i-1);
1554 delta_tmp = max( fabs(a + (c*height/2. + b)*height/2.),
1555 fabs(a + (c*height/-2. + b)*height/-2.));
1556 if (delta_tmp > delta_x) delta_x = (int)ceil(delta_tmp);
1559 cpl_msg_debug(__func__,
"Max delta_x from slit curv: %d pix.", delta_x);
1561 if (delta_x >= swath / 4){
1562 cpl_msg_error(__func__,
1563 "Curvature is larger than the swath, try again with a larger swath size");
1564 cpl_vector_delete(ycen);
1565 cpl_free(ycen_rest) ;
1566 cpl_image_delete(err_rect) ;
1567 cpl_image_delete(img_rect) ;
1568 cpl_polynomial_delete(slitcurve_A);
1569 cpl_polynomial_delete(slitcurve_B);
1570 cpl_polynomial_delete(slitcurve_C);
1575 ny_os = oversample*(height+1) +1;
1576 if ((swath = cr2res_extract_slitdec_adjust_swath(ycen, height, leny, swath,
1577 lenx, delta_x, &bins_begin, &bins_end)) == -1){
1578 cpl_msg_error(__func__,
"Cannot calculate swath size");
1579 cpl_vector_delete(ycen);
1580 cpl_free(ycen_rest) ;
1581 cpl_image_delete(err_rect) ;
1582 cpl_image_delete(img_rect) ;
1583 cpl_polynomial_delete(slitcurve_A);
1584 cpl_polynomial_delete(slitcurve_B);
1585 cpl_polynomial_delete(slitcurve_C);
1588 nswaths = cpl_vector_get_size(bins_begin);
1591 slit_func_in = NULL;
1592 if (slit_func_vec_in != NULL) {
1594 size = cpl_vector_get_size(slit_func_vec_in);
1596 slit_func_in = cpl_vector_get_data_const(slit_func_vec_in);
1598 cpl_msg_warning(__func__,
"Ignoring the given slit_func since it is"
1599 " of the wrong size, expected %i but got %lli points.",
1605 mask_sw = cpl_malloc(height * swath*
sizeof(
int));
1606 model_sw = cpl_malloc(height * swath*
sizeof(
double));
1607 unc_sw = cpl_vector_new(swath);
1608 img_sw = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1609 err_sw = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1610 ycen_sw = cpl_malloc(swath*
sizeof(
double));
1611 ycen_offset_sw = cpl_malloc(swath *
sizeof(
int));
1613 slitcurves_sw = cpl_malloc(swath *
sizeof(cpl_polynomial*));
1614 for (i=0; i<swath; i++) slitcurves_sw[i]= cpl_polynomial_new(1);
1617 slitfu = cpl_vector_new(ny_os);
1618 spectrum_loc = cpl_bivector_new(lenx);
1619 spc = cpl_bivector_get_x(spectrum_loc);
1620 unc_decomposition = cpl_bivector_get_y(spectrum_loc);
1621 for (j=0; j<lenx ; j++){
1622 cpl_vector_set(spc, j, 0.);
1623 cpl_vector_set(unc_decomposition, j, 0.);
1627 model_rect = cpl_image_new(lenx, height, CPL_TYPE_DOUBLE);
1630 slitfu_sw = cpl_vector_new(ny_os);
1631 for (j=0; j < ny_os; j++) cpl_vector_set(slitfu_sw, j, 0);
1632 slitfu_sw_data = cpl_vector_get_data(slitfu_sw);
1633 weights_sw = cpl_vector_new(swath);
1634 for (i = 0; i < swath; i++) cpl_vector_set(weights_sw, i, 0);
1637 for (i=delta_x; i < swath/2; i++) {
1638 j = i - delta_x + 1;
1639 cpl_vector_set(weights_sw, i, j);
1640 cpl_vector_set(weights_sw, swath - i - 1, j);
1643 cpl_vector_divide_scalar(weights_sw, swath/2 - delta_x + 1);
1648 ny = oversample * (height + 1) + 1;
1649 nx = 4 * delta_x + 1;
1652 sP_old = cpl_malloc(swath *
sizeof(
double));
1653 l_Aij = cpl_malloc(ny * (4*oversample+1) *
sizeof(
double));
1654 p_Aij = cpl_malloc(swath * nx *
sizeof(
double));
1655 l_bj = cpl_malloc(ny *
sizeof(
double));
1656 p_bj = cpl_malloc(swath *
sizeof(
double));
1657 img_mad = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1663 xi = cpl_malloc(swath * ny * 4 *
sizeof(xi_ref));
1668 zeta = cpl_malloc(swath * height * 3 * (oversample + 1)
1669 *
sizeof(zeta_ref));
1672 m_zeta = cpl_malloc(swath * height *
sizeof(
int));
1674 for (i = 0; i < nswaths; i++) {
1675 double *img_sw_data;
1676 double *err_sw_data;
1677 double *spec_sw_data;
1678 double *unc_sw_data;
1681 cpl_vector *spec_sw;
1682 cpl_vector *spec_tmp;
1684 int sw_start, sw_end, y_lower_limit;
1688 sw_start = cpl_vector_get(bins_begin, i);
1689 sw_end = cpl_vector_get(bins_end, i);
1692 for(col=1; col<=swath; col++){
1696 for(y=1;y<=height;y++){
1697 errval = cpl_image_get(err_rect, x, y, &badpix);
1698 if (isnan(errval) | badpix){
1703 pixval = cpl_image_get(img_rect, x, y, &badpix);
1704 if (isnan(pixval) | badpix){
1712 cpl_image_set(img_sw, col, y, pixval);
1713 cpl_image_set(err_sw, col, y, errval);
1717 cpl_image_reject(img_sw, col, y);
1721 j = (y-1)*swath + (col-1) ;
1724 mask_sw[j] = !badpix;
1730 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow,
1731 cpl_polynomial_eval_1d(slitcurve_C, x, NULL));
1733 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow,
1734 cpl_polynomial_eval_1d(slitcurve_B, x, NULL));
1736 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow,
1737 cpl_polynomial_eval_1d(slitcurve_A, x, NULL) - x);
1761 cpl_polynomial_shift_1d(slitcurves_sw[col-1], 0,
1762 cpl_vector_get(ycen, x-1));
1763 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow, 0);
1766 for (j=0; j< height * swath; j++) model_sw[j] = 0;
1767 img_sw_data = cpl_image_get_data_double(img_sw);
1768 err_sw_data = cpl_image_get_data_double(err_sw);
1769 unc_sw_data = cpl_vector_get_data(unc_sw);
1772 img_tmp = cpl_image_collapse_median_create(img_sw, 0, 0, 0);
1773 spec_tmp = cpl_vector_new_from_image_row(img_tmp, 1);
1774 cpl_vector_multiply_scalar(spec_tmp,
1775 (
double)cpl_image_get_size_y(img_sw));
1776 spec_sw = cpl_vector_filter_median_create(spec_tmp, 1);
1777 cpl_vector_delete(spec_tmp);
1778 cpl_image_delete(img_tmp);
1779 spec_sw_data = cpl_vector_get_data(spec_sw);
1781 for (j=sw_start;j<sw_end;j++){
1782 ycen_sw[j-sw_start] = ycen_rest[j];
1783 ycen_offset_sw[j-sw_start] = (int) cpl_vector_get(ycen, j);
1785 y_lower_limit = height / 2;
1787 img_tmp = cpl_image_wrap_int(swath, height, mask_sw);
1788 img_sum = cpl_image_get_flux(img_tmp);
1789 if (img_sum < 0.5 * swath*height){
1790 cpl_msg_error(__func__,
1791 "Only %.0f %% of pixels not masked, cannot extract",
1792 100*img_sum/(swath*height));
1793 cpl_image_unwrap(img_tmp);
1794 cpl_vector_delete(spec_sw);
1797 if (cpl_msg_get_level() == CPL_MSG_DEBUG)
1799 cpl_image_save(img_tmp,
"debug_mask_before_sw.fits", CPL_TYPE_INT, NULL, CPL_IO_CREATE);
1800 cpl_vector_save(spec_sw,
"debug_spc_initial_guess.fits",
1801 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1803 cpl_image_unwrap(img_tmp);
1806 cr2res_extract_slit_func_curved(error_factor, swath, height, oversample,
1807 img_sw_data, err_sw_data, mask_sw, ycen_sw, ycen_offset_sw,
1808 y_lower_limit, slitcurves_sw, delta_x, slitfu_sw_data,
1809 spec_sw_data, model_sw, unc_sw_data, smooth_spec, smooth_slit,
1810 5.e-5, niter, kappa, slit_func_in, sP_old, l_Aij, p_Aij, l_bj,
1811 p_bj, img_mad, xi, zeta, m_zeta);
1814 if (i==0) cpl_vector_copy(slitfu,slitfu_sw);
1815 else cpl_vector_add(slitfu,slitfu_sw);
1817 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1818 path = cpl_sprintf(
"debug_spc_%i.fits", i);
1819 cpl_vector_save(spec_sw, path , CPL_TYPE_DOUBLE, NULL,
1823 path = cpl_sprintf(
"debug_mask_%i.fits", i);
1824 img_tmp = cpl_image_wrap_int(swath, height, mask_sw);
1825 cpl_image_save(img_tmp, path, CPL_TYPE_INT, NULL, CPL_IO_CREATE);
1827 cpl_image_unwrap(img_tmp);
1829 tmp_vec = cpl_vector_wrap(swath, ycen_sw);
1830 path = cpl_sprintf(
"debug_ycen_%i.fits", i);
1831 cpl_vector_save(tmp_vec, path, CPL_TYPE_DOUBLE, NULL,
1833 cpl_vector_unwrap(tmp_vec);
1836 cpl_vector_save(weights_sw,
"debug_weights.fits", CPL_TYPE_DOUBLE,
1837 NULL, CPL_IO_CREATE);
1838 path = cpl_sprintf(
"debug_slitfu_%i.fits", i);
1839 cpl_vector_save(slitfu_sw, path, CPL_TYPE_DOUBLE,
1840 NULL, CPL_IO_CREATE);
1843 path = cpl_sprintf(
"debug_model_%i.fits", i);
1844 img_tmp = cpl_image_wrap_double(swath, height, model_sw);
1845 cpl_image_save(img_tmp, path, CPL_TYPE_DOUBLE,
1846 NULL, CPL_IO_CREATE);
1847 cpl_image_unwrap(img_tmp);
1850 path = cpl_sprintf(
"debug_img_sw_%i.fits", i);
1851 cpl_image_save(img_sw, path, CPL_TYPE_DOUBLE, NULL,
1855 path = cpl_sprintf(
"debug_img_mad_%i.fits", i);
1856 cpl_image_save(img_mad, path, CPL_TYPE_DOUBLE, NULL,
1866 if ((i == nswaths - 1) && (i != 0)){
1867 k = cpl_vector_get(bins_end, i-1) -
1868 cpl_vector_get(bins_begin, i) - swath / 2 - delta_x;
1870 for (j = 0; j < swath - k; j++){
1871 cpl_vector_set(spec_sw, j, cpl_vector_get(spec_sw, j + k));
1872 cpl_vector_set(unc_sw, j, cpl_vector_get(unc_sw, j + k));
1873 for (y = 0; y < height; y++)
1874 model_sw[y * swath + j] = model_sw[y * swath + j + k];
1876 sw_start = cpl_vector_get(bins_begin, i-1) + swath / 2 - delta_x;
1877 cpl_vector_set(bins_begin, i, sw_start);
1879 cpl_vector_set(bins_end, i, lenx);
1884 for (j = 0; j < delta_x; j++)
1886 cpl_vector_set(spec_sw, j, 0);
1887 cpl_vector_set(unc_sw, j, 0.);
1888 for (y = 0; y < height; y++) model_sw[y * swath + j] = 0;
1890 for (j = swath/2; j < swath; j++) {
1891 cpl_vector_set(spec_sw, j,
1892 cpl_vector_get(spec_sw,j) * cpl_vector_get(weights_sw,j));
1893 cpl_vector_set(unc_sw, j,
1894 cpl_vector_get(unc_sw, j) * cpl_vector_get(weights_sw, j));
1895 for (y = 0; y < height; y++) {
1896 model_sw[y * swath + j] *= cpl_vector_get(weights_sw, j);
1899 }
else if (i == nswaths - 1) {
1900 for (j = sw_end-sw_start-1; j >= sw_end-sw_start-delta_x-1; j--)
1902 cpl_vector_set(spec_sw, j, 0);
1903 cpl_vector_set(unc_sw, j, 0);
1904 for (y = 0; y < height; y++) model_sw[y * swath + j] = 0;
1906 for (j = 0; j < swath / 2; j++) {
1907 cpl_vector_set(spec_sw, j,
1908 cpl_vector_get(spec_sw,j) * cpl_vector_get(weights_sw,j));
1909 cpl_vector_set(unc_sw, j,
1910 cpl_vector_get(unc_sw,j) * cpl_vector_get(weights_sw,j));
1911 for (y = 0; y < height; y++) {
1912 model_sw[y * swath + j] *= cpl_vector_get(weights_sw,j);
1917 cpl_vector_multiply(spec_sw, weights_sw);
1918 cpl_vector_multiply(unc_sw, weights_sw);
1919 for (y = 0; y < height; y++) {
1920 for (j = 0; j < swath; j++){
1921 model_sw[y * swath + j] *= cpl_vector_get(weights_sw,j);
1926 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1927 img_tmp = cpl_image_wrap_double(swath, height, model_sw);
1928 cpl_image_save(img_tmp,
"debug_model_after_sw.fits", CPL_TYPE_DOUBLE,
1929 NULL, CPL_IO_CREATE);
1930 cpl_image_unwrap(img_tmp);
1934 for (j=sw_start;j<sw_end;j++) {
1935 cpl_vector_set(spc, j,
1936 cpl_vector_get(spec_sw, j-sw_start) + cpl_vector_get(spc, j));
1939 cpl_vector_set(unc_decomposition, j,
1940 cpl_vector_get(unc_sw, j - sw_start)
1941 + cpl_vector_get(unc_decomposition, j));
1943 for(y = 0; y < height; y++){
1944 cpl_image_set(model_rect, j+1, y+1,
1945 cpl_image_get(model_rect, j+1, y+1, &badpix)
1946 + model_sw[y * swath + j - sw_start]);
1947 if (badpix) cpl_image_reject(model_rect, j+1, y+1);
1951 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1952 cpl_image_save(model_rect,
"debug_model_after_merge.fits",
1953 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1956 cpl_vector_delete(spec_sw);
1960 cpl_vector_divide_scalar(slitfu, nswaths);
1963 cpl_image_delete(img_mad);
1974 cpl_image_delete(img_rect);
1975 cpl_image_delete(err_rect);
1976 cpl_image_delete(img_sw);
1977 cpl_image_delete(err_sw);
1981 cpl_vector_delete(unc_sw);
1982 cpl_free(ycen_rest);
1984 cpl_free(ycen_offset_sw);
1986 cpl_vector_delete(bins_begin);
1987 cpl_vector_delete(bins_end);
1988 cpl_vector_delete(slitfu_sw);
1989 cpl_vector_delete(weights_sw);
1991 cpl_polynomial_delete(slitcurve_A);
1992 cpl_polynomial_delete(slitcurve_B);
1993 cpl_polynomial_delete(slitcurve_C);
1994 for (i=0; i<swath; i++) cpl_polynomial_delete(slitcurves_sw[i]);
1995 cpl_free(slitcurves_sw);
2000 cpl_msg_error(__func__,
"failed to reinsert model swath into model image");
2001 cpl_image_delete(model_rect);
2003 cpl_vector_delete(ycen);
2004 cpl_bivector_delete(spectrum_loc);
2005 cpl_vector_delete(slitfu);
2009 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
2010 cpl_image_save(model_rect,
"debug_model_rect.fits", CPL_TYPE_DOUBLE,
2011 NULL, CPL_IO_CREATE);
2012 cpl_image_save(img_out,
"debug_model_all.fits", CPL_TYPE_DOUBLE,
2013 NULL, CPL_IO_CREATE);
2014 cpl_vector_save(spc,
"debug_spc_all.fits", CPL_TYPE_DOUBLE,
2015 NULL, CPL_IO_CREATE);
2018 cpl_image_delete(model_rect);
2019 cpl_vector_delete(ycen);
2021 if (cpl_error_get_code() != CPL_ERROR_NONE){
2022 cpl_msg_error(__func__,
2023 "Something went wrong in the extraction. Error Code: %i, loc: %s",
2024 cpl_error_get_code(), cpl_error_get_where());
2026 cpl_vector_delete(slitfu);
2027 cpl_bivector_delete(spectrum_loc);
2032 *slit_func = slitfu;
2033 *spec = spectrum_loc;
2057 const hdrl_image * img,
2058 const cpl_table * traces,
2061 cpl_table ** extracted)
2063 cpl_bivector ** spectrum ;
2064 cpl_bivector ** position ;
2065 cpl_vector ** wavelength ;
2066 cpl_vector ** slit_fraction ;
2067 cpl_table * extract_loc ;
2068 cpl_image * wavemap;
2069 cpl_image * slitmap;
2070 int nb_traces, i, npoints ;
2073 if (img == NULL || traces == NULL)
return -1 ;
2076 nb_traces = cpl_table_get_nrow(traces) ;
2077 npoints = CR2RES_DETECTOR_SIZE * CR2RES_DETECTOR_SIZE / nb_traces;
2080 spectrum = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
2081 position = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
2082 wavelength = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
2083 slit_fraction = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
2088 cpl_msg_error(__func__,
2089 "Could not create wavelength / slit_fraction image");
2092 cpl_free(wavelength);
2093 cpl_free(slit_fraction);
2098 for (i=0 ; i<nb_traces ; i++) {
2100 spectrum[i] = NULL ;
2101 position[i] = NULL ;
2102 wavelength[i] = NULL ;
2103 slit_fraction[i] = NULL ;
2105 int order, trace_id;
2108 order = cpl_table_get(traces, CR2RES_COL_ORDER, i, NULL) ;
2109 trace_id = cpl_table_get(traces, CR2RES_COL_TRACENB, i, NULL) ;
2112 if (reduce_order > -1 && order != reduce_order) continue ;
2115 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
2117 cpl_msg_info(__func__,
"Process Order %d/Trace %d",order,trace_id) ;
2118 cpl_msg_indent_more() ;
2122 npoints, wavemap, slitmap,
2123 &(spectrum[i]), &(position[i]), &(wavelength[i]),
2124 &(slit_fraction[i])) != 0) {
2125 cpl_msg_error(__func__,
"Cannot extract2d the trace") ;
2126 spectrum[i] = NULL ;
2127 position[i] = NULL ;
2128 wavelength[i] = NULL ;
2129 slit_fraction[i] = NULL ;
2131 cpl_msg_indent_less() ;
2134 cpl_msg_indent_less() ;
2139 wavelength, slit_fraction, traces) ;
2142 for (i=0 ; i<nb_traces ; i++) {
2143 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
2144 if (position[i] != NULL) cpl_bivector_delete(position[i]) ;
2145 if (wavelength[i] != NULL) cpl_vector_delete(wavelength[i]) ;
2146 if (slit_fraction[i] != NULL) cpl_vector_delete(slit_fraction[i]) ;
2148 cpl_free(spectrum) ;
2149 cpl_free(position) ;
2150 cpl_free(wavelength) ;
2151 cpl_free(slit_fraction) ;
2152 cpl_image_delete(wavemap);
2153 cpl_image_delete(slitmap);
2156 *extracted = extract_loc ;
2181 const hdrl_image * in,
2182 const cpl_table * trace_tab,
2186 const cpl_image * wavemap,
2187 const cpl_image * slitmap,
2188 cpl_bivector ** spectrum,
2189 cpl_bivector ** position,
2190 cpl_vector ** wavelength,
2191 cpl_vector ** slit_fraction)
2193 cpl_bivector * spectrum_local ;
2194 cpl_vector * spectrum_flux ;
2195 cpl_vector * spectrum_error ;
2196 cpl_bivector * position_local ;
2197 cpl_vector * position_x;
2198 cpl_vector * position_y;
2199 cpl_vector * wavelength_local ;
2200 cpl_vector * slit_fraction_local ;
2201 const cpl_array * lower_array;
2202 const cpl_array * upper_array;
2203 cpl_polynomial * lower_poly;
2204 cpl_polynomial * upper_poly;
2214 if (in==NULL || trace_tab==NULL || spectrum==NULL || position==NULL
2215 || wavelength==NULL || slit_fraction==NULL)
return -1 ;
2219 cpl_msg_error(__func__,
"Order and/or Trace not found in trace table");
2224 wavelength_local = cpl_vector_new(npoints);
2225 slit_fraction_local = cpl_vector_new(npoints);
2226 position_x = cpl_vector_new(npoints);
2227 position_y = cpl_vector_new(npoints);
2228 spectrum_flux = cpl_vector_new(npoints);
2229 spectrum_error = cpl_vector_new(npoints);
2235 x = cpl_vector_new(CR2RES_DETECTOR_SIZE);
2236 for (i = 0; i < CR2RES_DETECTOR_SIZE; i++) cpl_vector_set(x, i, i + 1);
2238 lower_array = cpl_table_get_array(trace_tab, CR2RES_COL_LOWER, k);
2239 upper_array = cpl_table_get_array(trace_tab, CR2RES_COL_UPPER, k);
2248 for (i = 0; i < CR2RES_DETECTOR_SIZE; i++)
2250 for (j = cpl_vector_get(lower, i); j < cpl_vector_get(upper, i); j++)
2253 if (j<1 || j>CR2RES_DETECTOR_SIZE) continue ;
2255 cpl_vector_set(position_x, row, i +1);
2256 cpl_vector_set(position_y, row, j);
2261 cpl_vector_set(spectrum_flux, row, flux);
2262 cpl_vector_set(spectrum_error, row, err);
2265 cpl_vector_set(wavelength_local, row, cpl_image_get(
2266 wavemap, i + 1, j, &bad_pix));
2268 cpl_vector_set(slit_fraction_local, row, cpl_image_get(
2269 slitmap, i + 1, j, &bad_pix));
2274 for (i = row; i < npoints; i++){
2275 cpl_vector_set(position_x, i, NAN);
2276 cpl_vector_set(position_y, i, NAN);
2277 cpl_vector_set(spectrum_flux, i, NAN);
2278 cpl_vector_set(spectrum_error, i, NAN);
2279 cpl_vector_set(wavelength_local, i, NAN);
2280 cpl_vector_set(slit_fraction_local, i, NAN);
2283 position_local = cpl_bivector_wrap_vectors(position_x, position_y);
2284 spectrum_local = cpl_bivector_wrap_vectors(spectrum_flux, spectrum_error);
2286 cpl_polynomial_delete(upper_poly);
2287 cpl_polynomial_delete(lower_poly);
2288 cpl_vector_delete(upper);
2289 cpl_vector_delete(lower);
2290 cpl_vector_delete(x);
2292 *spectrum = spectrum_local ;
2293 *position = position_local ;
2294 *wavelength = wavelength_local ;
2295 *slit_fraction = slit_fraction_local ;
2311 cpl_bivector ** spectrum,
2312 cpl_bivector ** position,
2313 cpl_vector ** wavelength,
2314 cpl_vector ** slit_fraction,
2315 const cpl_table * trace_table)
2319 const double * pspec ;
2320 const double * perr ;
2321 const double * pxposition ;
2322 const double * pyposition ;
2323 const double * pwave ;
2324 const double * pslit_frac ;
2325 int nrows, all_null, i, order, trace_id, nb_traces ;
2328 if (spectrum==NULL || trace_table==NULL || position==NULL ||
2329 wavelength==NULL || slit_fraction==NULL || trace_table==NULL)
2333 nb_traces = cpl_table_get_nrow(trace_table) ;
2337 for (i=0 ; i<nb_traces ; i++)
2338 if (spectrum[i] != NULL) {
2339 nrows = cpl_bivector_get_size(spectrum[i]) ;
2342 if (all_null == 1)
return NULL ;
2345 for (i=0 ; i<nb_traces ; i++)
2346 if (spectrum[i] != NULL && cpl_bivector_get_size(spectrum[i]) != nrows)
2350 out = cpl_table_new(nrows);
2351 for (i=0 ; i<nb_traces ; i++) {
2352 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
2353 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
2356 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2357 cpl_free(col_name) ;
2360 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2361 cpl_free(col_name) ;
2364 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2365 cpl_free(col_name) ;
2368 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2369 cpl_free(col_name) ;
2372 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2373 cpl_free(col_name) ;
2376 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2377 cpl_free(col_name) ;
2381 for (i=0 ; i<nb_traces ; i++) {
2382 if (spectrum[i]!=NULL && position[i]!=NULL &&
2383 wavelength[i]!=NULL && slit_fraction[i]!=NULL) {
2384 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
2385 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
2386 pspec = cpl_bivector_get_x_data_const(spectrum[i]) ;
2387 perr = cpl_bivector_get_y_data_const(spectrum[i]);
2388 pxposition = cpl_bivector_get_x_data_const(position[i]) ;
2389 pyposition = cpl_bivector_get_y_data_const(position[i]) ;
2390 pwave = cpl_vector_get_data_const(wavelength[i]) ;
2391 pslit_frac = cpl_vector_get_data_const(slit_fraction[i]) ;
2394 cpl_table_copy_data_double(out, col_name, pspec) ;
2395 cpl_free(col_name) ;
2398 cpl_table_copy_data_double(out, col_name, perr) ;
2399 cpl_free(col_name) ;
2402 cpl_table_copy_data_double(out, col_name, pwave) ;
2403 cpl_free(col_name) ;
2406 cpl_table_copy_data_double(out, col_name, pxposition) ;
2407 cpl_free(col_name) ;
2410 cpl_table_copy_data_double(out, col_name, pyposition) ;
2411 cpl_free(col_name) ;
2414 cpl_table_copy_data_double(out, col_name, pslit_frac) ;
2415 cpl_free(col_name) ;
2455static int cr2res_extract_xi_zeta_tensors(
2460 const int * ycen_offset,
2463 cpl_polynomial ** slitcurves,
2468 int x, xx, y, yy, ix, ix1, ix2, iy, m;
2469 double step, delta, w;
2470 step = 1.e0 / osample;
2473 for (x = 0; x < ncols; x++)
2475 for (iy = 0; iy < ny; iy++)
2477 for (m = 0; m < 4; m++)
2479 xi[xi_index(x, iy, m)].x = -1;
2480 xi[xi_index(x, iy, m)].y = -1;
2481 xi[xi_index(x, iy, m)].w = 0.;
2487 for (x = 0; x < ncols; x++)
2489 for (y = 0; y < nrows; y++)
2491 m_zeta[mzeta_index(x, y)] = 0;
2492 for (ix = 0; ix < 3 * (osample + 1); ix++)
2494 zeta[zeta_index(x, y, ix)].x = -1;
2495 zeta[zeta_index(x, y, ix)].iy = -1;
2496 zeta[zeta_index(x, y, ix)].w = 0.;
2508 for (x = 0; x < ncols; x++)
2530 iy2 = osample - floor(ycen[x] * osample);
2531 iy1 = iy2 - osample;
2550 d1 = fmod(ycen[x], step);
2576 dy = ycen[x] - floor((y_lower_lim + ycen[x]) / step) * step - step;
2585 for (y = 0; y < nrows; y++) {
2589 for (iy = iy1; iy <= iy2; iy++) {
2590 if (iy == iy1) w = d1;
2591 else if (iy == iy2) w = d2;
2594 delta = cpl_polynomial_eval_1d(slitcurves[x], dy - ycen[x], NULL);
2596 ix2 = ix1 + signum(delta);
2604 if (x + ix1 >= 0 && x + ix2 < ncols)
2607 yy = y + ycen_offset[x] - ycen_offset[xx];
2608 xi[xi_index(x, iy, 3)].x = xx;
2609 xi[xi_index(x, iy, 3)].y = yy;
2610 xi[xi_index(x, iy, 3)].w = w - fabs(delta - ix1) * w;
2612 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 3)].w > 0)
2614 m = m_zeta[mzeta_index(xx, yy)];
2615 zeta[zeta_index(xx, yy, m)].x = x;
2616 zeta[zeta_index(xx, yy, m)].iy = iy;
2617 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 3)].w;
2618 m_zeta[mzeta_index(xx, yy)]++;
2627 yy = y + ycen_offset[x] - ycen_offset[xx];
2629 xi[xi_index(x, iy, 2)].x = xx;
2630 xi[xi_index(x, iy, 2)].y = yy;
2631 xi[xi_index(x, iy, 2)].w = fabs(delta - ix1) * w;
2632 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 2)].w > 0)
2634 m = m_zeta[mzeta_index(xx, yy)];
2635 zeta[zeta_index(xx, yy, m)].x = x;
2636 zeta[zeta_index(xx, yy, m)].iy = iy;
2637 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 2)].w;
2638 m_zeta[mzeta_index(xx, yy)]++;
2644 if (x + ix2 >= 0 && x + ix1 < ncols)
2647 yy = y + ycen_offset[x] - ycen_offset[xx];
2648 xi[xi_index(x, iy, 2)].x = xx;
2649 xi[xi_index(x, iy, 2)].y = yy;
2650 xi[xi_index(x, iy, 2)].w = fabs(delta - ix1) * w;
2651 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 2)].w > 0)
2653 m = m_zeta[mzeta_index(xx, yy)];
2654 zeta[zeta_index(xx, yy, m)].x = x;
2655 zeta[zeta_index(xx, yy, m)].iy = iy;
2656 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 2)].w;
2657 m_zeta[mzeta_index(xx, yy)]++;
2660 yy = y + ycen_offset[x] - ycen_offset[xx];
2661 xi[xi_index(x, iy, 3)].x = xx;
2662 xi[xi_index(x, iy, 3)].y = yy;
2663 xi[xi_index(x, iy, 3)].w = w - fabs(delta - ix1) * w;
2664 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 3)].w > 0)
2666 m = m_zeta[mzeta_index(xx, yy)];
2667 zeta[zeta_index(xx, yy, m)].x = x;
2668 zeta[zeta_index(xx, yy, m)].iy = iy;
2669 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 3)].w;
2670 m_zeta[mzeta_index(xx, yy)]++;
2676 if (x + ix1 >= 0 && x + ix1 < ncols)
2679 yy = y + ycen_offset[x] - ycen_offset[xx];
2680 xi[xi_index(x, iy, 2)].x = xx;
2681 xi[xi_index(x, iy, 2)].y = yy;
2682 xi[xi_index(x, iy, 2)].w = w;
2683 if (yy >= 0 && yy < nrows && w > 0)
2685 m = m_zeta[mzeta_index(xx, yy)];
2686 zeta[zeta_index(xx, yy, m)].x = x;
2687 zeta[zeta_index(xx, yy, m)].iy = iy;
2688 zeta[zeta_index(xx, yy, m)].w = w;
2689 m_zeta[mzeta_index(xx, yy)]++;
2698 if (x + ix1 >= 0 && x + ix2 < ncols)
2701 yy = y + ycen_offset[x] - ycen_offset[xx];
2702 xi[xi_index(x, iy, 1)].x = xx;
2703 xi[xi_index(x, iy, 1)].y = yy;
2704 xi[xi_index(x, iy, 1)].w = w - fabs(delta - ix1) * w;
2705 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2707 m = m_zeta[mzeta_index(xx, yy)];
2708 zeta[zeta_index(xx, yy, m)].x = x;
2709 zeta[zeta_index(xx, yy, m)].iy = iy;
2710 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2711 m_zeta[mzeta_index(xx, yy)]++;
2714 yy = y + ycen_offset[x] - ycen_offset[xx];
2715 xi[xi_index(x, iy, 0)].x = xx;
2716 xi[xi_index(x, iy, 0)].y = yy;
2717 xi[xi_index(x, iy, 0)].w = fabs(delta - ix1) * w;
2718 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2720 m = m_zeta[mzeta_index(xx, yy)];
2721 zeta[zeta_index(xx, yy, m)].x = x;
2722 zeta[zeta_index(xx, yy, m)].iy = iy;
2723 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2724 m_zeta[mzeta_index(xx, yy)]++;
2730 if (x + ix2 >= 0 && x + ix1 < ncols)
2733 yy = y + ycen_offset[x] - ycen_offset[xx];
2734 xi[xi_index(x, iy, 0)].x = xx;
2735 xi[xi_index(x, iy, 0)].y = yy;
2736 xi[xi_index(x, iy, 0)].w = fabs(delta - ix1) * w;
2737 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2739 m = m_zeta[mzeta_index(xx, yy)];
2740 zeta[zeta_index(xx, yy, m)].x = x;
2741 zeta[zeta_index(xx, yy, m)].iy = iy;
2742 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2743 m_zeta[mzeta_index(xx, yy)]++;
2746 yy = y + ycen_offset[x] - ycen_offset[xx];
2747 xi[xi_index(x, iy, 1)].x = xx;
2748 xi[xi_index(x, iy, 1)].y = yy;
2749 xi[xi_index(x, iy, 1)].w = w - fabs(delta - ix1) * w;
2750 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2752 m = m_zeta[mzeta_index(xx, yy)];
2753 zeta[zeta_index(xx, yy, m)].x = x;
2754 zeta[zeta_index(xx, yy, m)].iy = iy;
2755 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2756 m_zeta[mzeta_index(xx, yy)]++;
2762 if (x + ix1 >= 0 && x + ix1 < ncols)
2765 yy = y + ycen_offset[x] - ycen_offset[xx];
2766 xi[xi_index(x, iy, 0)].x = xx;
2767 xi[xi_index(x, iy, 0)].y = yy;
2768 xi[xi_index(x, iy, 0)].w = w;
2769 if (yy >= 0 && yy < nrows && w > 0)
2771 m = m_zeta[mzeta_index(xx, yy)];
2772 zeta[zeta_index(xx, yy, m)].x = x;
2773 zeta[zeta_index(xx, yy, m)].iy = iy;
2774 zeta[zeta_index(xx, yy, m)].w = w;
2775 m_zeta[mzeta_index(xx, yy)]++;
2784 if (x + ix1 >= 0 && x + ix2 < ncols)
2787 yy = y + ycen_offset[x] - ycen_offset[xx];
2788 xi[xi_index(x, iy, 1)].x = xx;
2789 xi[xi_index(x, iy, 1)].y = yy;
2790 xi[xi_index(x, iy, 1)].w = w - fabs(delta - ix1) * w;
2791 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2793 m = m_zeta[mzeta_index(xx, yy)];
2794 zeta[zeta_index(xx, yy, m)].x = x;
2795 zeta[zeta_index(xx, yy, m)].iy = iy;
2796 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2797 m_zeta[mzeta_index(xx, yy)]++;
2800 yy = y + ycen_offset[x] - ycen_offset[xx];
2801 xi[xi_index(x, iy, 0)].x = xx;
2802 xi[xi_index(x, iy, 0)].y = yy;
2803 xi[xi_index(x, iy, 0)].w = fabs(delta - ix1) * w;
2804 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2806 m = m_zeta[mzeta_index(xx, yy)];
2807 zeta[zeta_index(xx, yy, m)].x = x;
2808 zeta[zeta_index(xx, yy, m)].iy = iy;
2809 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2810 m_zeta[mzeta_index(xx, yy)]++;
2816 if (x + ix2 >= 0 && x + ix1 < ncols)
2819 yy = y + ycen_offset[x] - ycen_offset[xx];
2820 xi[xi_index(x, iy, 1)].x = xx;
2821 xi[xi_index(x, iy, 1)].y = yy;
2822 xi[xi_index(x, iy, 1)].w = fabs(delta - ix1) * w;
2823 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2825 m = m_zeta[mzeta_index(xx, yy)];
2826 zeta[zeta_index(xx, yy, m)].x = x;
2827 zeta[zeta_index(xx, yy, m)].iy = iy;
2828 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2829 m_zeta[mzeta_index(xx, yy)]++;
2832 yy = y + ycen_offset[x] - ycen_offset[xx];
2833 xi[xi_index(x, iy, 0)].x = xx;
2834 xi[xi_index(x, iy, 0)].y = yy;
2835 xi[xi_index(x, iy, 0)].w = w - fabs(delta - ix1) * w;
2836 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2838 m = m_zeta[mzeta_index(xx, yy)];
2839 zeta[zeta_index(xx, yy, m)].x = x;
2840 zeta[zeta_index(xx, yy, m)].iy = iy;
2841 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2842 m_zeta[mzeta_index(xx, yy)]++;
2848 if (x + ix2 >= 0 && x + ix2 < ncols)
2851 yy = y + ycen_offset[x] - ycen_offset[xx];
2852 xi[xi_index(x, iy, 0)].x = xx;
2853 xi[xi_index(x, iy, 0)].y = yy;
2854 xi[xi_index(x, iy, 0)].w = w;
2855 if (yy >= 0 && yy < nrows && w > 0)
2857 m = m_zeta[mzeta_index(xx, yy)];
2858 zeta[zeta_index(xx, yy, m)].x = x;
2859 zeta[zeta_index(xx, yy, m)].iy = iy;
2860 zeta[zeta_index(xx, yy, m)].w = w;
2861 m_zeta[mzeta_index(xx, yy)]++;
2900static int cr2res_extract_slit_func_curved(
2901 double error_factor,
2911 cpl_polynomial ** slitcurves,
2922 const double * slit_func_in,
2928 cpl_image * img_mad,
2933 int x, xx, xxx, y, yy, iy, jy, n, m, ny, nx;
2934 double norm, lambda, diag_tot, ww, www, sP_change, sP_med;
2935 double tmp, sLmax, sum;
2937 cpl_vector *tmp_vec;
2941 ny = osample * (nrows + 1) + 1;
2942 nx = 4 * delta_x + 1;
2946 cr2res_extract_xi_zeta_tensors(ncols, nrows, ny, ycen, ycen_offset,
2947 y_lower_lim, osample, slitcurves, xi, zeta,
2951 if (slit_func_in != NULL) {
2954 for (iy = 0; iy < ny; iy++) {
2955 sL[iy] = slit_func_in[iy];
2959 for (iy = 0; iy < ny; iy++)
2982 if (slit_func_in == NULL) {
2985 for (iy = 0; iy < ny; iy++) {
2988 for (jy = 0; jy <= 4 * osample; jy++)
2989 l_Aij[iy + ny * jy] = 0.e0;
2993 for (iy = 0; iy < ny; iy++) {
2994 for (x = 0; x < ncols; x++) {
2995 for (n = 0; n < 4; n++) {
2996 ww = xi[xi_index(x, iy, n)].w;
2998 xx = xi[xi_index(x, iy, n)].x;
2999 yy = xi[xi_index(x, iy, n)].y;
3000 if (xx >= 0 && xx < ncols && yy >= 0 &&
3002 if (m_zeta[mzeta_index(xx, yy)] > 0) {
3003 for (m = 0; m < m_zeta[mzeta_index(xx, yy)];
3005 xxx = zeta[zeta_index(xx, yy, m)].x;
3006 jy = zeta[zeta_index(xx, yy, m)].iy;
3007 www = zeta[zeta_index(xx, yy, m)].w;
3008 if (jy - iy + 2 * osample >= 0)
3009 l_Aij[iy + ny * (jy - iy +
3011 sP[xxx] * sP[x] * www * ww *
3012 mask[yy * ncols + xx];
3014 l_bj[iy] += im[yy * ncols + xx] *
3015 mask[yy * ncols + xx] * sP[x] *
3022 diag_tot += fabs(l_Aij[iy + ny * 2 * osample]);
3025 lambda = lambda_sL * diag_tot / ny;
3028 l_Aij[ny * 2 * osample] += lambda;
3030 l_Aij[ny * (2 * osample + 1)] -= lambda;
3031 for (iy = 1; iy < ny - 1; iy++) {
3033 l_Aij[iy + ny * (2 * osample - 1)] -= lambda;
3035 l_Aij[iy + ny * 2 * osample] += lambda * 2.e0;
3037 l_Aij[iy + ny * (2 * osample + 1)] -= lambda;
3040 l_Aij[ny - 1 + ny * (2 * osample - 1)] -= lambda;
3042 l_Aij[ny - 1 + ny * 2 * osample] += lambda;
3045 info = cr2res_extract_slitdec_bandsol(l_Aij, l_bj, ny,
3046 4 * osample + 1, lambda);
3048 cpl_msg_error(__func__,
"info(sL)=%d\n", info);
3052 for (iy = 0; iy < ny; iy++) {
3054 norm += fabs(sL[iy]);
3057 for (iy = 0; iy < ny; iy++)
3062 for (x = 0; x < ncols; x++) {
3063 for (xx = 0; xx < nx; xx++)
3064 p_Aij[xx * ncols + x] = 0.;
3067 for (x = 0; x < ncols; x++) {
3068 for (iy = 0; iy < ny; iy++) {
3069 for (n = 0; n < 4; n++) {
3070 ww = xi[xi_index(x, iy, n)].w;
3072 xx = xi[xi_index(x, iy, n)].x;
3073 yy = xi[xi_index(x, iy, n)].y;
3074 if (xx >= 0 && xx < ncols && yy >= 0 && yy < nrows) {
3075 if (m_zeta[mzeta_index(xx, yy)] > 0) {
3076 for (m = 0; m < m_zeta[mzeta_index(xx, yy)];
3078 xxx = zeta[zeta_index(xx, yy, m)].x;
3079 jy = zeta[zeta_index(xx, yy, m)].iy;
3080 www = zeta[zeta_index(xx, yy, m)].w;
3082 ncols * (xxx - x + 2 * delta_x)] +=
3083 sL[jy] * sL[iy] * www * ww *
3084 mask[yy * ncols + xx];
3086 p_bj[x] += im[yy * ncols + xx] *
3087 mask[yy * ncols + xx] * sL[iy] * ww;
3096 for (x = 0; x < ncols; x++)
3100 if (lambda_sP > 0.e0) {
3102 p_Aij[ncols * (2 * delta_x)] += lambda;
3103 p_Aij[ncols * (2 * delta_x + 1)] -= lambda;
3104 for (x = 1; x < ncols - 1; x++) {
3106 p_Aij[x + ncols * (2 * delta_x - 1)] -= lambda;
3108 p_Aij[x + ncols * (2 * delta_x)] += lambda * 2.e0;
3110 p_Aij[x + ncols * (2 * delta_x + 1)] -= lambda;
3113 p_Aij[ncols - 1 + ncols * (2 * delta_x - 1)] -= lambda;
3115 p_Aij[ncols - 1 + ncols * (2 * delta_x)] += lambda;
3119 info = cr2res_extract_slitdec_bandsol(p_Aij, p_bj, ncols, nx, lambda);
3121 cpl_msg_error(__func__,
"info(sP)=%d\n", info);
3123 for (x = 0; x < ncols; x++)
3128 tmp_vec = cpl_vector_wrap(ncols, sP);
3129 sP_med = fabs(cpl_vector_get_median_const(tmp_vec));
3130 cpl_vector_unwrap(tmp_vec);
3134 for (x = 0; x < ncols; x++) {
3135 if (fabs(sP[x] - sP_old[x]) > sP_change)
3136 sP_change = fabs(sP[x] - sP_old[x]);
3139 if ((isnan(sP[0]) || (sP[ncols / 2] == 0)) &&
3140 (cpl_msg_get_level() == CPL_MSG_DEBUG)) {
3141 debug_output(ncols, nrows, osample, im, pix_unc, mask, ycen,
3142 ycen_offset, y_lower_lim, slitcurves);
3143 cpl_msg_error(__func__,
"Swath failed");
3147 for (y = 0; y < nrows * ncols; y++) {
3150 for (y = 0; y < nrows; y++) {
3151 for (x = 0; x < ncols; x++) {
3152 for (m = 0; m < m_zeta[mzeta_index(x, y)]; m++) {
3153 xx = zeta[zeta_index(x, y, m)].x;
3154 iy = zeta[zeta_index(x, y, m)].iy;
3155 ww = zeta[zeta_index(x, y, m)].w;
3156 model[y * ncols + x] += sP[xx] * sL[iy] * ww;
3171 for (y = 0; y < nrows; y++) {
3172 for (x = delta_x; x < ncols - delta_x; x++) {
3173 if (mask[y * ncols + x]) {
3174 tmp = model[y * ncols + x] - im[y * ncols + x];
3176 tmp /= max(pix_unc[y * ncols + x], 1);
3182 cost /= (isum - (ncols + ny));
3183 sigma = sqrt(sum / isum);
3186 for (y = 0; y < nrows; y++) {
3187 for (x = delta_x; x < ncols - delta_x; x++) {
3188 if (fabs(model[y * ncols + x] - im[y * ncols + x]) >
3190 mask[y * ncols + x] = 0;
3192 mask[y * ncols + x] = 1;
3196 for (y = 0; y < nrows; y++) {
3197 for (x = delta_x; x < ncols - delta_x; x++) {
3198 cpl_image_set(img_mad, x + 1, y + 1,
3199 (model[y * ncols + x] - im[y * ncols + x]));
3200 if ((mask[y * ncols + x] == 0) | (im[y * ncols + x] == 0))
3201 cpl_image_reject(img_mad, x + 1, y + 1);
3207 "Iter: %i, Sigma: %f, Cost: %f, sP_change: %f, sP_lim: %f", iter,
3208 sigma, cost, sP_change, sP_stop * sP_med);
3211 }
while (iter == 1 ||
3214 && sP_change > sP_stop * sP_med));
3216 if (iter == maxiter && sP_change > sP_stop * sP_med)
3219 "Maximum number of %d iterations reached without converging.",
3224 for (y = 0; y < ny; y++)
3227 for (y = 0; y < ny; y++)
3229 for (x = 0; x < ncols; x++)
3233 tmp_vec = cpl_vector_wrap(ny, sL);
3234 sLmax = cpl_vector_get_max(tmp_vec);
3235 cpl_vector_unwrap(tmp_vec);
3236 cpl_msg_debug(__func__,
3237 "sL-sum, sLmax, osample, nrows, ny: %g, %g, %d, %d, %d", sum,
3238 sLmax, osample, nrows, ny);
3241 for (x = 0; x < ncols; x++) {
3247 for (y = 0; y < nrows; y++) {
3248 if (mask[y * ncols + x]) {
3249 msum += (im[y * ncols + x] * model[y * ncols + x]) *
3250 mask[y * ncols + x];
3251 sum += (model[y * ncols + x] * model[y * ncols + x]) *
3252 mask[y * ncols + x];
3255 unc[x] = sqrt(sP[x] * sum / msum / error_factor);
3288int cr2res_extract_slitdec_bandsol(
3301 for(i=0; i<n-1; i++)
3304 if(aa==0.e0) aa = lambda;
3306 for(j=0; j<nd; j++) a[i+j*n]/=aa;
3307 for(j=1; j<min(nd/2+1,n-i); j++)
3309 aa=a[i+j+n*(nd/2-j)];
3311 for(k=0; k<n*(nd-j); k+=n) a[i+j+k]-=a[i+k+n*j]*aa;
3316 aa = a[n-1+n*(nd/2)];
3317 if (aa == 0) aa = lambda;
3319 for(i=n-1; i>0; i--)
3321 for(j=1; j<=min(nd/2,i); j++){
3322 r[i-j]-=r[i]*a[i-j+n*(nd/2+j)];
3324 aa = a[i-1+n*(nd/2)];
3325 if(aa==0.e0) aa = lambda;
3331 if(aa==0.e0) aa = lambda;
3348static int cr2res_extract_slitdec_adjust_swath(
3355 cpl_vector ** bins_begin,
3356 cpl_vector ** bins_end)
3358 if (sw <= 0 || lenx <= 0)
return -1;
3359 if (bins_begin == NULL || bins_end == NULL)
return -1;
3360 if (ycen == NULL)
return -1;
3363 if (sw==CR2RES_DETECTOR_SIZE){
3364 *bins_begin = cpl_vector_new(1);
3365 *bins_end = cpl_vector_new(1);
3366 cpl_vector_set(*bins_begin, 0, 0);
3367 cpl_vector_set(*bins_end, 0, CR2RES_DETECTOR_SIZE);
3368 return CR2RES_DETECTOR_SIZE;
3371 int nbin, nx, i = 0;
3373 int start = 0, end = lenx;
3378 for (i=0; i < lenx; i++){
3379 ymin = ycen_int[i] - (height/2);
3380 ymax = ycen_int[i] + (height/2) + height%2 ;
3381 if (!((ymax <= 1) || (ymin > leny))){
3387 for (i = lenx - 1; i >= 0; i--){
3388 ymin = ycen_int[i] - (height/2);
3389 ymax = ycen_int[i] + (height/2) + height%2 ;
3390 if (!((ymax <= 1) || (ymin > leny))){
3403 if (sw > nx - 2 * dx) {
3405 if (sw % 2 == 1) sw -= 1;
3406 }
else if (sw % 2 == 1) sw += 1;
3409 nbin = 2 * ((nx - 2 * dx) / sw);
3410 if ((nx - 2 * dx) % sw > sw / 2) nbin++;
3411 if (nbin < 1) nbin = 1;
3415 *bins_begin = cpl_vector_new(nbin);
3416 *bins_end = cpl_vector_new(nbin);
3419 for(i = 0; i < nbin; i++)
3422 bin = start + min(i * step, nx - sw - 2 * dx);
3423 cpl_vector_set(*bins_begin, i, bin);
3424 cpl_vector_set(*bins_end, i, bin + sw + 2 * dx);
3425 cpl_msg_debug(__func__,
"Swath %d goes from %d to %d.", i, bin,
3431static int debug_output(
3441 cpl_polynomial ** slitcurves)
3445 cpl_propertylist * pl;
3447 pl = cpl_propertylist_new();
3448 cpl_propertylist_append_int(pl,
"osample", osample);
3449 cpl_propertylist_append_int(pl,
"y_lower_lim", y_lower_lim);
3451 img = cpl_image_wrap_double(ncols, nrows, im);
3452 cpl_image_save(img,
"debug_image_at_error.fits", CPL_TYPE_DOUBLE, pl,
3454 cpl_image_unwrap(img);
3456 img = cpl_image_wrap_int(ncols, nrows, mask);
3457 cpl_image_save(img,
"debug_mask_after_error.fits", CPL_TYPE_INT, NULL,
3459 cpl_image_unwrap(img);
3461 img = cpl_image_wrap_double(ncols, nrows, pix_unc);
3462 cpl_image_save(img,
"debug_unc_at_error.fits", CPL_TYPE_DOUBLE, NULL,
3464 cpl_image_unwrap(img);
3466 vec = cpl_vector_wrap(ncols, ycen);
3467 cpl_vector_save(vec,
"debug_ycen_after_error.fits", CPL_TYPE_DOUBLE, NULL,
3469 cpl_vector_unwrap(vec);
3471 vec = cpl_vector_new(ncols);
3472 for (
int i = 0; i < ncols; i++) cpl_vector_set(vec, i, ycen_offset[i]);
3473 cpl_vector_save(vec,
"debug_offset_after_error.fits", CPL_TYPE_INT, NULL,
3475 cpl_vector_delete(vec);
3477 img = cpl_image_new(ncols, 3, CPL_TYPE_DOUBLE);
3478 for (cpl_size i = 0; i < ncols; i++){
3479 for (cpl_size j = 0; j < 3 ; j++){
3480 cpl_image_set(img, i+1, j+1,
3481 cpl_polynomial_get_coeff(slitcurves[i], &j));
3484 cpl_image_save(img,
"debug_slitcurves_at_error.fits", CPL_TYPE_DOUBLE,
3485 NULL, CPL_IO_CREATE);
3486 cpl_image_delete(img);
3488 cpl_propertylist_delete(pl);
char * cr2res_dfs_SLIT_FUNC_colname(int order_idx, int trace)
Get the SLIT_FUNC table column name for a given order/trace.
char * cr2res_dfs_SPEC_ERR_colname(int order_idx, int trace)
Get the ERR column name for a given order/trace.
char * cr2res_dfs_WAVELENGTH_colname(int order_idx, int trace)
Get the WAVELENGTH column name for a given order/trace.
char * cr2res_dfs_POSITIONY_colname(int order_idx, int trace)
Get the POSITIONY table column name for a given order/trace.
char * cr2res_dfs_SLIT_FRACTION_colname(int order_idx, int trace)
Get the SLIT_FRACTION table column name for a given order/trace.
char * cr2res_dfs_SPEC_colname(int order_idx, int trace)
Get the SPEC column name for a given order/trace.
char * cr2res_dfs_POSITIONX_colname(int order_idx, int trace)
Get the POSITIONX table column name for a given order/trace.
cpl_vector * cr2res_trace_get_ycen(const cpl_table *trace, int order_idx, int trace_nb, int size)
Retrieves the middle (All) polynomial from trace table and evaluates.
int cr2res_trace_get_height(const cpl_table *trace, cpl_size order_idx, cpl_size trace_nb)
Computes the average height (pix) of an order, from trace polys.
cpl_size cr2res_get_trace_table_index(const cpl_table *trace_wave, int order_idx, int trace_nb)
Get the index in a TRACE_WAVE table.
cpl_polynomial * cr2res_get_trace_wave_poly(const cpl_table *trace_wave, const char *poly_column, int order_idx, int trace_nb)
Get a polynomial from a TRACE_WAVE table.
cpl_vector * cr2res_trace_get_wl(const cpl_table *trace_wave, int order_idx, int trace_nb, int size)
Get the Wavelength vector from a TRACE_WAVE table.
cpl_image * cr2res_image_cut_rectify(const cpl_image *img_in, const cpl_vector *ycen, int height)
Cut a bent order into a rectangle, shifting columns.
int * cr2res_vector_get_int(const cpl_vector *ycen)
cpl_polynomial * cr2res_convert_array_to_poly(const cpl_array *arr)
Convert an array to polynomial.
double * cr2res_vector_get_rest(const cpl_vector *ycen)
cpl_vector * cr2res_polynomial_eval_vector(const cpl_polynomial *poly, const cpl_vector *vec)
Evaluate a polynomial on a vector.
int cr2res_slit_pos_image(const cpl_table *trace_wave, cpl_image **slitpos, cpl_image **wavelength)
get a image of the slitposition (and wavelength) along the slit
int cr2res_image_insert_rect(const cpl_image *rect_in, const cpl_vector *ycen, cpl_image *img_out)
Re-insert a rectangular cut-out of an order into the full frame.
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
cpl_error_code hdrl_image_set_pixel(hdrl_image *self, cpl_size xpos, cpl_size ypos, hdrl_value value)
set pixel values of hdrl_image
cpl_error_code hdrl_image_mul_scalar(hdrl_image *self, hdrl_value value)
Elementwise multiplication of an image with a scalar.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
const cpl_image * hdrl_image_get_error_const(const hdrl_image *himg)
get error as cpl image
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
hdrl_image * hdrl_image_new(cpl_size nx, cpl_size ny)
create new zero filled hdrl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image