30 #include <sinfo_cpl_size.h>
36 #include "sinfo_new_find_distortions.h"
37 #include "sinfo_pro_save.h"
38 #include "sinfo_pro_types.h"
39 #include "sinfo_finddist_ini_by_cpl.h"
40 #include "sinfo_wave_calibration.h"
41 #include "sinfo_cube_construct.h"
42 #include "sinfo_absolute.h"
43 #include "sinfo_distortion.h"
44 #include "sinfo_utilities.h"
45 #include "sinfo_recipes.h"
46 #include "sinfo_utils_wrappers.h"
47 #include "sinfo_error.h"
48 #include "sinfo_globals.h"
53 #define SINFO_ARC_SATURATION 100000
54 #define SINFO_ARC_MAX_WIDTH 64
77 new_compute_shift(
double x,
91 sinfo_new_find_distortions(
const char* plugin_id,
92 cpl_parameterlist* config,
94 cpl_frameset* set_fibre_ns)
97 finddist_config * cfg=NULL ;
98 cpl_image * imonind=NULL ;
99 cpl_image * impoly=NULL ;
100 cpl_image * im=NULL ;
101 cpl_image * map=NULL ;
102 cpl_image * mask=NULL ;
106 int* n_found_lines=NULL;
107 int* sum_pointer=NULL;
108 int** row_clean=NULL;
131 cpl_size coef_pow[2];
132 int arcs_window_size=0;
139 float* distances=NULL;
140 float** wavelength_clean=NULL;
141 float** slit_pos=NULL;
150 double arcs_thres_factor=0;
152 double arcs_min_arclen_factor=0;
153 double pcf[pdx][pdy];
156 char tbl_name[FILE_NAME_SZ];
157 char key_name[FILE_NAME_SZ];
159 cpl_table* poly_tbl=NULL;
160 cpl_table* tbl_spos=NULL;
161 cpl_table* tbl_line_list=NULL;
163 FitParams** par=NULL;
165 cpl_frameset* stk=NULL;
166 cpl_table* qclog_tbl=NULL;
168 cpl_polynomial* distor_poly=NULL;
169 cpl_apertures * arcs=NULL ;
170 cpl_parameter* p=NULL;
174 check_nomsg(p=cpl_parameterlist_find(config,
"sinfoni.product.density"));
175 check_nomsg(pdensity=cpl_parameter_get_int(p));
181 check_nomsg(stk=cpl_frameset_new());
182 cknull(cfg = sinfo_parse_cpl_input_finddist(config,sof,&stk),
183 "could not parse CPL input!");
185 if(sinfo_is_fits_file (cfg->inFrame) != 1) {
191 check(im = cpl_image_load(cfg->inFrame,CPL_TYPE_FLOAT,0,0),
192 "could not load arc image");
195 check(imonind = cpl_image_load(cfg->nsFrame,CPL_TYPE_FLOAT,0,0),
196 "could not load on-off fake image");
198 check(impoly = cpl_image_load(cfg->nsFrame,CPL_TYPE_FLOAT,0,0),
199 "could not load on-off fake image");
202 check(mask = cpl_image_load(cfg->mask,CPL_TYPE_FLOAT,0,0),
203 "could not load mask image");
205 check(cpl_image_multiply (im,mask),
206 "Failing to correct arc ima by bp mask");
208 check(cpl_image_multiply (imonind,mask),
209 "Failing to correct on-off fake ima by bp mask");
211 check(cpl_image_multiply(impoly,mask),
212 "Failing to correct on-off fake ima by bp mask");
214 sinfo_free_image(&mask);
216 check_nomsg(lx = cpl_image_get_size_x(im));
220 check(tbl_line_list = cpl_table_load(cfg->lineList,1,0),
221 "problems loading table %s",cfg->lineList);
223 check_nomsg(n_lines = cpl_table_get_nrow(tbl_line_list));
224 check_nomsg(wave=cpl_table_get_data_float(tbl_line_list,
"wave"));
225 cpl_type type=cpl_table_get_column_type(tbl_line_list,
"int");
226 if(type==CPL_TYPE_INT) {
227 check_nomsg(cpl_table_cast_column(tbl_line_list,
"int",
"fint",CPL_TYPE_FLOAT));
228 check_nomsg(intens = cpl_table_get_data_float(tbl_line_list,
"fint"));
230 check_nomsg(intens = cpl_table_get_data_float(tbl_line_list,
"int"));
238 sinfo_msg(
"Find Lines");
244 acoefs = sinfo_new_2Dfloatarray(cfg->nrDispCoefficients, lx);
246 n_found_lines = sinfo_new_intarray(lx);
247 row_clean = sinfo_new_2Dintarray(lx, n_lines);
248 wavelength_clean = sinfo_new_2Dfloatarray(lx, n_lines);
249 sum_pointer = sinfo_new_intarray(1);
252 sinfo_new_intarray_set_value(sum_pointer, 0, 0);
254 ck0(check = sinfo_new_find_lines(im,
260 cfg->guessBeginWavelength,
261 cfg->guessDispersion1,
262 cfg->guessDispersion2,
268 "FindLines failed!");
270 sinfo_free_table(&tbl_line_list);
277 sinfo_msg(
"Do wave calib");
278 sum = sinfo_new_intarray_get_value(sum_pointer,0);
281 cknull(par = sinfo_new_fit_params( sum ),
282 "sinfo_new_fit_params failed!");
288 cknull(map = sinfo_new_wave_cal(im,
295 cfg->guessDispersion1,
300 cfg->nrDispCoefficients,
301 cfg->nrCoefCoefficients,
304 cfg->pixel_tolerance),
305 "sinfo_waveCal failed!");
308 sinfo_msg(
"Check line positions");
309 shift = sinfo_new_check_line_positions (im, acoefs,
310 cfg->nrDispCoefficients,
311 cfg->guessDispersion1,par);
317 sinfo_free_image(&map);
321 sinfo_new_destroy_2Dfloatarray ( &wavelength_clean, lx );
322 sinfo_new_destroy_2Dintarray (&row_clean, lx);
323 sinfo_new_destroy_intarray(&n_found_lines );
324 sinfo_new_destroy_intarray(&sum_pointer );
325 sinfo_new_destroy_2Dfloatarray ( &acoefs, cfg->nrDispCoefficients );
337 sinfo_msg(
"Find slit pos");
339 slit_pos = sinfo_new_2Dfloatarray(32,2);
342 cfg->yBox, cfg->diffTol );
349 sinfo_new_destroy_fit_params(&par);
351 check_nomsg(tbl_spos=cpl_table_new(32));
352 check_nomsg(cpl_table_new_column(tbl_spos,
"pos1", CPL_TYPE_DOUBLE));
353 check_nomsg(cpl_table_new_column(tbl_spos,
"pos2", CPL_TYPE_DOUBLE));
354 check_nomsg(cpl_table_set_column_format(tbl_spos,
"pos1",
"15.9f"));
355 check_nomsg(cpl_table_set_column_format(tbl_spos,
"pos2",
"15.9f"));
357 for (i =0; i< 32; i++) {
358 check_nomsg(cpl_table_set_double(tbl_spos,
"pos1",i,
359 sinfo_new_array2D_get_value(slit_pos,i,0)));
360 check_nomsg(cpl_table_set_double(tbl_spos,
"pos2",i,
361 sinfo_new_array2D_get_value(slit_pos,i,1)));
366 strcpy(tbl_name,
"out_slitlets_pos_predist.fits");
367 ck0(sinfo_pro_save_tbl(tbl_spos,set_fibre_ns,sof,tbl_name,
368 PRO_SLITLETS_POS_PREDIST,NULL,plugin_id,config),
369 "cannot save tbl %s", tbl_name);
371 sinfo_free_table(&tbl_spos);
378 sinfo_msg(
"Do north south test");
389 cknull(distances = sinfo_north_south_test(imonind,
398 "north_south_test failed");
400 sinfo_free_image(&imonind);
407 sinfo_msg(
"get first col");
408 first = sinfo_new_floatarray(61);
412 for (i=0; i< 31; i++) {
413 total_dist=total_dist+sinfo_new_array_get_value(distances,i);
415 for (j=0; j< 2; j++) {
418 newval = sinfo_new_array2D_get_value(slit_pos,i+1,j) -
420 sinfo_new_array_set_value(first, newval, n);
425 newval = sinfo_new_array2D_get_value(slit_pos,i,j) - total_dist;
426 sinfo_new_array_set_value(first, newval, n);
431 value = sinfo_new_f_median(first,61);
432 sinfo_msg(
"Firstcol =%f", value);
433 sinfo_new_destroy_array(&first);
434 sinfo_new_destroy_array(&distances);
435 sinfo_new_destroy_2Dfloatarray ( &slit_pos, 32 );
442 sinfo_msg(
"Determine distortions");
443 degx=cpl_calloc(8,
sizeof(
int));
444 degy=cpl_calloc(8,
sizeof(
int));
445 coef=cpl_calloc(8,
sizeof(
double));
447 check_nomsg(p=cpl_parameterlist_find(config,
448 "sinfoni.distortion.arcs_thresh_factor"));
449 check_nomsg(arcs_thres_factor=cpl_parameter_get_double(p));
451 check_nomsg(p=cpl_parameterlist_find(config,
452 "sinfoni.distortion.arcs_min_arclen_factor"));
453 check_nomsg(arcs_min_arclen_factor=cpl_parameter_get_double(p));
455 check_nomsg(p=cpl_parameterlist_find(config,
456 "sinfoni.distortion.arcs_window_size"));
457 check_nomsg(arcs_window_size=cpl_parameter_get_int(p));
459 check_nomsg(p=cpl_parameterlist_find(config,
460 "sinfoni.distortion.smooth_rad"));
461 check_nomsg(smooth_rad=cpl_parameter_get_int(p));
464 cknull(distor_poly=sinfo_distortion_estimate_new(impoly,
467 cpl_image_get_size_x(impoly),
468 cpl_image_get_size_y(impoly),
470 SINFO_ARC_SATURATION,
473 arcs_min_arclen_factor,
479 "cannot estimage distortion") ;
482 sinfo_free_apertures(&arcs);
485 check_nomsg(pcf[0][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
486 sinfo_msg(
"Polynomial fit results: coeff[%d][%d]=%g",0,0,pcf[0][0]);
490 sinfo_msg(
"Polynomial fit results: coeff[%d][%d]=%g",0,0,pcf[0][0]);
491 check_nomsg(cpl_polynomial_set_coeff(distor_poly,coef_pow,pcf[0][0]));
495 sinfo_free_image(&impoly);
503 check_nomsg(pcf[0][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
508 check_nomsg(pcf[1][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
513 check_nomsg(pcf[0][1]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
518 check_nomsg(pcf[1][1]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
523 check_nomsg(pcf[2][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
528 check_nomsg(pcf[0][2]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
533 check_nomsg(pcf[2][1]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
538 check_nomsg(pcf[1][2]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
543 check_nomsg(pcf[3][0]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
548 check_nomsg(pcf[0][3]=cpl_polynomial_get_coeff(distor_poly,coef_pow));
551 sinfo_msg(
"Save results");
553 check_nomsg(poly_tbl=cpl_table_new(10));
554 check_nomsg(cpl_table_new_column(poly_tbl,
"degx", CPL_TYPE_INT));
555 check_nomsg(cpl_table_new_column(poly_tbl,
"degy", CPL_TYPE_INT));
556 check_nomsg(cpl_table_new_column(poly_tbl,
"coeff", CPL_TYPE_DOUBLE));
557 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",0,0));
558 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",1,1));
559 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",2,0));
560 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",3,1));
561 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",4,2));
562 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",5,0));
563 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",6,2));
564 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",7,1));
565 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",8,3));
566 check_nomsg(cpl_table_set_int(poly_tbl,
"degx",9,0));
568 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",0,0));
569 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",1,0));
570 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",2,1));
571 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",3,1));
572 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",4,0));
573 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",5,2));
574 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",6,1));
575 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",7,2));
576 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",8,0));
577 check_nomsg(cpl_table_set_int(poly_tbl,
"degy",9,3));
579 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",0,pcf[0][0]));
580 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",1,pcf[1][0]));
581 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",2,pcf[0][1]));
582 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",3,pcf[1][1]));
583 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",4,pcf[2][0]));
584 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",5,pcf[0][2]));
585 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",6,pcf[2][1]));
586 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",7,pcf[1][2]));
587 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",8,pcf[3][0]));
588 check_nomsg(cpl_table_set_double(poly_tbl,
"coeff",9,pcf[0][3]));
596 check_nomsg(qclog_tbl = sinfo_qclog_init());
597 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",0,0);
598 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][0],
599 "Polynomial distortion coefficient",
"%g"));
601 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",1,0);
602 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[1][0],
603 "Polynomial distortion coefficient",
"%g"));
605 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",0,1);
606 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][1],
607 "Polynomial distortion coefficient",
"%g"));
609 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",1,1);
610 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[1][1],
611 "Polynomial distortion coefficient",
"%g"));
613 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",2,0);
614 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[2][0],
615 "Polynomial distortion coefficient",
"%g"));
617 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",0,2);
618 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][2],
619 "Polynomial distortion coefficient",
"%g"));
621 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",2,1);
622 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[2][1],
623 "Polynomial distortion coefficient",
"%g"));
625 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",1,2);
626 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[1][2],
627 "Polynomial distortion coefficient",
"%g"));
629 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",3,0);
630 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[3][0],
631 "Polynomial distortion coefficient",
"%g"));
633 snprintf(key_name,MAX_NAME_SIZE-1,
"%s%d%d",
"QC COEFF",0,3);
634 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,pcf[0][3],
635 "Polynomial distortion coefficient",
"%g"));
637 snprintf(key_name,MAX_NAME_SIZE-1,
"%s",
"QC OFFSET");
638 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,key_name,value,
639 "Polynomial distortion coefficient",
"%g"));
641 xshift=new_compute_shift(x_c,y_c,pcf[0][0],pcf[1][0],pcf[0][1],
642 pcf[1][1],pcf[2][0],pcf[0][2],
643 pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
645 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,
"QC XSHIFT CC",xshift,
646 "X shift in x_c,y_c",
"%g"));
649 xshift=new_compute_shift(x_l,y_l,pcf[0][0],pcf[1][0],pcf[0][1],
650 pcf[1][1],pcf[2][0],pcf[0][2],
651 pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
653 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,
"QC XSHIFT LL",xshift,
654 "X shift in x_l,y_l",
"%g"));
656 xshift=new_compute_shift(x_l,y_u,pcf[0][0],pcf[1][0],pcf[0][1],
657 pcf[1][1],pcf[2][0],pcf[0][2],
658 pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
660 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,
"QC XSHIFT UL",xshift,
661 "X shift in x_l,y_u",
"%g"));
663 xshift=new_compute_shift(x_u,y_u,pcf[0][0],pcf[1][0],pcf[0][1],
664 pcf[1][1],pcf[2][0],pcf[0][2],
665 pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
667 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,
"QC XSHIFT UR",xshift,
668 "X shift in x_u,y_u",
"%g"));
671 xshift=new_compute_shift(x_u,y_l,pcf[0][0],pcf[1][0],pcf[0][1],
672 pcf[1][1],pcf[2][0],pcf[0][2],
673 pcf[2][1],pcf[1][2],pcf[3][0],pcf[0][3]);
675 ck0_nomsg(sinfo_qclog_add_double(qclog_tbl,
"QC XSHIFT LR",xshift,
676 "X shift in x_u,y_l",
"%g"));
679 ck0(sinfo_pro_save_tbl(poly_tbl,set_fibre_ns,sof,cfg->outName,
680 PRO_DISTORTION,qclog_tbl,plugin_id,config),
681 "cannot dump tbl %s", cfg->outName);
683 sinfo_free_table(&poly_tbl);
684 sinfo_free_table(&qclog_tbl);
685 sinfo_free_polynomial(&distor_poly);
686 sinfo_free_int(°x);
687 sinfo_free_int(°y);
688 sinfo_free_double(&coef);
689 sinfo_free_image(&im);
690 sinfo_free_frameset(&stk);
691 sinfo_finddist_free (&cfg);
696 sinfo_free_table(&poly_tbl);
697 sinfo_free_table(&qclog_tbl);
698 sinfo_free_polynomial(&distor_poly);
699 sinfo_free_int(°x);
700 sinfo_free_int(°y);
701 sinfo_free_double(&coef);
702 sinfo_free_apertures(&arcs);
708 if(first != NULL) sinfo_new_destroy_array(&first);
709 sinfo_free_table(&tbl_spos);
710 if(slit_pos != NULL) sinfo_new_destroy_2Dfloatarray (&slit_pos,32);
711 if(distances != NULL) sinfo_new_destroy_array(&distances);
712 if(par!=NULL) sinfo_new_destroy_fit_params(&par);
713 if(n_found_lines != NULL) sinfo_new_destroy_intarray(&n_found_lines );
714 if(row_clean != NULL) sinfo_new_destroy_2Dintarray(&row_clean, lx);
715 if(wavelength_clean != NULL) {
716 sinfo_new_destroy_2Dfloatarray(&wavelength_clean,lx);
718 if(sum_pointer != NULL) sinfo_new_destroy_intarray(&sum_pointer);
720 sinfo_new_destroy_2Dfloatarray(&acoefs, cfg->nrDispCoefficients );
722 sinfo_free_table(&tbl_line_list);
723 sinfo_free_image(&mask);
724 sinfo_free_image(&impoly);
725 sinfo_free_image(&imonind);
726 sinfo_free_image(&map);
727 sinfo_free_image(&im);
728 sinfo_finddist_free (&cfg);
729 sinfo_free_frameset(&stk);
736 new_compute_shift(
double x,
756 shift=c00+c10*x+c01*y+
757 c11*x*y+c20*x*x+c02*y*y+
758 c21*x*x*y+c12*x*y*y+c30*x*x*x+c03*y*y*y;