00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifdef HAVE_CONFIG_H
00027 #include <config.h>
00028 #endif
00029
00030
00037
00040
00041
00042
00043
00044 #include <math.h>
00045 #include <xsh_drl.h>
00046
00047 #include <xsh_baryvel.h>
00048 #include <xsh_badpixelmap.h>
00049 #include <xsh_data_rec.h>
00050 #include <xsh_data_localization.h>
00051 #include <xsh_data_pre.h>
00052 #include <xsh_data_order.h>
00053 #include <xsh_data_wavesol.h>
00054 #include <xsh_data_spectralformat.h>
00055 #include <xsh_dfs.h>
00056 #include <xsh_pfits.h>
00057 #include <xsh_error.h>
00058 #include <xsh_msg.h>
00059 #include <xsh_fit.h>
00060 #include <xsh_model_io.h>
00061 #include <xsh_model_kernel.h>
00062 #include <xsh_ifu_defs.h>
00063 #include <xsh_data_dispersol.h>
00064 #include <cpl.h>
00065 #include <xsh_utils.h>
00066 #include <xsh_utils_ifu.h>
00067 #include <xsh_utils_table.h>
00068 #include <xsh_rectify.h>
00069 #include <xsh_model_utils.h>
00070
00071
00072
00073
00074
00075
00076
00077 #define SLIT_FRAC_STEP 50
00078
00079 static cpl_vector * rec_profile = NULL ;
00080 static cpl_vector * err_profile = NULL ;
00081
00082 static double compute_shift_with_localization( cpl_frame *loc_frame,
00083 cpl_frame *loc0_frame);
00084
00085 static double compute_shift_with_kw( cpl_propertylist * header,
00086 xsh_rectify_param *rectify_par,
00087 double **ref_ra, double **ref_dec, int flag);
00088
00089 static cpl_frame*
00090 xsh_shift( cpl_frame *rec_frame, xsh_instrument *instrument,
00091 const char *fname, double slit_shift, cpl_frame** res_frame_ext);
00092
00093 static void xsh_frame_set_shiftifu_ref( cpl_propertylist *header,
00094 cpl_frame *shift_frame);
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 static void
00164 xsh_rec_list_rectify( xsh_rec_list *rec_list, int iorder, int irec,
00165 xsh_pre *sci_pre,cpl_image* var_img,
00166 double fx, double fy, double radius, cpl_vector *profile,
00167 cpl_vector* profile2,
00168 double mult)
00169 {
00170 int nx,ny;
00171 float *rec_flux = NULL;
00172 float *rec_errs = NULL;
00173 int *rec_qual = NULL;
00174 int ix,iy;
00175
00176 int xfirst=0;
00177 int xlast=0;
00178
00179 int yfirst=0;
00180 int ylast=0;
00181
00182 register int i=0;
00183 register int j=0;
00184 register int j_nx=0;
00185
00186 XSH_ASSURE_NOT_NULL( rec_list);
00187 XSH_ASSURE_NOT_NULL( sci_pre);
00188 XSH_ASSURE_NOT_NULL( profile);
00189
00190 check( rec_flux = xsh_rec_list_get_data1( rec_list, iorder));
00191 check( rec_errs = xsh_rec_list_get_errs1( rec_list, iorder));
00192 check( rec_qual = xsh_rec_list_get_qual1( rec_list, iorder));
00193
00194 check( nx = xsh_pre_get_nx( sci_pre));
00195 check( ny = xsh_pre_get_ny( sci_pre));
00196
00197 ix = floor( fx ) ;
00198 iy = floor( fy ) ;
00199 xfirst=ceil(fx-radius);
00200 xlast=floor(fx+radius);
00201
00202 yfirst=ceil(fy-radius);
00203 ylast=floor(fy+radius);
00204
00205
00206 if ( ix <0 || ix >= nx || iy < 0 || iy >= ny ) {
00207 xsh_msg_dbg_high( "OUT_OF_RANGE at %d,%d", ix, iy);
00208 rec_flux[irec] = 0;
00209 rec_errs[irec] = 1;
00210 rec_qual[irec] = QFLAG_OUTSIDE_DATA_RANGE;
00211 }
00212
00213
00214 else{
00215 cpl_image *sci_img = NULL;
00216 cpl_image *err_img = NULL;
00217 cpl_image *qua_img = NULL;
00218 float *data = NULL;
00219 float *errs = NULL;
00220 int *qual = NULL;
00221
00222 check( sci_img = xsh_pre_get_data( sci_pre));
00223 check( err_img = xsh_pre_get_errs( sci_pre));
00224 check( qua_img = xsh_pre_get_qual( sci_pre));
00225
00226 check( data = cpl_image_get_data_float( sci_img));
00227 check( errs = cpl_image_get_data_float( err_img));
00228 check( qual = cpl_image_get_data_int( qua_img));
00229
00230 int ix_iynx=ix+iy*nx;
00231
00232
00233 if ( radius == 0.){
00234 rec_flux[irec] = data[ix_iynx];
00235 rec_errs[irec] = errs[ix_iynx];
00236 rec_qual[irec] = qual[ix_iynx];
00237 }
00238
00239
00240 else {
00241 double flux_val=0, confidence=0 ;
00242 check( flux_val = cpl_image_get_interpolated( sci_img, fx, fy,
00243 profile, radius, profile, radius, &confidence));
00244
00245 if (confidence < 1) {
00246 rec_flux[irec] = 0;
00247 rec_errs[irec] = 1;
00248 rec_qual[irec] = QFLAG_MISSING_DATA;
00249
00250
00251 } else {
00252
00253
00254 float err_val = 0;
00255 check( err_val = cpl_image_get_interpolated( var_img, fx, fy,
00256 profile2, radius, profile2, radius, &confidence));
00257
00258
00259 int qual_val = 0;
00260 for(j=yfirst;j<ylast-1;j++) {
00261 j_nx=j*nx;
00262 for(i=xfirst;i<xlast-1;i++) {
00263 qual_val |= qual[j_nx+i];
00264 }
00265 }
00266
00267
00268 rec_flux[irec] = flux_val;
00269 rec_errs[irec] = sqrt(err_val);
00270 rec_qual[irec] = qual_val;
00271 }
00272 }
00273
00274
00275 rec_flux[irec] *= mult;
00276 rec_errs[irec] *= mult;
00277 }
00278
00279 cleanup: return;
00280 }
00281
00282
00283
00304
00305
00306 static inline void
00307 fill_rectified( xsh_pre *pre_sci,
00308 xsh_rec_list *rec_list,
00309 int idx,
00310 xsh_wavesol *wavesol,
00311 xsh_xs_3 *model_config,
00312 xsh_instrument *instrument,
00313 xsh_dispersol_list *disp_list,
00314 float slit_min,
00315 float slit_max,
00316 double lambda_min,
00317 int skip_low,
00318 int skip_up,
00319 xsh_rectify_param *rectify_par,
00320 double slit_shift,
00321 cpl_frame *slit_shiftab_frame)
00322 {
00323
00324 int ns, nl;
00325 int nslit, nlambda ;
00326 float * slit = NULL ;
00327 double * lambda = NULL ;
00328
00329
00330
00331 int order, last_slit, last_lambda;
00332 double *x_data = NULL;
00333 double *y_data = NULL;
00334
00335 double *slit_shift_data = NULL;
00336 const char *slit_shifttab_name = NULL;
00337 cpl_table *shift_tab = NULL;
00338 int shift_size;
00339 double *slit_shifttab_data = NULL;
00340 double *wave_shifttab_data = NULL;
00341 cpl_image* var_img=NULL;
00342
00343
00344 XSH_ASSURE_NOT_NULL( pre_sci);
00345 XSH_ASSURE_NOT_NULL( rec_list);
00346 check( slit = xsh_rec_list_get_slit( rec_list, idx));
00347 XSH_ASSURE_NOT_NULL( slit);
00348 check( lambda = xsh_rec_list_get_lambda( rec_list, idx));
00349 XSH_ASSURE_NOT_NULL( lambda);
00350
00351
00352
00353
00354 var_img=cpl_image_duplicate(xsh_pre_get_errs( pre_sci));
00355 cpl_image_multiply(var_img,var_img);
00356
00357
00358 if ( rec_profile == NULL && rectify_par->rectif_radius != 0 ) {
00359 check( rec_profile = cpl_vector_new( CPL_KERNEL_DEF_SAMPLES));
00360
00361 assure(rectify_par->rectif_radius > 0,CPL_ERROR_ILLEGAL_INPUT,
00362 "rectify-radius must be positive");
00363 check( cpl_vector_fill_kernel_profile( rec_profile,
00364 rectify_par->kernel_type, rectify_par->rectif_radius));
00365 err_profile=cpl_vector_duplicate(rec_profile);
00366 cpl_vector_multiply(err_profile,err_profile);
00367 }
00368
00369
00370 check( order = xsh_rec_list_get_order( rec_list, idx));
00371 check( nslit = xsh_rec_list_get_nslit( rec_list, idx));
00372 check( nlambda = xsh_rec_list_get_nlambda( rec_list, idx));
00373
00374 last_slit = nslit-1;
00375 last_lambda = nlambda-1;
00376
00377 XSH_CALLOC( x_data, double, nslit*nlambda);
00378 XSH_CALLOC( y_data, double, nslit*nlambda);
00379
00380
00381 for( ns = 0 ; ns < nslit ; ns++ ) {
00382
00383
00384
00385
00386 rec_list->list[idx].slit[ns] = slit_min +
00387 (double)ns*rectify_par->rectif_bin_space;
00388 }
00389
00390 for( nl = 0 ; nl < nlambda ; nl++ ) {
00391
00392 rec_list->list[idx].lambda[nl] = lambda_min +
00393 (double)nl*rectify_par->rectif_bin_lambda;
00394 }
00395
00396 xsh_msg_dbg_low( "Order %d slit (%f,%f):%d lambda (%f,%f):%d",
00397 order, rec_list->list[idx].slit[0],
00398 rec_list->list[idx].slit[last_slit], nslit,
00399 rec_list->list[idx].lambda[0],
00400 rec_list->list[idx].lambda[last_lambda], nlambda);
00401
00402
00403 XSH_CALLOC( slit_shift_data, double, nlambda);
00404 if( slit_shiftab_frame != NULL){
00405 check( slit_shifttab_name = cpl_frame_get_filename( slit_shiftab_frame));
00406 xsh_msg_dbg_low("Load slit shift tab %s", slit_shifttab_name);
00407 XSH_TABLE_LOAD( shift_tab, slit_shifttab_name);
00408 check( wave_shifttab_data = cpl_table_get_data_double( shift_tab,
00409 XSH_SHIFTIFU_COLNAME_WAVELENGTH));
00410 check( slit_shifttab_data = cpl_table_get_data_double( shift_tab,
00411 XSH_SHIFTIFU_COLNAME_SHIFTSLIT));
00412 shift_size = cpl_table_get_nrow( shift_tab);
00413
00414 for( nl = 0 ; nl < nlambda ; nl++ ) {
00415 double wave = lambda[nl];
00416 double cshift;
00417 cshift = xsh_data_interpolate( wave, shift_size, wave_shifttab_data,
00418 slit_shifttab_data);
00419 slit_shift_data[nl] = cshift;
00420 }
00421
00422 if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM) {
00423 FILE *shift_file = NULL;
00424 char shift_name[256];
00425
00426 sprintf( shift_name, "shift_%d_%.1f_%.1f.dat", order, slit_min, slit_max);
00427 shift_file = fopen( shift_name, "w+");
00428
00429 fprintf( shift_file, "# wave delta_s\n");
00430
00431 for( nl = 0 ; nl < nlambda ; nl++ ) {
00432 fprintf ( shift_file, "%f %f\n", lambda[nl], slit_shift_data[nl]);
00433 }
00434
00435 fclose( shift_file);
00436 }
00437 }
00438
00439
00440 if ( wavesol != NULL){
00441 for( ns = skip_low ; ns < (nslit - skip_up) ; ns++ ) {
00442 double xslit = slit[ns]+slit_shift;
00443
00444 for( nl = 0 ; nl < nlambda ; nl++ ) {
00445 int irec;
00446 double xlambda = lambda[nl];
00447 double xslitrec;
00448
00449 irec= nl+ns*nlambda;
00450 xslitrec = xslit+slit_shift_data[nl];
00451
00452 check( x_data[irec] = xsh_wavesol_eval_polx( wavesol, xlambda, order,
00453 xslitrec));
00454 check( y_data[irec] = xsh_wavesol_eval_poly( wavesol, xlambda, order,
00455 xslitrec));
00456 }
00457 }
00458 }
00459 else{
00460 XSH_ASSURE_NOT_NULL( model_config);
00461 for( ns = skip_low ; ns < (nslit - skip_up) ; ns++ ) {
00462 double xslit = slit[ns]+slit_shift;
00463 int ns_nl=ns*nlambda;
00464 for( nl = 0 ; nl < nlambda ; nl++ ) {
00465 int irec;
00466 double pm_x=0, pm_y=0;
00467 double xlambda = lambda[nl];
00468 double xslitrec;
00469
00470 irec= nl+ns_nl;
00471 xslitrec = xslit+slit_shift_data[nl];
00472 check( xsh_model_get_xy( model_config, instrument, xlambda, order,
00473 xslitrec,
00474 &pm_x, &pm_y));
00475 x_data[irec] = convert_data_to_bin( pm_x, instrument->binx );
00476 y_data[irec] = convert_data_to_bin( pm_y, instrument->biny );
00477 }
00478 }
00479 }
00480
00481 if ( xsh_debug_level_get() > XSH_DEBUG_LEVEL_MEDIUM) {
00482 FILE *rec_file = NULL;
00483 char recfile_name[256];
00484
00485 sprintf( recfile_name, "rec_%d_%.1f_%.1f.dat", order, slit_min ,slit_max);
00486 rec_file = fopen( recfile_name, "w+");
00487
00488 fprintf( rec_file, "#irec wave slit x y\n");
00489
00490 for( ns = skip_low ; ns < (nslit - skip_up) ; ns++ ) {
00491 double xslit = slit[ns]+slit_shift;
00492
00493 for( nl = 0 ; nl < nlambda ; nl++ ) {
00494 int irec;
00495 double xlambda = lambda[nl];
00496 double xslitrec;
00497
00498 irec= nl+ns*nlambda;
00499 xslitrec = xslit+slit_shift_data[nl];
00500 fprintf ( rec_file, "%d %f %f %f %f\n", irec, xlambda, xslitrec, x_data[irec],
00501 y_data[irec]);
00502 }
00503 }
00504 fclose( rec_file);
00505 }
00506
00507 if (disp_list == NULL) {
00508
00509 for( ns = skip_low ; ns < (nslit - skip_up) ; ns++ ) {
00510 int ns_nl=ns*nlambda;
00511 for( nl = 0 ; nl < nlambda ; nl++ ) {
00512 double fx=0, fy=0;
00513 int irec=0;
00514
00515 irec= nl+ns_nl;
00516 fx = x_data[irec];
00517 fy = y_data[irec];
00518
00519 check( xsh_rec_list_rectify( rec_list, idx, irec, pre_sci,var_img,
00520 fx, fy, rectify_par->rectif_radius,rec_profile,err_profile,1));
00521 }
00522
00523 }
00524 }
00525 else{
00526 cpl_polynomial *plambdadx = NULL, *plambdady = NULL;
00527 cpl_polynomial *pslitdx = NULL, *pslitdy = NULL;
00528 cpl_vector *val = NULL;
00529
00530
00531 check( plambdadx = cpl_polynomial_duplicate(
00532 disp_list->list[idx].lambda_poly));
00533 check( plambdady = cpl_polynomial_duplicate(
00534 disp_list->list[idx].lambda_poly));
00535 check( pslitdx = cpl_polynomial_duplicate(
00536 disp_list->list[idx].slit_poly));
00537 check( pslitdy = cpl_polynomial_duplicate(
00538 disp_list->list[idx].slit_poly));
00539
00540
00541
00542 check( cpl_polynomial_derivative( plambdadx, 0));
00543 check( cpl_polynomial_derivative( plambdady, 1));
00544 check( cpl_polynomial_derivative( pslitdx, 0));
00545 check( cpl_polynomial_derivative( pslitdy, 1));
00546
00547 check( val = cpl_vector_new(2));
00548 double fx, fy;
00549 double ldx, ldy, sdx, sdy, abs_determinant;
00550 int irec;
00551 int ns_nlambda=0;
00552 double bin_size=rectify_par->rectif_bin_space*rectify_par->rectif_bin_lambda;
00553 for( ns = skip_low ; ns < (nslit - skip_up) ; ns++ ) {
00554 ns_nlambda=ns*nlambda;
00555 for( nl = 0 ; nl < nlambda ; nl++ ) {
00556
00557 irec= nl+ns_nlambda;
00558 fx = x_data[irec];
00559 fy = y_data[irec];
00560
00561 check( cpl_vector_set( val, 0, fx));
00562 check( cpl_vector_set( val, 1, fy));
00563
00564 check( ldx = cpl_polynomial_eval( plambdadx, val));
00565 check( ldy = cpl_polynomial_eval( plambdady, val));
00566 check( sdx = cpl_polynomial_eval( pslitdx, val));
00567 check( sdy = cpl_polynomial_eval( pslitdy, val));
00568 abs_determinant = bin_size/(fabs(ldx*sdy-sdx*ldy));
00569
00570 check( xsh_rec_list_rectify( rec_list, idx, irec, pre_sci,var_img,
00571 fx, fy,
00572 rectify_par->rectif_radius,
00573 rec_profile, err_profile,abs_determinant));
00574 }
00575 }
00576 xsh_free_polynomial( &plambdadx);
00577 xsh_free_polynomial( &plambdady);
00578 xsh_free_polynomial( &pslitdx);
00579 xsh_free_polynomial( &pslitdy);
00580 xsh_free_vector( &val);
00581 }
00582
00583 cleanup:
00584 xsh_free_image(&var_img);
00585 xsh_free_vector( &rec_profile);
00586 xsh_free_vector( &err_profile);
00587 XSH_FREE( x_data);
00588 XSH_FREE( y_data);
00589 XSH_FREE( slit_shift_data);
00590 XSH_TABLE_FREE( shift_tab);
00591 return ;
00592 }
00593
00594
00595
00596
00606 void
00607 xsh_get_slit_edges( cpl_frame *slitmap_frame, double *sdown, double *sup,
00608 double *sldown, double *slup, xsh_instrument *instrument)
00609 {
00610 const char *slitmap_name = NULL;
00611 cpl_propertylist *slitmap_header = NULL;
00612
00613 if ( slitmap_frame != NULL) {
00614 XSH_ASSURE_NOT_NULL( sdown);
00615 XSH_ASSURE_NOT_NULL( sup);
00616
00617 check( slitmap_name = cpl_frame_get_filename( slitmap_frame));
00618 check( slitmap_header = cpl_propertylist_load( slitmap_name, 0));
00619
00620 *sdown = xsh_pfits_get_slitmap_median_edglo( slitmap_header);
00621 if ( cpl_error_get_code() != CPL_ERROR_NONE){
00622 xsh_msg_warning(
00623 "Keyword 'MEDIAN EDGLO SLIT' not found in SLIT_MAP %s. Using default value %f",
00624 slitmap_name, MIN_SLIT);
00625 xsh_error_reset();
00626 }
00627
00628 *sup = xsh_pfits_get_slitmap_median_edgup( slitmap_header);
00629 if ( cpl_error_get_code() != CPL_ERROR_NONE){
00630 xsh_msg_warning(
00631 "Keyword 'MEDIAN EDGUP SLIT' not found in SLIT_MAP %s. Using default value %f",
00632 slitmap_name, MAX_SLIT);
00633 xsh_error_reset();
00634 }
00635 if ( xsh_instrument_get_mode(instrument) == XSH_MODE_IFU){
00636 XSH_ASSURE_NOT_NULL( sldown);
00637 XSH_ASSURE_NOT_NULL( slup);
00638 *sldown = xsh_pfits_get_slitmap_median_sliclo( slitmap_header);
00639 if ( cpl_error_get_code() != CPL_ERROR_NONE){
00640 xsh_msg_warning(
00641 "Keyword 'MEDIAN SLICLO SLIT' not found in SLIT_MAP %s. Using default value %f",
00642 slitmap_name, SLITLET_CEN_CENTER-2);
00643 xsh_error_reset();
00644 }
00645 *slup = xsh_pfits_get_slitmap_median_slicup( slitmap_header);
00646 if ( cpl_error_get_code() != CPL_ERROR_NONE){
00647 xsh_msg_warning(
00648 "Keyword 'MEDIAN SLICUP SLIT' not found in SLIT_MAP %s. Using default value %f",
00649 slitmap_name, SLITLET_CEN_CENTER+2);
00650 xsh_error_reset();
00651 }
00652 }
00653 }
00654 else {
00655 xsh_msg_warning( "No provided SLIT_MAP. Using default values: 'MEDIAN EDGLO SLIT' %f - 'MEDIAN EDGUP SLIT' %f",
00656 MIN_SLIT, MAX_SLIT);
00657 *sdown = MIN_SLIT;
00658 *sup = MAX_SLIT;
00659 if ( xsh_instrument_get_mode(instrument) == XSH_MODE_IFU){
00660 xsh_msg_warning( "Using default values: 'MEDIAN SLICLO SLIT' %f - 'MEDIAN SLICUP SLIT' %f",
00661 SLITLET_CEN_CENTER-2, SLITLET_CEN_CENTER+2);
00662 xsh_error_reset();
00663 XSH_ASSURE_NOT_NULL( sldown);
00664 XSH_ASSURE_NOT_NULL( slup);
00665 *sldown = SLITLET_CEN_CENTER-2;
00666 *slup = SLITLET_CEN_CENTER+2;
00667 }
00668 }
00669
00670 if ( xsh_instrument_get_mode(instrument) == XSH_MODE_IFU){
00671 xsh_msg( "IFU limits: slitlet DOWN [%f %f], size: %f arcsec",
00672 *sdown, *sldown, *sldown-*sdown);
00673 xsh_msg( "IFU limits: slitlet CEN [%f %f], size: %f arcsec",
00674 *sldown, *slup, *slup-*sldown);
00675 xsh_msg( "IFU limits: slitlet UP [%f %f], size: %f arcsec",
00676 *slup, *sup, *sup-*slup);
00677 }
00678 else{
00679 xsh_msg( "SLIT limits: [%f %f], total size: %f arcsec", *sdown, *sup, *sup-*sdown);
00680 }
00681 cleanup:
00682 xsh_free_propertylist( &slitmap_header);
00683 return ;
00684 }
00685
00686
00694 void xsh_rec_slit_size( xsh_rectify_param *rectify_par,
00695 double *slit_min, int *nslit, XSH_MODE mode)
00696 {
00697 double smin= MIN_SLIT, smax=MAX_SLIT;
00698 double slit_step;
00699
00700 XSH_ASSURE_NOT_NULL( rectify_par);
00701 XSH_ASSURE_NOT_NULL( slit_min);
00702 XSH_ASSURE_NOT_NULL( nslit);
00703
00704 slit_step = rectify_par->rectif_bin_space;
00705
00706 if ( mode == XSH_MODE_SLIT){
00707 if ( rectify_par->rectify_full_slit != 1 ) {
00708 xsh_msg_warning(" Option not READY go to FULL_SLIT");
00709 }
00710 *nslit = (smax - smin)/slit_step;
00711 *slit_min = smin;
00712 smax = smin+(*nslit-1)*slit_step;
00713
00714 xsh_msg( "SLIT : (%.3f,%.3f) used only (%.3f,%.3f) in %d elts",
00715 MIN_SLIT, MAX_SLIT, smin, smax, *nslit);
00716 }
00717
00718 cleanup:
00719 return;
00720 }
00721
00722
00723 static void
00724 adjust_lambdas( xsh_spectralformat_list * spec_list,
00725 xsh_rectify_param * rectify_par )
00726 {
00727 int i ;
00728 double step = rectify_par->rectif_bin_lambda;
00729
00730 xsh_msg_dbg_high( "Adjust Lambdas: %d orders", spec_list->size ) ;
00731
00732
00733 for ( i = 0 ; i<spec_list->size ; i++ ) {
00734 double min, max ;
00735 int imin, imax ;
00736
00737 min = spec_list->list[i].lambda_min ;
00738 max = spec_list->list[i].lambda_max ;
00739 imin = ceil( min/step) ;
00740 min = (double)imin * step;
00741 imax = floor( max / step);
00742 max = (double)imax*step ;
00743 xsh_msg_dbg_high( "--- test lambdamin - %d : %.4lf -> %.4lf, %lf -> %lf", i,
00744 spec_list->list[i].lambda_min, min,
00745 spec_list->list[i].lambda_max, max ) ;
00746 spec_list->list[i].lambda_min = min;
00747 spec_list->list[i].lambda_max = max;
00748 }
00749 }
00750
00751 static float
00752 get_step_slit( float * slit, int nslit )
00753 {
00754 float result = 0. ;
00755 float min, max ;
00756
00757 max = *(slit+nslit-1) ;
00758 min = *slit ;
00759 result = (max-min)/(float)nslit ;
00760
00761 xsh_msg( " Step Slit = %f", result ) ;
00762 return result ;
00763
00764 }
00765
00766
00767
00800
00801 cpl_frame *
00802 xsh_rectify( cpl_frame *sci_frame,
00803 cpl_frame * orderlist_frame,
00804 cpl_frame *wavesol_frame,
00805 cpl_frame * model_frame,
00806 xsh_instrument *instrument,
00807 xsh_rectify_param *rectify_par,
00808 cpl_frame *spectralformat_frame,
00809 cpl_frame *disp_tab_frame,
00810 const char * res_name,
00811 cpl_frame** res_frame_ext,
00812 cpl_frame** res_frame_tab,
00813 const char* rec_prefix)
00814 {
00815 cpl_frame *result = NULL;
00816 xsh_order_list *orderlist = NULL ;
00817 int nslit;
00818 double slit_min;
00819 char tag[256];
00820
00821 XSH_ASSURE_NOT_NULL( orderlist_frame);
00822
00823 check( orderlist = xsh_order_list_load ( orderlist_frame, instrument));
00824
00825 sprintf(tag,"%s_%s",rec_prefix,
00826 XSH_GET_TAG_FROM_ARM( XSH_ORDER2D, instrument));
00827
00828 xsh_rec_slit_size( rectify_par, &slit_min, &nslit, XSH_MODE_SLIT);
00829
00830 check( result = xsh_rectify_orders( sci_frame, orderlist,
00831 wavesol_frame, model_frame, instrument, rectify_par, spectralformat_frame,
00832 disp_tab_frame, res_name, tag,
00833 res_frame_ext, res_frame_tab,
00834 0, 100, slit_min, nslit,0, NULL));
00835
00836 cleanup:
00837 xsh_order_list_free( &orderlist);
00838 return result;
00839 }
00840
00841
00863 cpl_frame * xsh_rectify_and_shift( cpl_frame *sci_frame,
00864 cpl_frame * orderlist_frame,
00865 cpl_frame *wavesol_frame,
00866 cpl_frame * model_frame,
00867 xsh_instrument *instrument,
00868 xsh_rectify_param *rectify_par,
00869 cpl_frame *spectralformat_frame,
00870 cpl_frame * loc_frame,
00871 cpl_frame * loc0_frame,
00872 double *throw_shift,
00873 cpl_frame *disp_tab_frame,
00874 const char * res_name,
00875 cpl_frame** res_frame_ext,
00876 cpl_frame** res_frame_tab)
00877 {
00878 cpl_frame *result = NULL, *shift_rec = NULL;
00879 cpl_frame * shift_rec_ext = NULL;
00880 xsh_order_list *orderlist = NULL ;
00881 int nslit;
00882 double slit_min;
00883
00884 const char *tag = NULL;
00885 cpl_propertylist *header = NULL;
00886 double bin_space;
00887 double shift_arcsec=0, shift_pix=0, shift_bin_arcsec=0;
00888 double rectify_shift;
00889 #if 0
00890
00891 cpl_frame * result0 = NULL;
00892 char * res0_name = NULL ;
00893 #endif
00894 xsh_msg( "===> xsh_rectify_and_shift" ) ;
00895
00896 XSH_ASSURE_NOT_NULL( orderlist_frame);
00897 XSH_ASSURE_NOT_NULL( rectify_par);
00898
00899 check( orderlist = xsh_order_list_load ( orderlist_frame, instrument));
00900
00901 tag = XSH_GET_TAG_FROM_ARM( XSH_ORDER2D, instrument);
00902 xsh_rec_slit_size( rectify_par, &slit_min, &nslit, XSH_MODE_SLIT);
00903 bin_space = rectify_par->rectif_bin_space;
00904
00905 if ( throw_shift == NULL) {
00906 if ( loc0_frame != NULL){
00907 XSH_ASSURE_NOT_NULL( loc_frame ) ;
00908 xsh_msg("Compute shift with localization");
00909 shift_arcsec = compute_shift_with_localization( loc0_frame, loc_frame);
00910 }
00911 else{
00912 xsh_msg("Fixed shift with localization to 0");
00913 shift_arcsec = 0;
00914 }
00915 }
00916 else {
00917 shift_arcsec = *throw_shift;
00918 xsh_msg("Use throw shift %f", shift_arcsec);
00919 }
00920
00921 shift_pix = xsh_round_double(shift_arcsec/bin_space);
00922 shift_bin_arcsec = shift_pix*bin_space;
00923 rectify_shift = shift_bin_arcsec-shift_arcsec;
00924
00925 xsh_msg(" Mesured Shift for rectify : %f", rectify_shift);
00926
00927 check( shift_rec = xsh_rectify_orders( sci_frame, orderlist,
00928 wavesol_frame, model_frame, instrument,
00929 rectify_par, spectralformat_frame,
00930 disp_tab_frame, res_name, tag,
00931 &shift_rec_ext, res_frame_tab,
00932 0, 100, slit_min, nslit, rectify_shift,
00933 NULL));
00934
00935 check( result = xsh_shift( shift_rec, instrument, res_name, shift_bin_arcsec,
00936 res_frame_ext));
00937
00938 cleanup:
00939 xsh_free_frame( &shift_rec);
00940 xsh_free_frame( &shift_rec_ext);
00941 xsh_order_list_free( &orderlist);
00942 xsh_free_propertylist( &header);
00943 return result;
00944 }
00945
00946
00947
00948
00949 cpl_frameset* xsh_rectify_ifu(cpl_frame *sci_frame,
00950 cpl_frame *orderlist_frame, cpl_frameset *wavesol_frameset,
00951 cpl_frameset *shiftifu_frameset,
00952 cpl_frame *model_frame, xsh_instrument *instrument,
00953 xsh_rectify_param *rectify_par, cpl_frame *spectralformat_frame,
00954 cpl_frame * slitmap_frame,
00955 cpl_frameset** rec_frameset_ext,
00956 cpl_frameset** rec_frameset_tab,
00957 const char* rec_prefix )
00958 {
00959 cpl_frameset *result = NULL;
00960 xsh_order_list *orderlist = NULL ;
00961
00962 XSH_ASSURE_NOT_NULL( orderlist_frame);
00963 check( orderlist = xsh_order_list_load ( orderlist_frame, instrument));
00964
00965
00966 XSH_REGDEBUG("TODO : ADD disp_tab frameset, res_frame_ext frameset");
00967
00968 check( result = xsh_rectify_orders_ifu( sci_frame, orderlist,
00969 wavesol_frameset, shiftifu_frameset, model_frame, instrument, rectify_par,
00970 spectralformat_frame,
00971 slitmap_frame,rec_frameset_ext,rec_frameset_tab, 0, 100, rec_prefix));
00972
00973 cleanup:
00974 xsh_order_list_free( &orderlist);
00975 return result;
00976 }
00977
00978
00979
01011
01012
01013 cpl_frame*
01014 xsh_rectify_orders( cpl_frame *sci_frame,
01015 xsh_order_list *orderlist,
01016 cpl_frame *wavesol_frame,
01017 cpl_frame *model_frame,
01018 xsh_instrument *instrument,
01019 xsh_rectify_param *rectify_par,
01020 cpl_frame *spectralformat_frame,
01021 cpl_frame *disp_tab_frame,
01022 const char *res_name,
01023 const char* tag,
01024 cpl_frame** res_frame_ext,
01025 cpl_frame** res_frame_tab,
01026 int min_index,
01027 int max_index,
01028 double slit_min,
01029 int nslit,
01030 double slit_shift,
01031 cpl_frame *slitshift_tab)
01032 {
01033 xsh_rec_list * rec_list = NULL ;
01034 xsh_xs_3 config_model ;
01035
01036 int solution_type = 0;
01037 xsh_wavesol * wavesol = NULL ;
01038 cpl_frame * res_frame = NULL ;
01039 xsh_pre * pre_sci = NULL ;
01040 int i, nlambda, order ;
01041 float slit_max ;
01042 xsh_spectralformat_list *spec_list = NULL ;
01043 char tag_drl[256];
01044 char res_name_drl[256];
01045
01046 xsh_dispersol_list* disp_list = NULL;
01047 int rec_min_index, rec_max_index;
01048 const char* solution_type_name[2] = { "POLY", "MODEL"};
01049 int found_line=true;
01050 double barycor=0;
01051 double helicor=0;
01052
01053 XSH_ASSURE_NOT_NULL( sci_frame);
01054 XSH_ASSURE_NOT_NULL( orderlist);
01055 XSH_ASSURE_NOT_NULL( spectralformat_frame);
01056 XSH_ASSURE_NOT_NULL( rectify_par);
01057 XSH_ASSURE_NOT_NULL( instrument);
01058 XSH_ASSURE_NOT_ILLEGAL( min_index <= max_index);
01059
01060 if (rectify_par->conserve_flux){
01061 assure( disp_tab_frame != NULL,CPL_ERROR_ILLEGAL_INPUT,
01062 "If -rectify-conserve-flux=TRUE "
01063 "you must provide an input dispersion table "
01064 "tagged as DISP_TAB_%s or DISP_TAB_AFC_%s .",
01065 xsh_instrument_arm_tostring(instrument),
01066 xsh_instrument_arm_tostring(instrument));
01067 check( disp_list = xsh_dispersol_list_load( disp_tab_frame, instrument));
01068 }
01069
01070 check( pre_sci = xsh_pre_load( sci_frame, instrument));
01071 check( rec_list = xsh_rec_list_create( instrument));
01072
01073 check( xsh_baryvel(pre_sci->data_header, &barycor,&helicor));
01074 cpl_propertylist_append_double(pre_sci->data_header,XSH_QC_VRAD_BARYCOR,barycor);
01075 cpl_propertylist_set_comment(pre_sci->data_header,XSH_QC_VRAD_BARYCOR,
01076 XSH_QC_VRAD_BARYCOR_C);
01077 cpl_propertylist_append_double(pre_sci->data_header,XSH_QC_VRAD_HELICOR,helicor);
01078 cpl_propertylist_set_comment(pre_sci->data_header,XSH_QC_VRAD_HELICOR,
01079 XSH_QC_VRAD_HELICOR_C);
01080
01081 if ( model_frame != NULL) {
01082 solution_type = XSH_RECTIFY_TYPE_MODEL;
01083 check(xsh_model_temperature_update_frame(&model_frame,sci_frame,
01084 instrument,&found_line));
01085 check( xsh_model_config_load_best( model_frame, &config_model));
01086 }
01087 else if ( wavesol_frame != NULL ) {
01088 solution_type = XSH_RECTIFY_TYPE_POLY;
01089 check( wavesol = xsh_wavesol_load( wavesol_frame, instrument));
01090 }
01091 else {
01092 xsh_error_msg(
01093 "Undefined solution type (POLY or MODEL). See your input sof");
01094 }
01095
01096 xsh_msg("===== Solution type %s", solution_type_name[solution_type]);
01097
01098 check( spec_list = xsh_spectralformat_list_load( spectralformat_frame,
01099 instrument));
01100
01101
01102 xsh_msg_dbg_high( "Kernel: %s, Radius: %lf", rectify_par->rectif_kernel,
01103 rectify_par->rectif_radius);
01104 xsh_msg_dbg_high( "Slit Binning: %f, Lambda Binning: %f",
01105 rectify_par->rectif_bin_space,
01106 rectify_par->rectif_bin_lambda);
01107
01108
01109 adjust_lambdas( spec_list, rectify_par);
01110
01111
01112 rec_list->nslit = nslit;
01113 rec_list->slit_min = slit_min;
01114 slit_max = slit_min+rectify_par->rectif_bin_space*nslit;
01115 rec_list->slit_max = slit_max;
01116
01117 if (min_index >= 0){
01118 rec_min_index = min_index;
01119 }
01120 else{
01121 rec_min_index = 0;
01122 }
01123 if ( max_index < rec_list->size){
01124 rec_max_index = max_index;
01125 }
01126 else{
01127 rec_max_index = rec_list->size-1;
01128 }
01129
01130 for( i = rec_min_index; i <= rec_max_index; i++ ) {
01131 double lambda_min, lambda_max ;
01132 double n;
01133
01134 order = spec_list->list[i].absorder ;
01135 rec_list->list[i].nslit = nslit ;
01136 lambda_min = spec_list->list[i].lambda_min ;
01137 lambda_max = spec_list->list[i].lambda_max ;
01138
01139
01140 n = (lambda_max-lambda_min)/rectify_par->rectif_bin_lambda+1.0;
01141 nlambda = (int)xsh_round_double(n);
01142 assure(nlambda>0,CPL_ERROR_ILLEGAL_INPUT,
01143 "Number of wavelength sampling points is %d. Must be > 0. "
01144 "You may have to decrease rectify-bin-lambda param value.",
01145 nlambda);
01146
01147 assure(nslit>0,CPL_ERROR_ILLEGAL_INPUT,
01148 "Number of spatial sampling points is %d. Must be > 0. "
01149 "You may have to decrease rectify-bin-slit param value.",
01150 nslit);
01151
01152 rec_list->list[i].nlambda = nlambda ;
01153
01154
01155 check( xsh_rec_list_set_data_size( rec_list, i, order, nlambda, nslit));
01156
01157
01158
01159
01160
01161 xsh_msg_dbg_medium( "Order %d, Nslit: %d, Nlambda: %d", order, nslit, nlambda ) ;
01162 xsh_msg_dbg_medium( " Lambda (%f,%f) Slit(%f,%f)",
01163 lambda_min, lambda_max , slit_min, slit_max);
01164
01165
01166
01167
01168
01169
01170 check( fill_rectified( pre_sci, rec_list, i, wavesol,
01171 &config_model, instrument, disp_list,
01172 slit_min, slit_max, lambda_min, 0, 0, rectify_par,
01173 slit_shift, slitshift_tab));
01174 }
01175
01176 rec_list->slit_min = rec_list->list[rec_min_index].slit[0];
01177 rec_list->slit_max = rec_list->list[rec_min_index].slit[nslit-1];
01178
01179 xsh_msg_dbg_medium( "Saving Rectified Frame '%s'", res_name);
01180
01181 sprintf( tag_drl ,"%s_DRL", tag);
01182 sprintf( res_name_drl ,"DRL_%s", res_name);
01183
01184
01185 check( xsh_rec_list_update_header( rec_list, pre_sci, rectify_par, tag_drl));
01186
01187 if ( slitshift_tab != NULL){
01188 xsh_frame_set_shiftifu_ref( rec_list->header, slitshift_tab);
01189 }
01190
01191 check( res_frame = xsh_rec_list_save( rec_list, res_name_drl, tag_drl, CPL_TRUE));
01192 xsh_add_temporary_file(res_name_drl);
01193
01194 if ( res_frame_ext != NULL){
01195
01196 check( *res_frame_ext = xsh_rec_list_save2(rec_list,res_name,tag));
01197 sprintf( tag_drl ,"%s_TAB", tag);
01198 sprintf( res_name_drl ,"TAB_%s", res_name);
01199 check( *res_frame_tab = xsh_rec_list_save_table(rec_list,res_name_drl,tag_drl,
01200 CPL_TRUE));
01201
01202 xsh_add_temporary_file(res_name_drl);
01203 }
01204
01205 cleanup :
01206 xsh_dispersol_list_free( &disp_list);
01207 xsh_rec_list_free( &rec_list);
01208 xsh_wavesol_free( &wavesol);
01209 xsh_spectralformat_list_free( &spec_list);
01210 xsh_pre_free( &pre_sci);
01211 return res_frame;
01212 }
01213
01214
01215 static void xsh_get_shift_ref( cpl_frameset *set,
01216 double *down, double *cen, double *up)
01217 {
01218 cpl_frame *offsetdown_frame = NULL;
01219 cpl_frame *offsetcen_frame = NULL;
01220 cpl_frame *offsetup_frame = NULL;
01221 const char *offsetdown_name = NULL;
01222 const char *offsetcen_name = NULL;
01223 const char *offsetup_name = NULL;
01224 cpl_propertylist *offsetdown_list = NULL;
01225 cpl_propertylist *offsetcen_list = NULL;
01226 cpl_propertylist *offsetup_list = NULL;
01227
01228 XSH_ASSURE_NOT_NULL( down);
01229 XSH_ASSURE_NOT_NULL( cen);
01230 XSH_ASSURE_NOT_NULL( up);
01231
01232 check( offsetdown_frame = cpl_frameset_get_frame( set, 0));
01233 check( offsetcen_frame = cpl_frameset_get_frame( set, 1));
01234 check( offsetup_frame = cpl_frameset_get_frame( set, 2));
01235 check( offsetdown_name = cpl_frame_get_filename( offsetdown_frame));
01236 check( offsetcen_name = cpl_frame_get_filename( offsetcen_frame));
01237 check( offsetup_name = cpl_frame_get_filename( offsetup_frame));
01238 check( offsetdown_list = cpl_propertylist_load( offsetdown_name, 0));
01239 check( offsetcen_list = cpl_propertylist_load( offsetcen_name, 0));
01240 check( offsetup_list = cpl_propertylist_load( offsetup_name, 0));
01241
01242 check( *down = xsh_pfits_get_shiftifu_slitref( offsetdown_list));
01243 check( *cen = xsh_pfits_get_shiftifu_slitref( offsetcen_list));
01244 check( *up = xsh_pfits_get_shiftifu_slitref( offsetup_list));
01245
01246 cleanup:
01247 xsh_free_propertylist( &offsetdown_list);
01248 xsh_free_propertylist( &offsetcen_list);
01249 xsh_free_propertylist( &offsetup_list);
01250 return;
01251 }
01252
01253
01254
01255
01256 static void xsh_frame_set_shiftifu_ref( cpl_propertylist *header,
01257 cpl_frame *shift_frame)
01258 {
01259 cpl_propertylist *shift_header = NULL;
01260 const char *shift_name = NULL;
01261 double waveref, slitref;
01262
01263 XSH_ASSURE_NOT_NULL( header);
01264 XSH_ASSURE_NOT_NULL( shift_frame);
01265
01266 check( shift_name = cpl_frame_get_filename( shift_frame));
01267 check( shift_header = cpl_propertylist_load( shift_name, 0));
01268
01269 check( waveref = xsh_pfits_get_shiftifu_lambdaref( shift_header));
01270 check( slitref = xsh_pfits_get_shiftifu_slitref( shift_header));
01271
01272 check( xsh_pfits_set_shiftifu_lambdaref( header, waveref));
01273 check( xsh_pfits_set_shiftifu_slitref( header, slitref));
01274
01275 cleanup:
01276 xsh_free_propertylist( &shift_header);
01277 return;
01278 }
01279
01280
01281
01296 void xsh_compute_slitlet_limits( cpl_frameset *shift_set, double sdown,
01297 double sldown, double slup, double sup, double slit_bin,
01298 double *slitmin_tab, int *nslit_tab, double *slitcen_tab)
01299 {
01300 double offset_down, offset_cen, offset_up;
01301 double cen_slitlet_down_size;
01302 double cen_slitlet_up_size;
01303 double down_slitlet_down_size;
01304 double down_slitlet_up_size;
01305 double up_slitlet_down_size;
01306 double up_slitlet_up_size;
01307 double slitlet_up_size;
01308 double slitlet_down_size;
01309 double cen_ref_down, cen_ref_up;
01310 double cen_pixpos = 0.0;
01311 int ref_slit_size;
01312 int down_nslit;
01313 int up_nslit;
01314
01315 XSH_ASSURE_NOT_NULL( shift_set);
01316 XSH_ASSURE_NOT_NULL( slitmin_tab);
01317 XSH_ASSURE_NOT_NULL( nslit_tab);
01318 XSH_ASSURE_NOT_NULL( slitcen_tab);
01319
01320 check( xsh_get_shift_ref( shift_set, &offset_down, &offset_cen,
01321 &offset_up));
01322
01323
01324 xsh_msg( "Shift reference: down %f arcsec, center %f arcsec, up %f arcsec",
01325 offset_down, offset_cen, offset_up);
01326
01327 slitcen_tab[0] = offset_down;
01328 slitcen_tab[1] = offset_cen;
01329 slitcen_tab[2] =offset_up;
01330
01331 down_slitlet_down_size = offset_down-sdown;
01332 down_slitlet_up_size = sldown-offset_down;
01333
01334 xsh_msg_dbg_medium("In down slitlet [%f,%f] size lo %f up %f", sdown, sldown,
01335 down_slitlet_down_size, down_slitlet_up_size);
01336
01337 cen_slitlet_down_size = offset_cen-sldown;
01338 cen_slitlet_up_size = slup-offset_cen;
01339
01340 xsh_msg_dbg_medium("In cen slitlet [%f,%f] size lo %f up %f", sldown, slup,
01341 cen_slitlet_down_size, cen_slitlet_up_size);
01342
01343 up_slitlet_down_size = offset_up-slup;
01344 up_slitlet_up_size = sup-offset_up;
01345
01346 xsh_msg_dbg_medium("In up slitlet [%f,%f] size lo %f up %f", slup, sup,
01347 up_slitlet_down_size, up_slitlet_up_size);
01348
01349
01350 if ( cen_slitlet_down_size < up_slitlet_up_size){
01351 slitlet_down_size = cen_slitlet_down_size;
01352 }
01353 else{
01354 slitlet_down_size = up_slitlet_up_size;
01355 }
01356 if ( slitlet_down_size > down_slitlet_up_size){
01357 slitlet_down_size = down_slitlet_up_size;
01358 }
01359
01360 if ( cen_slitlet_up_size < up_slitlet_down_size){
01361 slitlet_up_size = cen_slitlet_up_size;
01362 }
01363 else{
01364 slitlet_up_size = up_slitlet_down_size;
01365 }
01366 if ( slitlet_up_size > down_slitlet_down_size){
01367 slitlet_up_size = down_slitlet_down_size;
01368 }
01369
01370 xsh_msg_dbg_medium( "Slitlet size DOWN %f UP %f", slitlet_down_size, slitlet_up_size);
01371
01372
01373 cen_ref_down = offset_cen-slitlet_down_size;
01374 cen_ref_up = offset_cen+slitlet_up_size;
01375 if (cen_ref_down > 0){
01376 down_nslit = ceil( cen_ref_down/slit_bin);
01377 }
01378 else{
01379 down_nslit = floor( cen_ref_down/slit_bin);
01380 }
01381 if ( cen_ref_up > 0){
01382 up_nslit = ceil( cen_ref_up/slit_bin);
01383 }
01384 else{
01385 up_nslit = floor( cen_ref_up/slit_bin);
01386 }
01387
01388 xsh_msg( "Adjust central reference slitlet [%f %f] with bin %f arcsec: [%f %f]",
01389 cen_ref_down, cen_ref_up, slit_bin, down_nslit*slit_bin, up_nslit*slit_bin);
01390
01391 cen_pixpos = (offset_cen-down_nslit*slit_bin)/slit_bin;
01392 ref_slit_size = up_nslit-down_nslit+1;
01393 xsh_msg( "Center position in pixel %f (Total %d pix)", cen_pixpos, ref_slit_size);
01394 slitmin_tab[1] = down_nslit*slit_bin;
01395 nslit_tab[1] = ref_slit_size;
01396
01397 slitmin_tab[0] = offset_down-(ref_slit_size-1-cen_pixpos)*slit_bin;
01398 nslit_tab[0] = ref_slit_size;
01399
01400 slitmin_tab[2] = offset_up-(ref_slit_size-1-cen_pixpos)*slit_bin;
01401 nslit_tab[2] = ref_slit_size;
01402
01403 xsh_msg("Prepare the cube bin %f arcsec", slit_bin);
01404 xsh_msg("DOWN [%f, %f]", slitmin_tab[0], slitmin_tab[0]+nslit_tab[0]*slit_bin);
01405 xsh_msg("CEN [%f, %f]", slitmin_tab[1], slitmin_tab[1]+nslit_tab[1]*slit_bin);
01406 xsh_msg("UP [%f, %f]", slitmin_tab[2], slitmin_tab[2]+nslit_tab[2]*slit_bin);
01407
01408 cleanup:
01409 return;
01410 }
01411
01412
01413
01436
01437 cpl_frameset *
01438 xsh_rectify_orders_ifu(cpl_frame *sci_frame,
01439 xsh_order_list *orderlist,
01440 cpl_frameset *wavesol_frameset,
01441 cpl_frameset *shift_frameset,
01442 cpl_frame *model_frame,
01443 xsh_instrument *instrument,
01444 xsh_rectify_param *rectify_par,
01445 cpl_frame *spectralformat_frame,
01446 cpl_frame * slitmap_frame,
01447 cpl_frameset ** res_frameset_ext,
01448 cpl_frameset ** res_frameset_tab,
01449 int min_index,
01450 int max_index,
01451 const char* rec_prefix)
01452 {
01453 cpl_frameset *res_frameset = NULL ;
01454
01455 cpl_frame *wavesolup_frame = NULL;
01456 cpl_frame *wavesolcen_frame = NULL;
01457 cpl_frame *wavesoldown_frame = NULL;
01458 cpl_frame *shiftup_frame = NULL;
01459 cpl_frame *shiftcen_frame = NULL;
01460 cpl_frame *shiftdown_frame = NULL;
01461
01462 int slitlet=0;
01463 double sdown=0, sldown=0, slup=0, sup=0;
01464
01465 double slitlet_down_u=0;
01466
01467 double slitlet_cen_l=0, slitlet_cen_u=0;
01468 double slitlet_cen_u_bin=0;
01469
01470 double down_offset=0.0;
01471 int nslit=0;
01472 double bin_space;
01473
01474 int nslit_tab[3];
01475 double slitmin_tab[3];
01476 double slitcen_tab[3];
01477 int cut_edges = 0;
01478
01479 XSH_ASSURE_NOT_NULL( sci_frame);
01480 XSH_ASSURE_NOT_NULL( orderlist);
01481 XSH_ASSURE_NOT_NULL( rectify_par);
01482 XSH_ASSURE_NOT_NULL( instrument);
01483 XSH_ASSURE_NOT_NULL( spectralformat_frame);
01484
01485 bin_space = rectify_par->rectif_bin_space;
01486
01487
01488
01489
01490 if ( wavesol_frameset != NULL){
01491 check( wavesoldown_frame = cpl_frameset_get_frame( wavesol_frameset, 0));
01492 check( wavesolcen_frame = cpl_frameset_get_frame( wavesol_frameset, 1));
01493 check( wavesolup_frame = cpl_frameset_get_frame( wavesol_frameset, 2));
01494 }
01495
01496 if ( shift_frameset != NULL){
01497 check( shiftdown_frame = cpl_frameset_get_frame( shift_frameset, 0));
01498 check( shiftcen_frame = cpl_frameset_get_frame( shift_frameset, 1));
01499 check( shiftup_frame = cpl_frameset_get_frame( shift_frameset, 2));
01500 }
01501
01502
01503 check( res_frameset = cpl_frameset_new());
01504
01505 check( xsh_get_slit_edges( slitmap_frame, &sdown,
01506 &sup, &sldown, &slup, instrument));
01507
01508 if ( shift_frameset != NULL){
01509 check( xsh_compute_slitlet_limits( shift_frameset, sdown,
01510 sldown, slup, sup, bin_space,
01511 slitmin_tab, nslit_tab, slitcen_tab));
01512 }
01513 else{
01514 slitlet_cen_l = sldown;
01515 slitlet_cen_u = slup;
01516
01517
01518 slitlet_down_u = slitlet_cen_l;
01519
01520
01521
01522 slitmin_tab[1] = slitlet_cen_l;
01523 nslit_tab[1] = ceil((slitlet_cen_u-slitlet_cen_l)/rectify_par->rectif_bin_space);
01524 slitlet_cen_u_bin = slitmin_tab[1]+nslit_tab[1]*rectify_par->rectif_bin_space;
01525
01526
01527 nslit_tab[0] = nslit_tab[1];
01528 slitmin_tab[0] = slitlet_down_u-down_offset-
01529 nslit_tab[0]*rectify_par->rectif_bin_space;
01530
01531
01532 slitmin_tab[2] = slitlet_cen_u_bin;
01533 nslit_tab[2] = nslit_tab[1];
01534 }
01535
01536 for ( slitlet = LOWER_IFU_SLITLET ; slitlet <= UPPER_IFU_SLITLET ;
01537 slitlet++ ) {
01538
01539 cpl_frame *wavesol_frame = NULL;
01540 cpl_frame *shift_frame = NULL;
01541 cpl_frame *res_frame = NULL;
01542 cpl_frame *resext_frame = NULL;
01543 cpl_frame *restab_frame = NULL;
01544 double slitlet_slit_min = 0.0;
01545 char tag[256];
01546 char res_name[256];
01547 double rec_shift=0.0;
01548 double rec_min=0.0;
01549 const char *slitlet_name = NULL;
01550
01551 switch( slitlet ) {
01552 case LOWER_IFU_SLITLET:
01553
01554 slitlet_name = "DOWN";
01555 nslit = nslit_tab[0];
01556 slitlet_slit_min = slitmin_tab[0];
01557 wavesol_frame = wavesoldown_frame;
01558 shift_frame = shiftdown_frame;
01559 sprintf(tag,"%s_%s",rec_prefix,
01560 XSH_GET_TAG_FROM_ARM(XSH_ORDER2D_DOWN_IFU,instrument));
01561 sprintf(res_name,"%s.fits",tag);
01562 break ;
01563
01564 case CENTER_IFU_SLITLET:
01565 slitlet_name = "CEN";
01566 slitlet_slit_min = slitmin_tab[1];
01567 nslit = nslit_tab[1];
01568 wavesol_frame = wavesolcen_frame;
01569 shift_frame = shiftcen_frame;
01570 sprintf(tag,"%s_%s",rec_prefix,
01571 XSH_GET_TAG_FROM_ARM(XSH_ORDER2D_CEN_IFU,instrument));
01572 sprintf(res_name,"%s.fits",tag);
01573 break ;
01574
01575 case UPPER_IFU_SLITLET:
01576 slitlet_name = "UP";
01577 slitlet_slit_min = slitmin_tab[2];
01578 nslit = nslit_tab[2];
01579
01580 wavesol_frame = wavesolup_frame;
01581 shift_frame = shiftup_frame;
01582 sprintf(tag,"%s_%s",rec_prefix,
01583 XSH_GET_TAG_FROM_ARM(XSH_ORDER2D_UP_IFU,instrument));
01584 sprintf(res_name,"%s.fits",tag);
01585 break ;
01586 }
01587
01588 rec_min = slitlet_slit_min;
01589 rec_shift = 0;
01590
01591 xsh_msg("Cut edges with %d pix", cut_edges);
01592 rec_min += cut_edges*rectify_par->rectif_bin_space;
01593 nslit -= cut_edges*2;
01594
01595 XSH_CMP_INT( nslit, >, 0, "Check size in slit",);
01596
01597
01598 xsh_msg( "%s [%f %f] in %d pix of %f arcsec" ,slitlet_name,
01599 slitlet_slit_min,
01600 slitlet_slit_min+nslit*rectify_par->rectif_bin_space,
01601 nslit, rectify_par->rectif_bin_space);
01602
01603 check( res_frame = xsh_rectify_orders( sci_frame, orderlist,
01604 wavesol_frame, model_frame, instrument, rectify_par,
01605 spectralformat_frame, NULL, res_name, tag, &resext_frame, &restab_frame,
01606 min_index, max_index, rec_min, nslit, rec_shift,shift_frame));
01607
01608 check( cpl_frameset_insert( res_frameset, res_frame));
01609
01610 if(res_frameset_ext !=NULL && res_frameset_tab !=NULL) {
01611 check( cpl_frameset_insert(*res_frameset_ext, resext_frame));
01612 check( cpl_frameset_insert(*res_frameset_tab, restab_frame));
01613 }
01614 }
01615
01616 cleanup:
01617 return res_frameset ;
01618 }
01619
01620
01621
01622
01630
01631 static double
01632 compute_shift_with_localization( cpl_frame *loc_frame,
01633 cpl_frame *loc0_frame)
01634 {
01635 double shift_a=0, shift_b=0, shift=0;
01636 xsh_localization *loc = NULL, *loc0 = NULL;
01637
01638 XSH_ASSURE_NOT_NULL( loc_frame);
01639 XSH_ASSURE_NOT_NULL( loc0_frame);
01640
01641 check( loc = xsh_localization_load( loc_frame));
01642 check( loc0 = xsh_localization_load( loc0_frame));
01643
01644
01645 check( shift_a = cpl_polynomial_eval_1d( loc0->cenpoly, 0., NULL));
01646 check( shift_b = cpl_polynomial_eval_1d( loc->cenpoly, 0., NULL));
01647
01648 xsh_msg_dbg_medium("Shift A %f B %f", shift_a, shift_b)
01649 shift = shift_b-shift_a;
01650
01651 xsh_msg( "Shift (localization) = %lf", shift);
01652
01653 cleanup:
01654 xsh_localization_free( &loc);
01655 xsh_localization_free( &loc0);
01656 return shift;
01657 }
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809 static double
01810 compute_shift_with_kw( cpl_propertylist *header,
01811 xsh_rectify_param *rectify_par,
01812 double **ref_ra,
01813 double **ref_dec,
01814 int flag)
01815 {
01816 double ref_ra_cumoff, ref_dec_cumoff;
01817 double ra_cumoff, dec_cumoff;
01818 double ra_reloff, dec_reloff, ra_off, dec_off;
01819 double posang=0;
01820
01821 double shift_arcsec=0;
01822
01823
01824
01825 xsh_msg_dbg_high( "==> compute_shift_with_kw" ) ;
01826 XSH_ASSURE_NOT_NULL( header);
01827 XSH_ASSURE_NOT_NULL( rectify_par);
01828
01829 check( posang = xsh_pfits_get_posang( header));
01830 posang = posang/180.0* M_PI;
01831
01832 if ( *ref_ra != NULL){
01833 ref_ra_cumoff = **ref_ra;
01834 }
01835 else{
01836 check( ref_ra_cumoff = xsh_pfits_get_ra_cumoffset( header));
01837 XSH_MALLOC( *ref_ra, double, 1);
01838 **ref_ra = ref_ra_cumoff;
01839 }
01840 if ( *ref_dec != NULL){
01841 ref_dec_cumoff = **ref_dec;
01842 }
01843 else{
01844 check( ref_dec_cumoff = xsh_pfits_get_dec_cumoffset( header));
01845 XSH_MALLOC( *ref_dec, double, 1);
01846 **ref_dec = ref_dec_cumoff;
01847 }
01848
01849 if ( flag == 0){
01850 check( ra_cumoff = xsh_pfits_get_ra_cumoffset( header));
01851 check( dec_cumoff = xsh_pfits_get_dec_cumoffset( header));
01852 }
01853 else{
01854 check( ra_cumoff = xsh_pfits_get_b_ra_cumoffset( header));
01855 check( dec_cumoff = xsh_pfits_get_b_dec_cumoffset( header));
01856 }
01857
01858 check( ra_reloff = xsh_pfits_get_b_ra_reloffset( header));
01859 check( dec_reloff = xsh_pfits_get_b_dec_reloffset( header));
01860
01861
01862 xsh_msg( "POSANG %f (rad) REF CUM_(RA DEC) : %f %f ", posang, ref_ra_cumoff,
01863 ref_dec_cumoff);
01864 xsh_msg( "OBJ CUM_(RA DEC) : %f %f ", ra_cumoff, dec_cumoff);
01865 xsh_msg( "REL_(RA DEC) : %f %f", ra_reloff, dec_reloff);
01866
01867 ra_off = ra_cumoff-ref_ra_cumoff;
01868 dec_off = dec_cumoff-ref_dec_cumoff;
01869
01870 xsh_msg( "COMPUTE OFF_(RA DEC) : %f %f", ra_off, dec_off);
01871
01872 shift_arcsec = cos(-posang)*dec_off+sin(-posang)*ra_off;
01873
01874 xsh_msg( "COMPUTE shift in arcsec %f :", shift_arcsec);
01875
01876 cleanup:
01877 return shift_arcsec;
01878 }
01879
01880
01881
01896 cpl_frame*
01897 shift_with_kw( cpl_frame *rec_frame,
01898 xsh_instrument *instrument,
01899 xsh_rectify_param *rectify_par,
01900 const char *fname,
01901 cpl_frame** res_frame_ext,
01902 double **ref_ra,
01903 double **ref_dec,
01904 int flag)
01905 {
01906 cpl_frame *result = NULL ;
01907 int shift_pix;
01908 double bin_space, shift_arcsec;
01909 const char *filename = NULL;
01910 cpl_propertylist* header = NULL;
01911
01912
01913 XSH_ASSURE_NOT_NULL( rec_frame);
01914 XSH_ASSURE_NOT_NULL( instrument);
01915 XSH_ASSURE_NOT_NULL( fname);
01916 XSH_ASSURE_NOT_NULL( res_frame_ext);
01917 XSH_ASSURE_NOT_NULL( ref_ra);
01918 XSH_ASSURE_NOT_NULL( ref_dec);
01919
01920 check( filename = cpl_frame_get_filename( rec_frame));
01921 check( header = cpl_propertylist_load( filename, 0));
01922
01923 check( bin_space = xsh_pfits_get_rectify_bin_space( header));
01924
01925 check( shift_arcsec = compute_shift_with_kw( header,
01926 rectify_par, ref_ra, ref_dec, flag));
01927
01928
01929 shift_pix = xsh_round_double(shift_arcsec/bin_space);
01930
01931 shift_arcsec = shift_pix*bin_space;
01932
01933 xsh_msg( "SHIFT A-->B : %f in arcsec", shift_arcsec);
01934
01935 check( result = xsh_shift( rec_frame, instrument, fname, shift_arcsec,
01936 res_frame_ext));
01937
01938 cleanup:
01939 if ( cpl_error_get_code() !=CPL_ERROR_NONE){
01940 xsh_free_frame( &result);
01941 }
01942 xsh_free_propertylist( &header);
01943 return result ;
01944 }
01945
01946
01947
01948
01949 static cpl_frame*
01950 xsh_shift( cpl_frame *rec_frame,
01951 xsh_instrument *instrument,
01952 const char *fname,
01953 double slit_shift,
01954 cpl_frame** res_frame_ext)
01955 {
01956 xsh_rec_list *rec_list = NULL ;
01957 cpl_frame *result = NULL ;
01958 int nb_orders, order = 0 ;
01959 float *slit = NULL ;
01960
01961 char* fname_drl=NULL;
01962 char* tag_drl=NULL;
01963 char* tag=NULL;
01964 int nslit=0;
01965
01966 XSH_ASSURE_NOT_NULL( rec_frame);
01967 XSH_ASSURE_NOT_NULL( instrument);
01968 XSH_ASSURE_NOT_NULL( fname);
01969 XSH_ASSURE_NOT_NULL( res_frame_ext);
01970
01971 check( rec_list = xsh_rec_list_load( rec_frame, instrument));
01972
01973 nb_orders = rec_list->size ;
01974 check( nslit = xsh_rec_list_get_nslit( rec_list, 0));
01975
01976
01977 for( order = 0 ; order < nb_orders ; order++ ) {
01978 int ns;
01979
01980 check( slit = xsh_rec_list_get_slit( rec_list, order));
01981 for( ns = 0 ; ns < nslit ; ns++ ) {
01982 slit[ns]+=slit_shift;
01983 }
01984 }
01985 rec_list->slit_min = slit[0];
01986 rec_list->slit_max = slit[nslit-1];
01987
01988 check( xsh_pfits_set_rectify_space_min( rec_list->header,
01989 rec_list->slit_min));
01990 check( xsh_pfits_set_rectify_space_max( rec_list->header,
01991 rec_list->slit_max));
01992
01993
01994 tag= xsh_stringcat_any( cpl_frame_get_tag( rec_frame ), "", NULL ) ;
01995 tag_drl = xsh_stringcat_any( cpl_frame_get_tag( rec_frame ), "_DRL", NULL ) ;
01996 fname_drl = xsh_stringcat_any( "DRL_", fname, NULL);
01997
01998 check( *res_frame_ext=xsh_rec_list_save2( rec_list, fname,tag)) ;
01999 check( result = xsh_rec_list_save( rec_list, fname_drl,
02000 tag_drl, CPL_TRUE));
02001 xsh_add_temporary_file(fname_drl);
02002
02003 cleanup:
02004 if ( cpl_error_get_code() !=CPL_ERROR_NONE){
02005 xsh_free_frame( &result);
02006 }
02007 XSH_FREE( fname_drl);
02008 XSH_FREE( tag_drl);
02009 XSH_FREE( tag);
02010 xsh_rec_list_free( &rec_list);
02011 return result ;
02012 }
02013
02030 cpl_frame * xsh_shift_rectified( cpl_frame * rec_frame,
02031 cpl_frame * loc_frame,
02032 cpl_frame * loc0_frame,
02033 const char * file_name,
02034 xsh_combine_nod_param * combine_nod_param,
02035 xsh_rectify_param * rectif_par,
02036 xsh_instrument * instrument,
02037 cpl_frame** res_frame_ext )
02038 {
02039 cpl_frame * result = NULL ;
02040 double *ra = NULL, *dec = NULL;
02041
02042 xsh_msg( "===> xsh_shift_rectified" ) ;
02043
02044 XSH_ASSURE_NOT_NULL( combine_nod_param ) ;
02045 XSH_ASSURE_NOT_NULL( rec_frame ) ;
02046
02047 check( result = shift_with_kw( rec_frame, instrument,
02048 rectif_par, file_name, res_frame_ext, &ra, &dec, 1));
02049
02050 cleanup:
02051 return result ;
02052 }
02053
02054