38#include "irplib_utils.h"
40#include "cr2res_dfs.h"
41#include "cr2res_trace.h"
42#include "cr2res_extract.h"
43#include "cr2res_wave.h"
44#include "cr2res_bpm.h"
50typedef unsigned char byte;
51#define min(a,b) (((a)<(b))?(a):(b))
52#define max(a,b) (((a)>(b))?(a):(b))
53#define signum(a) (((a)>0)?1:((a)<0)?-1:0)
56#define zeta_index(x, y, z) \
57 ((z) + (y) * (3 * (osample + 1)) + (x) * (3 * (osample + 1)) * nrows)
58#define mzeta_index(x, y) ((y) + (x) * nrows)
62#define laij_index(x, y) ((x) * (4 * osample + 1) + (y))
63#define paij_index(x, y) ((x) * nx + (y))
65#define curve_index(x, y) ((x) * 6 + (y))
86static int cr2res_extract_slit_func_curved(
98 const double * slitcurve,
109 const double * slit_func_in,
121static int cr2res_extract_zeta_tensors(
125 const int * ycen_offset,
128 const double * slitcurve,
133static int cr2res_extract_bandsol_rowmajor(
139static int cr2res_extract_slitdec_adjust_swath(
146 cpl_vector ** bins_begin,
147 cpl_vector ** bins_end) ;
187 const hdrl_image * img,
188 const cpl_table * traces,
189 const cpl_table * slit_func_in,
190 const cpl_table * blaze_table_in,
194 cr2res_extr_method extr_method,
207 cpl_table ** extracted,
208 cpl_table ** slit_func,
209 hdrl_image ** model_master)
211 cpl_bivector ** spectrum ;
212 cpl_vector ** slit_func_vec ;
213 hdrl_image ** model_one ;
214 cpl_table * slit_func_loc ;
215 cpl_table * extract_loc ;
216 hdrl_image * model_loc ;
220 if (img == NULL || traces == NULL)
return -1 ;
223 nb_traces = cpl_table_get_nrow(traces) ;
226 spectrum = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
227 slit_func_vec = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
228 model_one = cpl_malloc(nb_traces *
sizeof(hdrl_image *)) ;
238#pragma omp parallel for schedule(dynamic, 1)
240 for (i=0 ; i<nb_traces ; i++) {
242 cpl_vector * slit_func_in_vec ;
243 hdrl_image * model_loc_one ;
246 slit_func_vec[i] = NULL ;
248 model_loc_one = NULL ;
249 model_one[i] = NULL ;
252 order = cpl_table_get(traces, CR2RES_COL_ORDER, i, NULL) ;
253 trace_id = cpl_table_get(traces, CR2RES_COL_TRACENB, i, NULL) ;
256 if (reduce_order > -1 && order != reduce_order) continue ;
259 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
261 cpl_msg_info(__func__,
"Process Order %d/Trace %d",order,trace_id) ;
262 cpl_msg_indent_more() ;
265 if (slit_func_in != NULL) {
268 trace_id, &slit_func_in_vec) ;
270 slit_func_in_vec = NULL ;
274 if (extr_method == CR2RES_EXTR_SUM) {
276 trace_id, extr_height, &(slit_func_vec[i]),
277 &(spectrum[i]), &model_loc_one) != 0) {
278 cpl_msg_error(__func__,
"Cannot (sum-)extract the trace") ;
279 if (slit_func_in_vec != NULL)
280 cpl_vector_delete(slit_func_in_vec) ;
281 slit_func_vec[i] = NULL ;
283 model_loc_one = NULL ;
285 cpl_msg_indent_less() ;
288 }
else if (extr_method == CR2RES_EXTR_MEDIAN) {
290 trace_id, extr_height, &(slit_func_vec[i]),
291 &(spectrum[i]), &model_loc_one) != 0) {
292 cpl_msg_error(__func__,
"Cannot (median-)extract the trace") ;
293 if (slit_func_in_vec != NULL)
294 cpl_vector_delete(slit_func_in_vec) ;
295 slit_func_vec[i] = NULL ;
297 model_loc_one = NULL ;
299 cpl_msg_indent_less() ;
302 }
else if (extr_method == CR2RES_EXTR_TILTSUM) {
304 trace_id, extr_height, &(slit_func_vec[i]),
305 &(spectrum[i]), &model_loc_one) != 0) {
306 cpl_msg_error(__func__,
"Cannot (tiltsum-)extract the trace") ;
307 if (slit_func_in_vec != NULL)
308 cpl_vector_delete(slit_func_in_vec) ;
309 slit_func_vec[i] = NULL ;
311 model_loc_one = NULL ;
313 cpl_msg_indent_less() ;
316 }
else if (extr_method == CR2RES_EXTR_OPT_CURV) {
318 order, trace_id, extr_height, swath_width,
319 oversample, pclip, smooth_slit, smooth_spec,
320 niter, kappa, error_factor,
322 &(spectrum[i]), &model_loc_one) != 0) {
323 cpl_msg_error(__func__,
324 "Cannot extract order %d, trace %d", order, trace_id) ;
325 if (slit_func_in_vec != NULL)
326 cpl_vector_delete(slit_func_in_vec) ;
327 slit_func_vec[i] = NULL ;
329 model_loc_one = NULL ;
331 cpl_msg_indent_less() ;
335 if (slit_func_in_vec != NULL) cpl_vector_delete(slit_func_in_vec) ;
338 if (blaze_table_in != NULL) {
339 cpl_bivector * blaze_biv ;
340 cpl_bivector * blaze_err_biv ;
342 trace_id, &blaze_biv, &blaze_err_biv)) {
343 cpl_msg_warning(__func__,
344 "Cannot Get the Blaze for order/trace:%d/%d - skip",
348 double * pblaze_err ;
349 double first_nonzero_value, first_nonzero_error ;
353 cpl_vector_get_data(cpl_bivector_get_y(blaze_biv)) ;
355 cpl_vector_get_data(cpl_bivector_get_y(blaze_err_biv)) ;
356 first_nonzero_value = first_nonzero_error = 0.0 ;
357 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
358 if (fabs(pblaze[j])>1e-3) {
359 first_nonzero_value = pblaze[j] ;
360 first_nonzero_error = pblaze_err[j] ;
364 if (fabs(first_nonzero_value)<1e-3) {
365 cpl_msg_warning(__func__,
"Blaze filled with zeros - skip");
369 double norm_factor, val, err ;
370 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
371 if (fabs(pblaze[j])<1e-3) {
372 pblaze[j] = first_nonzero_value ;
373 pblaze_err[j] = first_nonzero_error ;
383 norm_factor = blaze_norm;
385 cpl_vector * tmp_vec ;
387 tmp_vec=cpl_vector_duplicate(cpl_bivector_get_y(blaze_biv));
388 kth = (cpl_size)(cpl_bivector_get_size(blaze_biv)*0.95) ;
389 irplib_vector_get_kth(tmp_vec, kth) ;
390 norm_factor = cpl_vector_get(tmp_vec, kth) ;
391 cpl_vector_delete(tmp_vec) ;
395 pspec = cpl_bivector_get_x_data(spectrum[i]) ;
396 pspec_err = cpl_bivector_get_y_data(spectrum[i]);
397 for (j=0 ; j<cpl_bivector_get_size(blaze_biv) ; j++) {
398 if (fabs(pspec[j]) > 1e-3) {
400 val = pspec[j] / (pblaze[j]/norm_factor) ;
404 err = fabs(val) * sqrt(((pspec_err[j]*pspec_err[j])/
405 (pspec[j]*pspec[j]))+
406 ((pblaze_err[j]*pblaze_err[j])/
407 (pblaze[j]*pblaze[j])));
416 if (cpl_error_get_code()) {
418 cpl_msg_warning(__func__,
419 "Cannot Correct Blaze for order/trace:%d/%d - skip",
423 cpl_bivector_delete(blaze_biv) ;
424 cpl_bivector_delete(blaze_err_biv) ;
429 model_one[i] = model_loc_one ;
431 cpl_msg_indent_less() ;
439 for (i=0 ; i<nb_traces ; i++) {
440 if (model_one[i] != NULL) {
441 const cpl_image * src_data =
443 const cpl_image * src_err =
445 const double * sd = cpl_image_get_data_double_const(src_data) ;
446 const double * se = cpl_image_get_data_double_const(src_err) ;
447 const cpl_mask * src_bpm = cpl_image_get_bpm_const(src_data) ;
448 const cpl_binary * sb =
449 src_bpm ? cpl_mask_get_data_const(src_bpm) : NULL ;
452 double * dd = cpl_image_get_data_double(dst_data) ;
453 double * de = cpl_image_get_data_double(dst_err) ;
455 cpl_binary * dbd = cpl_image_get_bpm_const(dst_data) ?
456 cpl_mask_get_data(cpl_image_get_bpm(dst_data)) : NULL ;
457 cpl_binary * dbe = cpl_image_get_bpm_const(dst_err) ?
458 cpl_mask_get_data(cpl_image_get_bpm(dst_err)) : NULL ;
462 for (k = 0 ; k < npix ; k++) {
463 if (sd[k] != 0 && (sb == NULL || !sb[k])) {
466 if (dbd != NULL) dbd[k] = CPL_BINARY_0 ;
467 if (dbe != NULL) dbe[k] = CPL_BINARY_0 ;
471 model_one[i] = NULL ;
475 if (display && spectrum[i] != NULL &&
477 cpl_table_get(traces, CR2RES_COL_ORDER, i, NULL) &&
479 cpl_table_get(traces, CR2RES_COL_TRACENB, i, NULL)) {
481 "set grid;set xlabel 'pixels';set ylabel 'Flux (ADU)';",
482 "t 'Extracted Spectrum' w lines",
"",
483 cpl_bivector_get_x_const(spectrum[i])) ;
486 cpl_free(model_one) ;
491 cpl_msg_error(__func__,
"Cannot compute the slit function") ;
492 for (i=0 ; i<nb_traces ; i++) {
493 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
494 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
497 cpl_free(slit_func_vec) ;
505 for (i=0 ; i<nb_traces ; i++) {
506 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
507 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
510 cpl_free(slit_func_vec) ;
512 cpl_table_delete(slit_func_loc);
517 for (i=0 ; i<nb_traces ; i++) {
518 if (slit_func_vec[i] != NULL) cpl_vector_delete(slit_func_vec[i]) ;
519 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
522 cpl_free(slit_func_vec) ;
525 *extracted = extract_loc ;
526 *slit_func = slit_func_loc ;
527 *model_master = model_loc;
556 const hdrl_image * hdrl_in,
557 const cpl_table * trace_tab,
561 cpl_vector ** slit_func,
562 cpl_bivector ** spec,
569 const cpl_image * img_in;
570 const cpl_image * err_in;
576 double trace_cen, trace_height ;
580 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
586 imtyp = cpl_image_get_type(img_in);
587 lenx = cpl_image_get_size_x(img_in);
588 leny = cpl_image_get_size_y(img_in);
594 cpl_msg_error(__func__,
"Cannot compute height");
600 trace_id, lenx)) == NULL) {
601 cpl_msg_error(__func__,
"Cannot get ycen");
604 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
606 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
607 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
610 if (img_tmp == NULL) {
611 cpl_msg_error(__func__,
"Cannot rectify order");
612 cpl_vector_delete(ycen);
616 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
617 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
618 NULL, CPL_IO_CREATE);
620 img_1d = cpl_image_collapse_create(img_tmp, 0);
621 spc = cpl_vector_new_from_image_row(img_1d, 1);
622 cpl_image_delete(img_1d);
624 img_1d = cpl_image_collapse_create(img_tmp, 1);
625 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
626 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
627 cpl_image_delete(img_1d);
628 cpl_image_delete(img_tmp);
631 if (img_tmp == NULL) {
632 cpl_msg_error(__func__,
"Cannot rectify error");
633 cpl_vector_delete(ycen);
636 cpl_image_multiply(img_tmp, img_tmp);
637 img_1d = cpl_image_collapse_create(img_tmp, 0);
638 sigma = cpl_vector_new_from_image_row(img_1d, 1);
639 cpl_vector_sqrt(sigma);
640 cpl_image_delete(img_tmp);
641 cpl_image_delete(img_1d);
644 img_tmp = cpl_image_new(lenx, leny, imtyp);
646 for (i=1;i<=lenx;i++){
647 for (j=1;j<=height;j++){
648 y = ycen_int[i-1]-(height/2)+j;
649 if ((y <=0) || (y > leny)){
continue; }
650 cpl_image_set(img_tmp, i, y,
651 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
654 cpl_vector_delete(ycen);
657 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
658 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
659 NULL, CPL_IO_CREATE);
664 *spec = cpl_bivector_wrap_vectors(spc, sigma);
666 cpl_image_delete(img_tmp);
668 if (cpl_error_get_code() != CPL_ERROR_NONE){
669 cpl_msg_error(__func__,
"Error in the vertical sum extraction %s",
670 cpl_error_get_where());
704 const hdrl_image * hdrl_in,
705 const cpl_table * trace_tab,
709 cpl_vector ** slit_func,
710 cpl_bivector ** spec,
717 const cpl_image * img_in;
718 const cpl_image * err_in;
724 double trace_cen, trace_height ;
728 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
734 imtyp = cpl_image_get_type(img_in);
735 lenx = cpl_image_get_size_x(img_in);
736 leny = cpl_image_get_size_y(img_in);
742 cpl_msg_error(__func__,
"Cannot compute height");
748 trace_id, lenx)) == NULL) {
749 cpl_msg_error(__func__,
"Cannot get ycen");
752 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
754 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
755 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
758 if (img_tmp == NULL) {
759 cpl_msg_error(__func__,
"Cannot rectify order");
760 cpl_vector_delete(ycen);
764 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
765 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
766 NULL, CPL_IO_CREATE);
768 img_1d = cpl_image_collapse_median_create(img_tmp, 0, 0, 0);
769 spc = cpl_vector_new_from_image_row(img_1d, 1);
772 cpl_vector_multiply_scalar(spc,(
double)height);
773 cpl_image_delete(img_1d);
775 img_1d = cpl_image_collapse_median_create(img_tmp, 1, 0, 0);
776 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
777 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
778 cpl_image_delete(img_1d);
779 cpl_image_delete(img_tmp);
784 cpl_msg_error(__func__,
"Cannot rectify error");
785 cpl_vector_delete(ycen);
788 cpl_image_multiply(img_tmp, img_tmp);
789 img_1d = cpl_image_collapse_create(img_tmp, 0);
790 sigma = cpl_vector_new_from_image_row(img_1d, 1);
791 cpl_vector_sqrt(sigma);
792 cpl_image_delete(img_tmp);
793 cpl_image_delete(img_1d);
796 img_tmp = cpl_image_new(lenx, leny, imtyp);
798 for (i=1;i<=lenx;i++){
799 for (j=1;j<=height;j++){
800 cpl_image_set(img_tmp, i, ycen_int[i-1]-(height/2)+j,
801 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
804 cpl_vector_delete(ycen);
807 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
808 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
809 NULL, CPL_IO_CREATE);
814 *spec = cpl_bivector_wrap_vectors(spc, sigma);
816 cpl_image_delete(img_tmp);
847 const hdrl_image * hdrl_in,
848 const cpl_table * trace_tab,
852 cpl_vector ** slit_func,
853 cpl_bivector ** spec,
860 const cpl_image * img_in;
861 const cpl_image * err_in;
867 double trace_cen, trace_height ;
871 double a, b, c, value;
872 cpl_polynomial * slitcurve_A, * slitcurve_B, *slitcurve_C;
873 cpl_bivector * xi, *xt;
876 if (hdrl_in == NULL || trace_tab == NULL)
return -1 ;
882 imtyp = cpl_image_get_type(img_in);
883 lenx = cpl_image_get_size_x(img_in);
884 leny = cpl_image_get_size_y(img_in);
890 cpl_msg_error(__func__,
"Cannot compute height");
896 trace_id, lenx)) == NULL) {
897 cpl_msg_error(__func__,
"Cannot get ycen");
900 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
902 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
903 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
906 if (img_tmp == NULL) {
907 cpl_msg_error(__func__,
"Cannot rectify order");
908 cpl_vector_delete(ycen);
912 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
913 cpl_image_save(img_tmp,
"debug_rectorder.fits", imtyp,
914 NULL, CPL_IO_CREATE);
934 if ((slitcurve_A == NULL) || (slitcurve_B == NULL) || (slitcurve_C == NULL))
936 cpl_msg_error(__func__,
937 "No (or incomplete) slitcurve data found in trace table");
938 cpl_vector_delete(ycen);
939 cpl_polynomial_delete(slitcurve_A);
940 cpl_polynomial_delete(slitcurve_B);
941 cpl_polynomial_delete(slitcurve_C);
948 xi = cpl_bivector_new(lenx);
949 xt = cpl_bivector_new(lenx);
950 for (i = 0; i < lenx; i++){
951 cpl_vector_set(cpl_bivector_get_x(xi), i, i);
952 cpl_vector_set(cpl_bivector_get_x(xt), i, i);
953 cpl_vector_set(cpl_bivector_get_y(xi), i, 0);
954 cpl_vector_set(cpl_bivector_get_y(xt), i, 0);
957 for (i = 0; i < height; i++){
958 int yt = i - height / 2 + 0.5;
959 int yc = cpl_vector_get(ycen, i);
961 for (j = 1; j < lenx - 1; j++){
963 b = cpl_polynomial_eval_1d(slitcurve_B, j, NULL);
964 c = cpl_polynomial_eval_1d(slitcurve_C, j, NULL);
971 value = j - a - yt * b - yt * yt * c;
972 value = max(min(value, lenx-1), 0);
973 cpl_vector_set(cpl_bivector_get_x(xt), j, value);
974 value = cpl_image_get(img_tmp, j + 1, i + 1, &badpix);
975 if (badpix) value = NAN;
976 cpl_vector_set(cpl_bivector_get_y(xt), j, value);
979 cpl_bivector_interpolate_linear(xi, xt);
981 for (j = 0; j < lenx; j++){
982 value = cpl_vector_get(cpl_bivector_get_y(xi), j);
983 cpl_image_set(img_tmp, j+1, i+1, value);
985 cpl_image_set(img_tmp, j+1, i+1, 0);
986 cpl_image_reject(img_tmp, j+1, i+1);
991 cpl_bivector_delete(xi);
992 cpl_bivector_delete(xt);
993 cpl_polynomial_delete(slitcurve_A);
994 cpl_polynomial_delete(slitcurve_B);
995 cpl_polynomial_delete(slitcurve_C);
997 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
998 cpl_image_save(img_tmp,
"debug_img_shifted.fits", imtyp,
999 NULL, CPL_IO_CREATE);
1005 xi = cpl_bivector_new(height);
1006 xt = cpl_bivector_new(height);
1008 for (j = 0; j < lenx; j++){
1010 cpl_vector_set(cpl_bivector_get_x(xi), 0, 0);
1011 cpl_vector_set(cpl_bivector_get_y(xi), 0, 0);
1012 cpl_vector_set(cpl_bivector_get_x(xi), height-1, height-1);
1013 cpl_vector_set(cpl_bivector_get_y(xi), height-1, 0);
1014 for (i = 0; i < height; i++){
1015 cpl_vector_set(cpl_bivector_get_x(xt), i, i);
1016 cpl_vector_set(cpl_bivector_get_y(xt), i, 0);
1018 value = cpl_image_get(img_tmp, j+1, i+1, &badpix);
1020 cpl_vector_set(cpl_bivector_get_x(xi), i, i);
1021 cpl_vector_set(cpl_bivector_get_y(xi), i, value);
1024 cpl_bivector_interpolate_linear(xt, xi);
1025 for (i = 0; i < height; i++){
1026 value = cpl_vector_get(cpl_bivector_get_y(xt), i);
1027 cpl_image_set(img_tmp, j+1, i+1, value);
1031 cpl_bivector_delete(xi);
1032 cpl_bivector_delete(xt);
1034 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1035 cpl_image_save(img_tmp,
"debug_img_shifted_corrected.fits", imtyp,
1036 NULL, CPL_IO_CREATE);
1039 img_1d = cpl_image_collapse_create(img_tmp, 0);
1040 spc = cpl_vector_new_from_image_row(img_1d, 1);
1041 cpl_image_delete(img_1d);
1043 img_1d = cpl_image_collapse_create(img_tmp, 1);
1044 slitfu = cpl_vector_new_from_image_column(img_1d, 1);
1045 cpl_vector_divide_scalar(slitfu, cpl_vector_get_sum(slitfu));
1046 cpl_image_delete(img_1d);
1047 cpl_image_delete(img_tmp);
1050 if (img_tmp == NULL)
1052 cpl_msg_error(__func__,
"Cannot rectify error");
1053 cpl_vector_delete(ycen);
1056 cpl_image_multiply(img_tmp, img_tmp);
1057 img_1d = cpl_image_collapse_create(img_tmp, 0);
1058 sigma = cpl_vector_new_from_image_row(img_1d, 1);
1059 cpl_vector_sqrt(sigma);
1060 cpl_image_delete(img_tmp);
1061 cpl_image_delete(img_1d);
1064 img_tmp = cpl_image_new(lenx, leny, imtyp);
1066 for (i=1;i<=lenx;i++){
1067 for (j=1;j<=height;j++){
1068 cpl_image_set(img_tmp, i, ycen_int[i-1]-(height/2)+j,
1069 cpl_vector_get(spc,i-1)*cpl_vector_get(slitfu,j-1) );
1072 cpl_vector_delete(ycen);
1075 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1076 cpl_image_save(img_tmp,
"debug_model.fits", imtyp,
1077 NULL, CPL_IO_CREATE);
1081 *slit_func = slitfu;
1082 *spec = cpl_bivector_wrap_vectors(spc, sigma);
1084 cpl_image_delete(img_tmp);
1098 cpl_bivector ** spectrum,
1099 const cpl_table * trace_table)
1103 const double * pspec ;
1104 const double * perr ;
1105 cpl_vector * wave_vec ;
1106 const double * pwl ;
1107 int nrows, all_null, i, order, trace_id, nb_traces ;
1110 if (spectrum == NULL || trace_table == NULL)
return NULL ;
1113 nb_traces = cpl_table_get_nrow(trace_table) ;
1117 for (i=0 ; i<nb_traces ; i++)
1118 if (spectrum[i] != NULL) {
1119 nrows = cpl_bivector_get_size(spectrum[i]) ;
1122 if (all_null == 1)
return NULL ;
1125 for (i=0 ; i<nb_traces ; i++)
1126 if (spectrum[i] != NULL && cpl_bivector_get_size(spectrum[i]) != nrows)
1130 out = cpl_table_new(nrows);
1131 for (i=0 ; i<nb_traces ; i++) {
1132 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1133 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1136 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1137 cpl_free(col_name) ;
1140 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1141 cpl_free(col_name) ;
1144 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1145 cpl_free(col_name) ;
1149 for (i=0 ; i<nb_traces ; i++) {
1150 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1151 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1152 if (spectrum[i] != NULL) {
1153 pspec = cpl_bivector_get_x_data_const(spectrum[i]) ;
1154 perr = cpl_bivector_get_y_data_const(spectrum[i]);
1157 cpl_table_copy_data_double(out, col_name, pspec) ;
1158 cpl_free(col_name) ;
1161 cpl_table_copy_data_double(out, col_name, perr) ;
1162 cpl_free(col_name) ;
1166 CR2RES_DETECTOR_SIZE);
1167 if (wave_vec == NULL) {
1168 wave_vec = cpl_vector_new(CR2RES_DETECTOR_SIZE) ;
1169 cpl_vector_fill(wave_vec, 0.0) ;
1171 pwl = cpl_vector_get_data(wave_vec) ;
1175 cpl_table_copy_data_double(out, col_name, pwl) ;
1176 cpl_free(col_name) ;
1177 cpl_vector_delete(wave_vec) ;
1181 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1182 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1183 cpl_free(col_name) ;
1186 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1187 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1188 cpl_free(col_name) ;
1191 cpl_table_fill_column_window_double(out, col_name, 0, CR2RES_DETECTOR_SIZE, NAN);
1192 cpl_table_set_column_invalid(out, col_name, 0, CR2RES_DETECTOR_SIZE);
1193 cpl_free(col_name) ;
1208 cpl_vector ** slit_func,
1209 const cpl_table * trace_table)
1213 const double * pslit ;
1214 int nrows, nrows_max, all_null, i, order, trace_id,
1218 if (slit_func == NULL || trace_table == NULL)
return NULL ;
1222 nb_traces = cpl_table_get_nrow(trace_table) ;
1226 for (i=0 ; i<nb_traces ; i++)
1227 if (slit_func[i] != NULL) {
1228 nrows = cpl_vector_get_size(slit_func[i]) ;
1229 if (nrows > nrows_max) nrows_max = nrows ;
1232 if (all_null == 1)
return NULL ;
1236 for (i = 0; i < nb_traces; i++)
1237 if (slit_func[i] != NULL)
1239 nrows = cpl_vector_get_size(slit_func[i]);
1240 cpl_vector_set_size(slit_func[i], nrows_max);
1241 for (
int j = nrows; j < nrows_max; j++)
1243 cpl_vector_set(slit_func[i], j, 0.0);
1248 out = cpl_table_new(nrows_max);
1249 for (i=0 ; i<nb_traces ; i++) {
1250 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1251 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1253 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
1254 cpl_free(col_name) ;
1258 for (i=0 ; i<nb_traces ; i++) {
1259 if (slit_func[i] != NULL) {
1260 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1261 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1262 pslit = cpl_vector_get_data_const(slit_func[i]) ;
1264 cpl_table_copy_data_double(out, col_name, pslit) ;
1265 cpl_free(col_name) ;
1267 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
1268 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
1270 cpl_table_fill_column_window_double(out, col_name, 0, nrows_max, NAN);
1271 cpl_table_set_column_invalid(out, col_name, 0, nrows_max);
1272 cpl_free(col_name) ;
1290 const cpl_table * tab,
1293 cpl_bivector ** spec,
1294 cpl_bivector ** spec_err)
1298 char * spec_err_name ;
1299 const double * pspec ;
1300 const double * pwave ;
1301 const double * pspec_err ;
1304 double * pxspec_err ;
1305 double * pyspec_err ;
1309 if (tab == NULL || spec == NULL || spec_err == NULL)
return -1 ;
1313 if ((pspec = cpl_table_get_data_double_const(tab, spec_name)) == NULL) {
1314 cpl_msg_error(__func__,
"Cannot find the spectrum") ;
1315 cpl_free(spec_name) ;
1318 cpl_free(spec_name) ;
1322 if ((pwave = cpl_table_get_data_double_const(tab, wave_name)) == NULL) {
1323 cpl_msg_error(__func__,
"Cannot find the wavelength") ;
1324 cpl_free(wave_name) ;
1327 cpl_free(wave_name) ;
1331 if ((pspec_err = cpl_table_get_data_double_const(tab, spec_err_name))
1333 cpl_msg_error(__func__,
"Cannot find the spectrum error") ;
1334 cpl_free(spec_err_name) ;
1337 cpl_free(spec_err_name) ;
1340 tab_size = cpl_table_get_nrow(tab) ;
1341 *spec = cpl_bivector_new(tab_size) ;
1342 *spec_err = cpl_bivector_new(tab_size) ;
1343 pxspec = cpl_bivector_get_x_data(*spec) ;
1344 pyspec = cpl_bivector_get_y_data(*spec) ;
1345 pxspec_err = cpl_bivector_get_x_data(*spec_err) ;
1346 pyspec_err = cpl_bivector_get_y_data(*spec_err) ;
1347 for (i=0 ; i<tab_size ; i++) {
1348 pxspec[i] = pwave[i] ;
1349 pyspec[i] = pspec[i] ;
1350 pxspec_err[i] = pwave[i] ;
1351 pyspec_err[i] = pspec_err[i] ;
1367 const cpl_table * tab,
1373 const double * ptab ;
1378 if (tab == NULL || vec == NULL)
return -1 ;
1382 if ((ptab = cpl_table_get_data_double_const(tab, vec_name)) == NULL) {
1383 cpl_msg_error(__func__,
"Cannot find the slit_func") ;
1384 cpl_free(vec_name) ;
1389 cpl_free(vec_name) ;
1392 tab_size = cpl_table_get_nrow(tab) ;
1393 *vec = cpl_vector_new(tab_size) ;
1394 pvec = cpl_vector_get_data(*vec) ;
1395 for (i=0 ; i<tab_size ; i++) pvec[i] = ptab[i] ;
1439 const hdrl_image * img_hdrl,
1440 const cpl_table * trace_tab,
1441 const cpl_vector * slit_func_vec_in,
1452 double error_factor,
1453 cpl_vector ** slit_func,
1454 cpl_bivector ** spec,
1455 hdrl_image ** model)
1459 int * ycen_offset_sw;
1460 double * slitfu_sw_data;
1462 const double * slit_func_in;
1464 const cpl_image * img_in;
1465 const cpl_image * err_in;
1468 cpl_image * img_rect;
1469 cpl_image * err_rect;
1470 cpl_image * model_rect;
1472 cpl_image * img_out;
1473 cpl_vector * slitfu_sw;
1474 cpl_vector * unc_sw;
1476 cpl_vector * slitfu;
1477 cpl_vector * weights_sw;
1478 cpl_vector * tmp_vec;
1479 cpl_vector * bins_begin;
1480 cpl_vector * bins_end;
1481 cpl_vector * unc_decomposition;
1482 cpl_size lenx, leny;
1484 cpl_polynomial *slitcurve_A, *slitcurve_B, *slitcurve_C;
1485 double * slitcurve_sw;
1486 hdrl_image * model_out;
1487 cpl_bivector * spectrum_loc;
1499 double pixval, errval;
1500 double trace_cen, trace_height;
1501 int i, j, k, nswaths, col, x, y, ny_os,
1507 if (img_hdrl == NULL || trace_tab == NULL)
return -1 ;
1509 if (smooth_slit == 0.0) {
1510 cpl_msg_error(__func__,
"Slit-smoothing cannot be 0.0");
1512 }
else if (smooth_slit < 0.1) {
1513 cpl_msg_warning(__func__,
"Slit-smoothing unreasonably small");
1514 }
else if (smooth_slit > 100.0) {
1515 cpl_msg_warning(__func__,
"Slit-smoothing unreasonably big");
1517 if (oversample < 3){
1518 cpl_msg_error(__func__,
"Oversampling too small");
1520 }
else if (oversample > 15) {
1521 cpl_msg_warning(__func__,
"Large oversampling, runtime will be long");
1524 cpl_msg_warning(__func__,
1525 "Allowing at least 5 iterations is recommended.");
1528 cpl_msg_warning(__func__,
1529 "Rejecting outliers < 4 sigma risks making good data.");
1535 imtyp = cpl_image_get_type(img_in);
1536 lenx = cpl_image_get_size_x(img_in);
1537 leny = cpl_image_get_size_y(img_in);
1543 cpl_msg_error(__func__,
"Cannot compute height");
1549 cpl_msg_warning(__func__,
1550 "Given height larger than image, clipping height");
1555 trace_id, lenx)) == NULL) {
1556 cpl_msg_error(__func__,
"Cannot get ycen");
1559 trace_cen = cpl_vector_get(ycen, cpl_vector_get_size(ycen)/2) ;
1561 cpl_msg_info(__func__,
"Y position of the trace: %g -> %g",
1562 trace_cen-(trace_height/2), trace_cen+(trace_height/2)) ;
1563 if (trace_cen-(height/2) < 0.0 ||
1564 trace_cen+(height/2) > CR2RES_DETECTOR_SIZE) {
1565 cpl_msg_error(__func__,
"Extraction outside detector edges impossible");
1566 cpl_vector_delete(ycen);
1572 if (img_rect == NULL){
1573 cpl_msg_error(__func__,
"Cannot rectify order");
1574 cpl_vector_delete(ycen);
1577 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1578 cpl_image_save(img_rect,
"debug_rectorder_curved.fits", imtyp,
1579 NULL, CPL_IO_CREATE);
1591 if ((slitcurve_A == NULL) || (slitcurve_B == NULL) || (slitcurve_C == NULL))
1593 cpl_msg_error(__func__,
1594 "No (or incomplete) slitcurve data found in trace table");
1595 cpl_vector_delete(ycen);
1596 cpl_free(ycen_rest) ;
1597 cpl_image_delete(err_rect) ;
1598 cpl_image_delete(img_rect) ;
1599 cpl_polynomial_delete(slitcurve_A);
1600 cpl_polynomial_delete(slitcurve_B);
1601 cpl_polynomial_delete(slitcurve_C);
1607 for (i=1; i<=lenx; i+=swath/2){
1608 double delta_tmp, a, b, c, yc;
1614 b = cpl_polynomial_eval_1d(slitcurve_B, i, NULL);
1615 c = cpl_polynomial_eval_1d(slitcurve_C, i, NULL);
1616 yc = cpl_vector_get(ycen, i-1);
1624 delta_tmp = max( fabs(a + (c*height/2. + b)*height/2.),
1625 fabs(a + (c*height/-2. + b)*height/-2.));
1626 if (delta_tmp > delta_x) delta_x = (int)ceil(delta_tmp);
1629 cpl_msg_debug(__func__,
"Max delta_x from slit curv: %d pix.", delta_x);
1631 if (delta_x >= swath / 4){
1632 cpl_msg_error(__func__,
1633 "Curvature is larger than the swath, try again with a larger swath size");
1634 cpl_vector_delete(ycen);
1635 cpl_free(ycen_rest) ;
1636 cpl_image_delete(err_rect) ;
1637 cpl_image_delete(img_rect) ;
1638 cpl_polynomial_delete(slitcurve_A);
1639 cpl_polynomial_delete(slitcurve_B);
1640 cpl_polynomial_delete(slitcurve_C);
1645 ny_os = oversample*(height+1) +1;
1646 if ((swath = cr2res_extract_slitdec_adjust_swath(ycen, height, leny, swath,
1647 lenx, delta_x, &bins_begin, &bins_end)) == -1){
1648 cpl_msg_error(__func__,
"Cannot calculate swath size");
1649 cpl_vector_delete(ycen);
1650 cpl_free(ycen_rest) ;
1651 cpl_image_delete(err_rect) ;
1652 cpl_image_delete(img_rect) ;
1653 cpl_polynomial_delete(slitcurve_A);
1654 cpl_polynomial_delete(slitcurve_B);
1655 cpl_polynomial_delete(slitcurve_C);
1658 nswaths = cpl_vector_get_size(bins_begin);
1661 slit_func_in = NULL;
1662 if (slit_func_vec_in != NULL) {
1664 size = cpl_vector_get_size(slit_func_vec_in);
1666 slit_func_in = cpl_vector_get_data_const(slit_func_vec_in);
1668 cpl_msg_warning(__func__,
"Ignoring the given slit_func since it is"
1669 " of the wrong size, expected %i but got %lli points.",
1675 mask_sw = cpl_malloc(height * swath*
sizeof(
int));
1676 model_sw = cpl_malloc(height * swath*
sizeof(
double));
1677 unc_sw = cpl_vector_new(swath);
1678 img_sw = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1679 err_sw = cpl_image_new(swath, height, CPL_TYPE_DOUBLE);
1680 ycen_sw = cpl_malloc(swath*
sizeof(
double));
1681 ycen_offset_sw = cpl_malloc(swath *
sizeof(
int));
1683 slitcurve_sw = cpl_malloc(swath * 6 *
sizeof(
double));
1686 slitfu = cpl_vector_new(ny_os);
1687 spectrum_loc = cpl_bivector_new(lenx);
1688 spc = cpl_bivector_get_x(spectrum_loc);
1689 unc_decomposition = cpl_bivector_get_y(spectrum_loc);
1690 for (j=0; j<lenx ; j++){
1691 cpl_vector_set(spc, j, 0.);
1692 cpl_vector_set(unc_decomposition, j, 0.);
1696 model_rect = cpl_image_new(lenx, height, CPL_TYPE_DOUBLE);
1699 slitfu_sw = cpl_vector_new(ny_os);
1700 for (j=0; j < ny_os; j++) cpl_vector_set(slitfu_sw, j, 0);
1701 slitfu_sw_data = cpl_vector_get_data(slitfu_sw);
1702 weights_sw = cpl_vector_new(swath);
1703 for (i = 0; i < swath; i++) cpl_vector_set(weights_sw, i, 0);
1706 for (i=delta_x; i < swath/2; i++) {
1707 j = i - delta_x + 1;
1708 cpl_vector_set(weights_sw, i, j);
1709 cpl_vector_set(weights_sw, swath - i - 1, j);
1712 cpl_vector_divide_scalar(weights_sw, swath/2 - delta_x + 1);
1717 ny = oversample * (height + 1) + 1;
1718 nx = 4 * delta_x + 1;
1721 sP_old = cpl_malloc(swath *
sizeof(
double));
1722 l_Aij = cpl_malloc(ny * (4*oversample+1) *
sizeof(
double));
1723 p_Aij = cpl_malloc(swath * nx *
sizeof(
double));
1724 l_bj = cpl_malloc(ny *
sizeof(
double));
1725 p_bj = cpl_malloc(swath *
sizeof(
double));
1730 i = 3 * (oversample + 1);
1732 zw = cpl_malloc(i *
sizeof(
double));
1733 zk = cpl_malloc(i *
sizeof(
int));
1738 zeta = cpl_malloc(swath * height * 3 * (oversample + 1)
1739 *
sizeof(zeta_ref));
1743 m_zeta = cpl_malloc(swath * height *
sizeof(
int));
1744 z_rng = cpl_malloc(swath * height *
sizeof(zeta_rng));
1746 for (i = 0; i < nswaths; i++) {
1747 double *img_sw_data;
1748 double *err_sw_data;
1749 double *spec_sw_data;
1750 double *unc_sw_data;
1753 cpl_vector *spec_sw;
1754 cpl_vector *spec_tmp;
1756 int sw_start, sw_end, y_lower_limit;
1760 sw_start = cpl_vector_get(bins_begin, i);
1761 sw_end = cpl_vector_get(bins_end, i);
1764 for(col=1; col<=swath; col++){
1768 for(y=1;y<=height;y++){
1769 errval = cpl_image_get(err_rect, x, y, &badpix);
1770 if (isnan(errval) || badpix){
1775 pixval = cpl_image_get(img_rect, x, y, &badpix);
1776 if (isnan(pixval) || badpix){
1784 cpl_image_set(img_sw, col, y, pixval);
1785 cpl_image_set(err_sw, col, y, errval);
1789 cpl_image_reject(img_sw, col, y);
1793 j = (y-1)*swath + (col-1) ;
1796 mask_sw[j] = !badpix;
1822 b = cpl_polynomial_eval_1d(slitcurve_B, x, NULL);
1823 c = cpl_polynomial_eval_1d(slitcurve_C, x, NULL);
1824 yc = cpl_vector_get(ycen, x-1);
1825 slitcurve_sw[curve_index(col-1, 0)] = 0;
1826 slitcurve_sw[curve_index(col-1, 1)] = b + 2 * yc * c;
1827 slitcurve_sw[curve_index(col-1, 2)] = c;
1828 slitcurve_sw[curve_index(col-1, 3)] = 0;
1829 slitcurve_sw[curve_index(col-1, 4)] = 0;
1830 slitcurve_sw[curve_index(col-1, 5)] = 0;
1834 for (j=0; j< height * swath; j++) model_sw[j] = 0;
1835 img_sw_data = cpl_image_get_data_double(img_sw);
1836 err_sw_data = cpl_image_get_data_double(err_sw);
1837 unc_sw_data = cpl_vector_get_data(unc_sw);
1840 img_tmp = cpl_image_collapse_median_create(img_sw, 0, 0, 0);
1841 spec_tmp = cpl_vector_new_from_image_row(img_tmp, 1);
1842 cpl_vector_multiply_scalar(spec_tmp,
1843 (
double)cpl_image_get_size_y(img_sw));
1844 spec_sw = cpl_vector_filter_median_create(spec_tmp, 1);
1845 cpl_vector_delete(spec_tmp);
1846 cpl_image_delete(img_tmp);
1847 spec_sw_data = cpl_vector_get_data(spec_sw);
1849 for (j=sw_start;j<sw_end;j++){
1850 ycen_sw[j-sw_start] = ycen_rest[j];
1851 ycen_offset_sw[j-sw_start] = (int) cpl_vector_get(ycen, j);
1853 y_lower_limit = height / 2;
1855 img_tmp = cpl_image_wrap_int(swath, height, mask_sw);
1856 img_sum = cpl_image_get_flux(img_tmp);
1857 if (img_sum < 0.5 * swath*height){
1858 cpl_msg_error(__func__,
1859 "Only %.0f %% of pixels not masked, cannot extract",
1860 100*img_sum/(swath*height));
1861 cpl_image_unwrap(img_tmp);
1862 cpl_vector_delete(spec_sw);
1865 if (cpl_msg_get_level() == CPL_MSG_DEBUG)
1867 cpl_image_save(img_tmp,
"debug_mask_before_sw.fits", CPL_TYPE_INT, NULL, CPL_IO_CREATE);
1868 cpl_vector_save(spec_sw,
"debug_spc_initial_guess.fits",
1869 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
1871 cpl_image_unwrap(img_tmp);
1874 cr2res_extract_slit_func_curved(error_factor, swath, height, oversample, pclip,
1875 img_sw_data, err_sw_data, mask_sw, ycen_sw, ycen_offset_sw,
1876 y_lower_limit, slitcurve_sw, delta_x, slitfu_sw_data,
1877 spec_sw_data, model_sw, unc_sw_data, smooth_spec, smooth_slit,
1878 5.e-5, niter, kappa, slit_func_in, sP_old, l_Aij, p_Aij, l_bj,
1879 p_bj, zw, zk, zeta, m_zeta, z_rng);
1882 if (i==0) cpl_vector_copy(slitfu,slitfu_sw);
1883 else cpl_vector_add(slitfu,slitfu_sw);
1885 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1886 path = cpl_sprintf(
"debug_spc_%i.fits", i);
1887 cpl_vector_save(spec_sw, path , CPL_TYPE_DOUBLE, NULL,
1891 path = cpl_sprintf(
"debug_mask_%i.fits", i);
1892 img_tmp = cpl_image_wrap_int(swath, height, mask_sw);
1893 cpl_image_save(img_tmp, path, CPL_TYPE_INT, NULL, CPL_IO_CREATE);
1895 cpl_image_unwrap(img_tmp);
1897 tmp_vec = cpl_vector_wrap(swath, ycen_sw);
1898 path = cpl_sprintf(
"debug_ycen_%i.fits", i);
1899 cpl_vector_save(tmp_vec, path, CPL_TYPE_DOUBLE, NULL,
1901 cpl_vector_unwrap(tmp_vec);
1904 cpl_vector_save(weights_sw,
"debug_weights.fits", CPL_TYPE_DOUBLE,
1905 NULL, CPL_IO_CREATE);
1906 path = cpl_sprintf(
"debug_slitfu_%i.fits", i);
1907 cpl_vector_save(slitfu_sw, path, CPL_TYPE_DOUBLE,
1908 NULL, CPL_IO_CREATE);
1911 path = cpl_sprintf(
"debug_model_%i.fits", i);
1912 img_tmp = cpl_image_wrap_double(swath, height, model_sw);
1913 cpl_image_save(img_tmp, path, CPL_TYPE_DOUBLE,
1914 NULL, CPL_IO_CREATE);
1915 cpl_image_unwrap(img_tmp);
1918 path = cpl_sprintf(
"debug_img_sw_%i.fits", i);
1919 cpl_image_save(img_sw, path, CPL_TYPE_DOUBLE, NULL,
1929 if ((i == nswaths - 1) && (i != 0)){
1930 k = cpl_vector_get(bins_end, i-1) -
1931 cpl_vector_get(bins_begin, i) - swath / 2 - delta_x;
1933 for (j = 0; j < swath - k; j++){
1934 cpl_vector_set(spec_sw, j, cpl_vector_get(spec_sw, j + k));
1935 cpl_vector_set(unc_sw, j, cpl_vector_get(unc_sw, j + k));
1936 for (y = 0; y < height; y++)
1937 model_sw[y * swath + j] = model_sw[y * swath + j + k];
1939 sw_start = cpl_vector_get(bins_begin, i-1) + swath / 2 - delta_x;
1940 cpl_vector_set(bins_begin, i, sw_start);
1942 cpl_vector_set(bins_end, i, lenx);
1947 for (j = 0; j < delta_x; j++)
1949 cpl_vector_set(spec_sw, j, 0);
1950 cpl_vector_set(unc_sw, j, 0.);
1951 for (y = 0; y < height; y++) model_sw[y * swath + j] = 0;
1953 for (j = swath/2; j < swath; j++) {
1954 cpl_vector_set(spec_sw, j,
1955 cpl_vector_get(spec_sw,j) * cpl_vector_get(weights_sw,j));
1956 cpl_vector_set(unc_sw, j,
1957 cpl_vector_get(unc_sw, j) * cpl_vector_get(weights_sw, j));
1958 for (y = 0; y < height; y++) {
1959 model_sw[y * swath + j] *= cpl_vector_get(weights_sw, j);
1962 }
else if (i == nswaths - 1) {
1963 for (j = sw_end-sw_start-1; j >= sw_end-sw_start-delta_x-1; j--)
1965 cpl_vector_set(spec_sw, j, 0);
1966 cpl_vector_set(unc_sw, j, 0);
1967 for (y = 0; y < height; y++) model_sw[y * swath + j] = 0;
1969 for (j = 0; j < swath / 2; j++) {
1970 cpl_vector_set(spec_sw, j,
1971 cpl_vector_get(spec_sw,j) * cpl_vector_get(weights_sw,j));
1972 cpl_vector_set(unc_sw, j,
1973 cpl_vector_get(unc_sw,j) * cpl_vector_get(weights_sw,j));
1974 for (y = 0; y < height; y++) {
1975 model_sw[y * swath + j] *= cpl_vector_get(weights_sw,j);
1980 cpl_vector_multiply(spec_sw, weights_sw);
1981 cpl_vector_multiply(unc_sw, weights_sw);
1982 for (y = 0; y < height; y++) {
1983 for (j = 0; j < swath; j++){
1984 model_sw[y * swath + j] *= cpl_vector_get(weights_sw,j);
1989 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
1990 img_tmp = cpl_image_wrap_double(swath, height, model_sw);
1991 cpl_image_save(img_tmp,
"debug_model_after_sw.fits", CPL_TYPE_DOUBLE,
1992 NULL, CPL_IO_CREATE);
1993 cpl_image_unwrap(img_tmp);
1997 for (j=sw_start;j<sw_end;j++) {
1998 cpl_vector_set(spc, j,
1999 cpl_vector_get(spec_sw, j-sw_start) + cpl_vector_get(spc, j));
2002 cpl_vector_set(unc_decomposition, j,
2003 cpl_vector_get(unc_sw, j - sw_start)
2004 + cpl_vector_get(unc_decomposition, j));
2006 for(y = 0; y < height; y++){
2007 cpl_image_set(model_rect, j+1, y+1,
2008 cpl_image_get(model_rect, j+1, y+1, &badpix)
2009 + model_sw[y * swath + j - sw_start]);
2010 if (badpix) cpl_image_reject(model_rect, j+1, y+1);
2014 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
2015 cpl_image_save(model_rect,
"debug_model_after_merge.fits",
2016 CPL_TYPE_DOUBLE, NULL, CPL_IO_CREATE);
2019 cpl_vector_delete(spec_sw);
2023 cpl_vector_divide_scalar(slitfu, nswaths);
2038 cpl_image_delete(img_rect);
2039 cpl_image_delete(err_rect);
2040 cpl_image_delete(img_sw);
2041 cpl_image_delete(err_sw);
2045 cpl_vector_delete(unc_sw);
2046 cpl_free(ycen_rest);
2048 cpl_free(ycen_offset_sw);
2050 cpl_vector_delete(bins_begin);
2051 cpl_vector_delete(bins_end);
2052 cpl_vector_delete(slitfu_sw);
2053 cpl_vector_delete(weights_sw);
2055 cpl_polynomial_delete(slitcurve_A);
2056 cpl_polynomial_delete(slitcurve_B);
2057 cpl_polynomial_delete(slitcurve_C);
2058 cpl_free(slitcurve_sw);
2063 cpl_msg_error(__func__,
"failed to reinsert model swath into model image");
2064 cpl_image_delete(model_rect);
2066 cpl_vector_delete(ycen);
2067 cpl_bivector_delete(spectrum_loc);
2068 cpl_vector_delete(slitfu);
2072 if (cpl_msg_get_level() == CPL_MSG_DEBUG) {
2073 cpl_image_save(model_rect,
"debug_model_rect.fits", CPL_TYPE_DOUBLE,
2074 NULL, CPL_IO_CREATE);
2075 cpl_image_save(img_out,
"debug_model_all.fits", CPL_TYPE_DOUBLE,
2076 NULL, CPL_IO_CREATE);
2077 cpl_vector_save(spc,
"debug_spc_all.fits", CPL_TYPE_DOUBLE,
2078 NULL, CPL_IO_CREATE);
2081 cpl_image_delete(model_rect);
2082 cpl_vector_delete(ycen);
2084 if (cpl_error_get_code() != CPL_ERROR_NONE){
2085 cpl_msg_error(__func__,
2086 "Something went wrong in the extraction. Error Code: %i, loc: %s",
2087 cpl_error_get_code(), cpl_error_get_where());
2089 cpl_vector_delete(slitfu);
2090 cpl_bivector_delete(spectrum_loc);
2095 *slit_func = slitfu;
2096 *spec = spectrum_loc;
2120 const hdrl_image * img,
2121 const cpl_table * traces,
2124 cpl_table ** extracted)
2126 cpl_bivector ** spectrum ;
2127 cpl_bivector ** position ;
2128 cpl_vector ** wavelength ;
2129 cpl_vector ** slit_fraction ;
2130 cpl_table * extract_loc ;
2131 cpl_image * wavemap;
2132 cpl_image * slitmap;
2133 int nb_traces, i, npoints ;
2136 if (img == NULL || traces == NULL)
return -1 ;
2139 nb_traces = cpl_table_get_nrow(traces) ;
2140 npoints = CR2RES_DETECTOR_SIZE * CR2RES_DETECTOR_SIZE / nb_traces;
2143 spectrum = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
2144 position = cpl_malloc(nb_traces *
sizeof(cpl_bivector *)) ;
2145 wavelength = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
2146 slit_fraction = cpl_malloc(nb_traces *
sizeof(cpl_vector *)) ;
2151 cpl_msg_error(__func__,
2152 "Could not create wavelength / slit_fraction image");
2155 cpl_free(wavelength);
2156 cpl_free(slit_fraction);
2161 for (i=0 ; i<nb_traces ; i++) {
2163 spectrum[i] = NULL ;
2164 position[i] = NULL ;
2165 wavelength[i] = NULL ;
2166 slit_fraction[i] = NULL ;
2168 int order, trace_id;
2171 order = cpl_table_get(traces, CR2RES_COL_ORDER, i, NULL) ;
2172 trace_id = cpl_table_get(traces, CR2RES_COL_TRACENB, i, NULL) ;
2175 if (reduce_order > -1 && order != reduce_order) continue ;
2178 if (reduce_trace > -1 && trace_id != reduce_trace) continue ;
2180 cpl_msg_info(__func__,
"Process Order %d/Trace %d",order,trace_id) ;
2181 cpl_msg_indent_more() ;
2185 npoints, wavemap, slitmap,
2186 &(spectrum[i]), &(position[i]), &(wavelength[i]),
2187 &(slit_fraction[i])) != 0) {
2188 cpl_msg_error(__func__,
"Cannot extract2d the trace") ;
2189 spectrum[i] = NULL ;
2190 position[i] = NULL ;
2191 wavelength[i] = NULL ;
2192 slit_fraction[i] = NULL ;
2194 cpl_msg_indent_less() ;
2197 cpl_msg_indent_less() ;
2202 wavelength, slit_fraction, traces) ;
2205 for (i=0 ; i<nb_traces ; i++) {
2206 if (spectrum[i] != NULL) cpl_bivector_delete(spectrum[i]) ;
2207 if (position[i] != NULL) cpl_bivector_delete(position[i]) ;
2208 if (wavelength[i] != NULL) cpl_vector_delete(wavelength[i]) ;
2209 if (slit_fraction[i] != NULL) cpl_vector_delete(slit_fraction[i]) ;
2211 cpl_free(spectrum) ;
2212 cpl_free(position) ;
2213 cpl_free(wavelength) ;
2214 cpl_free(slit_fraction) ;
2215 cpl_image_delete(wavemap);
2216 cpl_image_delete(slitmap);
2219 *extracted = extract_loc ;
2244 const hdrl_image * in,
2245 const cpl_table * trace_tab,
2249 const cpl_image * wavemap,
2250 const cpl_image * slitmap,
2251 cpl_bivector ** spectrum,
2252 cpl_bivector ** position,
2253 cpl_vector ** wavelength,
2254 cpl_vector ** slit_fraction)
2256 cpl_bivector * spectrum_local ;
2257 cpl_vector * spectrum_flux ;
2258 cpl_vector * spectrum_error ;
2259 cpl_bivector * position_local ;
2260 cpl_vector * position_x;
2261 cpl_vector * position_y;
2262 cpl_vector * wavelength_local ;
2263 cpl_vector * slit_fraction_local ;
2264 const cpl_array * lower_array;
2265 const cpl_array * upper_array;
2266 cpl_polynomial * lower_poly;
2267 cpl_polynomial * upper_poly;
2277 if (in==NULL || trace_tab==NULL || spectrum==NULL || position==NULL
2278 || wavelength==NULL || slit_fraction==NULL)
return -1 ;
2282 cpl_msg_error(__func__,
"Order and/or Trace not found in trace table");
2287 wavelength_local = cpl_vector_new(npoints);
2288 slit_fraction_local = cpl_vector_new(npoints);
2289 position_x = cpl_vector_new(npoints);
2290 position_y = cpl_vector_new(npoints);
2291 spectrum_flux = cpl_vector_new(npoints);
2292 spectrum_error = cpl_vector_new(npoints);
2298 x = cpl_vector_new(CR2RES_DETECTOR_SIZE);
2299 for (i = 0; i < CR2RES_DETECTOR_SIZE; i++) cpl_vector_set(x, i, i + 1);
2301 lower_array = cpl_table_get_array(trace_tab, CR2RES_COL_LOWER, k);
2302 upper_array = cpl_table_get_array(trace_tab, CR2RES_COL_UPPER, k);
2311 for (i = 0; i < CR2RES_DETECTOR_SIZE; i++)
2313 for (j = cpl_vector_get(lower, i); j < cpl_vector_get(upper, i); j++)
2316 if (j<1 || j>CR2RES_DETECTOR_SIZE) continue ;
2318 cpl_vector_set(position_x, row, i +1);
2319 cpl_vector_set(position_y, row, j);
2324 cpl_vector_set(spectrum_flux, row, flux);
2325 cpl_vector_set(spectrum_error, row, err);
2328 cpl_vector_set(wavelength_local, row, cpl_image_get(
2329 wavemap, i + 1, j, &bad_pix));
2331 cpl_vector_set(slit_fraction_local, row, cpl_image_get(
2332 slitmap, i + 1, j, &bad_pix));
2337 for (i = row; i < npoints; i++){
2338 cpl_vector_set(position_x, i, NAN);
2339 cpl_vector_set(position_y, i, NAN);
2340 cpl_vector_set(spectrum_flux, i, NAN);
2341 cpl_vector_set(spectrum_error, i, NAN);
2342 cpl_vector_set(wavelength_local, i, NAN);
2343 cpl_vector_set(slit_fraction_local, i, NAN);
2346 position_local = cpl_bivector_wrap_vectors(position_x, position_y);
2347 spectrum_local = cpl_bivector_wrap_vectors(spectrum_flux, spectrum_error);
2349 cpl_polynomial_delete(upper_poly);
2350 cpl_polynomial_delete(lower_poly);
2351 cpl_vector_delete(upper);
2352 cpl_vector_delete(lower);
2353 cpl_vector_delete(x);
2355 *spectrum = spectrum_local ;
2356 *position = position_local ;
2357 *wavelength = wavelength_local ;
2358 *slit_fraction = slit_fraction_local ;
2374 cpl_bivector ** spectrum,
2375 cpl_bivector ** position,
2376 cpl_vector ** wavelength,
2377 cpl_vector ** slit_fraction,
2378 const cpl_table * trace_table)
2382 const double * pspec ;
2383 const double * perr ;
2384 const double * pxposition ;
2385 const double * pyposition ;
2386 const double * pwave ;
2387 const double * pslit_frac ;
2388 int nrows, all_null, i, order, trace_id, nb_traces ;
2391 if (spectrum==NULL || trace_table==NULL || position==NULL ||
2392 wavelength==NULL || slit_fraction==NULL)
2396 nb_traces = cpl_table_get_nrow(trace_table) ;
2400 for (i=0 ; i<nb_traces ; i++)
2401 if (spectrum[i] != NULL) {
2402 nrows = cpl_bivector_get_size(spectrum[i]) ;
2405 if (all_null == 1)
return NULL ;
2408 for (i=0 ; i<nb_traces ; i++)
2409 if (spectrum[i] != NULL && cpl_bivector_get_size(spectrum[i]) != nrows)
2413 out = cpl_table_new(nrows);
2414 for (i=0 ; i<nb_traces ; i++) {
2415 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
2416 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
2419 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2420 cpl_free(col_name) ;
2423 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2424 cpl_free(col_name) ;
2427 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2428 cpl_free(col_name) ;
2431 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2432 cpl_free(col_name) ;
2435 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2436 cpl_free(col_name) ;
2439 cpl_table_new_column(out, col_name, CPL_TYPE_DOUBLE);
2440 cpl_free(col_name) ;
2444 for (i=0 ; i<nb_traces ; i++) {
2445 if (spectrum[i]!=NULL && position[i]!=NULL &&
2446 wavelength[i]!=NULL && slit_fraction[i]!=NULL) {
2447 order = cpl_table_get(trace_table, CR2RES_COL_ORDER, i, NULL) ;
2448 trace_id = cpl_table_get(trace_table, CR2RES_COL_TRACENB, i, NULL) ;
2449 pspec = cpl_bivector_get_x_data_const(spectrum[i]) ;
2450 perr = cpl_bivector_get_y_data_const(spectrum[i]);
2451 pxposition = cpl_bivector_get_x_data_const(position[i]) ;
2452 pyposition = cpl_bivector_get_y_data_const(position[i]) ;
2453 pwave = cpl_vector_get_data_const(wavelength[i]) ;
2454 pslit_frac = cpl_vector_get_data_const(slit_fraction[i]) ;
2457 cpl_table_copy_data_double(out, col_name, pspec) ;
2458 cpl_free(col_name) ;
2461 cpl_table_copy_data_double(out, col_name, perr) ;
2462 cpl_free(col_name) ;
2465 cpl_table_copy_data_double(out, col_name, pwave) ;
2466 cpl_free(col_name) ;
2469 cpl_table_copy_data_double(out, col_name, pxposition) ;
2470 cpl_free(col_name) ;
2473 cpl_table_copy_data_double(out, col_name, pyposition) ;
2474 cpl_free(col_name) ;
2477 cpl_table_copy_data_double(out, col_name, pslit_frac) ;
2478 cpl_free(col_name) ;
2492static inline void cr2res_extract_zeta_add(
2505 if (xx >= 0 && xx < ncols && yy >= 0 && yy < nrows && w > 0)
2507 const int m = m_zeta[mzeta_index(xx, yy)];
2508 zeta_rng * zr = &z_rng[mzeta_index(xx, yy)];
2509 zeta[zeta_index(xx, yy, m)].x = x;
2510 zeta[zeta_index(xx, yy, m)].iy = iy;
2511 zeta[zeta_index(xx, yy, m)].w = w;
2512 m_zeta[mzeta_index(xx, yy)]++;
2513 if (iy < zr->min_iy) zr->min_iy = iy;
2514 if (iy > zr->max_iy) zr->max_iy = iy;
2515 if (x < zr->min_x) zr->min_x = x;
2516 if (x > zr->max_x) zr->max_x = x;
2553static int cr2res_extract_zeta_tensors(
2556 const double * ycen,
2557 const int * ycen_offset,
2560 const double * slitcurve,
2565 int x, xx, y, yy, ix1, ix2, iy, iy1, iy2;
2566 double step, delta, dy, w, d1, d2;
2568 step = 1.e0 / osample;
2573 for (x = 0; x < ncols; x++)
2574 for (y = 0; y < nrows; y++) {
2575 zeta_rng * zr = &z_rng[mzeta_index(x, y)];
2576 m_zeta[mzeta_index(x, y)] = 0;
2577 zr->min_iy = INT_MAX;
2578 zr->max_iy = INT_MIN;
2579 zr->min_x = INT_MAX;
2580 zr->max_x = INT_MIN;
2589 for (x = 0; x < ncols; x++)
2609 iy2 = osample - floor(ycen[x] * osample);
2610 iy1 = iy2 - osample;
2629 d1 = fmod(ycen[x], step);
2637 dy = ycen[x] - floor((y_lower_lim + ycen[x]) / step) * step - step;
2653 for (y = 0; y < nrows; y++)
2658 for (iy = iy1; iy <= iy2; iy++)
2669 delta = t * (slitcurve[curve_index(x, 1)] +
2670 t * (slitcurve[curve_index(x, 2)] +
2671 t * (slitcurve[curve_index(x, 3)] +
2672 t * (slitcurve[curve_index(x, 4)] +
2673 t * slitcurve[curve_index(x, 5)]))));
2675 ix2 = ix1 + signum(delta);
2679 if (x + ix1 >= 0 && x + ix2 < ncols)
2682 yy = y + ycen_offset[x] - ycen_offset[xx];
2683 cr2res_extract_zeta_add(zeta, m_zeta, z_rng, ncols, nrows,
2684 osample, x, iy, xx, yy,
2685 w - fabs(delta - ix1) * w);
2687 yy = y + ycen_offset[x] - ycen_offset[xx];
2688 cr2res_extract_zeta_add(zeta, m_zeta, z_rng, ncols, nrows,
2689 osample, x, iy, xx, yy,
2690 fabs(delta - ix1) * w);
2695 if (x + ix2 >= 0 && x + ix1 < ncols)
2698 yy = y + ycen_offset[x] - ycen_offset[xx];
2699 cr2res_extract_zeta_add(zeta, m_zeta, z_rng, ncols, nrows,
2700 osample, x, iy, xx, yy,
2701 fabs(delta - ix1) * w);
2703 yy = y + ycen_offset[x] - ycen_offset[xx];
2704 cr2res_extract_zeta_add(zeta, m_zeta, z_rng, ncols, nrows,
2705 osample, x, iy, xx, yy,
2706 w - fabs(delta - ix1) * w);
2712 yy = y + ycen_offset[x] - ycen_offset[xx];
2713 cr2res_extract_zeta_add(zeta, m_zeta, z_rng, ncols, nrows,
2714 osample, x, iy, xx, yy, w);
2761static int cr2res_extract_slit_func_curved(
2762 double error_factor,
2773 const double * slitcurve,
2784 const double * slit_func_in,
2796 int x, xx, y, yy, iy, n, m, nk, mz, ny, nx;
2797 double norm, lambda, diag_tot, ww, dev, cost, tmp, sum;
2798 double sP_change, sP_med;
2799 cpl_vector * tmp_vec;
2800 int nclip, iter, isum;
2804 ny = osample * (nrows + 1) + 1;
2805 nx = 4 * delta_x + 1;
2809 cr2res_extract_zeta_tensors(ncols, nrows, ycen, ycen_offset,
2810 y_lower_lim, osample, slitcurve, zeta, m_zeta,
2814 if (slit_func_in != NULL) {
2817 for (iy = 0; iy < ny; iy++) {
2818 sL[iy] = slit_func_in[iy];
2822 for (iy = 0; iy < ny; iy++)
2827 nclip = (int)(ncols * nrows * pclip / 100);
2830 if (nclip > ncols * nrows / 2)
2831 nclip = (ncols * nrows / 2) - 1;
2832 cpl_vector *im_vec = cpl_vector_wrap(ncols * nrows, im);
2833 cpl_vector *pos_vec = cpl_vector_new(ncols * nrows);
2834 for (x = 0; x < ncols; x++)
2836 for (y = 0; y < nrows; y++)
2838 cpl_vector_set(pos_vec, y * ncols + x, y * ncols + x);
2841 cpl_bivector *im_in_bvec = cpl_bivector_wrap_vectors(pos_vec, im_vec);
2842 cpl_bivector *im_sort_bvec = cpl_bivector_new(ncols * nrows);
2843 cpl_bivector_sort(im_sort_bvec, im_in_bvec, CPL_SORT_ASCENDING, CPL_SORT_BY_Y);
2844 cpl_bivector_unwrap_vectors(im_in_bvec);
2845 cpl_vector_unwrap(im_vec);
2846 cpl_vector_delete(pos_vec);
2848 cpl_vector *pos_sort_vec = cpl_bivector_get_x(im_sort_bvec);
2853 int pos = (int)cpl_vector_get(pos_sort_vec, ii);
2862 ii = ncols * nrows - 1;
2866 int pos = (int)cpl_vector_get(pos_sort_vec, ii);
2874 cpl_bivector_delete(im_sort_bvec);
2875 pos_sort_vec = NULL;
2882 for (x = 0; x < ncols; x++)
2885 if (slit_func_in == NULL) {
2889 for (iy = 0; iy < ny; iy++)
2891 for (iy = 0; iy < ny * (4 * osample + 1); iy++)
2895 for (xx = 0; xx < ncols; xx++) {
2896 for (yy = 0; yy < nrows; yy++) {
2897 const zeta_ref *zrow;
2901 mz = m_zeta[mzeta_index(xx, yy)];
2902 if (mz <= 0 || !mask[yy * ncols + xx])
2904 zrow = &zeta[zeta_index(xx, yy, 0)];
2905 imv = im[yy * ncols + xx];
2912 zr = &z_rng[mzeta_index(xx, yy)];
2914 rng = zr->max_iy - k0;
2915 if (rng <= 2 * osample) {
2916 for (n = 0; n <= rng; n++)
2918 for (m = 0; m < mz; m++)
2919 zw[zrow[m].iy - k0] += sP[zrow[m].x] * zrow[m].w;
2926 for (m = 0; m <= rng; m++) {
2927 const double um = zw[m];
2928 const double *restrict uv = zw + m;
2929 double *restrict arow =
2930 &l_Aij[laij_index(k0 + m, 2 * osample)];
2931 const int dmax = rng - m;
2937 for (n = 0; n <= dmax; n++)
2938 arow[n] += um * uv[n];
2939 l_bj[k0 + m] += imv * um;
2946 for (m = 0; m < mz; m++) {
2947 const int key = zrow[m].iy;
2948 const double v = sP[zrow[m].x] * zrow[m].w;
2949 for (n = 0; n < nk; n++) {
2960 for (m = 0; m < nk; m++) {
2961 const double um = zw[m];
2963 l_Aij[laij_index(iy, 2 * osample)] += um * um;
2964 for (n = m + 1; n < nk; n++) {
2965 const int iyn = zk[n];
2966 const int lo = min(iy, iyn);
2967 const int d = iyn > iy ? iyn - iy : iy - iyn;
2968 l_Aij[laij_index(lo, d + 2 * osample)] +=
2971 l_bj[iy] += imv * um;
2978 for (m = 1; m <= 2 * osample; m++)
2979 for (iy = 0; iy < ny - m; iy++)
2980 l_Aij[laij_index(iy + m, 2 * osample - m)] =
2981 l_Aij[laij_index(iy, 2 * osample + m)];
2984 for (iy = 0; iy < ny; iy++)
2985 diag_tot += l_Aij[laij_index(iy, 2 * osample)];
2988 lambda = lambda_sL * diag_tot / ny;
2991 l_Aij[laij_index(0, 2 * osample)] += lambda;
2992 l_Aij[laij_index(0, 2 * osample + 1)] -= lambda;
2993 for (iy = 1; iy < ny - 1; iy++) {
2994 l_Aij[laij_index(iy, 2 * osample - 1)] -= lambda;
2995 l_Aij[laij_index(iy, 2 * osample)] += lambda * 2.e0;
2996 l_Aij[laij_index(iy, 2 * osample + 1)] -= lambda;
2998 l_Aij[laij_index(ny - 1, 2 * osample - 1)] -= lambda;
2999 l_Aij[laij_index(ny - 1, 2 * osample)] += lambda;
3004 double max_diag = 0.0;
3005 for (iy = 0; iy < ny; iy++)
3006 if (l_Aij[laij_index(iy, 2 * osample)] > max_diag)
3007 max_diag = l_Aij[laij_index(iy, 2 * osample)];
3008 if (max_diag > 0.0) {
3009 const double min_diag = max_diag * 1.0e-10;
3010 for (iy = 0; iy < ny; iy++)
3011 if (l_Aij[laij_index(iy, 2 * osample)] < min_diag)
3012 l_Aij[laij_index(iy, 2 * osample)] = min_diag;
3017 cr2res_extract_bandsol_rowmajor(l_Aij, l_bj, ny, 4 * osample + 1);
3023 for (iy = 0; iy < ny; iy++) {
3025 norm += fabs(sL[iy]);
3028 for (iy = 0; iy < ny; iy++)
3033 for (x = 0; x < ncols; x++)
3035 for (x = 0; x < ncols * nx; x++)
3039 for (xx = 0; xx < ncols; xx++) {
3040 for (yy = 0; yy < nrows; yy++) {
3041 const zeta_ref *zrow;
3045 mz = m_zeta[mzeta_index(xx, yy)];
3046 if (mz <= 0 || !mask[yy * ncols + xx])
3048 zrow = &zeta[zeta_index(xx, yy, 0)];
3049 imv = im[yy * ncols + xx];
3054 zr = &z_rng[mzeta_index(xx, yy)];
3056 rng = zr->max_x - k0;
3057 if (rng <= 2 * delta_x) {
3058 for (n = 0; n <= rng; n++)
3060 for (m = 0; m < mz; m++)
3061 zw[zrow[m].x - k0] += sL[zrow[m].iy] * zrow[m].w;
3064 for (m = 0; m <= rng; m++) {
3065 const double um = zw[m];
3066 const double *restrict uv = zw + m;
3067 double *restrict arow =
3068 &p_Aij[paij_index(k0 + m, 2 * delta_x)];
3069 const int dmax = rng - m;
3073 for (n = 0; n <= dmax; n++)
3074 arow[n] += um * uv[n];
3075 p_bj[k0 + m] += imv * um;
3081 for (m = 0; m < mz; m++) {
3082 const int key = zrow[m].x;
3083 const double v = sL[zrow[m].iy] * zrow[m].w;
3084 for (n = 0; n < nk; n++) {
3095 for (m = 0; m < nk; m++) {
3096 const double um = zw[m];
3098 p_Aij[paij_index(x, 2 * delta_x)] += um * um;
3099 for (n = m + 1; n < nk; n++) {
3100 const int xn = zk[n];
3101 const int lo = min(x, xn);
3102 const int d = xn > x ? xn - x : x - xn;
3103 p_Aij[paij_index(lo, d + 2 * delta_x)] += zw[n] * um;
3105 p_bj[x] += imv * um;
3111 for (m = 1; m <= 2 * delta_x; m++)
3112 for (x = 0; x < ncols - m; x++)
3113 p_Aij[paij_index(x + m, 2 * delta_x - m)] =
3114 p_Aij[paij_index(x, 2 * delta_x + m)];
3116 if (lambda_sP > 0.e0) {
3118 p_Aij[paij_index(0, 2 * delta_x)] += lambda;
3119 p_Aij[paij_index(0, 2 * delta_x + 1)] -= lambda;
3120 for (x = 1; x < ncols - 1; x++) {
3121 p_Aij[paij_index(x, 2 * delta_x - 1)] -= lambda;
3122 p_Aij[paij_index(x, 2 * delta_x)] += lambda * 2.e0;
3123 p_Aij[paij_index(x, 2 * delta_x + 1)] -= lambda;
3125 p_Aij[paij_index(ncols - 1, 2 * delta_x - 1)] -= lambda;
3126 p_Aij[paij_index(ncols - 1, 2 * delta_x)] += lambda;
3135 double max_diag = 0.0;
3136 for (x = 0; x < ncols; x++)
3137 if (p_Aij[paij_index(x, 2 * delta_x)] > max_diag)
3138 max_diag = p_Aij[paij_index(x, 2 * delta_x)];
3139 if (max_diag > 0.0) {
3140 const double min_diag = max_diag * 1.0e-10;
3141 for (x = 0; x < ncols; x++)
3142 if (p_Aij[paij_index(x, 2 * delta_x)] < min_diag)
3143 p_Aij[paij_index(x, 2 * delta_x)] = min_diag;
3148 cr2res_extract_bandsol_rowmajor(p_Aij, p_bj, ncols, nx);
3150 for (x = 0; x < ncols; x++)
3154 tmp_vec = cpl_vector_wrap(ncols, sP);
3155 sP_med = fabs(cpl_vector_get_median_const(tmp_vec));
3156 cpl_vector_unwrap(tmp_vec);
3160 for (x = 0; x < ncols; x++) {
3161 if (fabs(sP[x] - sP_old[x]) > sP_change)
3162 sP_change = fabs(sP[x] - sP_old[x]);
3167 for (x = 0; x < ncols; x++) {
3168 for (y = 0; y < nrows; y++) {
3169 const zeta_ref *zrow = &zeta[zeta_index(x, y, 0)];
3171 mz = m_zeta[mzeta_index(x, y)];
3172 for (m = 0; m < mz; m++) {
3176 acc += sP[xx] * sL[iy] * ww;
3178 model[y * ncols + x] = acc;
3187 for (y = 0; y < nrows; y++) {
3188 for (x = delta_x; x < ncols - delta_x; x++) {
3189 if (mask[y * ncols + x]) {
3190 tmp = model[y * ncols + x] - im[y * ncols + x];
3192 tmp /= max(pix_unc[y * ncols + x], 1);
3198 cost /= (isum - (ncols + ny));
3199 dev = sqrt(sum / isum);
3203 for (y = 0; y < nrows; y++) {
3204 for (x = delta_x; x < ncols - delta_x; x++) {
3205 if (fabs(model[y * ncols + x] - im[y * ncols + x]) <
3207 mask[y * ncols + x] = 1;
3209 mask[y * ncols + x] = 0;
3216 "Iter: %i, Sigma: %g, Cost: %g, sP_change: %g, sP_lim: %g",
3217 iter, dev, cost, sP_change, sP_stop * sP_med);
3225 }
while (iter == 1 ||
3226 (iter <= maxiter && sP_change > sP_stop * sP_med));
3228 if (iter > maxiter && sP_change > sP_stop * sP_med)
3231 "Maximum number of %d iterations reached without converging.",
3236 for (y = 0; y < ny; y++)
3239 for (y = 0; y < ny; y++)
3241 for (x = 0; x < ncols; x++)
3245 if (error_factor == -1)
3248 for (x = 0; x < ncols; x++)
3252 double model_sum = 0.0;
3257 for (y = 0; y < nrows; y++)
3259 model_sum += model[y * ncols + x];
3261 for (y = 0; y < nrows; y++)
3263 double model_norm = model[y * ncols + x] / model_sum;
3264 num_sum += model_norm * mask[y * ncols + x];
3265 den_sum += (model_norm * model_norm) * mask[y * ncols + x] / (pix_unc[y * ncols + x] * pix_unc[y * ncols + x]);
3269 unc[x] = sqrt(fabs(num_sum / den_sum));
3280 for (x = 0; x < ncols; x++)
3287 for (y = 0; y < nrows; y++)
3289 if (mask[y * ncols + x])
3291 msum += (im[y * ncols + x] * model[y * ncols + x]) *
3292 mask[y * ncols + x];
3293 sum += (model[y * ncols + x] * model[y * ncols + x]) *
3294 mask[y * ncols + x];
3301 unc[x] = sqrt(fabs(sP[x]) * fabs(sum) / fabs(msum) / error_factor);
3329static int cr2res_extract_bandsol_rowmajor(
3339 for (i = 0; i < n - 1; i++)
3341 aa = a[i * nd + nd / 2];
3343 for (j = 0; j < nd; j++)
3344 a[i * nd + j] /= aa;
3345 for (j = 1; j < min(nd / 2 + 1, n - i); j++)
3347 aa = a[(i + j) * nd + nd / 2 - j];
3348 r[i + j] -= r[i] * aa;
3349 for (k = 0; k < nd - j; k++)
3350 a[(i + j) * nd + k] -= a[i * nd + k + j] * aa;
3355 r[n - 1] /= a[(n - 1) * nd + nd / 2];
3356 for (i = n - 1; i > 0; i--)
3358 for (j = 1; j <= min(nd / 2, i); j++)
3359 r[i - j] -= r[i] * a[(i - j) * nd + nd / 2 + j];
3360 r[i - 1] /= a[(i - 1) * nd + nd / 2];
3394int cr2res_extract_slitdec_bandsol(
3407 for(i=0; i<n-1; i++)
3410 if(aa==0.e0) aa = lambda;
3412 for(j=0; j<nd; j++) a[i+j*n]/=aa;
3413 for(j=1; j<min(nd/2+1,n-i); j++)
3415 aa=a[i+j+n*(nd/2-j)];
3417 for(k=0; k<n*(nd-j); k+=n) a[i+j+k]-=a[i+k+n*j]*aa;
3422 aa = a[n-1+n*(nd/2)];
3423 if (aa == 0) aa = lambda;
3425 for(i=n-1; i>0; i--)
3427 for(j=1; j<=min(nd/2,i); j++){
3428 r[i-j]-=r[i]*a[i-j+n*(nd/2+j)];
3430 aa = a[i-1+n*(nd/2)];
3431 if(aa==0.e0) aa = lambda;
3437 if(aa==0.e0) aa = lambda;
3454static int cr2res_extract_slitdec_adjust_swath(
3461 cpl_vector ** bins_begin,
3462 cpl_vector ** bins_end)
3464 if (sw <= 0 || lenx <= 0)
return -1;
3465 if (bins_begin == NULL || bins_end == NULL)
return -1;
3466 if (ycen == NULL)
return -1;
3469 if (sw==CR2RES_DETECTOR_SIZE){
3470 *bins_begin = cpl_vector_new(1);
3471 *bins_end = cpl_vector_new(1);
3472 cpl_vector_set(*bins_begin, 0, 0);
3473 cpl_vector_set(*bins_end, 0, CR2RES_DETECTOR_SIZE);
3474 return CR2RES_DETECTOR_SIZE;
3477 int nbin, nx, i = 0;
3479 int start = 0, end = lenx;
3484 for (i=0; i < lenx; i++){
3485 ymin = ycen_int[i] - (height/2);
3486 ymax = ycen_int[i] + (height/2) + height%2 ;
3487 if (!((ymax <= 1) || (ymin > leny))){
3493 for (i = lenx - 1; i >= 0; i--){
3494 ymin = ycen_int[i] - (height/2);
3495 ymax = ycen_int[i] + (height/2) + height%2 ;
3496 if (!((ymax <= 1) || (ymin > leny))){
3509 if (sw > nx - 2 * dx) {
3511 if (sw % 2 == 1) sw -= 1;
3512 }
else if (sw % 2 == 1) sw += 1;
3515 nbin = 2 * ((nx - 2 * dx) / sw);
3516 if ((nx - 2 * dx) % sw > sw / 2) nbin++;
3517 if (nbin < 1) nbin = 1;
3521 *bins_begin = cpl_vector_new(nbin);
3522 *bins_end = cpl_vector_new(nbin);
3525 for(i = 0; i < nbin; i++)
3528 bin = start + min(i * step, nx - sw - 2 * dx);
3529 cpl_vector_set(*bins_begin, i, bin);
3530 cpl_vector_set(*bins_end, i, bin + sw + 2 * dx);
3531 cpl_msg_debug(__func__,
"Swath %d goes from %d to %d.", i, bin,
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.
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_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl 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