54 #include "gravi_data.h" 55 #include "gravi_calib.h" 56 #include "gravi_dfs.h" 57 #include "gravi_pfits.h" 58 #include "gravi_cpl.h" 60 #include "gravi_utils.h" 61 #include "gravi_preproc.h" 67 cpl_table * sky_table_avg, cpl_table * badft_table,
68 int n_region,
double gain);
71 cpl_imagelist * raw_imglist,
72 cpl_imagelist * rawVar_imglist,
76 cpl_table * wave_table,
77 cpl_table ** oiwave_tables,
78 cpl_table * detector_table,
79 cpl_table * specflat_table,
80 const cpl_parameterlist * parlist,
104 bad = cpl_image_get (bad_img, x, y, &nv);
105 if ((bad & BADPIX_DARK) || (bad & BADPIX_RMS) || (bad & BADPIX_FLAT))
127 gravi_msg_function_start(0);
128 cpl_ensure_code (imglist_sc, CPL_ERROR_NULL_INPUT);
129 cpl_ensure_code (bad_img, CPL_ERROR_NULL_INPUT);
132 int middel = 3, size = 7, nv, comp, badpix_comp;
133 cpl_vector * x = NULL;
135 cpl_size nrow = cpl_imagelist_get_size (imglist_sc);
136 cpl_size nx = cpl_image_get_size_x (bad_img);
137 cpl_size ny = cpl_image_get_size_y (bad_img);
140 if ((nx != cpl_image_get_size_x (cpl_imagelist_get (imglist_sc, 0))) ||
141 (ny != cpl_image_get_size_y (cpl_imagelist_get (imglist_sc, 0))) ){
142 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_INPUT,
143 "The image lists have not the same size");
148 for (cpl_size k = 0; k < ny; k++)
149 for (cpl_size i = 0; i < nx; i++)
150 if (cpl_image_get (bad_img, i+1, k+1, &nv) != 0) nbad++;
153 if (nbad > 0.25 * nx*ny) {
154 return cpl_error_set_message (cpl_func, CPL_ERROR_ILLEGAL_INPUT,
155 "Too many bad pixels (more than 25 percent)");
159 for (cpl_size k = 0; k < ny; k++){
160 for (cpl_size i = 0; i < nx; i++){
163 if (cpl_image_get (bad_img, i+1, k+1, &nv) != 0) {
166 for (cpl_size row = 0; row < nrow; row ++){
168 img = cpl_imagelist_get (imglist_sc, row);
169 x = cpl_vector_new (size-1);
171 if ((i - middel) < 0 ){
174 for (cpl_size j = 0; j < size; j++){
176 while (cpl_image_get (bad_img, i + badpix_comp, k + 1, &nv) != 0){
179 cpl_vector_set(x, comp, cpl_image_get (img, i + badpix_comp, k + 1, &nv));
183 CPLCHECK_MSG(
"Fail 1");
185 else if ((i + middel) >= nx){
188 for (cpl_size j = 0; (j < size); j++){
190 while (cpl_image_get (bad_img, nx - (j + 1) + badpix_comp, k + 1, &nv) != 0){
194 cpl_vector_set(x, comp, cpl_image_get (img, nx - (j + 1) + badpix_comp, k + 1 , &nv));
198 CPLCHECK_MSG(
"Fail 2");
203 int test1 = 0, test2 = 0;
204 for (cpl_size j = 0; j < size; j++){
206 if (i + j - middel + badpix_comp <= 1){
207 while (cpl_image_get (bad_img, i + j - middel + badpix_comp, k+1, &nv) != 0){
212 else if (i + j - middel + badpix_comp >= nx){
213 while (cpl_image_get (bad_img, i + j - middel + badpix_comp, k+1, &nv) != 0){
219 if ((test1 == 0) && (test2 == 0)){
230 cpl_vector_set(x, comp, cpl_image_get (img, i + j - middel + badpix_comp, k+1, &nv));
234 CPLCHECK_MSG(
"Fail 3");
237 double mean = cpl_vector_get_median (x);
238 cpl_vector_delete (x);
239 cpl_image_set (img, i + 1, k + 1, mean);
241 CPLCHECK_MSG(
"Fail 4");
248 gravi_msg_function_exit(0);
249 return CPL_ERROR_NONE;
272 cpl_table * skystd_table,
273 cpl_table * skyavg_table,
274 cpl_table * badft_table,
275 int n_region,
double gain)
278 gravi_msg_function_start(0);
279 cpl_ensure (pix_table, CPL_ERROR_NULL_INPUT, NULL);
282 cpl_size nrow = cpl_table_get_nrow (pix_table);
283 cpl_table * output_table = cpl_table_new (nrow);
286 cpl_array ** arr_data = cpl_table_get_data_array (pix_table,
"PIX");
287 CPLCHECK_NUL (
"Cannot get data");
290 cpl_array ** arr_badft = cpl_table_get_data_array (badft_table,
"PIX");
291 CPLCHECK_NUL (
"Cannot get data");
294 cpl_size npix = cpl_table_get_column_depth (pix_table,
"PIX");
295 cpl_size sizex = cpl_table_get_column_dimension(pix_table,
"PIX", 0);
296 cpl_size sizey = cpl_table_get_column_dimension(pix_table,
"PIX", 1);
298 int npol = n_region > 24 ? 2 : 1;
299 cpl_size ny = sizey / npol;
306 cpl_size n_output = 24;
307 cpl_size nx = sizex / n_output;
308 cpl_msg_info (cpl_func,
"Descramble %lld x %lld as %lld outputs x %lld pixels x %lld channels x %i pol",
309 sizex, sizey, n_output, nx, ny, npol);
312 if (cpl_table_has_column (pix_table,
"TIME")) {
313 cpl_table_duplicate_column (output_table,
"TIME", pix_table,
"TIME");
314 CPLCHECK_NUL (
"Cannot get TIME data");
318 double * pSky = cpl_calloc (sizex * sizey,
sizeof(
double));
320 for (cpl_size pix = 0; pix < npix; pix++) {
321 pSky[pix] = gravi_table_get_value (skyavg_table,
"PIX", 0, pix) / gain;
324 CPLCHECK_NUL (
"Cannot get the sky data");
327 double * pSkyVar = cpl_calloc (sizex * sizey,
sizeof(
double));
329 for (cpl_size pix = 0; pix < npix; pix++) {
330 pSkyVar[pix] = gravi_table_get_value (skystd_table,
"PIX", 0, pix);
331 pSkyVar[pix] = pow (pSkyVar[pix] / gain, 2.0);
334 CPLCHECK_NUL (
"Cannot get sky variance");
338 for (cpl_size region = 0; region < n_output; region++) {
341 for (
int pol = 0; pol < npol; pol ++) {
344 if ( !(region+pol) || !((region*npol+pol+1)%6) )
345 cpl_msg_info_overwritable (cpl_func,
346 "Extract region of FT %lld over %lld (fast-no-cpl)",
347 (region*npol+pol+1), n_output*npol);
350 const char * data = GRAVI_DATA[region*npol + pol];
351 cpl_table_new_column_array (output_table, data, CPL_TYPE_DOUBLE, ny_out);
352 cpl_array ** tData = cpl_table_get_data_array (output_table, data);
353 CPLCHECK_NUL (
"Cannot create DATA column");
356 const char * dataerr = GRAVI_DATAERR[region*npol + pol];
357 cpl_table_new_column_array (output_table, dataerr, CPL_TYPE_DOUBLE, ny_out);
358 cpl_array ** tDataErr = cpl_table_get_data_array (output_table, dataerr);
359 CPLCHECK_NUL (
"Cannot create DATAERR column");
372 for (cpl_size row = 0; row < nrow; row ++) {
373 double *pData = cpl_malloc (ny_out *
sizeof(
double));
374 double *pDataErr = cpl_malloc (ny_out *
sizeof(
double));
375 for (cpl_size j = 0; j < ny_out; j++) {
376 long idx = sizex * (j + ny*pol) + region*nx;
379 if (cpl_array_get (arr_badft[0], idx, NULL) == 0) {
380 value += cpl_array_get (arr_data[row], idx, NULL) / gain - pSky[idx];
383 if (nx>1 && cpl_array_get (arr_badft[0], idx+1, NULL) == 0) {
384 value += cpl_array_get (arr_data[row], idx+1, NULL) / gain - pSky[idx+1];
385 var += pSkyVar[idx+1];
388 pDataErr[j] = sqrt (CPL_MAX (value,0.0) + var);
390 tData[row] = cpl_array_wrap_double (pData, ny_out);
391 tDataErr[row] = cpl_array_wrap_double (pDataErr, ny_out);
393 CPLCHECK_NUL (
"Cannot extract and wrap data");
396 CPLCHECK_NUL (
"Cannot compute region");
402 FREE (cpl_free, pSky);
403 FREE (cpl_free, pSkyVar);
405 CPLCHECK_NUL (
"Cannot format ft");
407 gravi_msg_function_exit(0);
437 cpl_imagelist * raw_imglist,
438 cpl_imagelist * rawVar_imglist,
442 gravi_msg_function_start(1);
444 cpl_ensure (profile_table, CPL_ERROR_NULL_INPUT, NULL);
445 cpl_ensure (raw_imglist, CPL_ERROR_NULL_INPUT, NULL);
446 cpl_ensure (rawVar_imglist, CPL_ERROR_NULL_INPUT, NULL);
449 cpl_size n_region = gravi_spectrum_get_nregion (profile_table);
450 cpl_size n_row = cpl_imagelist_get_size (raw_imglist);
451 cpl_ensure (n_row > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
452 cpl_ensure (n_region==24 || n_region==48, CPL_ERROR_ILLEGAL_INPUT, NULL);
455 cpl_type type0 = cpl_image_get_type (cpl_imagelist_get (raw_imglist, 0));
456 cpl_type type1 = cpl_image_get_type (cpl_imagelist_get (rawVar_imglist, 0));
457 cpl_ensure (type0 == CPL_TYPE_DOUBLE, CPL_ERROR_ILLEGAL_INPUT, NULL);
458 cpl_ensure (type1 == CPL_TYPE_DOUBLE, CPL_ERROR_ILLEGAL_INPUT, NULL);
461 cpl_table * spectrum_table = cpl_table_new (n_row);
464 cpl_size nx = cpl_table_get_column_dimension (profile_table,
"DATA1",0);
465 cpl_size ny = cpl_table_get_column_dimension (profile_table,
"DATA1",1);
466 CPLCHECK_NUL (
"Cannot get profile dimension");
469 for (cpl_size region = 0; region < n_region; region++){
472 if ( !region || !((region+1)%6) )
473 cpl_msg_info_overwritable(cpl_func,
"Extract region of SC %lld over %lld",region+1,n_region);
476 const char * regionNameData = GRAVI_DATA[region];
477 cpl_table_new_column_array (spectrum_table, regionNameData, CPL_TYPE_DOUBLE, nx);
480 const char * regionNameErr = GRAVI_DATAERR[region];
481 cpl_table_new_column_array (spectrum_table, regionNameErr, CPL_TYPE_DOUBLE, nx);
485 cpl_image * profile_img = cpl_imagelist_get (profile_imglist, 0);
486 CPLCHECK_NUL (
"Cannot get data");
490 int xmin = 1, xmax = nx;
491 int ymin = ny, ymax = 0;
492 for (cpl_size jy = 1 ; jy <= ny ; jy++ ) {
493 for (cpl_size ix = 1 ; ix <= nx ; ix++ ) {
494 if ( !cpl_image_get (profile_img, ix, jy, &nv) )
continue;
495 if ( jy<ymin ) ymin=jy;
496 if ( jy>ymax ) ymax=jy;
499 CPLCHECK_NUL (
"Cannot get profile limits");
502 cpl_msg_debug (cpl_func,
"Found limits: x=[%4d, %4d] y=[%4d, %4d] (nx=%lld,ny=%lld, FITS convention)",
503 xmin,xmax,ymin,ymax,nx,ny);
506 cpl_image * profile_crop = cpl_image_extract (profile_img, xmin, ymin, xmax, ymax);
507 CPLCHECK_NUL (
"Cannot extract profile");
510 cpl_array ** tData = cpl_table_get_data_array (spectrum_table, regionNameData);
511 cpl_array ** tDataErr = cpl_table_get_data_array (spectrum_table, regionNameErr);
514 for (cpl_size row = 0; row < n_row; row ++) {
518 cpl_image * rawFlux_profiled = cpl_image_extract (cpl_imagelist_get (raw_imglist, row),
519 xmin+startx-1, ymin, xmax+startx-1, ymax);
520 cpl_image_multiply (rawFlux_profiled, profile_crop);
522 cpl_image *rawFlux = cpl_image_collapse_create (rawFlux_profiled,0);
523 cpl_image_delete (rawFlux_profiled);
524 CPLCHECK_NUL (
"Cannot collapse flux");
528 cpl_image * rawVar_profiled = cpl_image_extract (cpl_imagelist_get (rawVar_imglist, row),
529 xmin+startx-1, ymin, xmax+startx-1, ymax);
530 cpl_image_multiply (rawVar_profiled, profile_crop);
531 cpl_image_multiply (rawVar_profiled, profile_crop);
533 cpl_image *rawErr = cpl_image_collapse_create (rawVar_profiled,0);
534 cpl_image_delete (rawVar_profiled);
535 cpl_image_threshold (rawErr, 0.0, DBL_MAX, 0.0, DBL_MAX);
536 cpl_image_power (rawErr, 0.5);
537 CPLCHECK_NUL (
"Cannot collapse variance");
540 tData[row] = cpl_array_wrap_double (cpl_image_get_data_double (rawFlux), nx);
543 tDataErr[row] = cpl_array_wrap_double (cpl_image_get_data_double (rawErr), nx);
546 FREE (cpl_image_unwrap, rawFlux);
547 FREE (cpl_image_unwrap, rawErr);
552 FREE (cpl_image_delete, profile_crop);
556 gravi_msg_function_exit(1);
557 return spectrum_table;
591 gravi_data * profile_map,
592 gravi_data * dark_map,
593 gravi_data * bad_map,
594 gravi_data * sky_map,
595 const cpl_parameterlist * parlist,
596 enum gravi_detector_type det_type)
598 gravi_msg_function_start(1);
599 cpl_ensure (raw_data, CPL_ERROR_NULL_INPUT, NULL);
600 cpl_ensure (profile_map, CPL_ERROR_NULL_INPUT, NULL);
601 cpl_ensure (bad_map, CPL_ERROR_NULL_INPUT, NULL);
602 cpl_ensure (dark_map || sky_map, CPL_ERROR_NULL_INPUT, NULL);
603 cpl_ensure (parlist, CPL_ERROR_NULL_INPUT, NULL);
606 cpl_propertylist * raw_header = gravi_data_get_header (raw_data);
611 cpl_propertylist * spectrum_header = gravi_data_get_header (spectrum_data);
614 cpl_propertylist_append (spectrum_header, raw_header);
616 if ((det_type == GRAVI_DET_FT || det_type == GRAVI_DET_ALL) &&
617 gravi_data_has_detector (raw_data, GRAVI_FT)) {
626 CPLCHECK_NUL (
"Cannot duplicate necessary extensions");
630 cpl_size n_region = cpl_table_get_nrow (
gravi_data_get_table (raw_data,GRAVI_IMAGING_DETECTOR_FT_EXT));
635 cpl_table * skyavg_table, * skystd_table;
636 if (sky_map != NULL) {
637 cpl_msg_info (cpl_func,
"Extract FT spectra with SKY as background and variance");
641 else if (dark_map != NULL) {
642 if ( !gravi_data_is_internal(raw_data) )
645 cpl_msg_info (cpl_func,
"Extract FT spectra with DARK as background and variance");
652 cpl_propertylist_update_double (spectrum_header,
"ESO QC USEDGAIN FT", gain_ft);
653 cpl_propertylist_set_comment (spectrum_header,
"ESO QC USEDGAIN FT",
"[ADU/e-] value used for reduction");
655 CPLCHECK_NUL(
"Problem while getting the tables");
661 cpl_table * spectrum_ft;
662 spectrum_ft =
gravi_table_ft_format (imaging_data_ft, skystd_table, skyavg_table, badft_table, n_region, gain_ft);
663 CPLCHECK_NUL (
"Cannot format FT data");
666 for (cpl_size reg=0; reg<n_region; reg++) {
667 cpl_table_set_column_unit (spectrum_ft, GRAVI_DATA[reg],
"e");
668 cpl_table_set_column_unit (spectrum_ft, GRAVI_DATAERR[reg],
"e");
672 cpl_propertylist * spectrum_plist = cpl_propertylist_new ();
673 int nx = gravi_spectrum_get_nwave (spectrum_ft);
674 cpl_propertylist_update_int (spectrum_plist, PROFILE_NX, nx);
675 cpl_propertylist_update_int (spectrum_plist, PROFILE_STARTX, 1);
676 cpl_propertylist_update_int (spectrum_plist, PROFILE_FULLSTARTX, 0);
682 if ((det_type == GRAVI_DET_SC || det_type == GRAVI_DET_ALL) &&
683 gravi_data_has_detector (raw_data, GRAVI_SC)) {
692 CPLCHECK_NUL (
"Cannot duplicate necessary extensions");
696 cpl_ensure (profile_table, CPL_ERROR_ILLEGAL_INPUT, NULL);
701 CPLCHECK_NUL (
"Cannot get data");
705 cpl_propertylist_update_double (spectrum_header,
"ESO QC USEDGAIN SC", gain_sc);
706 cpl_propertylist_set_comment (spectrum_header,
"ESO QC USEDGAIN SC",
"[ADU/e-] value used for reduction");
709 cpl_image * badpix_img = gravi_data_get_img (bad_map, GRAVI_IMAGING_DATA_SC_EXT);
713 cpl_image * skyavg_img;
714 if (sky_map != NULL){
715 cpl_msg_info (cpl_func,
"Extract SC spectra with SKY as background");
716 skyavg_img = gravi_data_get_img (sky_map, GRAVI_IMAGING_DATA_SC_EXT);
718 else if (dark_map != NULL) {
719 if ( !gravi_data_is_internal(raw_data) )
722 cpl_msg_info (cpl_func,
"Extract SC spectra with DARK as background");
723 skyavg_img = gravi_data_get_img (dark_map, GRAVI_IMAGING_DATA_SC_EXT);
729 cpl_image * darkavg_img;
730 cpl_image * darkstd_img;
731 if (dark_map != NULL) {
732 cpl_msg_info (cpl_func,
"Extract SC photonic variance with DARK as background and variance");
733 darkavg_img = gravi_data_get_img (dark_map, GRAVI_IMAGING_DATA_SC_EXT);
734 darkstd_img = gravi_data_get_img (dark_map, GRAVI_IMAGING_ERR_SC_EXT);
736 else if (sky_map != NULL) {
737 gravi_pfits_add_check (spectrum_header,
"Extract SC photonic variance with SKY as background and variance");
738 darkavg_img = gravi_data_get_img (sky_map, GRAVI_IMAGING_DATA_SC_EXT);
739 darkstd_img = gravi_data_get_img (sky_map, GRAVI_IMAGING_ERR_SC_EXT);
744 CPLCHECK_NUL (
"The coordinate dimensions of the new window is missing");
747 cpl_msg_info (cpl_func,
"Compute flux image");
748 cpl_imagelist * raw_imglist;
749 raw_imglist = cpl_imagelist_duplicate (imaging_data);
750 cpl_imagelist_subtract_image (raw_imglist, skyavg_img);
751 cpl_imagelist_divide_scalar (raw_imglist, gain_sc);
753 CPLCHECK_NUL (
"Cannot extract the data");
756 cpl_msg_info (cpl_func,
"Compute variance image");
757 cpl_imagelist * rawVar_imglist;
758 rawVar_imglist = cpl_imagelist_duplicate (imaging_data);
759 cpl_imagelist_subtract_image (rawVar_imglist, darkavg_img);
760 cpl_imagelist_divide_scalar (rawVar_imglist, gain_sc);
761 CPLCHECK_NUL (
"Cannot extract the data");
764 cpl_image * darkvar_img = cpl_image_power_create (darkstd_img, 2.0);
765 cpl_image_divide_scalar (darkvar_img, gain_sc * gain_sc);
766 cpl_imagelist_add_image (rawVar_imglist, darkvar_img);
767 FREE (cpl_image_delete, darkvar_img);
768 CPLCHECK_NUL (
"Cannot extract the data");
772 cpl_table * spectrum_table;
774 rawVar_imglist, startx);
775 CPLCHECK_NUL (
"Cannot collapse the spectrum");
777 cpl_size n_row = cpl_table_get_nrow (spectrum_table);
778 cpl_size n_region = cpl_table_get_ncol (profile_table);
781 for (cpl_size reg=0; reg<n_region; reg++) {
782 cpl_table_set_column_unit (spectrum_table, GRAVI_DATA[reg],
"e");
783 cpl_table_set_column_unit (spectrum_table, GRAVI_DATAERR[reg],
"e");
787 int ditshift = gravi_param_get_int_default (parlist,
"gravity.preproc.ditshift-sc", 0);
788 cpl_msg_info (cpl_func,
"ditshift = %i", ditshift);
791 gravi_msg_warning (
"CRITICAL",
"DITSHIFT is not set to zero... are you sure??");
795 cpl_table_new_column (spectrum_table,
"TIME", CPL_TYPE_INT);
796 for (cpl_size row = 0; row < n_row; row ++) {
797 cpl_table_set_int (spectrum_table,
"TIME", row,
805 cpl_msg_info (cpl_func,
"Total flux in REGIONs: %.2e [e], in IMGs:%.2e [e] (ratio=%.5f)",
806 full_flux_reg,full_flux_img,full_flux_reg/full_flux_img);
808 cpl_propertylist_update_double (spectrum_header,
"ESO QC TRANS PROFILE SC", full_flux_reg/full_flux_img);
809 cpl_propertylist_set_comment (spectrum_header,
"ESO QC TRANS PROFILE SC",
"[e/e] at profile extraction");
811 CPLCHECK_NUL (
"Cannot verify if extraction was flux-conservative");
814 cpl_propertylist * spectrum_plist = cpl_propertylist_new ();
815 cpl_propertylist_copy_property (spectrum_plist, profile_plist, PROFILE_FULLSTARTX);
816 cpl_propertylist_copy_property (spectrum_plist, profile_plist, PROFILE_STARTX);
817 cpl_propertylist_copy_property (spectrum_plist, profile_plist, PROFILE_NX);
820 GRAVI_SPECTRUM_DATA_SC_EXT, spectrum_table);
825 cpl_msg_info (cpl_func,
"Extract the FLAT");
827 cpl_table * spectrumflat_table;
828 cpl_imagelist * flat_imglist =
gravi_data_get_cube (profile_map, GRAVI_IMAGING_DATA_SC_EXT);
831 CPLCHECK_NUL (
"Cannot collapse the flat");
834 cpl_propertylist * spectrumflat_plist = cpl_propertylist_new ();
836 GRAVI_SPECTRUMFLAT_DATA_SC_EXT, spectrumflat_table);
839 FREE (cpl_imagelist_delete, raw_imglist);
840 FREE (cpl_imagelist_delete, rawVar_imglist);
843 gravi_msg_function_exit(1);
844 return spectrum_data;
861 gravi_data * dark_map)
864 gravi_msg_function_start(1);
865 cpl_ensure_code (dark_map , CPL_ERROR_NULL_INPUT);
868 cpl_msg_warning (cpl_func,
"The DARK data has no METROLOGY extension");
874 CPLCHECK_MSG(
"Problem while getting the tables");
877 const char * data_x=
"VOLT";
878 cpl_size nrow = cpl_table_get_nrow (met_data_table);
879 cpl_array ** met_data_array = cpl_table_get_data_array (met_data_table, data_x);
880 cpl_ensure_code (met_data_array, CPL_ERROR_ILLEGAL_INPUT);
881 cpl_array ** met_dark_array = cpl_table_get_data_array (met_dark_table, data_x);
882 cpl_ensure_code (met_dark_array, CPL_ERROR_ILLEGAL_INPUT);
886 for (cpl_size j = 0; j < nrow ; j++)
888 cpl_array_subtract(met_data_array[j],met_dark_array[0]);
891 cpl_msg_info (cpl_func,
"METROLOGY Volts have been subtracted from dark");
894 gravi_msg_function_exit(1);
895 return CPL_ERROR_NONE;
921 cpl_table * wave_table,
922 cpl_table ** oiwave_tables,
923 cpl_table * detector_table,
924 cpl_table * specflat_table,
925 const cpl_parameterlist * parlist,
928 gravi_msg_function_start(1);
931 cpl_ensure_code (spectrum_table, CPL_ERROR_NULL_INPUT);
932 cpl_ensure_code (wave_table, CPL_ERROR_NULL_INPUT);
933 cpl_ensure_code (oiwave_tables, CPL_ERROR_NULL_INPUT);
934 cpl_ensure_code (oiwave_tables[0], CPL_ERROR_NULL_INPUT);
937 cpl_size nb_region = gravi_spectrum_get_nregion (spectrum_table);
938 cpl_size nb_pol = gravi_spectrum_get_npol (spectrum_table);
939 cpl_size nb_wave = gravi_spectrum_get_nwave (spectrum_table);
940 cpl_size nb_row = cpl_table_get_nrow (spectrum_table);
941 cpl_size nb_oiwave = cpl_table_get_nrow (oiwave_tables[0]);
945 cpl_ensure_code (oiwave_tables[1], CPL_ERROR_NULL_INPUT);
946 cpl_ensure_code (cpl_table_get_nrow (oiwave_tables[0]) ==
947 cpl_table_get_nrow (oiwave_tables[1]),
948 CPL_ERROR_ILLEGAL_INPUT);
952 cpl_ensure_code (nb_region == 24 || nb_region == 48,
953 CPL_ERROR_ILLEGAL_INPUT);
956 cpl_msg_info (cpl_func,
"nb_oiwave=%lld, nb_wave=%lld", nb_oiwave, nb_wave);
957 cpl_ensure_code (nb_oiwave <= nb_wave, CPL_ERROR_ILLEGAL_INPUT);
961 cpl_msg_info (cpl_func,
"Change the target wavelength because of FLAT");
963 cpl_msg_info (cpl_func,
"Don't change the target wavelenght because of FLAT");
968 double * xout = cpl_malloc (nb_oiwave *
sizeof(
double));
969 double * yout = cpl_malloc (nb_oiwave *
sizeof(
double));
970 cpl_size *
id = cpl_malloc (nb_oiwave *
sizeof(cpl_size));
972 double * outputData = cpl_malloc (nb_oiwave *
sizeof(
double));
973 double * outputErr = cpl_malloc (nb_oiwave *
sizeof(
double));
976 for (
int pol = 0; pol < nb_pol; pol++) {
979 double oiwave_min = cpl_table_get_column_min (oiwave_tables[pol],
"EFF_WAVE");
980 double oiwave_max = cpl_table_get_column_max (oiwave_tables[pol],
"EFF_WAVE");
982 cpl_msg_info(cpl_func,
"Reinterpolate pol %i: oiwave_min=%g, oiwave_max=%g [um]",
983 pol, oiwave_min*1e6, oiwave_max*1e6);
986 for (cpl_size reg = 0; reg < nb_region; reg++){
992 const char * data_x = GRAVI_DATA[reg];
993 const char * data_errx = GRAVI_DATAERR[reg];
996 int nbd = cpl_table_get_column_depth (spectrum_table, data_x);
997 cpl_ensure_code (nbd == nb_wave, CPL_ERROR_ILLEGAL_INPUT);
1000 int nbw = cpl_table_get_column_depth (wave_table, data_x);
1001 cpl_ensure_code (nbw == nb_wave, CPL_ERROR_ILLEGAL_INPUT);
1004 double wave_first = gravi_table_get_value (wave_table, data_x, 0, 0);
1005 double wave_last = gravi_table_get_value (wave_table, data_x, 0, nb_wave-1);
1006 cpl_ensure_code (wave_first < wave_last, CPL_ERROR_ILLEGAL_INPUT);
1017 cpl_array ** inputData = cpl_table_get_data_array (spectrum_table, data_x);
1018 cpl_array ** inputErr = cpl_table_get_data_array (spectrum_table, data_errx);
1019 const cpl_array * flat = NULL;
1020 if (specflat_table){
1021 flat = cpl_table_get_array (specflat_table, data_x, 0);
1023 cpl_array * wave = cpl_table_get_data_array(wave_table, data_x)[0];
1024 CPLCHECK_MSG(
"Cannot get data");
1027 cpl_ensure_code ((cpl_array_get_type (inputData[0]) == CPL_TYPE_DOUBLE) &&
1028 (cpl_array_get_type (inputErr[0]) == CPL_TYPE_DOUBLE) &&
1029 (cpl_array_get_type (wave) == CPL_TYPE_DOUBLE),
1030 CPL_ERROR_ILLEGAL_INPUT);
1034 double * wave_ref = cpl_array_get_data_double (wave);
1035 CPLCHECK_MSG(
"Cannot get data");
1046 if ( ( nb_oiwave <= 50 ) && ( type_data == GRAVI_SC) && (flat != NULL) ) {
1047 cpl_msg_info_overwritable (cpl_func,
"Reinterpolate (3 pixels) region %lld " 1048 "over %lld (%lld->%lld channels)",
1049 reg+1,nb_region,nb_wave,nb_oiwave);
1058 double * weight_m = cpl_malloc (nb_oiwave *
sizeof(
double));
1059 double * weight_i = cpl_malloc (nb_oiwave *
sizeof(
double));
1060 double * weight_p = cpl_malloc (nb_oiwave *
sizeof(
double));
1062 for (cpl_size iw = 0 ; iw < nb_oiwave ; iw ++)
1065 double l0=cpl_table_get (oiwave_tables[pol],
"EFF_WAVE", iw, NULL);
1071 if (iw == 0)
id[iw] = 1;
1072 else id[iw] =
id[iw-1];
1073 while ( (1./l0 < 0.5/wave_ref[
id[iw]]+0.5/wave_ref[
id[iw]+1]) && (
id[iw] < nb_wave-2 ) ){
1079 double xm=l0/wave_ref[
id[iw]-1]-1.;
1080 double xi=l0/wave_ref[
id[iw]]-1.;
1081 double xp=l0/wave_ref[
id[iw]+1]-1.;
1082 double xT=(xp-xm)/2;
1090 Fm=cpl_array_get (flat,
id[iw]-1, NULL);
1091 Fi=cpl_array_get (flat,
id[iw], NULL);
1092 Fp=cpl_array_get (flat,
id[iw]+1, NULL);
1103 if ( (Fi>1e-4) && (Fp>1e-4) && (Fm>1e-4) && (xm-xi>1e-4) && (xi-xp>1e-4) )
1116 weight_p[iw]= (xT-2*xi)/(4*xp) ;
1118 weight_m[iw]= -(xT+2*xi)/(4*xm);
1130 norm = weight_m[iw] + weight_i[iw] + weight_p[iw];
1146 for (cpl_size j = 0; j < nb_row; j++){
1152 yref = cpl_array_get_data_double (inputData[j]);
1154 for (cpl_size iw=0 ; iw < nb_oiwave ; iw ++) {
1155 outputData[iw]=yref[
id[iw]-1]*weight_m[iw] + yref[
id[iw]]*weight_i[iw] + yref[
id[iw]+1]*weight_p[iw];
1158 for (cpl_size iw = 0 ; iw < nb_oiwave ; iw ++){
1159 yref[iw]=outputData[iw];
1165 yref = cpl_array_get_data_double (inputErr[j]);
1167 for (cpl_size iw=0 ; iw < nb_oiwave ; iw ++) {
1168 outputErr[iw]=sqrt(pow(yref[
id[iw]-1]*weight_m[iw],2) + pow(yref[
id[iw]]*weight_i[iw],2) + pow(yref[
id[iw]+1]*weight_p[iw],2));
1171 for (cpl_size iw = 0 ; iw < nb_oiwave ; iw ++){
1172 yref[iw]=outputErr[iw];
1177 FREE (cpl_free, weight_m);
1178 FREE (cpl_free, weight_i);
1179 FREE (cpl_free, weight_p);
1186 cpl_msg_info_overwritable (cpl_func,
"Reinterpolate region %lld " 1187 "over %lld (%lld->%lld channels)",
1188 reg+1,nb_region,nb_wave,nb_oiwave);
1196 double * weight_m = cpl_malloc (nb_oiwave *
sizeof(
double));
1197 double * weight_p = cpl_malloc (nb_oiwave *
sizeof(
double));
1199 for (cpl_size iw = 0 ; iw < nb_oiwave ; iw ++)
1202 double l0=cpl_table_get (oiwave_tables[pol],
"EFF_WAVE", iw, NULL);
1208 if (iw == 0)
id[iw] = 1;
1209 else id[iw] =
id[iw-1];
1210 while ( (1./l0 < 1./wave_ref[
id[iw]]) && (
id[iw] < nb_wave-1 ) ){
1216 double xm=l0/wave_ref[
id[iw]-1]-1.;
1217 double xp=l0/wave_ref[
id[iw]]-1.;
1225 Fm=cpl_array_get (flat,
id[iw]-1, NULL);
1226 Fp=cpl_array_get (flat,
id[iw], NULL);
1236 if ( (Fp>1e-4) && (Fm>1e-4) && (xm>=0.0) && (xp<=0.0) )
1254 norm = weight_m[iw]+ weight_p[iw];
1271 for (cpl_size j = 0; j < nb_row; j++){
1277 yref = cpl_array_get_data_double (inputData[j]);
1279 for (cpl_size iw=0 ; iw < nb_oiwave ; iw ++) {
1280 outputData[iw]=yref[
id[iw]-1]*weight_m[iw] + yref[
id[iw]]*weight_p[iw];
1283 for (cpl_size iw = 0 ; iw < nb_oiwave ; iw ++){
1284 yref[iw]=outputData[iw];
1290 yref = cpl_array_get_data_double (inputErr[j]);
1292 for (cpl_size iw=0 ; iw < nb_oiwave ; iw ++) {
1293 outputErr[iw]=sqrt(pow(yref[
id[iw]-1]*weight_m[iw],2) + pow(yref[
id[iw]]*weight_p[iw],2));
1296 for (cpl_size iw = 0 ; iw < nb_oiwave ; iw ++){
1297 yref[iw]=outputErr[iw];
1302 FREE (cpl_free, weight_m);
1303 FREE (cpl_free, weight_p);
1309 if (nb_wave > nb_oiwave) {
1310 cpl_msg_debug (cpl_func,
"Modify depth of column %s (%lld->%lld)", data_x, nb_wave, nb_oiwave);
1311 cpl_table_set_column_depth (spectrum_table, data_x, nb_oiwave);
1312 cpl_table_set_column_depth (spectrum_table, data_errx, nb_oiwave);
1313 CPLCHECK_MSG (
"Cannot change column depth");
1321 FREE (cpl_free, yout);
1322 FREE (cpl_free, xout);
1325 FREE (cpl_free,
id);
1326 FREE (cpl_free, outputData);
1327 FREE (cpl_free, outputErr);
1330 gravi_msg_function_exit(1);
1331 return CPL_ERROR_NONE;
1359 gravi_data * wave_map,
1360 gravi_data * p2vm_map,
1361 enum gravi_detector_type det_type,
1362 const cpl_parameterlist * parlist)
1364 gravi_msg_function_start(1);
1368 cpl_ensure_code (spectrum_data, CPL_ERROR_NULL_INPUT);
1369 cpl_ensure_code (wave_map, CPL_ERROR_NULL_INPUT);
1370 cpl_ensure_code (p2vm_map, CPL_ERROR_NULL_INPUT);
1375 CPLCHECK_MSG (
"Cannot copy OI_WAVELENGTH extention(s)");
1378 int init_type_data = 1;
1379 int end_type_data = 1;
1380 if(det_type == GRAVI_DET_SC || det_type == GRAVI_DET_ALL) {
1383 if(det_type == GRAVI_DET_FT || det_type == GRAVI_DET_ALL) {
1386 for (
int type_data = init_type_data; type_data <= end_type_data; type_data++ ) {
1389 if (!gravi_data_has_spectrum (spectrum_data, type_data)) {
1390 cpl_msg_info (cpl_func,
"No data for %s, skip it", GRAVI_TYPE(type_data));
1395 cpl_msg_info (cpl_func,
"Re-interpolate the %s",GRAVI_TYPE(type_data));
1398 cpl_table * spectrum_table, * wave_table, * detector_table;
1399 spectrum_table = gravi_data_get_spectrum_data (spectrum_data, type_data);
1400 wave_table = gravi_data_get_wave_data (wave_map, type_data);
1401 detector_table = gravi_data_get_imaging_detector (spectrum_data, type_data);
1403 cpl_table * specflat_table;
1404 if (type_data == GRAVI_SC)
1407 specflat_table = NULL;
1409 CPLCHECK_MSG (
"Cannot load the extention data");
1415 int npol = gravi_spectrum_get_npol (wave_table);
1425 parlist, type_data);
1427 FREE (cpl_free, oiwave_tables);
1428 CPLCHECK_MSG (
"Cannot interpolate");
1434 cpl_propertylist * spectrum_plist = gravi_data_get_spectrum_data_plist (spectrum_data, type_data);
1435 int nwave = gravi_spectrum_get_nwave (spectrum_table);
1436 cpl_propertylist_erase (spectrum_plist, PROFILE_FULLSTARTX);
1437 cpl_propertylist_erase (spectrum_plist, PROFILE_STARTX);
1438 cpl_propertylist_erase (spectrum_plist, PROFILE_NX);
1439 cpl_propertylist_update_int (spectrum_plist,
"NWAVE", nwave);
1440 CPLCHECK_MSG (
"Cannot replace STARTX by NWAVE");
1443 cpl_msg_info (cpl_func,
"Total flux in REGION1s: %.2e [e], in REGION0s:%.2e [e] (ratio=%.5f)",
1444 full_flux_reg1,full_flux_reg0,full_flux_reg1/full_flux_reg0);
1447 cpl_propertylist * spectrum_header = gravi_data_get_header (spectrum_data);
1448 sprintf (qc_name,
"ESO QC TRANS INTERP %s",GRAVI_TYPE(type_data));
1449 cpl_propertylist_update_double (spectrum_header, qc_name, full_flux_reg1/full_flux_reg0);
1450 cpl_propertylist_set_comment (spectrum_header, qc_name,
"[e/e] at interpolation");
1451 CPLCHECK_MSG (
"Cannot set QC parameters");
1455 gravi_msg_function_exit(1);
1456 return CPL_ERROR_NONE;
gravi_data * gravi_data_new(int nb_ext)
Create an empty gravi_data.
double gravi_pfits_get_time_sc(const cpl_propertylist *header, cpl_size row)
Time of the middle of the SC exposure row in [us], counted from PRC.ACQ.START.
int gravi_region_get_pol(cpl_table *imaging_detector, int region)
Return the polarisation id of a region.
cpl_error_code gravi_data_copy_ext(gravi_data *output, gravi_data *input, const char *name)
Copy extensions from one data to another.
cpl_error_code gravi_interpolate_spectrum_table(cpl_table *spectrum_table, cpl_table *wave_table, cpl_table **oiwave_tables, cpl_table *detector_table, cpl_table *specflat_table, const cpl_parameterlist *parlist, int type_data)
Re-interpolate in-place a spectrum table.
int gravi_data_has_extension(gravi_data *raw_calib, const char *ext_name)
Check if data has extension with given EXTNAME.
int gravi_pfits_get_startx(const cpl_propertylist *plist)
find out the name of the propertylist
cpl_error_code gravi_pfits_add_check(cpl_propertylist *header, char *msg)
Add a QC.CHECK keyword to the header.
double gravi_pfits_get_sc_gain(const cpl_propertylist *plist)
SC system gain in [ADU/e].
double gravi_imagelist_get_flux(const cpl_imagelist *imglist)
Return the total flux in imagelist.
cpl_table ** gravi_data_get_oiwave_tables(gravi_data *data, int type_data, int npol)
Get pointer to the OI_WAVELENGTH tables of both polarisations.
cpl_table * gravi_data_get_table(gravi_data *self, const char *extname)
Return a pointer on a table extension by its EXTNAME.
double gravi_pfits_get_ft_gain(const cpl_propertylist *plist)
FT system gain in [ADU/e].
cpl_error_code gravi_remove_badpixel_sc(cpl_imagelist *imglist_sc, cpl_image *bad_img)
Remove the badpixel of the SC.
int gravi_pixel_is_good(cpl_image *bad_img, int x, int y)
Check if the pixel in the BADPIX map is a good pixel.
cpl_table * gravi_table_ft_format(cpl_table *table_ft, cpl_table *sky_table_std, cpl_table *sky_table_avg, cpl_table *badft_table, int n_region, double gain)
Extract FT spectrum from PIX column.
double gravi_spectrum_get_flux(const cpl_table *table)
Return the total flux in DATA# regions.
cpl_error_code gravi_imagelist_unwrap_images(cpl_imagelist *imglist)
Unwrap an imagelist an all its images.
cpl_propertylist * gravi_data_get_plist(gravi_data *self, const char *extname)
Get the propertylist from EXTNAME.
cpl_imagelist * gravi_data_get_cube(gravi_data *self, const char *extname)
Return a pointer on an IMAGE extension by its EXTNAME.
cpl_error_code gravi_align_spectrum(gravi_data *spectrum_data, gravi_data *wave_map, gravi_data *p2vm_map, enum gravi_detector_type det_type, const cpl_parameterlist *parlist)
Regrid the regions into a common wavelength (in-place)
cpl_error_code gravi_data_add_table(gravi_data *self, cpl_propertylist *plist, const char *extname, cpl_table *table)
Add a BINTABLE extension in gravi_data.
cpl_table * gravi_imglist_sc_collapse(cpl_table *profile_table, cpl_imagelist *raw_imglist, cpl_imagelist *rawVar_imglist, cpl_size startx)
Extract the SC spectrum with profile.
cpl_error_code gravi_subtract_met_dark(gravi_data *preproc_data, gravi_data *dark_map)
Substract metrology dark.
gravi_data * gravi_extract_spectrum(gravi_data *raw_data, gravi_data *profile_map, gravi_data *dark_map, gravi_data *bad_map, gravi_data *sky_map, const cpl_parameterlist *parlist, enum gravi_detector_type det_type)
Create the SPECTRUM gravi_data with extracted spectrum per region.
cpl_imagelist * gravi_imagelist_wrap_column(cpl_table *table_data, const char *data_x)
Wrap a column array of a table into an imagelist.