69#define RECIPE_ID "xsh_util_ifu_build_cube"
70#define RECIPE_AUTHOR "A. Modigliani"
71#define RECIPE_CONTACT "Andrea.Modigliani@eso.org"
92"Produces the spatial geometry of the IFU pattern on the sky";
95"This recipe Produces the spatial geometry of the IFU pattern on the sky\n\
97 - A set of n Science frames ( n == 1 or >=3, \
98Tag = OBJECT_IFU_STARE_UVB)\n\
99 - [UVB,VIS] A master bias frame (Tag = MASTER_BIAS_arm)\n\
100 - A master dark frame (Tag = MASTER_DARK_arm)\n\
101 - A master flat frame (Tag = MASTER_FLAT_IFU_arm)\n\
102 - An order table frame(Tag = ORDER_TABLE_arm)\n\
103 - 3 wave solution frames, one per slitlet(Tag = WAVE_SOLUTION_IFU_slitlet_arm)\n\
104 where 'slitlet' is DOWN, CEN or UP\n\
105 - [OPTIONAL] A badpixel map (Tag = BADPIXEL_MAP_arm)\n\
107 - A Slice Offset Table (similar to a localization table)\n\
108 Tag = SLICE_OFFSET_TABLE_arm\n" ;
125 cpl_recipe *recipe = NULL;
126 cpl_plugin *plugin = NULL;
128 recipe = cpl_calloc(1,
sizeof(*recipe));
129 if ( recipe == NULL ){
133 plugin = &recipe->interface ;
135 cpl_plugin_init(plugin,
138 CPL_PLUGIN_TYPE_RECIPE,
149 cpl_pluginlist_append(list, plugin);
151 return (cpl_error_get_code() != CPL_ERROR_NONE);
167 cpl_recipe *recipe = NULL;
173 assure( plugin != NULL, CPL_ERROR_NULL_INPUT,
"Null plugin");
176 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
177 CPL_ERROR_TYPE_MISMATCH,
178 "Plugin is not a recipe");
180 recipe = (cpl_recipe *)plugin;
183 recipe->parameters = cpl_parameterlist_new();
184 assure( recipe->parameters != NULL,
185 CPL_ERROR_ILLEGAL_OUTPUT,
186 "Memory allocation failed!");
193 if ( cpl_error_get_code() != CPL_ERROR_NONE ){
220 cpl_recipe *recipe = NULL;
224 assure( plugin != NULL, CPL_ERROR_NULL_INPUT,
"Null plugin" );
227 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
228 CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
230 recipe = (cpl_recipe *)plugin;
236 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
255 cpl_recipe *recipe = NULL;
260 assure( plugin != NULL, CPL_ERROR_NULL_INPUT,
"Null plugin" );
263 assure( cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE,
264 CPL_ERROR_TYPE_MISMATCH,
"Plugin is not a recipe");
266 recipe = (cpl_recipe *)plugin;
271 if (cpl_error_get_code() != CPL_ERROR_NONE)
293 cpl_frameset* frameset)
296 int recipe_tags_size = 1;
299 cpl_frameset *raws = NULL;
300 cpl_frameset *calib = NULL;
304 cpl_frame *sci_frame=NULL;
305 cpl_frame *spectral_format_frame = NULL;
306 cpl_frame *model_config_frame = NULL ;
307 cpl_frame *ifu_config_frame = NULL ;
311 char rec_prefix[256];
313 cpl_image* data_img=NULL;
314 cpl_image* errs_img=NULL;
315 cpl_image* qual_img=NULL;
317 cpl_image* data_tmp=NULL;
318 cpl_image* errs_tmp=NULL;
319 cpl_image* qual_tmp=NULL;
320 cpl_image* mask_tmp=NULL;
321 cpl_frame* qc_trace_frame=NULL;
322 cpl_frame* qc_trace_merged_frame=NULL;
323 cpl_frame* frame_cube=NULL;
324 cpl_frame* frame_merged_cube=NULL;
327 cpl_propertylist* data_plist=NULL;
328 cpl_propertylist* errs_plist=NULL;
329 cpl_propertylist* qual_plist=NULL;
338 cpl_table* ifu_cfg_tab=NULL;
339 cpl_table* sp_fmt_tab=NULL;
340 cpl_vector* profile=NULL;
341 cpl_imagelist* data_cube=NULL;
342 cpl_imagelist* errs_cube=NULL;
343 cpl_imagelist* qual_cube=NULL;
345 cpl_imagelist* data_cube_merge=NULL;
346 cpl_imagelist* errs_cube_merge=NULL;
347 cpl_imagelist* qual_cube_merge=NULL;
348 cpl_imagelist* mask_cube_merge=NULL;
360 const int peack_search_hsize=5;
363 const char* sci_name=NULL;
364 const char* sp_fmt_name=NULL;
365 const char* ifu_cfg_name=NULL;
371 int recipe_use_model=0;
384 double cube_wave_min=0;
385 double cube_wave_max=0;
392 double cube_wmin=550;
393 double cube_wmax=1000;
408 double wave_min_old=0;
409 double wave_max_old=0;
439 double w_low_coeff1=0;
440 double w_low_coeff2=0;
442 double w_upp_coeff1=0;
443 double w_upp_coeff2=0;
445 double w_low_coeff1_uvb=-0.002972;
446 double w_low_coeff2_uvb=2.26497e-6;
447 double w_upp_coeff1_uvb=8.3355331e-5;
448 double w_upp_coeff2_uvb=-1.0682e-6;
452 double w_low_coeff1_vis=-0.0016549569;
453 double w_low_coeff2_vis=1.183805e-6;
454 double w_upp_coeff1_vis=-0.0016610719;
455 double w_upp_coeff2_vis=1.0823013e-6;
457 double w_low_coeff1_nir=0;
458 double w_low_coeff2_nir=0;
459 double w_upp_coeff1_nir=0;
460 double w_upp_coeff2_nir=0;
462 double s_upp_off_uvb=4.0514429+0.16;
463 double s_upp_off_vis=5.2504895+0.16;
464 double s_upp_off_nir=3.5452+0.31;
467 double s_low_off_uvb=-3.4636662+0.16;
468 double s_low_off_vis=-2.9428071+0.16;
469 double s_low_off_nir=-4.451682+0.21;
486 "Instrument NOT in IFU Mode");
489 check(strcpy(rec_prefix,
511 recipe_use_model = ( model_config_frame != NULL);
517 sci_name=cpl_frame_get_filename(sci_frame);
518 data_plist=cpl_propertylist_load(sci_name,0);
532 s_low_off=s_low_off_uvb;
533 s_upp_off=s_upp_off_uvb;
534 w_low_coeff1=w_low_coeff1_uvb;
535 w_low_coeff2=w_low_coeff2_uvb;
537 w_upp_coeff1=w_upp_coeff1_uvb;
538 w_upp_coeff2=w_upp_coeff2_uvb;
539 save_size=save_size_uvb;
552 s_low_off=s_low_off_vis;
553 s_upp_off=s_upp_off_vis;
555 w_low_coeff1=w_low_coeff1_vis;
556 w_low_coeff2=w_low_coeff2_vis;
558 w_upp_coeff1=w_upp_coeff1_vis;
559 w_upp_coeff2=w_upp_coeff2_vis;
560 save_size=save_size_vis;
570 s_low_off=s_low_off_nir;
571 s_upp_off=s_upp_off_nir;
574 w_low_coeff1=w_low_coeff1_nir;
575 w_low_coeff2=w_low_coeff2_nir;
577 w_upp_coeff1=w_upp_coeff1_nir;
578 w_upp_coeff2=w_upp_coeff2_nir;
579 save_size=save_size_nir;
585 if(ifu_config_frame) {
587 ifu_cfg_name=cpl_frame_get_filename(ifu_config_frame);
588 ifu_cfg_tab=cpl_table_load(ifu_cfg_name,1,0);
589 s_upp_off=cpl_table_get_double(ifu_cfg_tab,
"S_UPP_OFF",arm,&status);
590 s_low_off=cpl_table_get_double(ifu_cfg_tab,
"S_LOW_OFF",arm,&status);
592 w_upp_coeff1=cpl_table_get_double(ifu_cfg_tab,
"W_UPP_COEF1",arm,&status);
593 w_low_coeff1=cpl_table_get_double(ifu_cfg_tab,
"W_LOW_COEF1",arm,&status);
594 w_upp_coeff2=cpl_table_get_double(ifu_cfg_tab,
"W_UPP_COEF2",arm,&status);
595 w_low_coeff2=cpl_table_get_double(ifu_cfg_tab,
"W_LOW_COEF2",arm,&status);
597 w_step_fct=cpl_table_get_int(ifu_cfg_tab,
"W_STEP_FCT",arm,&status);
598 xsh_msg(
"s_upp_off=%10.8g",s_upp_off);
599 xsh_msg(
"s_low_off=%10.8g",s_low_off);
602 xsh_msg(
"w_upp_coeff1=%10.8g",w_upp_coeff1);
603 xsh_msg(
"w_upp_coeff2=%10.8g",w_upp_coeff2);
604 xsh_msg(
"w_low_coeff1=%10.8g",w_low_coeff1);
605 xsh_msg(
"w_low_coeff2=%10.8g",w_low_coeff2);
607 xsh_msg(
"w_step_fct=%d",w_step_fct);
610 cube_wstep*=w_step_fct; ;
627 check( profile = cpl_vector_new( CPL_KERNEL_DEF_SAMPLES));
628 check(cpl_vector_fill_kernel_profile( profile,CPL_KERNEL_DEFAULT,
629 CPL_KERNEL_DEF_WIDTH));
630 check(sci_name=cpl_frame_get_filename(sci_frame));
635 check(sp_fmt_name=cpl_frame_get_filename(spectral_format_frame));
636 check(sp_fmt_tab=cpl_table_load(sp_fmt_name,1,0));
637 check(ord_min=cpl_table_get_column_min(sp_fmt_tab,
"ORDER"));
638 check(ord_max=cpl_table_get_column_max(sp_fmt_tab,
"ORDER"));
639 nord=ord_max-ord_min+1;
641 check(cube_wave_min=cpl_table_get(sp_fmt_tab,
"WLMIN",nord-1,&status));
642 check(cube_wave_max=cpl_table_get(sp_fmt_tab,
"WLMAX",0,&status));
644 xsh_msg(
"cube_wave_min=%10.8g cube_wave_max=%10.8g",cube_wave_min,cube_wave_max);
648 xsh_msg(
"ord_min=%d ord_max=%d",ord_min,ord_max);
649 wave_step= cube_wstep;
656 data_cube_merge=cpl_imagelist_new();
657 errs_cube_merge=cpl_imagelist_new();
658 qual_cube_merge=cpl_imagelist_new();
659 mask_cube_merge=cpl_imagelist_new();
668 for( ord = ord_max; ord >= ord_min; ord-- ) {
670 naxis2=(int)((s_max-s_min)/s_step+0.5)+1;
675 data_cube=cpl_imagelist_new();
676 errs_cube=cpl_imagelist_new();
677 qual_cube=cpl_imagelist_new();
685 check(pima=cpl_image_get_data_float(data_tmp));
686 check(perr=cpl_image_get_data_float(errs_tmp));
687 check(pqua=cpl_image_get_data_int(qual_tmp));
688 check(pmsk=cpl_image_get_data_int(mask_tmp));
692 check(wave_min=cpl_table_get(sp_fmt_tab,
"WLMIN",ord-ord_min,&status));
693 check(wave_max=cpl_table_get(sp_fmt_tab,
"WLMAX",ord-ord_min,&status));
695 naxis3=(wave_max-wave_min)/wave_step+1;
696 xsh_msg(
"order=%d naxis1=%d,naxis2=%d naxis3=%d, wave_min=%g wave_max=%g",
697 ord,naxis1,naxis2,naxis3,wave_min,wave_max);
723 nstep_off=(int)((wave_min-wave_min_old)/wave_step+0.5);
729 wave_min=wave_min_old+nstep_off*wave_step;
740 for( wave = wave_min; wave <= wave_max; wave+=wave_step) {
742 for(
s = s_min;
s <= s_max;
s+=s_step ) {
748 s_upp=-
s+s_upp_off+w_upp_coeff1*wave+w_upp_coeff2*wave*wave;
752 check(flux_upp=cpl_image_get_interpolated(data_img,
x,
y,
756 check(errs_upp=cpl_image_get_interpolated(errs_img,
x,
y,
760 check(qual_upp=cpl_image_get_interpolated(qual_img,
x,
y,
765 pima[is*naxis1+0]=flux_upp;
766 perr[is*naxis1+0]=errs_upp;
767 pqua[is*naxis1+0]=qual_upp;
775 check(flux_cen=cpl_image_get_interpolated(data_img,
x,
y,
780 check(errs_cen=cpl_image_get_interpolated(errs_img,
x,
y,
785 check(qual_cen=cpl_image_get_interpolated(qual_img,
x,
y,
790 pima[is*naxis1+1]=flux_cen;
791 perr[is*naxis1+1]=errs_cen;
792 pqua[is*naxis1+1]=qual_cen;
803 s_low=-
s+s_low_off+w_low_coeff1*wave+w_low_coeff2*wave*wave;
807 check(flux_low=cpl_image_get_interpolated(data_img,
x,
y,
811 check(errs_low=cpl_image_get_interpolated(errs_img,
x,
y,
815 check(qual_low=cpl_image_get_interpolated(qual_img,
x,
y,
820 pima[is*naxis1+2]=flux_low;
821 perr[is*naxis1+2]=errs_low;
822 pqua[is*naxis1+2]=qual_low;
828 wave_max_old=wave_max;
829 wave_min_old=wave_min;
831 check(cpl_imagelist_set(data_cube,cpl_image_duplicate(data_tmp),ik));
832 check(cpl_imagelist_set(errs_cube,cpl_image_duplicate(errs_tmp),ik));
833 check(cpl_imagelist_set(qual_cube,cpl_image_duplicate(qual_tmp),ik));
839 data_tmp,mask_tmp,mk));
862 mk=(int)((wave-cube_wave_min)/wave_step+0.5);
867 sprintf(name,
"%s_%2.2d.fits",tag,ord);
872 cpl_imagelist_save(data_cube,name,CPL_BPP_IEEE_FLOAT,data_plist,CPL_IO_DEFAULT);
875 frame_cube=
xsh_frame_product(name,tag,CPL_FRAME_TYPE_IMAGE,CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
877 sprintf(tag,
"ORD%2.2d",ord);
882 peack_search_hsize,
method));
890 sprintf(name,
"%s_%2.2d.fits",tag,ord);
891 cpl_imagelist_save(errs_cube,name,CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
894 sprintf(name,
"%s_%2.2d.fits",tag,ord);
895 cpl_imagelist_save(qual_cube,name,CPL_BPP_IEEE_FLOAT,NULL,CPL_IO_DEFAULT);
898 sprintf(name,
"QC%s_%2.2d.fits",tag,ord);
909 sprintf(name,
"%s.fits",tag);
913 cpl_imagelist_save(data_cube_merge,name,CPL_BPP_IEEE_FLOAT,data_plist,CPL_IO_DEFAULT);
916 xsh_msg(
"merge cube size=%d",cpl_imagelist_get_size(data_cube_merge));
919 CPL_FRAME_GROUP_PRODUCT,CPL_FRAME_LEVEL_FINAL);
928 peack_search_hsize,
method));
static xsh_instrument * instrument
void xsh_rec_list_free(xsh_rec_list **list)
free memory associated to a rec_list
xsh_rec_list * xsh_rec_list_create(xsh_instrument *instr)
Create an empty order list.
#define assure(CONDITION, ERROR_CODE,...)
#define xsh_error_dump(level)
#define xsh_error_reset()
const char * xsh_arm_tostring(XSH_ARM arm)
Get the string associated with an arm.
void xsh_instrument_free(xsh_instrument **instrument)
free an instrument structure
cpl_error_code xsh_model_config_load_best(cpl_frame *config_frame, xsh_xs_3 *p_xs_3)
Load the config model table and fill the struct.
void xsh_model_get_xy(xsh_xs_3 *p_xs_3, xsh_instrument *instr, double lambda_nm, int morder, double ent_slit_pos, double *x, double *y)
Compute the detector location (floating point pixels) of a given wavelength/entrance slit position.
void xsh_model_binxy(xsh_xs_3 *p_xs_3, int bin_X, int bin_Y)
corrects model for detector's binning
#define xsh_msg(...)
Print a message on info level.
int xsh_pfits_get_binx(const cpl_propertylist *plist)
find out the BINX value
void xsh_pfits_set_cdelt1(cpl_propertylist *plist, double value)
Write the CDELT1 value.
int xsh_pfits_get_biny(const cpl_propertylist *plist)
find out the BINY value
void xsh_pfits_set_crval1(cpl_propertylist *plist, double value)
Write the CRVAL1 value.
static char xsh_util_ifu_build_cube_description_short[]
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
static char xsh_util_ifu_build_cube_description[]
static int xsh_util_ifu_build_cube_create(cpl_plugin *)
Setup the recipe options.
static void xsh_util_ifu_build_cube(cpl_parameterlist *, cpl_frameset *)
Interpret the command line options and execute the data processing.
static int xsh_util_ifu_build_cube_destroy(cpl_plugin *)
Destroy what has been created by the 'create' function.
static int xsh_util_ifu_build_cube_exec(cpl_plugin *)
Interpret the command line options and execute the data processing.
void xsh_free_vector(cpl_vector **v)
Deallocate a vector and set the pointer to NULL.
void xsh_free_parameterlist(cpl_parameterlist **p)
Deallocate a parameter list and set the pointer to NULL.
void xsh_free_image(cpl_image **i)
Deallocate an image and set the pointer to NULL.
void xsh_free_frame(cpl_frame **f)
Deallocate a frame and set the pointer to NULL.
void xsh_free_frameset(cpl_frameset **f)
Deallocate a frame set and set the pointer to NULL.
char * xsh_set_recipe_file_prefix(cpl_frameset *raw, const char *recipe)
Set recipe frames prefix.
const char * xsh_get_license(void)
Get the pipeline copyright and license.
void xsh_init(void)
Reset library state.
cpl_error_code xsh_begin(cpl_frameset *frames, const cpl_parameterlist *parameters, xsh_instrument **instrument, cpl_frameset **raws, cpl_frameset **calib, const char *tag_list[], int tag_list_size, const char *recipe_id, unsigned int binary_version, const char *short_descr)
Recipe initialization.
void xsh_free_table(cpl_table **t)
Deallocate a table and set the pointer to NULL.
void xsh_free_propertylist(cpl_propertylist **p)
Deallocate a property list and set the pointer to NULL.
cpl_error_code xsh_end(const char *recipe_id, cpl_frameset *frames, cpl_parameterlist *parameters)
Recipe termination.
void xsh_free_imagelist(cpl_imagelist **i)
Deallocate an image list and set the pointer to NULL.
#define XSH_PRE_DATA_TYPE
#define XSH_PRE_QUAL_TYPE
#define XSH_PRE_ERRS_TYPE
void xsh_add_product_imagelist(cpl_frame *frame, cpl_frameset *frameset, const cpl_parameterlist *parameters, const char *recipe_id, xsh_instrument *instrument, const char *final_prefix)
void xsh_add_product_table(cpl_frame *frame, cpl_frameset *frameset, const cpl_parameterlist *parameters, const char *recipe_id, xsh_instrument *instrument, const char *final_prefix)
Save Table product (input frame has several extensions, 1 table per extension)
cpl_frame * xsh_frame_product(const char *fname, const char *tag, cpl_frame_type type, cpl_frame_group group, cpl_frame_level level)
Creates a frame with given characteristics.
cpl_frame * xsh_find_frame_with_tag(cpl_frameset *frames, const char *tag, xsh_instrument *instr)
Find frame with a given tag.
cpl_frame * xsh_find_model_config(cpl_frameset *frames, xsh_instrument *instr)
Find a model config.
#define XSH_SLIT_BIN_SIZE_NARROW_SLIT_VIS
#define XSH_WAVE_BIN_SIZE_NARROW_SLIT_NIR
#define XSH_WAVE_BIN_SIZE_NARROW_SLIT_VIS
#define XSH_SLIT_BIN_SIZE_NARROW_SLIT_UVB
#define XSH_SLIT_BIN_SIZE_NARROW_SLIT_NIR
#define XSH_WAVE_BIN_SIZE_NARROW_SLIT_UVB
#define XSH_SPECTRAL_FORMAT
cpl_error_code xsh_parameters_decode_bp(const char *recipe_id, cpl_parameterlist *plist, const int ival)
void xsh_parameters_generic(const char *recipe_id, cpl_parameterlist *plist)
cpl_error_code xsh_iml_merge_avg(cpl_imagelist **data, cpl_imagelist **mask, const cpl_image *data_ima, const cpl_image *mask_ima, const int mk)
merge imagelist via average
cpl_frame * xsh_cube_qc_trace_window(cpl_frame *frm_cube, xsh_instrument *instrument, const char *suffix, const char *rec_prefix, const int win_min, const int win_max, const int hsize, const int method, const int compute_qc)
Trace object position in a cube.