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(
92 cpl_polynomial ** slitcurves,
103 const double * slit_func_in,
114static int cr2res_extract_xi_zeta_tensors(
119 const int * ycen_offset,
122 cpl_polynomial ** slitcurves,
127static int cr2res_extract_slitdec_adjust_swath(
134 cpl_vector ** bins_begin,
135 cpl_vector ** bins_end) ;
137static int debug_output(
int ncols,
146 cpl_polynomial ** slitcurves);
186 const hdrl_image * img,
187 const cpl_table * traces,
188 const cpl_table * slit_func_in,
189 const cpl_table * blaze_table_in,
193 cr2res_extr_method extr_method,
206 cpl_table ** extracted,
207 cpl_table ** slit_func,
208 hdrl_image ** model_master)
210 cpl_bivector ** spectrum ;
213 cpl_bivector * blaze_biv ;
214 cpl_bivector * blaze_err_biv ;
216 double * pblaze_err ;
217 cpl_vector * tmp_vec ;
218 cpl_vector * slit_func_in_vec ;
219 cpl_vector ** slit_func_vec ;
220 cpl_table * slit_func_loc ;
221 cpl_table * extract_loc ;
222 hdrl_image * model_loc ;
223 hdrl_image * model_loc_one ;
224 double first_nonzero_value, first_nonzero_error,
225 norm_factor, val, err ;
232 if (img == NULL || traces == NULL)
return -1 ;
235 nb_traces = cpl_table_get_nrow(traces) ;
238 spectrum = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
239 slit_func_vec = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
244 for (i=0 ; i<nb_traces ; i++) {
248 slit_func_vec[i] = NULL ;
250 model_loc_one = NULL ;
253 order = cpl_table_get(traces, CR2RES_COL_ORDER, i, NULL) ;
254 trace_id = cpl_table_get(traces, CR2RES_COL_TRACENB, i, NULL) ;
257 if (reduce_order > -1 && order != reduce_order) continue ;
260 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
262 cpl_msg_info(__func__,
"Process Order %d/Trace %d",order,trace_id) ;
263 cpl_msg_indent_more() ;
266 if (slit_func_in != NULL) {
269 trace_id, &slit_func_in_vec) ;
271 slit_func_in_vec = NULL ;
275 if (extr_method == CR2RES_EXTR_SUM) {
277 trace_id, extr_height, &(slit_func_vec[i]),
278 &(spectrum[i]), &model_loc_one) != 0) {
279 cpl_msg_error(__func__,
"Cannot (sum-)extract the trace") ;
280 if (slit_func_in_vec != NULL)
281 cpl_vector_delete(slit_func_in_vec) ;
282 slit_func_vec[i] = NULL ;
284 model_loc_one = NULL ;
286 cpl_msg_indent_less() ;
289 }
else if (extr_method == CR2RES_EXTR_MEDIAN) {
291 trace_id, extr_height, &(slit_func_vec[i]),
292 &(spectrum[i]), &model_loc_one) != 0) {
293 cpl_msg_error(__func__,
"Cannot (median-)extract the trace") ;
294 if (slit_func_in_vec != NULL)
295 cpl_vector_delete(slit_func_in_vec) ;
296 slit_func_vec[i] = NULL ;
298 model_loc_one = NULL ;
300 cpl_msg_indent_less() ;
303 }
else if (extr_method == CR2RES_EXTR_TILTSUM) {
305 trace_id, extr_height, &(slit_func_vec[i]),
306 &(spectrum[i]), &model_loc_one) != 0) {
307 cpl_msg_error(__func__,
"Cannot (tiltsum-)extract the trace") ;
308 if (slit_func_in_vec != NULL)
309 cpl_vector_delete(slit_func_in_vec) ;
310 slit_func_vec[i] = NULL ;
312 model_loc_one = NULL ;
314 cpl_msg_indent_less() ;
317 }
else if (extr_method == CR2RES_EXTR_OPT_CURV) {
319 order, trace_id, extr_height, swath_width,
320 oversample, pclip, smooth_slit, smooth_spec,
321 niter, kappa, error_factor,
323 &(spectrum[i]), &model_loc_one) != 0) {
324 cpl_msg_error(__func__,
325 "Cannot extract order %d, trace %d", order, trace_id) ;
326 if (slit_func_in_vec != NULL)
327 cpl_vector_delete(slit_func_in_vec) ;
328 slit_func_vec[i] = NULL ;
330 model_loc_one = NULL ;
332 cpl_msg_indent_less() ;
336 if (slit_func_in_vec != NULL) cpl_vector_delete(slit_func_in_vec) ;
339 if (blaze_table_in != NULL) {
341 trace_id, &blaze_biv, &blaze_err_biv)) {
342 cpl_msg_warning(__func__,
343 "Cannot Get the Blaze for order/trace:%d/%d - skip",
348 cpl_vector_get_data(cpl_bivector_get_y(blaze_biv)) ;
350 cpl_vector_get_data(cpl_bivector_get_y(blaze_err_biv)) ;
351 first_nonzero_value = first_nonzero_error = 0.0 ;
352 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
353 if (fabs(pblaze[j])>1e-3) {
354 first_nonzero_value = pblaze[j] ;
355 first_nonzero_error = pblaze_err[j] ;
359 if (fabs(first_nonzero_value)<1e-3) {
360 cpl_msg_warning(__func__,
"Blaze filled with zeros - skip");
362 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
363 if (fabs(pblaze[j])<1e-3) {
364 pblaze[j] = first_nonzero_value ;
365 pblaze_err[j] = first_nonzero_error ;
375 norm_factor = blaze_norm;
377 tmp_vec=cpl_vector_duplicate(cpl_bivector_get_y(blaze_biv));
378 kth = (cpl_size)(cpl_bivector_get_size(blaze_biv)*0.95) ;
379 irplib_vector_get_kth(tmp_vec, kth) ;
380 norm_factor = cpl_vector_get(tmp_vec, kth) ;
381 cpl_vector_delete(tmp_vec) ;
385 pspec = cpl_bivector_get_x_data(spectrum[i]) ;
386 pspec_err = cpl_bivector_get_y_data(spectrum[i]);
387 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
388 if (fabs(pspec[j]) > 1e-3) {
390 val = pspec[j] / (pblaze[j]/norm_factor) ;
394 err = fabs(val) * sqrt(((pspec_err[j]*pspec_err[j])/
395 (pspec[j]*pspec[j]))+
396 ((pblaze_err[j]*pblaze_err[j])/
397 (pblaze[j]*pblaze[j])));
406 if (cpl_error_get_code()) {
408 cpl_msg_warning(__func__,
409 "Cannot Correct Blaze for order/trace:%d/%d - skip",
413 cpl_bivector_delete(blaze_biv) ;
414 cpl_bivector_delete(blaze_err_biv) ;
419 if (model_loc_one != NULL) {
425 if (pixval.data != 0 && badpix == 0){
434 if (display && disp_order_idx==order && disp_trace==trace_id) {
436 "set grid;set xlabel 'pixels';set ylabel 'Flux (ADU)';",
437 "t 'Extracted Spectrum' w lines",
"",
438 cpl_bivector_get_x_const(spectrum[i])) ;
440 cpl_msg_indent_less() ;
446 cpl_msg_error(__func__,
"Cannot compute the slit function") ;
447 for (i=0 ; i<nb_traces ; i++) {
448 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
449 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
452 cpl_free(slit_func_vec) ;
460 for (i=0 ; i<nb_traces ; i++) {
461 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
462 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
465 cpl_free(slit_func_vec) ;
467 cpl_table_delete(slit_func_loc);
472 for (i=0 ; i<nb_traces ; i++) {
473 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
474 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
477 cpl_free(slit_func_vec) ;
480 *extracted = extract_loc ;
481 *slit_func = slit_func_loc ;
482 *model_master = model_loc;
511 const hdrl_image * hdrl_in,
512 const cpl_table * trace_tab,
516 cpl_vector ** slit_func,
517 cpl_bivector ** spec,
524 const cpl_image * img_in;
525 const cpl_image * err_in;
531 double trace_cen, trace_height ;
535 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
541 imtyp = cpl_image_get_type(img_in);
542 lenx = cpl_image_get_size_x(img_in);
543 leny = cpl_image_get_size_y(img_in);
549 cpl_msg_error(__func__,
"Cannot compute height");
555 trace_id, lenx)) == NULL) {
556 cpl_msg_error(__func__,
"Cannot get ycen");
559 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
561 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
562 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
565 if (img_tmp == NULL) {
566 cpl_msg_error(__func__,
"Cannot rectify order");
567 cpl_vector_delete(ycen);
571 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
572 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
573 NULL, CPL_IO_CREATE);
575 img_1d = cpl_image_collapse_create(img_tmp, 0);
576 spc = cpl_vector_new_from_image_row(img_1d, 1);
577 cpl_image_delete(img_1d);
579 img_1d = cpl_image_collapse_create(img_tmp, 1);
580 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
581 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
582 cpl_image_delete(img_1d);
583 cpl_image_delete(img_tmp);
586 if (img_tmp == NULL) {
587 cpl_msg_error(__func__,
"Cannot rectify error");
588 cpl_vector_delete(ycen);
591 cpl_image_multiply(img_tmp, img_tmp);
592 img_1d = cpl_image_collapse_create(img_tmp, 0);
593 sigma = cpl_vector_new_from_image_row(img_1d, 1);
594 cpl_vector_sqrt(sigma);
595 cpl_image_delete(img_tmp);
596 cpl_image_delete(img_1d);
599 img_tmp = cpl_image_new(lenx, leny, imtyp);
601 for (i=1;i<=lenx;i++){
602 for (j=1;j<=height;j++){
603 y = ycen_int[i-1]-(height/2)+j;
604 if ((y <=0) || (y > leny)){
continue; }
605 cpl_image_set(img_tmp, i, y,
606 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
609 cpl_vector_delete(ycen);
612 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
613 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
614 NULL, CPL_IO_CREATE);
619 *spec = cpl_bivector_wrap_vectors(spc, sigma);
621 cpl_image_delete(img_tmp);
623 if (cpl_error_get_code() != CPL_ERROR_NONE){
624 cpl_msg_error(__func__,
"Error in the vertical sum extraction %s",
625 cpl_error_get_where());
659 const hdrl_image * hdrl_in,
660 const cpl_table * trace_tab,
664 cpl_vector ** slit_func,
665 cpl_bivector ** spec,
672 const cpl_image * img_in;
673 const cpl_image * err_in;
679 double trace_cen, trace_height ;
683 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
689 imtyp = cpl_image_get_type(img_in);
690 lenx = cpl_image_get_size_x(img_in);
691 leny = cpl_image_get_size_y(img_in);
697 cpl_msg_error(__func__,
"Cannot compute height");
703 trace_id, lenx)) == NULL) {
704 cpl_msg_error(__func__,
"Cannot get ycen");
707 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
709 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
710 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
713 if (img_tmp == NULL) {
714 cpl_msg_error(__func__,
"Cannot rectify order");
715 cpl_vector_delete(ycen);
719 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
720 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
721 NULL, CPL_IO_CREATE);
723 img_1d = cpl_image_collapse_median_create(img_tmp, 0, 0, 0);
724 spc = cpl_vector_new_from_image_row(img_1d, 1);
727 cpl_vector_multiply_scalar(spc,(
double)height);
728 cpl_image_delete(img_1d);
730 img_1d = cpl_image_collapse_median_create(img_tmp, 1, 0, 0);
731 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
732 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
733 cpl_image_delete(img_1d);
734 cpl_image_delete(img_tmp);
739 cpl_msg_error(__func__,
"Cannot rectify error");
740 cpl_vector_delete(ycen);
743 cpl_image_multiply(img_tmp, img_tmp);
744 img_1d = cpl_image_collapse_create(img_tmp, 0);
745 sigma = cpl_vector_new_from_image_row(img_1d, 1);
746 cpl_vector_sqrt(sigma);
747 cpl_image_delete(img_tmp);
748 cpl_image_delete(img_1d);
751 img_tmp = cpl_image_new(lenx, leny, imtyp);
753 for (i=1;i<=lenx;i++){
754 for (j=1;j<=height;j++){
755 cpl_image_set(img_tmp, i, ycen_int[i-1]-(height/2)+j,
756 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
759 cpl_vector_delete(ycen);
762 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
763 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
764 NULL, CPL_IO_CREATE);
769 *spec = cpl_bivector_wrap_vectors(spc, sigma);
771 cpl_image_delete(img_tmp);
802 const hdrl_image * hdrl_in,
803 const cpl_table * trace_tab,
807 cpl_vector ** slit_func,
808 cpl_bivector ** spec,
815 const cpl_image * img_in;
816 const cpl_image * err_in;
822 double trace_cen, trace_height ;
826 double a, b, c, value;
827 cpl_polynomial * slitcurve_A, * slitcurve_B, *slitcurve_C;
828 cpl_bivector * xi, *xt;
831 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
837 imtyp = cpl_image_get_type(img_in);
838 lenx = cpl_image_get_size_x(img_in);
839 leny = cpl_image_get_size_y(img_in);
845 cpl_msg_error(__func__,
"Cannot compute height");
851 trace_id, lenx)) == NULL) {
852 cpl_msg_error(__func__,
"Cannot get ycen");
855 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
857 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
858 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
861 if (img_tmp == NULL) {
862 cpl_msg_error(__func__,
"Cannot rectify order");
863 cpl_vector_delete(ycen);
867 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
868 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
869 NULL, CPL_IO_CREATE);
889 if ((slitcurve_A == NULL) || (slitcurve_B == NULL) || (slitcurve_C == NULL))
891 cpl_msg_error(__func__,
892 "No (or incomplete) slitcurve data found in trace table");
893 cpl_vector_delete(ycen);
894 cpl_polynomial_delete(slitcurve_A);
895 cpl_polynomial_delete(slitcurve_B);
896 cpl_polynomial_delete(slitcurve_C);
903 xi = cpl_bivector_new(lenx);
904 xt = cpl_bivector_new(lenx);
905 for (i = 0; i < lenx; i++){
906 cpl_vector_set(cpl_bivector_get_x(xi), i, i);
907 cpl_vector_set(cpl_bivector_get_x(xt), i, i);
908 cpl_vector_set(cpl_bivector_get_y(xi), i, 0);
909 cpl_vector_set(cpl_bivector_get_y(xt), i, 0);
912 for (i = 0; i < height; i++){
913 int yt = i - height / 2 + 0.5;
914 int yc = cpl_vector_get(ycen, i);
916 for (j = 1; j < lenx - 1; j++){
918 b = cpl_polynomial_eval_1d(slitcurve_B, j, NULL);
919 c = cpl_polynomial_eval_1d(slitcurve_C, j, NULL);
926 value = j - a - yt * b - yt * yt * c;
927 value = max(min(value, lenx-1), 0);
928 cpl_vector_set(cpl_bivector_get_x(xt), j, value);
929 value = cpl_image_get(img_tmp, j + 1, i + 1, &badpix);
930 if (badpix) value = NAN;
931 cpl_vector_set(cpl_bivector_get_y(xt), j, value);
934 cpl_bivector_interpolate_linear(xi, xt);
936 for (j = 0; j < lenx; j++){
937 value = cpl_vector_get(cpl_bivector_get_y(xi), j);
938 cpl_image_set(img_tmp, j+1, i+1, value);
940 cpl_image_set(img_tmp, j+1, i+1, 0);
941 cpl_image_reject(img_tmp, j+1, i+1);
946 cpl_bivector_delete(xi);
947 cpl_bivector_delete(xt);
948 cpl_polynomial_delete(slitcurve_A);
949 cpl_polynomial_delete(slitcurve_B);
950 cpl_polynomial_delete(slitcurve_C);
952 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
953 cpl_image_save(img_tmp,
"debug_img_shifted.fits", imtyp,
954 NULL, CPL_IO_CREATE);
960 xi = cpl_bivector_new(height);
961 xt = cpl_bivector_new(height);
963 for (j = 0; j < lenx; j++){
965 cpl_vector_set(cpl_bivector_get_x(xi), 0, 0);
966 cpl_vector_set(cpl_bivector_get_y(xi), 0, 0);
967 cpl_vector_set(cpl_bivector_get_x(xi), height-1, height-1);
968 cpl_vector_set(cpl_bivector_get_y(xi), height-1, 0);
969 for (i = 0; i < height; i++){
970 cpl_vector_set(cpl_bivector_get_x(xt), i, i);
971 cpl_vector_set(cpl_bivector_get_y(xt), i, 0);
973 value = cpl_image_get(img_tmp, j+1, i+1, &badpix);
975 cpl_vector_set(cpl_bivector_get_x(xi), i, i);
976 cpl_vector_set(cpl_bivector_get_y(xi), i, value);
979 cpl_bivector_interpolate_linear(xt, xi);
980 for (i = 0; i < height; i++){
981 value = cpl_vector_get(cpl_bivector_get_y(xt), i);
982 cpl_image_set(img_tmp, j+1, i+1, value);
986 cpl_bivector_delete(xi);
987 cpl_bivector_delete(xt);
989 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
990 cpl_image_save(img_tmp,
"debug_img_shifted_corrected.fits", imtyp,
991 NULL, CPL_IO_CREATE);
994 img_1d = cpl_image_collapse_create(img_tmp, 0);
995 spc = cpl_vector_new_from_image_row(img_1d, 1);
996 cpl_image_delete(img_1d);
998 img_1d = cpl_image_collapse_create(img_tmp, 1);
999 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
1000 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
1001 cpl_image_delete(img_1d);
1002 cpl_image_delete(img_tmp);
1005 if (img_tmp == NULL)
1007 cpl_msg_error(__func__,
"Cannot rectify error");
1008 cpl_vector_delete(ycen);
1011 cpl_image_multiply(img_tmp, img_tmp);
1012 img_1d = cpl_image_collapse_create(img_tmp, 0);
1013 sigma = cpl_vector_new_from_image_row(img_1d, 1);
1014 cpl_vector_sqrt(sigma);
1015 cpl_image_delete(img_tmp);
1016 cpl_image_delete(img_1d);
1019 img_tmp = cpl_image_new(lenx, leny, imtyp);
1021 for (i=1;i<=lenx;i++){
1022 for (j=1;j<=height;j++){
1023 cpl_image_set(img_tmp, i, ycen_int[i-1]-(height/2)+j,
1024 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
1027 cpl_vector_delete(ycen);
1030 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1031 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
1032 NULL, CPL_IO_CREATE);
1036 *slit_func = slitfu;
1037 *spec = cpl_bivector_wrap_vectors(spc, sigma);
1039 cpl_image_delete(img_tmp);
1053 cpl_bivector ** spectrum,
1054 const cpl_table * trace_table)
1058 const double * pspec ;
1059 const double * perr ;
1060 cpl_vector * wave_vec ;
1061 const double * pwl ;
1062 int nrows, all_null, i, order, trace_id, nb_traces ;
1065 if (spectrum == NULL || trace_table == NULL)
return NULL ;
1068 nb_traces = cpl_table_get_nrow(trace_table) ;
1072 for (i=0 ; i<nb_traces ; i++)
1073 if (spectrum[i] != NULL) {
1074 nrows = cpl_bivector_get_size(spectrum[i]) ;
1077 if (all_null == 1)
return NULL ;
1080 for (i=0 ; i<nb_traces ; i++)
1081 if (spectrum[i] != NULL && cpl_bivector_get_size(spectrum[i]) != nrows)
1085 out = cpl_table_new(nrows);
1086 for (i=0 ; i<nb_traces ; i++) {
1087 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1088 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1091 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1092 cpl_free(col_name) ;
1095 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1096 cpl_free(col_name) ;
1099 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1100 cpl_free(col_name) ;
1104 for (i=0 ; i<nb_traces ; i++) {
1105 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1106 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1107 if (spectrum[i] != NULL) {
1108 pspec = cpl_bivector_get_x_data_const(spectrum[i]) ;
1109 perr = cpl_bivector_get_y_data_const(spectrum[i]);
1112 cpl_table_copy_data_double(out, col_name, pspec) ;
1113 cpl_free(col_name) ;
1116 cpl_table_copy_data_double(out, col_name, perr) ;
1117 cpl_free(col_name) ;
1121 CR2RES_DETECTOR_SIZE);
1122 if (wave_vec == NULL) {
1123 wave_vec = cpl_vector_new(CR2RES_DETECTOR_SIZE) ;
1124 cpl_vector_fill(wave_vec, 0.0) ;
1126 pwl = cpl_vector_get_data(wave_vec) ;
1130 cpl_table_copy_data_double(out, col_name, pwl) ;
1131 cpl_free(col_name) ;
1132 cpl_vector_delete(wave_vec) ;
1136 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1137 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1138 cpl_free(col_name) ;
1141 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1142 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1143 cpl_free(col_name) ;
1146 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1147 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1148 cpl_free(col_name) ;
1163 cpl_vector ** slit_func,
1164 const cpl_table * trace_table)
1168 const double * pslit ;
1169 int nrows, nrows_max, all_null, i, order, trace_id,
1173 if (slit_func == NULL || trace_table == NULL)
return NULL ;
1177 nb_traces = cpl_table_get_nrow(trace_table) ;
1181 for (i=0 ; i<nb_traces ; i++)
1182 if (slit_func[i] != NULL) {
1183 nrows = cpl_vector_get_size(slit_func[i]) ;
1184 if (nrows > nrows_max) nrows_max = nrows ;
1187 if (all_null == 1)
return NULL ;
1191 for (i = 0; i < nb_traces; i++)
1192 if (slit_func[i] != NULL)
1194 nrows = cpl_vector_get_size(slit_func[i]);
1195 cpl_vector_set_size(slit_func[i], nrows_max);
1196 for (
int j = nrows; j < nrows_max; j++)
1198 cpl_vector_set(slit_func[i], j, 0.0);
1203 out = cpl_table_new(nrows_max);
1204 for (i=0 ; i<nb_traces ; i++) {
1205 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1206 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1208 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1209 cpl_free(col_name) ;
1213 for (i=0 ; i<nb_traces ; i++) {
1214 if (slit_func[i] != NULL) {
1215 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1216 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1217 pslit = cpl_vector_get_data_const(slit_func[i]) ;
1219 cpl_table_copy_data_double(out, col_name, pslit) ;
1220 cpl_free(col_name) ;
1222 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1223 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1225 cpl_table_fill_column_window_double(out, col_name, 0, nrows_max, NAN);
1226 cpl_table_set_column_invalid(out, col_name, 0, nrows_max);
1227 cpl_free(col_name) ;
1245 const cpl_table * tab,
1248 cpl_bivector ** spec,
1249 cpl_bivector ** spec_err)
1253 char * spec_err_name ;
1254 const double * pspec ;
1255 const double * pwave ;
1256 const double * pspec_err ;
1259 double * pxspec_err ;
1260 double * pyspec_err ;
1264 if (tab == NULL || spec == NULL || spec_err == NULL)
return -1 ;
1268 if ((pspec = cpl_table_get_data_double_const(tab, spec_name)) == NULL) {
1269 cpl_msg_error(__func__,
"Cannot find the spectrum") ;
1270 cpl_free(spec_name) ;
1273 cpl_free(spec_name) ;
1277 if ((pwave = cpl_table_get_data_double_const(tab, wave_name)) == NULL) {
1278 cpl_msg_error(__func__,
"Cannot find the wavelength") ;
1279 cpl_free(wave_name) ;
1282 cpl_free(wave_name) ;
1286 if ((pspec_err = cpl_table_get_data_double_const(tab, spec_err_name))
1288 cpl_msg_error(__func__,
"Cannot find the spectrum error") ;
1289 cpl_free(spec_err_name) ;
1292 cpl_free(spec_err_name) ;
1295 tab_size = cpl_table_get_nrow(tab) ;
1296 *spec = cpl_bivector_new(tab_size) ;
1297 *spec_err = cpl_bivector_new(tab_size) ;
1298 pxspec = cpl_bivector_get_x_data(*spec) ;
1299 pyspec = cpl_bivector_get_y_data(*spec) ;
1300 pxspec_err = cpl_bivector_get_x_data(*spec_err) ;
1301 pyspec_err = cpl_bivector_get_y_data(*spec_err) ;
1302 for (i=0 ; i<tab_size ; i++) {
1303 pxspec[i] = pwave[i] ;
1304 pyspec[i] = pspec[i] ;
1305 pxspec_err[i] = pwave[i] ;
1306 pyspec_err[i] = pspec_err[i] ;
1322 const cpl_table * tab,
1328 const double * ptab ;
1333 if (tab == NULL || vec == NULL)
return -1 ;
1337 if ((ptab = cpl_table_get_data_double_const(tab, vec_name)) == NULL) {
1338 cpl_msg_error(__func__,
"Cannot find the slit_func") ;
1339 cpl_free(vec_name) ;
1344 cpl_free(vec_name) ;
1347 tab_size = cpl_table_get_nrow(tab) ;
1348 *vec = cpl_vector_new(tab_size) ;
1349 pvec = cpl_vector_get_data(*vec) ;
1350 for (i=0 ; i<tab_size ; i++) pvec[i] = ptab[i] ;
1394 const hdrl_image * img_hdrl,
1395 const cpl_table * trace_tab,
1396 const cpl_vector * slit_func_vec_in,
1407 double error_factor,
1408 cpl_vector ** slit_func,
1409 cpl_bivector ** spec,
1410 hdrl_image ** model)
1414 int * ycen_offset_sw;
1415 double * slitfu_sw_data;
1417 const double * slit_func_in;
1419 const cpl_image * img_in;
1420 const cpl_image * err_in;
1423 cpl_image * img_rect;
1424 cpl_image * err_rect;
1425 cpl_image * model_rect;
1427 cpl_image * img_out;
1428 cpl_vector * slitfu_sw;
1429 cpl_vector * unc_sw;
1431 cpl_vector * slitfu;
1432 cpl_vector * weights_sw;
1433 cpl_vector * tmp_vec;
1434 cpl_vector * bins_begin;
1435 cpl_vector * bins_end;
1436 cpl_vector * unc_decomposition;
1437 cpl_size lenx, leny, pow;
1439 cpl_polynomial *slitcurve_A, *slitcurve_B, *slitcurve_C;
1440 cpl_polynomial ** slitcurves_sw;
1441 hdrl_image * model_out;
1442 cpl_bivector * spectrum_loc;
1448 cpl_image * img_mad;
1453 double pixval, errval;
1454 double trace_cen, trace_height;
1455 int i, j, k, nswaths, col, x, y, ny_os,
1461 if (img_hdrl == NULL || trace_tab == NULL)
return -1 ;
1463 if (smooth_slit == 0.0) {
1464 cpl_msg_error(__func__,
"Slit-smoothing cannot be 0.0");
1466 }
else if (smooth_slit < 0.1) {
1467 cpl_msg_warning(__func__,
"Slit-smoothing unreasonably small");
1468 }
else if (smooth_slit > 100.0) {
1469 cpl_msg_warning(__func__,
"Slit-smoothing unreasonably big");
1471 if (oversample < 3){
1472 cpl_msg_error(__func__,
"Oversampling too small");
1474 }
else if (oversample > 15) {
1475 cpl_msg_warning(__func__,
"Large oversampling, runtime will be long");
1478 cpl_msg_warning(__func__,
1479 "Allowing at least 5 iterations is recommended.");
1482 cpl_msg_warning(__func__,
1483 "Rejecting outliers < 4 sigma risks making good data.");
1489 imtyp = cpl_image_get_type(img_in);
1490 lenx = cpl_image_get_size_x(img_in);
1491 leny = cpl_image_get_size_y(img_in);
1497 cpl_msg_error(__func__,
"Cannot compute height");
1503 cpl_msg_warning(__func__,
1504 "Given height larger than image, clipping height");
1509 trace_id, lenx)) == NULL) {
1510 cpl_msg_error(__func__,
"Cannot get ycen");
1513 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
1515 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
1516 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
1517 if (trace_cen-(height/2) < 0.0 ||
1518 trace_cen+(height/2) > CR2RES_DETECTOR_SIZE) {
1519 cpl_msg_error(__func__,
"Extraction outside detector edges impossible");
1520 cpl_vector_delete(ycen);
1526 if (img_rect == NULL){
1527 cpl_msg_error(__func__,
"Cannot rectify order");
1528 cpl_vector_delete(ycen);
1531 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1532 cpl_image_save(img_rect,
"debug_rectorder_curved.fits", imtyp,
1533 NULL, CPL_IO_CREATE);
1545 if ((slitcurve_A == NULL) || (slitcurve_B == NULL) || (slitcurve_C == NULL))
1547 cpl_msg_error(__func__,
1548 "No (or incomplete) slitcurve data found in trace table");
1549 cpl_vector_delete(ycen);
1550 cpl_free(ycen_rest) ;
1551 cpl_image_delete(err_rect) ;
1552 cpl_image_delete(img_rect) ;
1553 cpl_polynomial_delete(slitcurve_A);
1554 cpl_polynomial_delete(slitcurve_B);
1555 cpl_polynomial_delete(slitcurve_C);
1561 for (i=1; i<=lenx; i+=swath/2){
1562 double delta_tmp, a, b, c, yc;
1568 b = cpl_polynomial_eval_1d(slitcurve_B, i, NULL);
1569 c = cpl_polynomial_eval_1d(slitcurve_C, i, NULL);
1570 yc = cpl_vector_get(ycen, i-1);
1578 delta_tmp = max( fabs(a + (c*height/2. + b)*height/2.),
1579 fabs(a + (c*height/-2. + b)*height/-2.));
1580 if (delta_tmp > delta_x) delta_x = (int)ceil(delta_tmp);
1583 cpl_msg_debug(__func__,
"Max delta_x from slit curv: %d pix.", delta_x);
1585 if (delta_x >= swath / 4){
1586 cpl_msg_error(__func__,
1587 "Curvature is larger than the swath, try again with a larger swath size");
1588 cpl_vector_delete(ycen);
1589 cpl_free(ycen_rest) ;
1590 cpl_image_delete(err_rect) ;
1591 cpl_image_delete(img_rect) ;
1592 cpl_polynomial_delete(slitcurve_A);
1593 cpl_polynomial_delete(slitcurve_B);
1594 cpl_polynomial_delete(slitcurve_C);
1599 ny_os = oversample*(height+1) +1;
1600 if ((swath = cr2res_extract_slitdec_adjust_swath(ycen, height, leny, swath,
1601 lenx, delta_x, &bins_begin, &bins_end)) == -1){
1602 cpl_msg_error(__func__,
"Cannot calculate swath size");
1603 cpl_vector_delete(ycen);
1604 cpl_free(ycen_rest) ;
1605 cpl_image_delete(err_rect) ;
1606 cpl_image_delete(img_rect) ;
1607 cpl_polynomial_delete(slitcurve_A);
1608 cpl_polynomial_delete(slitcurve_B);
1609 cpl_polynomial_delete(slitcurve_C);
1612 nswaths = cpl_vector_get_size(bins_begin);
1615 slit_func_in = NULL;
1616 if (slit_func_vec_in != NULL) {
1618 size = cpl_vector_get_size(slit_func_vec_in);
1620 slit_func_in = cpl_vector_get_data_const(slit_func_vec_in);
1622 cpl_msg_warning(__func__,
"Ignoring the given slit_func since it is"
1623 " of the wrong size, expected %i but got %lli points.",
1629 mask_sw = cpl_malloc(height * swath*
sizeof(
int));
1630 model_sw = cpl_malloc(height * swath*
sizeof(
double));
1631 unc_sw = cpl_vector_new(swath);
1632 img_sw = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1633 err_sw = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1634 ycen_sw = cpl_malloc(swath*
sizeof(
double));
1635 ycen_offset_sw = cpl_malloc(swath *
sizeof(
int));
1637 slitcurves_sw = cpl_malloc(swath *
sizeof(cpl_polynomial*));
1638 for (i=0; i<swath; i++) slitcurves_sw[i]= cpl_polynomial_new(1);
1641 slitfu = cpl_vector_new(ny_os);
1642 spectrum_loc = cpl_bivector_new(lenx);
1643 spc = cpl_bivector_get_x(spectrum_loc);
1644 unc_decomposition = cpl_bivector_get_y(spectrum_loc);
1645 for (j=0; j<lenx ; j++){
1646 cpl_vector_set(spc, j, 0.);
1647 cpl_vector_set(unc_decomposition, j, 0.);
1651 model_rect = cpl_image_new(lenx, height, CPL_TYPE_DOUBLE);
1654 slitfu_sw = cpl_vector_new(ny_os);
1655 for (j=0; j < ny_os; j++) cpl_vector_set(slitfu_sw, j, 0);
1656 slitfu_sw_data = cpl_vector_get_data(slitfu_sw);
1657 weights_sw = cpl_vector_new(swath);
1658 for (i = 0; i < swath; i++) cpl_vector_set(weights_sw, i, 0);
1661 for (i=delta_x; i < swath/2; i++) {
1662 j = i - delta_x + 1;
1663 cpl_vector_set(weights_sw, i, j);
1664 cpl_vector_set(weights_sw, swath - i - 1, j);
1667 cpl_vector_divide_scalar(weights_sw, swath/2 - delta_x + 1);
1672 ny = oversample * (height + 1) + 1;
1673 nx = 4 * delta_x + 1;
1676 sP_old = cpl_malloc(swath *
sizeof(
double));
1677 l_Aij = cpl_malloc(ny * (4*oversample+1) *
sizeof(
double));
1678 p_Aij = cpl_malloc(swath * nx *
sizeof(
double));
1679 l_bj = cpl_malloc(ny *
sizeof(
double));
1680 p_bj = cpl_malloc(swath *
sizeof(
double));
1681 img_mad = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1687 xi = cpl_malloc(swath * ny * 4 *
sizeof(xi_ref));
1692 zeta = cpl_malloc(swath * height * 3 * (oversample + 1)
1693 *
sizeof(zeta_ref));
1696 m_zeta = cpl_malloc(swath * height *
sizeof(
int));
1698 for (i = 0; i < nswaths; i++) {
1699 double *img_sw_data;
1700 double *err_sw_data;
1701 double *spec_sw_data;
1702 double *unc_sw_data;
1705 cpl_vector *spec_sw;
1706 cpl_vector *spec_tmp;
1708 int sw_start, sw_end, y_lower_limit;
1712 sw_start = cpl_vector_get(bins_begin, i);
1713 sw_end = cpl_vector_get(bins_end, i);
1716 for(col=1; col<=swath; col++){
1720 for(y=1;y<=height;y++){
1721 errval = cpl_image_get(err_rect, x, y, &badpix);
1722 if (isnan(errval) || badpix){
1727 pixval = cpl_image_get(img_rect, x, y, &badpix);
1728 if (isnan(pixval) || badpix){
1736 cpl_image_set(img_sw, col, y, pixval);
1737 cpl_image_set(err_sw, col, y, errval);
1741 cpl_image_reject(img_sw, col, y);
1745 j = (y-1)*swath + (col-1) ;
1748 mask_sw[j] = !badpix;
1754 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow,
1755 cpl_polynomial_eval_1d(slitcurve_C, x, NULL));
1757 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow,
1758 cpl_polynomial_eval_1d(slitcurve_B, x, NULL));
1760 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow,
1761 cpl_polynomial_eval_1d(slitcurve_A, x, NULL) - x);
1785 cpl_polynomial_shift_1d(slitcurves_sw[col-1], 0,
1786 cpl_vector_get(ycen, x-1));
1787 cpl_polynomial_set_coeff(slitcurves_sw[col-1], &pow, 0);
1790 for (j=0; j< height * swath; j++) model_sw[j] = 0;
1791 img_sw_data = cpl_image_get_data_double(img_sw);
1792 err_sw_data = cpl_image_get_data_double(err_sw);
1793 unc_sw_data = cpl_vector_get_data(unc_sw);
1796 img_tmp = cpl_image_collapse_median_create(img_sw, 0, 0, 0);
1797 spec_tmp = cpl_vector_new_from_image_row(img_tmp, 1);
1798 cpl_vector_multiply_scalar(spec_tmp,
1799 (
double)cpl_image_get_size_y(img_sw));
1800 spec_sw = cpl_vector_filter_median_create(spec_tmp, 1);
1801 cpl_vector_delete(spec_tmp);
1802 cpl_image_delete(img_tmp);
1803 spec_sw_data = cpl_vector_get_data(spec_sw);
1805 for (j=sw_start;j<sw_end;j++){
1806 ycen_sw[j-sw_start] = ycen_rest[j];
1807 ycen_offset_sw[j-sw_start] = (int) cpl_vector_get(ycen, j);
1809 y_lower_limit = height / 2;
1811 img_tmp = cpl_image_wrap_int(swath, height, mask_sw);
1812 img_sum = cpl_image_get_flux(img_tmp);
1813 if (img_sum < 0.5 * swath*height){
1814 cpl_msg_error(__func__,
1815 "Only %.0f %% of pixels not masked, cannot extract",
1816 100*img_sum/(swath*height));
1817 cpl_image_unwrap(img_tmp);
1818 cpl_vector_delete(spec_sw);
1821 if (cpl_msg_get_level() == CPL_MSG_DEBUG)
1823 cpl_image_save(img_tmp,
"debug_mask_before_sw.fits", CPL_TYPE_INT, NULL, CPL_IO_CREATE);
1824 cpl_vector_save(spec_sw,
"debug_spc_initial_guess.fits",
1825 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1827 cpl_image_unwrap(img_tmp);
1830 cr2res_extract_slit_func_curved(error_factor, swath, height, oversample, pclip,
1831 img_sw_data, err_sw_data, mask_sw, ycen_sw, ycen_offset_sw,
1832 y_lower_limit, slitcurves_sw, delta_x, slitfu_sw_data,
1833 spec_sw_data, model_sw, unc_sw_data, smooth_spec, smooth_slit,
1834 5.e-5, niter, kappa, slit_func_in, sP_old, l_Aij, p_Aij, l_bj,
1835 p_bj, img_mad, xi, zeta, m_zeta);
1838 if (i==0) cpl_vector_copy(slitfu,slitfu_sw);
1839 else cpl_vector_add(slitfu,slitfu_sw);
1841 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1842 path = cpl_sprintf(
"debug_spc_%i.fits", i);
1843 cpl_vector_save(spec_sw, path , CPL_TYPE_DOUBLE, NULL,
1847 path = cpl_sprintf(
"debug_mask_%i.fits", i);
1848 img_tmp = cpl_image_wrap_int(swath, height, mask_sw);
1849 cpl_image_save(img_tmp, path, CPL_TYPE_INT, NULL, CPL_IO_CREATE);
1851 cpl_image_unwrap(img_tmp);
1853 tmp_vec = cpl_vector_wrap(swath, ycen_sw);
1854 path = cpl_sprintf(
"debug_ycen_%i.fits", i);
1855 cpl_vector_save(tmp_vec, path, CPL_TYPE_DOUBLE, NULL,
1857 cpl_vector_unwrap(tmp_vec);
1860 cpl_vector_save(weights_sw,
"debug_weights.fits", CPL_TYPE_DOUBLE,
1861 NULL, CPL_IO_CREATE);
1862 path = cpl_sprintf(
"debug_slitfu_%i.fits", i);
1863 cpl_vector_save(slitfu_sw, path, CPL_TYPE_DOUBLE,
1864 NULL, CPL_IO_CREATE);
1867 path = cpl_sprintf(
"debug_model_%i.fits", i);
1868 img_tmp = cpl_image_wrap_double(swath, height, model_sw);
1869 cpl_image_save(img_tmp, path, CPL_TYPE_DOUBLE,
1870 NULL, CPL_IO_CREATE);
1871 cpl_image_unwrap(img_tmp);
1874 path = cpl_sprintf(
"debug_img_sw_%i.fits", i);
1875 cpl_image_save(img_sw, path, CPL_TYPE_DOUBLE, NULL,
1879 path = cpl_sprintf(
"debug_img_mad_%i.fits", i);
1880 cpl_image_save(img_mad, path, CPL_TYPE_DOUBLE, NULL,
1890 if ((i == nswaths - 1) && (i != 0)){
1891 k = cpl_vector_get(bins_end, i-1) -
1892 cpl_vector_get(bins_begin, i) - swath / 2 - delta_x;
1894 for (j = 0; j < swath - k; j++){
1895 cpl_vector_set(spec_sw, j, cpl_vector_get(spec_sw, j + k));
1896 cpl_vector_set(unc_sw, j, cpl_vector_get(unc_sw, j + k));
1897 for (y = 0; y < height; y++)
1898 model_sw[y * swath + j] = model_sw[y * swath + j + k];
1900 sw_start = cpl_vector_get(bins_begin, i-1) + swath / 2 - delta_x;
1901 cpl_vector_set(bins_begin, i, sw_start);
1903 cpl_vector_set(bins_end, i, lenx);
1908 for (j = 0; j < delta_x; j++)
1910 cpl_vector_set(spec_sw, j, 0);
1911 cpl_vector_set(unc_sw, j, 0.);
1912 for (y = 0; y < height; y++) model_sw[y * swath + j] = 0;
1914 for (j = swath/2; j < swath; j++) {
1915 cpl_vector_set(spec_sw, j,
1916 cpl_vector_get(spec_sw,j) * cpl_vector_get(weights_sw,j));
1917 cpl_vector_set(unc_sw, j,
1918 cpl_vector_get(unc_sw, j) * cpl_vector_get(weights_sw, j));
1919 for (y = 0; y < height; y++) {
1920 model_sw[y * swath + j] *= cpl_vector_get(weights_sw, j);
1923 }
else if (i == nswaths - 1) {
1924 for (j = sw_end-sw_start-1; j >= sw_end-sw_start-delta_x-1; j--)
1926 cpl_vector_set(spec_sw, j, 0);
1927 cpl_vector_set(unc_sw, j, 0);
1928 for (y = 0; y < height; y++) model_sw[y * swath + j] = 0;
1930 for (j = 0; j < swath / 2; j++) {
1931 cpl_vector_set(spec_sw, j,
1932 cpl_vector_get(spec_sw,j) * cpl_vector_get(weights_sw,j));
1933 cpl_vector_set(unc_sw, j,
1934 cpl_vector_get(unc_sw,j) * cpl_vector_get(weights_sw,j));
1935 for (y = 0; y < height; y++) {
1936 model_sw[y * swath + j] *= cpl_vector_get(weights_sw,j);
1941 cpl_vector_multiply(spec_sw, weights_sw);
1942 cpl_vector_multiply(unc_sw, weights_sw);
1943 for (y = 0; y < height; y++) {
1944 for (j = 0; j < swath; j++){
1945 model_sw[y * swath + j] *= cpl_vector_get(weights_sw,j);
1950 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1951 img_tmp = cpl_image_wrap_double(swath, height, model_sw);
1952 cpl_image_save(img_tmp,
"debug_model_after_sw.fits", CPL_TYPE_DOUBLE,
1953 NULL, CPL_IO_CREATE);
1954 cpl_image_unwrap(img_tmp);
1958 for (j=sw_start;j<sw_end;j++) {
1959 cpl_vector_set(spc, j,
1960 cpl_vector_get(spec_sw, j-sw_start) + cpl_vector_get(spc, j));
1963 cpl_vector_set(unc_decomposition, j,
1964 cpl_vector_get(unc_sw, j - sw_start)
1965 + cpl_vector_get(unc_decomposition, j));
1967 for(y = 0; y < height; y++){
1968 cpl_image_set(model_rect, j+1, y+1,
1969 cpl_image_get(model_rect, j+1, y+1, &badpix)
1970 + model_sw[y * swath + j - sw_start]);
1971 if (badpix) cpl_image_reject(model_rect, j+1, y+1);
1975 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1976 cpl_image_save(model_rect,
"debug_model_after_merge.fits",
1977 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1980 cpl_vector_delete(spec_sw);
1984 cpl_vector_divide_scalar(slitfu, nswaths);
1987 cpl_image_delete(img_mad);
1998 cpl_image_delete(img_rect);
1999 cpl_image_delete(err_rect);
2000 cpl_image_delete(img_sw);
2001 cpl_image_delete(err_sw);
2005 cpl_vector_delete(unc_sw);
2006 cpl_free(ycen_rest);
2008 cpl_free(ycen_offset_sw);
2010 cpl_vector_delete(bins_begin);
2011 cpl_vector_delete(bins_end);
2012 cpl_vector_delete(slitfu_sw);
2013 cpl_vector_delete(weights_sw);
2015 cpl_polynomial_delete(slitcurve_A);
2016 cpl_polynomial_delete(slitcurve_B);
2017 cpl_polynomial_delete(slitcurve_C);
2018 for (i=0; i<swath; i++) cpl_polynomial_delete(slitcurves_sw[i]);
2019 cpl_free(slitcurves_sw);
2024 cpl_msg_error(__func__,
"failed to reinsert model swath into model image");
2025 cpl_image_delete(model_rect);
2027 cpl_vector_delete(ycen);
2028 cpl_bivector_delete(spectrum_loc);
2029 cpl_vector_delete(slitfu);
2033 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
2034 cpl_image_save(model_rect,
"debug_model_rect.fits", CPL_TYPE_DOUBLE,
2035 NULL, CPL_IO_CREATE);
2036 cpl_image_save(img_out,
"debug_model_all.fits", CPL_TYPE_DOUBLE,
2037 NULL, CPL_IO_CREATE);
2038 cpl_vector_save(spc,
"debug_spc_all.fits", CPL_TYPE_DOUBLE,
2039 NULL, CPL_IO_CREATE);
2042 cpl_image_delete(model_rect);
2043 cpl_vector_delete(ycen);
2045 if (cpl_error_get_code() != CPL_ERROR_NONE){
2046 cpl_msg_error(__func__,
2047 "Something went wrong in the extraction. Error Code: %i, loc: %s",
2048 cpl_error_get_code(), cpl_error_get_where());
2050 cpl_vector_delete(slitfu);
2051 cpl_bivector_delete(spectrum_loc);
2056 *slit_func = slitfu;
2057 *spec = spectrum_loc;
2081 const hdrl_image * img,
2082 const cpl_table * traces,
2085 cpl_table ** extracted)
2087 cpl_bivector ** spectrum ;
2088 cpl_bivector ** position ;
2089 cpl_vector ** wavelength ;
2090 cpl_vector ** slit_fraction ;
2091 cpl_table * extract_loc ;
2092 cpl_image * wavemap;
2093 cpl_image * slitmap;
2094 int nb_traces, i, npoints ;
2097 if (img == NULL || traces == NULL)
return -1 ;
2100 nb_traces = cpl_table_get_nrow(traces) ;
2101 npoints = CR2RES_DETECTOR_SIZE * CR2RES_DETECTOR_SIZE / nb_traces;
2104 spectrum = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
2105 position = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
2106 wavelength = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
2107 slit_fraction = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
2112 cpl_msg_error(__func__,
2113 "Could not create wavelength / slit_fraction image");
2116 cpl_free(wavelength);
2117 cpl_free(slit_fraction);
2122 for (i=0 ; i<nb_traces ; i++) {
2124 spectrum[i] = NULL ;
2125 position[i] = NULL ;
2126 wavelength[i] = NULL ;
2127 slit_fraction[i] = NULL ;
2129 int order, trace_id;
2132 order = cpl_table_get(traces, CR2RES_COL_ORDER, i, NULL) ;
2133 trace_id = cpl_table_get(traces, CR2RES_COL_TRACENB, i, NULL) ;
2136 if (reduce_order > -1 && order != reduce_order) continue ;
2139 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
2141 cpl_msg_info(__func__,
"Process Order %d/Trace %d",order,trace_id) ;
2142 cpl_msg_indent_more() ;
2146 npoints, wavemap, slitmap,
2147 &(spectrum[i]), &(position[i]), &(wavelength[i]),
2148 &(slit_fraction[i])) != 0) {
2149 cpl_msg_error(__func__,
"Cannot extract2d the trace") ;
2150 spectrum[i] = NULL ;
2151 position[i] = NULL ;
2152 wavelength[i] = NULL ;
2153 slit_fraction[i] = NULL ;
2155 cpl_msg_indent_less() ;
2158 cpl_msg_indent_less() ;
2163 wavelength, slit_fraction, traces) ;
2166 for (i=0 ; i<nb_traces ; i++) {
2167 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
2168 if (position[i] != NULL) cpl_bivector_delete(position[i]) ;
2169 if (wavelength[i] != NULL) cpl_vector_delete(wavelength[i]) ;
2170 if (slit_fraction[i] != NULL) cpl_vector_delete(slit_fraction[i]) ;
2172 cpl_free(spectrum) ;
2173 cpl_free(position) ;
2174 cpl_free(wavelength) ;
2175 cpl_free(slit_fraction) ;
2176 cpl_image_delete(wavemap);
2177 cpl_image_delete(slitmap);
2180 *extracted = extract_loc ;
2205 const hdrl_image * in,
2206 const cpl_table * trace_tab,
2210 const cpl_image * wavemap,
2211 const cpl_image * slitmap,
2212 cpl_bivector ** spectrum,
2213 cpl_bivector ** position,
2214 cpl_vector ** wavelength,
2215 cpl_vector ** slit_fraction)
2217 cpl_bivector * spectrum_local ;
2218 cpl_vector * spectrum_flux ;
2219 cpl_vector * spectrum_error ;
2220 cpl_bivector * position_local ;
2221 cpl_vector * position_x;
2222 cpl_vector * position_y;
2223 cpl_vector * wavelength_local ;
2224 cpl_vector * slit_fraction_local ;
2225 const cpl_array * lower_array;
2226 const cpl_array * upper_array;
2227 cpl_polynomial * lower_poly;
2228 cpl_polynomial * upper_poly;
2238 if (in==NULL || trace_tab==NULL || spectrum==NULL || position==NULL
2239 || wavelength==NULL || slit_fraction==NULL)
return -1 ;
2243 cpl_msg_error(__func__,
"Order and/or Trace not found in trace table");
2248 wavelength_local = cpl_vector_new(npoints);
2249 slit_fraction_local = cpl_vector_new(npoints);
2250 position_x = cpl_vector_new(npoints);
2251 position_y = cpl_vector_new(npoints);
2252 spectrum_flux = cpl_vector_new(npoints);
2253 spectrum_error = cpl_vector_new(npoints);
2259 x = cpl_vector_new(CR2RES_DETECTOR_SIZE);
2260 for (i = 0; i < CR2RES_DETECTOR_SIZE; i++) cpl_vector_set(x, i, i + 1);
2262 lower_array = cpl_table_get_array(trace_tab, CR2RES_COL_LOWER, k);
2263 upper_array = cpl_table_get_array(trace_tab, CR2RES_COL_UPPER, k);
2272 for (i = 0; i < CR2RES_DETECTOR_SIZE; i++)
2274 for (j = cpl_vector_get(lower, i); j < cpl_vector_get(upper, i); j++)
2277 if (j<1 || j>CR2RES_DETECTOR_SIZE) continue ;
2279 cpl_vector_set(position_x, row, i +1);
2280 cpl_vector_set(position_y, row, j);
2285 cpl_vector_set(spectrum_flux, row, flux);
2286 cpl_vector_set(spectrum_error, row, err);
2289 cpl_vector_set(wavelength_local, row, cpl_image_get(
2290 wavemap, i + 1, j, &bad_pix));
2292 cpl_vector_set(slit_fraction_local, row, cpl_image_get(
2293 slitmap, i + 1, j, &bad_pix));
2298 for (i = row; i < npoints; i++){
2299 cpl_vector_set(position_x, i, NAN);
2300 cpl_vector_set(position_y, i, NAN);
2301 cpl_vector_set(spectrum_flux, i, NAN);
2302 cpl_vector_set(spectrum_error, i, NAN);
2303 cpl_vector_set(wavelength_local, i, NAN);
2304 cpl_vector_set(slit_fraction_local, i, NAN);
2307 position_local = cpl_bivector_wrap_vectors(position_x, position_y);
2308 spectrum_local = cpl_bivector_wrap_vectors(spectrum_flux, spectrum_error);
2310 cpl_polynomial_delete(upper_poly);
2311 cpl_polynomial_delete(lower_poly);
2312 cpl_vector_delete(upper);
2313 cpl_vector_delete(lower);
2314 cpl_vector_delete(x);
2316 *spectrum = spectrum_local ;
2317 *position = position_local ;
2318 *wavelength = wavelength_local ;
2319 *slit_fraction = slit_fraction_local ;
2335 cpl_bivector ** spectrum,
2336 cpl_bivector ** position,
2337 cpl_vector ** wavelength,
2338 cpl_vector ** slit_fraction,
2339 const cpl_table * trace_table)
2343 const double * pspec ;
2344 const double * perr ;
2345 const double * pxposition ;
2346 const double * pyposition ;
2347 const double * pwave ;
2348 const double * pslit_frac ;
2349 int nrows, all_null, i, order, trace_id, nb_traces ;
2352 if (spectrum==NULL || trace_table==NULL || position==NULL ||
2353 wavelength==NULL || slit_fraction==NULL)
2357 nb_traces = cpl_table_get_nrow(trace_table) ;
2361 for (i=0 ; i<nb_traces ; i++)
2362 if (spectrum[i] != NULL) {
2363 nrows = cpl_bivector_get_size(spectrum[i]) ;
2366 if (all_null == 1)
return NULL ;
2369 for (i=0 ; i<nb_traces ; i++)
2370 if (spectrum[i] != NULL && cpl_bivector_get_size(spectrum[i]) != nrows)
2374 out = cpl_table_new(nrows);
2375 for (i=0 ; i<nb_traces ; i++) {
2376 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
2377 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
2380 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2381 cpl_free(col_name) ;
2384 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2385 cpl_free(col_name) ;
2388 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2389 cpl_free(col_name) ;
2392 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2393 cpl_free(col_name) ;
2396 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2397 cpl_free(col_name) ;
2400 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2401 cpl_free(col_name) ;
2405 for (i=0 ; i<nb_traces ; i++) {
2406 if (spectrum[i]!=NULL && position[i]!=NULL &&
2407 wavelength[i]!=NULL && slit_fraction[i]!=NULL) {
2408 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
2409 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
2410 pspec = cpl_bivector_get_x_data_const(spectrum[i]) ;
2411 perr = cpl_bivector_get_y_data_const(spectrum[i]);
2412 pxposition = cpl_bivector_get_x_data_const(position[i]) ;
2413 pyposition = cpl_bivector_get_y_data_const(position[i]) ;
2414 pwave = cpl_vector_get_data_const(wavelength[i]) ;
2415 pslit_frac = cpl_vector_get_data_const(slit_fraction[i]) ;
2418 cpl_table_copy_data_double(out, col_name, pspec) ;
2419 cpl_free(col_name) ;
2422 cpl_table_copy_data_double(out, col_name, perr) ;
2423 cpl_free(col_name) ;
2426 cpl_table_copy_data_double(out, col_name, pwave) ;
2427 cpl_free(col_name) ;
2430 cpl_table_copy_data_double(out, col_name, pxposition) ;
2431 cpl_free(col_name) ;
2434 cpl_table_copy_data_double(out, col_name, pyposition) ;
2435 cpl_free(col_name) ;
2438 cpl_table_copy_data_double(out, col_name, pslit_frac) ;
2439 cpl_free(col_name) ;
2479static int cr2res_extract_xi_zeta_tensors(
2484 const int * ycen_offset,
2487 cpl_polynomial ** slitcurves,
2492 int x, xx, y, yy, ix, ix1, ix2, iy, m;
2493 double step, delta, w;
2494 step = 1.e0 / osample;
2497 for (x = 0; x < ncols; x++)
2499 for (iy = 0; iy < ny; iy++)
2501 for (m = 0; m < 4; m++)
2503 xi[xi_index(x, iy, m)].x = -1;
2504 xi[xi_index(x, iy, m)].y = -1;
2505 xi[xi_index(x, iy, m)].w = 0.;
2511 for (x = 0; x < ncols; x++)
2513 for (y = 0; y < nrows; y++)
2515 m_zeta[mzeta_index(x, y)] = 0;
2516 for (ix = 0; ix < 3 * (osample + 1); ix++)
2518 zeta[zeta_index(x, y, ix)].x = -1;
2519 zeta[zeta_index(x, y, ix)].iy = -1;
2520 zeta[zeta_index(x, y, ix)].w = 0.;
2532 for (x = 0; x < ncols; x++)
2554 iy2 = osample - floor(ycen[x] * osample);
2555 iy1 = iy2 - osample;
2574 d1 = fmod(ycen[x], step);
2600 dy = ycen[x] - floor((y_lower_lim + ycen[x]) / step) * step - step;
2609 for (y = 0; y < nrows; y++) {
2613 for (iy = iy1; iy <= iy2; iy++) {
2614 if (iy == iy1) w = d1;
2615 else if (iy == iy2) w = d2;
2618 delta = cpl_polynomial_eval_1d(slitcurves[x], dy - ycen[x], NULL);
2620 ix2 = ix1 + signum(delta);
2628 if (x + ix1 >= 0 && x + ix2 < ncols)
2631 yy = y + ycen_offset[x] - ycen_offset[xx];
2632 xi[xi_index(x, iy, 3)].x = xx;
2633 xi[xi_index(x, iy, 3)].y = yy;
2634 xi[xi_index(x, iy, 3)].w = w - fabs(delta - ix1) * w;
2636 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 3)].w > 0)
2638 m = m_zeta[mzeta_index(xx, yy)];
2639 zeta[zeta_index(xx, yy, m)].x = x;
2640 zeta[zeta_index(xx, yy, m)].iy = iy;
2641 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 3)].w;
2642 m_zeta[mzeta_index(xx, yy)]++;
2651 yy = y + ycen_offset[x] - ycen_offset[xx];
2653 xi[xi_index(x, iy, 2)].x = xx;
2654 xi[xi_index(x, iy, 2)].y = yy;
2655 xi[xi_index(x, iy, 2)].w = fabs(delta - ix1) * w;
2656 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 2)].w > 0)
2658 m = m_zeta[mzeta_index(xx, yy)];
2659 zeta[zeta_index(xx, yy, m)].x = x;
2660 zeta[zeta_index(xx, yy, m)].iy = iy;
2661 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 2)].w;
2662 m_zeta[mzeta_index(xx, yy)]++;
2668 if (x + ix2 >= 0 && x + ix1 < ncols)
2671 yy = y + ycen_offset[x] - ycen_offset[xx];
2672 xi[xi_index(x, iy, 2)].x = xx;
2673 xi[xi_index(x, iy, 2)].y = yy;
2674 xi[xi_index(x, iy, 2)].w = fabs(delta - ix1) * w;
2675 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 2)].w > 0)
2677 m = m_zeta[mzeta_index(xx, yy)];
2678 zeta[zeta_index(xx, yy, m)].x = x;
2679 zeta[zeta_index(xx, yy, m)].iy = iy;
2680 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 2)].w;
2681 m_zeta[mzeta_index(xx, yy)]++;
2684 yy = y + ycen_offset[x] - ycen_offset[xx];
2685 xi[xi_index(x, iy, 3)].x = xx;
2686 xi[xi_index(x, iy, 3)].y = yy;
2687 xi[xi_index(x, iy, 3)].w = w - fabs(delta - ix1) * w;
2688 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 3)].w > 0)
2690 m = m_zeta[mzeta_index(xx, yy)];
2691 zeta[zeta_index(xx, yy, m)].x = x;
2692 zeta[zeta_index(xx, yy, m)].iy = iy;
2693 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 3)].w;
2694 m_zeta[mzeta_index(xx, yy)]++;
2700 if (x + ix1 >= 0 && x + ix1 < ncols)
2703 yy = y + ycen_offset[x] - ycen_offset[xx];
2704 xi[xi_index(x, iy, 2)].x = xx;
2705 xi[xi_index(x, iy, 2)].y = yy;
2706 xi[xi_index(x, iy, 2)].w = w;
2707 if (yy >= 0 && yy < nrows && w > 0)
2709 m = m_zeta[mzeta_index(xx, yy)];
2710 zeta[zeta_index(xx, yy, m)].x = x;
2711 zeta[zeta_index(xx, yy, m)].iy = iy;
2712 zeta[zeta_index(xx, yy, m)].w = w;
2713 m_zeta[mzeta_index(xx, yy)]++;
2722 if (x + ix1 >= 0 && x + ix2 < ncols)
2725 yy = y + ycen_offset[x] - ycen_offset[xx];
2726 xi[xi_index(x, iy, 1)].x = xx;
2727 xi[xi_index(x, iy, 1)].y = yy;
2728 xi[xi_index(x, iy, 1)].w = w - fabs(delta - ix1) * w;
2729 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2731 m = m_zeta[mzeta_index(xx, yy)];
2732 zeta[zeta_index(xx, yy, m)].x = x;
2733 zeta[zeta_index(xx, yy, m)].iy = iy;
2734 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2735 m_zeta[mzeta_index(xx, yy)]++;
2738 yy = y + ycen_offset[x] - ycen_offset[xx];
2739 xi[xi_index(x, iy, 0)].x = xx;
2740 xi[xi_index(x, iy, 0)].y = yy;
2741 xi[xi_index(x, iy, 0)].w = fabs(delta - ix1) * w;
2742 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2744 m = m_zeta[mzeta_index(xx, yy)];
2745 zeta[zeta_index(xx, yy, m)].x = x;
2746 zeta[zeta_index(xx, yy, m)].iy = iy;
2747 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2748 m_zeta[mzeta_index(xx, yy)]++;
2754 if (x + ix2 >= 0 && x + ix1 < ncols)
2757 yy = y + ycen_offset[x] - ycen_offset[xx];
2758 xi[xi_index(x, iy, 0)].x = xx;
2759 xi[xi_index(x, iy, 0)].y = yy;
2760 xi[xi_index(x, iy, 0)].w = fabs(delta - ix1) * w;
2761 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2763 m = m_zeta[mzeta_index(xx, yy)];
2764 zeta[zeta_index(xx, yy, m)].x = x;
2765 zeta[zeta_index(xx, yy, m)].iy = iy;
2766 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2767 m_zeta[mzeta_index(xx, yy)]++;
2770 yy = y + ycen_offset[x] - ycen_offset[xx];
2771 xi[xi_index(x, iy, 1)].x = xx;
2772 xi[xi_index(x, iy, 1)].y = yy;
2773 xi[xi_index(x, iy, 1)].w = w - fabs(delta - ix1) * w;
2774 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2776 m = m_zeta[mzeta_index(xx, yy)];
2777 zeta[zeta_index(xx, yy, m)].x = x;
2778 zeta[zeta_index(xx, yy, m)].iy = iy;
2779 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2780 m_zeta[mzeta_index(xx, yy)]++;
2786 if (x + ix1 >= 0 && x + ix1 < ncols)
2789 yy = y + ycen_offset[x] - ycen_offset[xx];
2790 xi[xi_index(x, iy, 0)].x = xx;
2791 xi[xi_index(x, iy, 0)].y = yy;
2792 xi[xi_index(x, iy, 0)].w = w;
2793 if (yy >= 0 && yy < nrows && w > 0)
2795 m = m_zeta[mzeta_index(xx, yy)];
2796 zeta[zeta_index(xx, yy, m)].x = x;
2797 zeta[zeta_index(xx, yy, m)].iy = iy;
2798 zeta[zeta_index(xx, yy, m)].w = w;
2799 m_zeta[mzeta_index(xx, yy)]++;
2808 if (x + ix1 >= 0 && x + ix2 < ncols)
2811 yy = y + ycen_offset[x] - ycen_offset[xx];
2812 xi[xi_index(x, iy, 1)].x = xx;
2813 xi[xi_index(x, iy, 1)].y = yy;
2814 xi[xi_index(x, iy, 1)].w = w - fabs(delta - ix1) * w;
2815 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2817 m = m_zeta[mzeta_index(xx, yy)];
2818 zeta[zeta_index(xx, yy, m)].x = x;
2819 zeta[zeta_index(xx, yy, m)].iy = iy;
2820 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2821 m_zeta[mzeta_index(xx, yy)]++;
2824 yy = y + ycen_offset[x] - ycen_offset[xx];
2825 xi[xi_index(x, iy, 0)].x = xx;
2826 xi[xi_index(x, iy, 0)].y = yy;
2827 xi[xi_index(x, iy, 0)].w = fabs(delta - ix1) * w;
2828 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2830 m = m_zeta[mzeta_index(xx, yy)];
2831 zeta[zeta_index(xx, yy, m)].x = x;
2832 zeta[zeta_index(xx, yy, m)].iy = iy;
2833 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2834 m_zeta[mzeta_index(xx, yy)]++;
2840 if (x + ix2 >= 0 && x + ix1 < ncols)
2843 yy = y + ycen_offset[x] - ycen_offset[xx];
2844 xi[xi_index(x, iy, 1)].x = xx;
2845 xi[xi_index(x, iy, 1)].y = yy;
2846 xi[xi_index(x, iy, 1)].w = fabs(delta - ix1) * w;
2847 if (xx < ncols && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 1)].w > 0)
2849 m = m_zeta[mzeta_index(xx, yy)];
2850 zeta[zeta_index(xx, yy, m)].x = x;
2851 zeta[zeta_index(xx, yy, m)].iy = iy;
2852 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 1)].w;
2853 m_zeta[mzeta_index(xx, yy)]++;
2856 yy = y + ycen_offset[x] - ycen_offset[xx];
2857 xi[xi_index(x, iy, 0)].x = xx;
2858 xi[xi_index(x, iy, 0)].y = yy;
2859 xi[xi_index(x, iy, 0)].w = w - fabs(delta - ix1) * w;
2860 if (xx >= 0 && yy >= 0 && yy < nrows && xi[xi_index(x, iy, 0)].w > 0)
2862 m = m_zeta[mzeta_index(xx, yy)];
2863 zeta[zeta_index(xx, yy, m)].x = x;
2864 zeta[zeta_index(xx, yy, m)].iy = iy;
2865 zeta[zeta_index(xx, yy, m)].w = xi[xi_index(x, iy, 0)].w;
2866 m_zeta[mzeta_index(xx, yy)]++;
2872 if (x + ix2 >= 0 && x + ix2 < ncols)
2875 yy = y + ycen_offset[x] - ycen_offset[xx];
2876 xi[xi_index(x, iy, 0)].x = xx;
2877 xi[xi_index(x, iy, 0)].y = yy;
2878 xi[xi_index(x, iy, 0)].w = w;
2879 if (yy >= 0 && yy < nrows && w > 0)
2881 m = m_zeta[mzeta_index(xx, yy)];
2882 zeta[zeta_index(xx, yy, m)].x = x;
2883 zeta[zeta_index(xx, yy, m)].iy = iy;
2884 zeta[zeta_index(xx, yy, m)].w = w;
2885 m_zeta[mzeta_index(xx, yy)]++;
2924static int cr2res_extract_slit_func_curved(
2925 double error_factor,
2936 cpl_polynomial ** slitcurves,
2947 const double * slit_func_in,
2953 cpl_image * img_mad,
2958 int x, xx, xxx, y, yy, iy, jy, n, m, ny, nx;
2959 double norm, lambda, diag_tot, ww, www, sP_change, sP_med;
2960 double tmp, sLmax, sum;
2962 cpl_vector *tmp_vec;
2966 ny = osample * (nrows + 1) + 1;
2967 nx = 4 * delta_x + 1;
2971 cr2res_extract_xi_zeta_tensors(ncols, nrows, ny, ycen, ycen_offset,
2972 y_lower_lim, osample, slitcurves, xi, zeta,
2976 if (slit_func_in != NULL) {
2979 for (iy = 0; iy < ny; iy++) {
2980 sL[iy] = slit_func_in[iy];
2984 for (iy = 0; iy < ny; iy++)
2999 int nclip = (int)(ncols * nrows * pclip / 100);
3002 if (nclip > ncols * nrows / 2)
3003 nclip = (ncols * nrows / 2) - 1;
3004 cpl_vector *im_vec = cpl_vector_wrap(ncols * nrows, im);
3005 cpl_vector *pos_vec = cpl_vector_new(ncols * nrows);
3006 for (x = 0; x < ncols; x++)
3008 for (y = 0; y < nrows; y++)
3010 cpl_vector_set(pos_vec, y * ncols + x, y * ncols + x);
3013 cpl_bivector *im_in_bvec = cpl_bivector_wrap_vectors(pos_vec, im_vec);
3014 cpl_bivector *im_sort_bvec = cpl_bivector_new(ncols * nrows);
3015 cpl_bivector_sort(im_sort_bvec, im_in_bvec, CPL_SORT_ASCENDING, CPL_SORT_BY_Y);
3016 cpl_bivector_unwrap_vectors(im_in_bvec);
3017 cpl_vector_unwrap(im_vec);
3018 cpl_vector_delete(pos_vec);
3020 cpl_vector *pos_sort_vec = cpl_bivector_get_x(im_sort_bvec);
3025 int pos = (int)cpl_vector_get(pos_sort_vec, ii);
3034 ii = ncols * nrows - 1;
3038 int pos = (int)cpl_vector_get(pos_sort_vec, ii);
3046 cpl_bivector_delete(im_sort_bvec);
3047 pos_sort_vec = NULL;
3057 if (slit_func_in == NULL) {
3060 for (iy = 0; iy < ny; iy++) {
3063 for (jy = 0; jy <= 4 * osample; jy++)
3064 l_Aij[iy + ny * jy] = 0.e0;
3068 for (iy = 0; iy < ny; iy++) {
3069 for (x = 0; x < ncols; x++) {
3070 for (n = 0; n < 4; n++) {
3071 ww = xi[xi_index(x, iy, n)].w;
3073 xx = xi[xi_index(x, iy, n)].x;
3074 yy = xi[xi_index(x, iy, n)].y;
3075 if (xx >= 0 && xx < ncols && yy >= 0 &&
3077 if (m_zeta[mzeta_index(xx, yy)] > 0) {
3078 for (m = 0; m < m_zeta[mzeta_index(xx, yy)];
3080 xxx = zeta[zeta_index(xx, yy, m)].x;
3081 jy = zeta[zeta_index(xx, yy, m)].iy;
3082 www = zeta[zeta_index(xx, yy, m)].w;
3083 if (jy - iy + 2 * osample >= 0)
3084 l_Aij[iy + ny * (jy - iy +
3086 sP[xxx] * sP[x] * www * ww *
3087 mask[yy * ncols + xx];
3089 l_bj[iy] += im[yy * ncols + xx] *
3090 mask[yy * ncols + xx] * sP[x] *
3097 diag_tot += fabs(l_Aij[iy + ny * 2 * osample]);
3100 lambda = lambda_sL * diag_tot / ny;
3103 l_Aij[ny * 2 * osample] += lambda;
3105 l_Aij[ny * (2 * osample + 1)] -= lambda;
3106 for (iy = 1; iy < ny - 1; iy++) {
3108 l_Aij[iy + ny * (2 * osample - 1)] -= lambda;
3110 l_Aij[iy + ny * 2 * osample] += lambda * 2.e0;
3112 l_Aij[iy + ny * (2 * osample + 1)] -= lambda;
3115 l_Aij[ny - 1 + ny * (2 * osample - 1)] -= lambda;
3117 l_Aij[ny - 1 + ny * 2 * osample] += lambda;
3120 info = cr2res_extract_slitdec_bandsol(l_Aij, l_bj, ny,
3121 4 * osample + 1, lambda);
3123 cpl_msg_error(__func__,
"info(sL)=%d\n", info);
3127 for (iy = 0; iy < ny; iy++) {
3129 norm += fabs(sL[iy]);
3132 for (iy = 0; iy < ny; iy++)
3137 for (x = 0; x < ncols; x++) {
3138 for (xx = 0; xx < nx; xx++)
3139 p_Aij[xx * ncols + x] = 0.;
3142 for (x = 0; x < ncols; x++) {
3143 for (iy = 0; iy < ny; iy++) {
3144 for (n = 0; n < 4; n++) {
3145 ww = xi[xi_index(x, iy, n)].w;
3147 xx = xi[xi_index(x, iy, n)].x;
3148 yy = xi[xi_index(x, iy, n)].y;
3149 if (xx >= 0 && xx < ncols && yy >= 0 && yy < nrows) {
3150 if (m_zeta[mzeta_index(xx, yy)] > 0) {
3151 for (m = 0; m < m_zeta[mzeta_index(xx, yy)];
3153 xxx = zeta[zeta_index(xx, yy, m)].x;
3154 jy = zeta[zeta_index(xx, yy, m)].iy;
3155 www = zeta[zeta_index(xx, yy, m)].w;
3157 ncols * (xxx - x + 2 * delta_x)] +=
3158 sL[jy] * sL[iy] * www * ww *
3159 mask[yy * ncols + xx];
3161 p_bj[x] += im[yy * ncols + xx] *
3162 mask[yy * ncols + xx] * sL[iy] * ww;
3171 for (x = 0; x < ncols; x++)
3175 if (lambda_sP > 0.e0) {
3177 p_Aij[ncols * (2 * delta_x)] += lambda;
3178 p_Aij[ncols * (2 * delta_x + 1)] -= lambda;
3179 for (x = 1; x < ncols - 1; x++) {
3181 p_Aij[x + ncols * (2 * delta_x - 1)] -= lambda;
3183 p_Aij[x + ncols * (2 * delta_x)] += lambda * 2.e0;
3185 p_Aij[x + ncols * (2 * delta_x + 1)] -= lambda;
3188 p_Aij[ncols - 1 + ncols * (2 * delta_x - 1)] -= lambda;
3190 p_Aij[ncols - 1 + ncols * (2 * delta_x)] += lambda;
3194 info = cr2res_extract_slitdec_bandsol(p_Aij, p_bj, ncols, nx, lambda);
3196 cpl_msg_error(__func__,
"info(sP)=%d\n", info);
3198 for (x = 0; x < ncols; x++)
3203 tmp_vec = cpl_vector_wrap(ncols, sP);
3204 sP_med = fabs(cpl_vector_get_median_const(tmp_vec));
3205 cpl_vector_unwrap(tmp_vec);
3209 for (x = 0; x < ncols; x++) {
3210 if (fabs(sP[x] - sP_old[x]) > sP_change)
3211 sP_change = fabs(sP[x] - sP_old[x]);
3214 if ((isnan(sP[0]) || (sP[ncols / 2] == 0)) &&
3215 (cpl_msg_get_level() == CPL_MSG_DEBUG)) {
3216 debug_output(ncols, nrows, osample, im, pix_unc, mask, ycen,
3217 ycen_offset, y_lower_lim, slitcurves);
3218 cpl_msg_error(__func__,
"Swath failed");
3222 for (y = 0; y < nrows * ncols; y++) {
3225 for (y = 0; y < nrows; y++) {
3226 for (x = 0; x < ncols; x++) {
3227 for (m = 0; m < m_zeta[mzeta_index(x, y)]; m++) {
3228 xx = zeta[zeta_index(x, y, m)].x;
3229 iy = zeta[zeta_index(x, y, m)].iy;
3230 ww = zeta[zeta_index(x, y, m)].w;
3231 model[y * ncols + x] += sP[xx] * sL[iy] * ww;
3246 for (y = 0; y < nrows; y++) {
3247 for (x = delta_x; x < ncols - delta_x; x++) {
3248 if (mask[y * ncols + x]) {
3249 tmp = model[y * ncols + x] - im[y * ncols + x];
3251 tmp /= max(pix_unc[y * ncols + x], 1);
3257 cost /= (isum - (ncols + ny));
3258 sigma = sqrt(sum / isum);
3261 for (y = 0; y < nrows; y++) {
3262 for (x = delta_x; x < ncols - delta_x; x++) {
3263 if (fabs(model[y * ncols + x] - im[y * ncols + x]) >
3265 mask[y * ncols + x] = 0;
3267 mask[y * ncols + x] = 1;
3271 for (y = 0; y < nrows; y++) {
3272 for (x = delta_x; x < ncols - delta_x; x++) {
3273 cpl_image_set(img_mad, x + 1, y + 1,
3274 (model[y * ncols + x] - im[y * ncols + x]));
3275 if ((mask[y * ncols + x] == 0) || (im[y * ncols + x] == 0))
3276 cpl_image_reject(img_mad, x + 1, y + 1);
3282 "Iter: %i, Sigma: %f, Cost: %f, sP_change: %f, sP_lim: %f", iter,
3283 sigma, cost, sP_change, sP_stop * sP_med);
3286 }
while (iter == 1 ||
3289 && sP_change > sP_stop * sP_med));
3291 if (iter == maxiter && sP_change > sP_stop * sP_med)
3294 "Maximum number of %d iterations reached without converging.",
3299 for (y = 0; y < ny; y++)
3302 for (y = 0; y < ny; y++)
3304 for (x = 0; x < ncols; x++)
3308 tmp_vec = cpl_vector_wrap(ny, sL);
3309 sLmax = cpl_vector_get_max(tmp_vec);
3310 cpl_vector_unwrap(tmp_vec);
3311 cpl_msg_debug(__func__,
3312 "sL-sum, sLmax, osample, nrows, ny: %g, %g, %d, %d, %d", sum,
3313 sLmax, osample, nrows, ny);
3341 if (error_factor == -1)
3344 for (x = 0; x < ncols; x++)
3348 double model_sum = 0.0;
3353 for (y = 0; y < nrows; y++)
3355 model_sum += model[y * ncols + x];
3357 for (y = 0; y < nrows; y++)
3359 double model_norm = model[y * ncols + x] / model_sum;
3360 num_sum += model_norm * mask[y * ncols + x];
3361 den_sum += (model_norm * model_norm) * mask[y * ncols + x] / (pix_unc[y * ncols + x] * pix_unc[y * ncols + x]);
3365 unc[x] = sqrt(fabs(num_sum / den_sum));
3376 for (x = 0; x < ncols; x++)
3383 for (y = 0; y < nrows; y++)
3385 if (mask[y * ncols + x])
3387 msum += (im[y * ncols + x] * model[y * ncols + x]) *
3388 mask[y * ncols + x];
3389 sum += (model[y * ncols + x] * model[y * ncols + x]) *
3390 mask[y * ncols + x];
3397 unc[x] = sqrt(fabs(sP[x]) * fabs(sum) / fabs(msum) / error_factor);
3436int cr2res_extract_slitdec_bandsol(
3449 for(i=0; i<n-1; i++)
3452 if(aa==0.e0) aa = lambda;
3454 for(j=0; j<nd; j++) a[i+j*n]/=aa;
3455 for(j=1; j<min(nd/2+1,n-i); j++)
3457 aa=a[i+j+n*(nd/2-j)];
3459 for(k=0; k<n*(nd-j); k+=n) a[i+j+k]-=a[i+k+n*j]*aa;
3464 aa = a[n-1+n*(nd/2)];
3465 if (aa == 0) aa = lambda;
3467 for(i=n-1; i>0; i--)
3469 for(j=1; j<=min(nd/2,i); j++){
3470 r[i-j]-=r[i]*a[i-j+n*(nd/2+j)];
3472 aa = a[i-1+n*(nd/2)];
3473 if(aa==0.e0) aa = lambda;
3479 if(aa==0.e0) aa = lambda;
3496static int cr2res_extract_slitdec_adjust_swath(
3503 cpl_vector ** bins_begin,
3504 cpl_vector ** bins_end)
3506 if (sw <= 0 || lenx <= 0)
return -1;
3507 if (bins_begin == NULL || bins_end == NULL)
return -1;
3508 if (ycen == NULL)
return -1;
3511 if (sw==CR2RES_DETECTOR_SIZE){
3512 *bins_begin = cpl_vector_new(1);
3513 *bins_end = cpl_vector_new(1);
3514 cpl_vector_set(*bins_begin, 0, 0);
3515 cpl_vector_set(*bins_end, 0, CR2RES_DETECTOR_SIZE);
3516 return CR2RES_DETECTOR_SIZE;
3519 int nbin, nx, i = 0;
3521 int start = 0, end = lenx;
3526 for (i=0; i < lenx; i++){
3527 ymin = ycen_int[i] - (height/2);
3528 ymax = ycen_int[i] + (height/2) + height%2 ;
3529 if (!((ymax <= 1) || (ymin > leny))){
3535 for (i = lenx - 1; i >= 0; i--){
3536 ymin = ycen_int[i] - (height/2);
3537 ymax = ycen_int[i] + (height/2) + height%2 ;
3538 if (!((ymax <= 1) || (ymin > leny))){
3551 if (sw > nx - 2 * dx) {
3553 if (sw % 2 == 1) sw -= 1;
3554 }
else if (sw % 2 == 1) sw += 1;
3557 nbin = 2 * ((nx - 2 * dx) / sw);
3558 if ((nx - 2 * dx) % sw > sw / 2) nbin++;
3559 if (nbin < 1) nbin = 1;
3563 *bins_begin = cpl_vector_new(nbin);
3564 *bins_end = cpl_vector_new(nbin);
3567 for(i = 0; i < nbin; i++)
3570 bin = start + min(i * step, nx - sw - 2 * dx);
3571 cpl_vector_set(*bins_begin, i, bin);
3572 cpl_vector_set(*bins_end, i, bin + sw + 2 * dx);
3573 cpl_msg_debug(__func__,
"Swath %d goes from %d to %d.", i, bin,
3579static int debug_output(
3589 cpl_polynomial ** slitcurves)
3593 cpl_propertylist * pl;
3595 pl = cpl_propertylist_new();
3596 cpl_propertylist_append_int(pl,
"osample", osample);
3597 cpl_propertylist_append_int(pl,
"y_lower_lim", y_lower_lim);
3599 img = cpl_image_wrap_double(ncols, nrows, im);
3600 cpl_image_save(img,
"debug_image_at_error.fits", CPL_TYPE_DOUBLE, pl,
3602 cpl_image_unwrap(img);
3604 img = cpl_image_wrap_int(ncols, nrows, mask);
3605 cpl_image_save(img,
"debug_mask_after_error.fits", CPL_TYPE_INT, NULL,
3607 cpl_image_unwrap(img);
3609 img = cpl_image_wrap_double(ncols, nrows, pix_unc);
3610 cpl_image_save(img,
"debug_unc_at_error.fits", CPL_TYPE_DOUBLE, NULL,
3612 cpl_image_unwrap(img);
3614 vec = cpl_vector_wrap(ncols, ycen);
3615 cpl_vector_save(vec,
"debug_ycen_after_error.fits", CPL_TYPE_DOUBLE, NULL,
3617 cpl_vector_unwrap(vec);
3619 vec = cpl_vector_new(ncols);
3620 for (
int i = 0; i < ncols; i++) cpl_vector_set(vec, i, ycen_offset[i]);
3621 cpl_vector_save(vec,
"debug_offset_after_error.fits", CPL_TYPE_INT, NULL,
3623 cpl_vector_delete(vec);
3625 img = cpl_image_new(ncols, 3, CPL_TYPE_DOUBLE);
3626 for (cpl_size i = 0; i < ncols; i++){
3627 for (cpl_size j = 0; j < 3 ; j++){
3628 cpl_image_set(img, i+1, j+1,
3629 cpl_polynomial_get_coeff(slitcurves[i], &j));
3632 cpl_image_save(img,
"debug_slitcurves_at_error.fits", CPL_TYPE_DOUBLE,
3633 NULL, CPL_IO_CREATE);
3634 cpl_image_delete(img);
3636 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