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
00043
00046
00047
00048
00049 #include <math.h>
00050 #include <xsh_drl.h>
00051 #include <xsh_data_pre.h>
00052 #include <xsh_dfs.h>
00053 #include <xsh_pfits.h>
00054 #include <xsh_error.h>
00055 #include <xsh_msg.h>
00056 #include <xsh_utils_wrappers.h>
00057 #include <xsh_badpixelmap.h>
00058 #include <xsh_data_order.h>
00059 #include <xsh_data_the_map.h>
00060 #include <xsh_data_arclist.h>
00061 #include <xsh_data_wavesol.h>
00062 #include <xsh_data_wavemap.h>
00063 #include <xsh_data_resid_tab.h>
00064 #include <xsh_data_linetilt.h>
00065 #include <xsh_utils.h>
00066 #include <xsh_ifu_defs.h>
00067 #include <xsh_model_io.h>
00068 #include <xsh_model_kernel.h>
00069 #include <xsh_model_utils.h>
00070 #include <xsh_data_spectralformat.h>
00071 #include <xsh_data_shift_tab.h>
00072 #include <xsh_data_dispersol.h>
00073
00074 #define XSH_SPECRES_CLIP_KAPPA 3.
00075 #define XSH_SPECRES_CLIP_NITER 2
00076 #define XSH_SPECRES_CLIP_FRAC 0.5
00077
00078
00079
00080
00081
00082 static const char* fwhm_debug_mode = NULL;
00083
00084 enum {
00085 LAMBDA_FOUND, LAMBDA_TOO_SMALL, LAMBDA_NOT_FOUND
00086 } ;
00087
00088 enum {
00089 FIND_TILT_UNKNOW_ORDER = 1, FIND_TILT_BAD_EDGES, FIND_TILT_BAD_CENTER,
00090 FIND_TILT_CLIPPED, FIND_TILT_BAD_FIT
00091 } ;
00092
00093 typedef struct {
00094 double xpos ;
00095 double ypos ;
00096 double fwhm ;
00097 double area;
00098 int good ;
00099 } CENTROIDS ;
00100
00101 static int detect_centroid( xsh_pre * pre,
00102 float lambda, int ordnum, double xpix,
00103 double ypix,
00104 xsh_follow_arclines_param * follow_param,
00105 xsh_instrument * instrument, int is_center,
00106 XSH_GAUSSIAN_FIT * fit_res );
00107
00108
00109
00110
00111
00128
00129 static int
00130 detect_centroid( xsh_pre * pre,
00131 float lambda,
00132 int ordnum,
00133 double xpix,
00134 double y,
00135 xsh_follow_arclines_param * follow_param,
00136 xsh_instrument * instrument,
00137 int is_center,
00138 XSH_GAUSSIAN_FIT * fit_res )
00139 {
00140 cpl_vector * pixpos = NULL ;
00141 cpl_vector * pixval = NULL ;
00142 int first, last, i, nelem, ny, ix ;
00143 double dy, ypix;
00144 int ret = 1 ;
00145
00146 if ( xpix <= 0 || xpix > pre->nx || y <= 0 || y > pre->ny )
00147 return ret ;
00148
00149 XSH_ASSURE_NOT_ILLEGAL( xpix > 0 && xpix <= pre->nx &&
00150 y > 0 && y <= pre->ny );
00151
00152 ix = xsh_round_double(xpix);
00153 ypix = xsh_round_double( y);
00154
00155 first = ypix - follow_param->range;
00156
00157 if ( first < 0 ) {
00158 xsh_msg_dbg_high( "%lf - %d : Y pixel < 0 (%d)", lambda, ordnum, first ) ;
00159 first = 1 ;
00160 }
00161 last = ypix + follow_param->range ;
00162 if( last > pre->ny ) {
00163 xsh_msg_dbg_low( "Y = %d too high, ignore", last ) ;
00164 return ret ;
00165 }
00166
00167 dy = ypix - follow_param->range ;
00168 nelem = (follow_param->range*2) + 1 ;
00169
00170 check( pixpos = cpl_vector_new( nelem ) ) ;
00171 check( pixval = cpl_vector_new( nelem ) ) ;
00172
00173 for( i = 0, ny = first ; ny <= last ; ny++, i++, dy += 1. ) {
00174 int rej ;
00175 double value ;
00176
00177 cpl_error_reset() ;
00178 value = cpl_image_get( pre->data, ix, ny, &rej ) ;
00179 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
00180 xsh_msg_dbg_high( " *** X,Y out of range %d,%d", ix, ny ) ;
00181 cpl_error_reset() ;
00182 continue ;
00183 }
00184 cpl_vector_set( pixval, i, value ) ;
00185 cpl_vector_set( pixpos, i, dy ) ;
00186 }
00187
00188 cpl_error_reset() ;
00189 xsh_vector_fit_gaussian( pixpos, pixval, fit_res ) ;
00190 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
00191 xsh_msg_dbg_high("Failed to fit Y centroid for x %d y [%d, %d], wavelength %f",
00192 ix, first, last, lambda);
00193 cpl_error_reset() ;
00194 }
00195 else {
00196 if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_HIGH){
00197 FILE *debug_file = NULL;
00198 char name[256];
00199 int idebug = 0;
00200
00201
00202 sprintf( name, "profil_%d_%f_%f.dat", ordnum, lambda, xpix);
00203
00204 debug_file = fopen( name, "w");
00205 fprintf( debug_file, "# ypos yflux yfit\n");
00206 for( idebug=0; idebug< nelem; idebug++){
00207 double gauss;
00208 double x;
00209
00210 x = cpl_vector_get( pixpos, idebug);
00211 gauss = fit_res->area / sqrt(2 *M_PI*fit_res->sigma*fit_res->sigma)*
00212 exp( -(x-fit_res->peakpos)*(x-fit_res->peakpos)/(2*fit_res->sigma*fit_res->sigma)) + fit_res->offset;
00213
00214 fprintf( debug_file, "%f %f %f\n", x, cpl_vector_get( pixval, idebug), gauss);
00215 }
00216 fclose( debug_file);
00217 }
00218 xsh_msg_dbg_medium( "For x %d, y [%d, %d] centroid fit in Y = %lf",
00219 ix, first, last, fit_res->peakpos);
00220 ret = 0;
00221 }
00222
00223 cleanup:
00224 xsh_free_vector( &pixpos ) ;
00225 xsh_free_vector( &pixval ) ;
00226 return ret ;
00227 }
00228
00229 static cpl_polynomial *
00230 get_slit_ifu_lo_poly( xsh_order * porder,int ifu_flag )
00231 {
00232 switch ( ifu_flag ) {
00233 case CENTER_SLIT:
00234 return porder->edglopoly ;
00235 case UPPER_IFU_SLITLET:
00236 return porder->edglopoly ;
00237 case CENTER_IFU_SLITLET:
00238 return porder->sliclopoly ;
00239 case LOWER_IFU_SLITLET:
00240 return porder->slicuppoly ;
00241 default:
00242 return NULL ;
00243 }
00244 }
00245
00246 static cpl_polynomial *
00247 get_slit_ifu_up_poly( xsh_order * porder,int ifu_flag )
00248 {
00249 switch ( ifu_flag ) {
00250 case CENTER_SLIT:
00251 return porder->edguppoly ;
00252 case UPPER_IFU_SLITLET:
00253 return porder->sliclopoly ;
00254 case CENTER_IFU_SLITLET:
00255 return porder->slicuppoly ;
00256 case LOWER_IFU_SLITLET:
00257 return porder->edguppoly ;
00258 default:
00259 return NULL ;
00260 }
00261 }
00262
00263 static char *
00264 get_wave_ifu_slitlet_tag( int ifu, xsh_instrument * instrument )
00265 {
00266 char * tag = NULL ;
00267
00268 switch( ifu ) {
00269 case LOWER_IFU_SLITLET:
00270 tag = xsh_stringcat_any( XSH_WAVE_TAB_ARC_DOWN_IFU, "_",
00271 xsh_instrument_arm_tostring( instrument ),
00272 NULL ) ;
00273 break ;
00274 case CENTER_IFU_SLITLET:
00275 tag = xsh_stringcat_any( XSH_WAVE_TAB_ARC_CEN_IFU, "_",
00276 xsh_instrument_arm_tostring( instrument ),
00277 NULL ) ;
00278 break ;
00279 case UPPER_IFU_SLITLET:
00280 tag = xsh_stringcat_any( XSH_WAVE_TAB_ARC_UP_IFU, "_",
00281 xsh_instrument_arm_tostring( instrument ),
00282 NULL ) ;
00283 break ;
00284 }
00285 return tag ;
00286 }
00287
00288 static char *
00289 get_resid_ifu_slitlet_tag( int ifu, xsh_instrument * instrument )
00290 {
00291 char * tag = NULL ;
00292
00293 switch( ifu ) {
00294 case LOWER_IFU_SLITLET:
00295 tag = xsh_stringcat_any( XSH_RESID_TAB_DOWN_IFU, "_",
00296 xsh_instrument_arm_tostring( instrument ),
00297 NULL ) ;
00298 break ;
00299 case CENTER_IFU_SLITLET:
00300 tag = xsh_stringcat_any( XSH_RESID_TAB_CEN_IFU, "_",
00301 xsh_instrument_arm_tostring( instrument ),
00302 NULL ) ;
00303 break ;
00304 case UPPER_IFU_SLITLET:
00305 tag = xsh_stringcat_any( XSH_RESID_TAB_UP_IFU, "_",
00306 xsh_instrument_arm_tostring( instrument ),
00307 NULL ) ;
00308 break ;
00309 }
00310 return tag ;
00311 }
00312
00313 static char *
00314 get_tilt_ifu_slitlet_tag( int ifu, xsh_instrument * instrument )
00315 {
00316 char * tag = NULL ;
00317
00318 switch( ifu ) {
00319 case LOWER_IFU_SLITLET:
00320 tag = xsh_stringcat_any( XSH_TILT_TAB_DOWN_IFU, "_",
00321 xsh_instrument_arm_tostring( instrument ),
00322 NULL ) ;
00323 break ;
00324 case CENTER_IFU_SLITLET:
00325 tag = xsh_stringcat_any( XSH_TILT_TAB_CEN_IFU, "_",
00326 xsh_instrument_arm_tostring( instrument ),
00327 NULL ) ;
00328 break ;
00329 case UPPER_IFU_SLITLET:
00330 tag = xsh_stringcat_any( XSH_TILT_TAB_UP_IFU, "_",
00331 xsh_instrument_arm_tostring( instrument ),
00332 NULL ) ;
00333 break ;
00334 }
00335 return tag ;
00336 }
00337
00338
00339
00340
00341 static int
00342 find_tilt( double yp0, double xc, float lambda, int ordnum,
00343 xsh_follow_arclines_param * follow_param,
00344 xsh_pre * pre, xsh_order_list * orders,
00345 xsh_instrument * instrument, double * slope,
00346 double * chisq, double * minx, double * maxx,
00347 int * nt, int * ng, double * fwhm_center,
00348 double * good_center, int ifu_flag )
00349 {
00350 int result=0;
00351 cpl_polynomial * lo_poly = NULL;
00352 cpl_polynomial * up_poly = NULL;
00353
00354 CENTROIDS * centers = NULL ;
00355 double x0, x, ycenter ;
00356 XSH_GAUSSIAN_FIT fit_res ;
00357 cpl_vector *pos_vect =NULL, *val_vect = NULL;
00358 int *flags = NULL;
00359 cpl_polynomial * poly_tilt = NULL ;
00360 double xmin, xmax ;
00361 int iorder ;
00362 int i, j, k, ngood;
00363 int csize ;
00364 cpl_vector *fwhm_median_vect = NULL;
00365 double *median_data = NULL;
00366 double fwhm_median = 0.0;
00367 int tilt_niter;
00368 double tilt_kappa, tilt_frac, good_frac;
00369 int ntot, no_centroid =0;
00370 int deg1 = 1;
00371
00372 XSH_ASSURE_NOT_NULL( follow_param);
00373 XSH_ASSURE_NOT_NULL( follow_param->tilt_clipping);
00374
00375 tilt_niter = follow_param->tilt_clipping->niter;
00376 tilt_kappa = follow_param->tilt_clipping->sigma;
00377 tilt_frac = follow_param->tilt_clipping->frac;
00378
00379
00380 check( iorder = xsh_order_list_get_order( orders, ordnum));
00381
00382 if ( iorder < 0 ) {
00383 xsh_msg( "Unknown Absolute Order %d", ordnum);
00384 return FIND_TILT_UNKNOW_ORDER ;
00385 }
00386
00387 lo_poly = get_slit_ifu_lo_poly( &orders->list[iorder], ifu_flag ) ;
00388 up_poly = get_slit_ifu_up_poly( &orders->list[iorder], ifu_flag ) ;
00389
00390 check( xmin = xsh_order_list_eval( orders, lo_poly, yp0));
00391 check( xmax = xsh_order_list_eval( orders, up_poly, yp0));
00392
00393
00394 xmin = *minx;
00395 xmax = *maxx;
00396
00397 xmin += follow_param->margin ;
00398 xmax -= follow_param->margin ;
00399
00400 *minx = xmin ;
00401 *maxx = xmax ;
00402
00403 xsh_msg_dbg_medium( " Find_tilt - order %d, idx %d, xmin = %.2lf, xmax = %.2lf, yc = %.2lf",
00404 ordnum, iorder, xmin, xmax, yp0 ) ;
00405
00406 if ( xmax <= xmin ) {
00407 xsh_msg( "******* Something Wrong in Edges!" ) ;
00408 return FIND_TILT_BAD_EDGES ;
00409 }
00410
00411 if ( xc <= xmin || xc >= xmax ) {
00412 xsh_msg( "lambda %f, order %d: Center (from wavesol) %lf not in ] %lf, %lf [",
00413 lambda, ordnum, xc, xmin, xmax ) ;
00414 return FIND_TILT_BAD_CENTER ;
00415 }
00416
00417
00418
00419 csize = ceil(xmax) - floor(xmin);
00420 XSH_CALLOC( centers, CENTROIDS, csize);
00421
00422 x0 = xsh_round_double(xc);
00423 ngood = 0 ;
00424 ntot = 0;
00425
00426 ycenter = xsh_round_double(yp0);
00427
00428
00429 for( x = x0 ; x >= xmin ; x--) {
00430 int ok;
00431
00432 centers[ntot].xpos = x;
00433 ok = detect_centroid( pre, lambda, ordnum, x, ycenter,
00434 follow_param, instrument, 0, &fit_res);
00435 if ( ok == 0 && fit_res.peakpos > 0. ) {
00436 centers[ntot].ypos = fit_res.peakpos ;
00437 centers[ntot].fwhm = CPL_MATH_FWHM_SIG*fit_res.sigma;
00438 centers[ntot].area = fit_res.area;
00439 centers[ntot].good = 0 ;
00440 ycenter = fit_res.peakpos ;
00441 ngood++ ;
00442 }
00443 else {
00444 no_centroid++ ;
00445 centers[ntot].good = 1 ;
00446 }
00447 ntot++;
00448 }
00449 ycenter = xsh_round_double( yp0);
00450
00451
00452 for( x = x0+1 ; x <= xmax ; x++) {
00453 int ok;
00454
00455 centers[ntot].xpos = x;
00456 ok = detect_centroid( pre, lambda, ordnum, x, ycenter,
00457 follow_param, instrument, 0, &fit_res);
00458 if ( ok == 0 && fit_res.peakpos > 0. ) {
00459 centers[ntot].ypos = fit_res.peakpos ;
00460 centers[ntot].fwhm = CPL_MATH_FWHM_SIG*fit_res.sigma ;
00461 centers[ntot].area = fit_res.area;
00462 centers[ntot].good = 0 ;
00463 ycenter = fit_res.peakpos ;
00464 ngood++ ;
00465 }
00466 else {
00467 no_centroid++ ;
00468 centers[ntot].good = 1 ;
00469 }
00470 ntot++;
00471 }
00472 xsh_msg_dbg_medium(" For lambda %f in order %d : Fitted %d/%d (%d no centroid)",
00473 lambda, ordnum, ngood, ntot, no_centroid);
00474
00475 good_frac = (double)ngood/(double) ntot;
00476
00477 if ( ngood >= 2 && good_frac >= tilt_frac){
00478
00479 xsh_msg_dbg_medium("---Clipping on tilt");
00480
00481 check( pos_vect = cpl_vector_new( ngood));
00482 check( val_vect = cpl_vector_new( ngood));
00483
00484 j = 0;
00485 for( i = 0 ; i< ntot; i++ ) {
00486 if ( centers[i].good == 0){
00487 cpl_vector_set( pos_vect, j, centers[i].xpos);
00488 cpl_vector_set( val_vect, j, centers[i].ypos);
00489 j++;
00490 }
00491 }
00492
00493 check( xsh_array_clip_poly1d( pos_vect, val_vect, tilt_kappa, tilt_niter,
00494 tilt_frac, 1, &poly_tilt, chisq, &flags));
00495
00496
00497 j = 0;
00498 k = 0;
00499 XSH_CALLOC( median_data, double, ngood);
00500
00501 for( i = 0 ; i< ntot; i++ ) {
00502 if ( centers[i].good == 0){
00503 if (flags[j] == 0){
00504 median_data[k] = centers[i].fwhm;
00505 k++;
00506 }
00507 else{
00508 centers[i].good = 2;
00509 }
00510 j++;
00511 }
00512 }
00513
00514 check( fwhm_median_vect = cpl_vector_wrap( k, median_data));
00515
00516 check( fwhm_median = cpl_vector_get_median( fwhm_median_vect));
00517 *fwhm_center = fwhm_median;
00518
00519
00520 check( *good_center = cpl_polynomial_eval_1d( poly_tilt, x0, NULL));
00521 check( *slope = cpl_polynomial_get_coeff( poly_tilt, °1));
00522
00523 xsh_msg_dbg_medium(" find_tilt : slope %f fwhm_median %f tilt at center %f %f ",
00524 *slope, fwhm_median, x0, *good_center);
00525
00526 *nt = ntot;
00527 *ng = ngood;
00528
00529
00530 {
00531 FILE *fwhm_debug_file = NULL;
00532 char name[256];
00533 int idebug = 0;
00534
00535 sprintf( name, "fwhm.dat", ordnum, lambda);
00536
00537 if ( fwhm_debug_mode == NULL){
00538 fwhm_debug_file = fopen( name, "w");
00539 fwhm_debug_mode = "a+";
00540 fprintf( fwhm_debug_file,
00541 "# wavelength order xcen xcen-x0 ygauss ytilt fwhm area good\n");
00542 }
00543 else{
00544 fwhm_debug_file = fopen( name, fwhm_debug_mode);
00545 }
00546 for( idebug=0; idebug< ntot; idebug++){
00547 double fit;
00548 double xpos;
00549
00550 xpos = xsh_round_double( centers[idebug].xpos );
00551
00552 fit = cpl_polynomial_eval_1d( poly_tilt, xpos, NULL);
00553 fprintf( fwhm_debug_file, "%f %d %f %f %f %f %f %f %d\n",
00554 lambda, ordnum,
00555 xpos, xpos-x0,
00556 centers[idebug].ypos, fit, centers[idebug].fwhm,
00557 centers[idebug].area, centers[idebug].good);
00558 }
00559 fclose( fwhm_debug_file);
00560 }
00561 }
00562 else{
00563 result = FIND_TILT_BAD_FIT;
00564 xsh_msg( "Not enough points to do the fit: Good fraction points (%f < %f)",
00565 good_frac, tilt_frac);
00566 }
00567
00568 cleanup:
00569 xsh_free_vector( &pos_vect);
00570 xsh_free_vector(&val_vect);
00571 xsh_free_polynomial( &poly_tilt);
00572 XSH_FREE( flags);
00573 xsh_unwrap_vector( &fwhm_median_vect);
00574 XSH_FREE( median_data);
00575 XSH_FREE( centers);
00576 return result;
00577 }
00578
00579
00580 static float linear_interpol( float xa, float ya, float xb, float yb, float x )
00581 {
00582 float xb_xa ;
00583
00584 xb_xa = xb-xa ;
00585 return (ya*(xb-x))/(xb_xa) + (yb*(x-xa))/(xb_xa) ;
00586
00587 }
00588
00589 static float get_lambda( float * data, float x, float y, int nx, int ny )
00590 {
00591
00592
00593
00594 float lambda, lm, lp;
00595 int ym, yp;
00596 int xpos;
00597
00598 if(y>ny) return 0;
00599
00600
00601 yp = (int) ceil( y);
00602 ym = (int) floor( y);
00603
00604 xpos = (int) xsh_round_double( x);
00605 lm = data[(ym-1)*nx+xpos];
00606 lp = data[(yp-1)*nx+xpos];
00607
00608
00609 lambda = linear_interpol( ym, lm, yp, lp, y ) ;
00610 xsh_msg_dbg_high( " ym: %d, lm: %f, yp: %d, lp: %f, y: %f ==> %f",
00611 ym, lm, yp, lp, y, lambda ) ;
00612
00613 return lambda ;
00614 }
00615
00616
00630
00631 static void
00632 compute_specres( cpl_frame *wavemap_frame,
00633 cpl_frame *disptab_frame,
00634 xsh_instrument* instr,
00635 xsh_linetilt_list *tilt_list,
00636 int niter,
00637 double kappa,
00638 double frac,
00639 double *specres_med,
00640 double *specres_stdev)
00641 {
00642 cpl_array *a_specres = NULL ;
00643 int i, j, status ;
00644 xsh_dispersol_list* displist = NULL;
00645 cpl_vector* positions = NULL;
00646 const char *wavemap_name = NULL;
00647 cpl_image *wavemap_img = NULL;
00648 float *wavemap_data = NULL ;
00649 int nx, ny;
00650 int tilt_list_size =0;
00651
00652 XSH_ASSURE_NOT_NULL( tilt_list);
00653
00654
00655 if (disptab_frame != NULL){
00656 xsh_msg("Use the DISP_TAB");
00657 check( displist = xsh_dispersol_list_load( disptab_frame, instr));
00658 check( positions = cpl_vector_new(2));
00659 }
00660 else{
00661 xsh_msg("Use the WAVE_MAP");
00662 XSH_ASSURE_NOT_NULL( wavemap_frame);
00663 check( wavemap_name = cpl_frame_get_filename( wavemap_frame));
00664 check( wavemap_img = cpl_image_load( wavemap_name, CPL_TYPE_FLOAT, 0, 0));
00665 check( wavemap_data = cpl_image_get_data_float( wavemap_img));
00666 nx = cpl_image_get_size_x( wavemap_img);
00667 ny = cpl_image_get_size_y( wavemap_img);
00668 }
00669
00670
00671 tilt_list_size = tilt_list->size;
00672 check( a_specres = cpl_array_new( tilt_list_size, CPL_TYPE_DOUBLE));
00673
00674
00675 for( i=0 ; i< tilt_list_size; i++) {
00676 double xc, yc, yc0, yc1;
00677 double pix_width ;
00678 float lambda0, lambda1, lambdac;
00679 double tilt =0.0;
00680
00681
00682 xc = tilt_list->list[i]->cenposx;
00683 yc = tilt_list->list[i]->tilt_y;
00684
00685 pix_width = tilt_list->list[i]->deltay;
00686 lambdac = tilt_list->list[i]->wavelength;
00687 tilt = tilt_list->list[i]->tilt;
00688
00689
00690 tilt_list->list[i]->specres = 0;
00691 tilt_list->list[i]->flag = 1;
00692
00693
00694 yc0 = yc - (pix_width/2.);
00695 yc1 = yc + (pix_width/2.);
00696
00697 if ( displist != NULL){
00698 int absorder = tilt_list->list[i]->order;
00699 int iorder=0;
00700
00701 while( absorder != displist->list[iorder].absorder){
00702 iorder++;
00703 }
00704 cpl_vector_set( positions, 0, xc);
00705 cpl_vector_set( positions, 1, yc0);
00706
00707 check( lambda0 = xsh_dispersol_list_eval( displist,
00708 displist->list[iorder].lambda_poly, positions));
00709
00710 cpl_vector_set( positions, 1, yc1);
00711 check( lambda1 = xsh_dispersol_list_eval( displist,
00712 displist->list[iorder].lambda_poly, positions));
00713 }
00714 else{
00715 if( (yc0 >= 1) && (yc1 <= ny-1) ) {
00716
00717 lambda0 = get_lambda( wavemap_data, xc, yc0, nx,ny);
00718 lambda1 = get_lambda( wavemap_data, xc, yc1, nx,ny);
00719 }
00720 }
00721 xsh_msg_dbg_high("Lambda1: %f, Lambda0: %f, Lambdac: %f, Pix_width: %lf",
00722 lambda0, lambda1, lambdac, pix_width);
00723
00724 if ( lambda0 != 0. && lambda1 != 0.) {
00725 tilt_list->list[i]->flag = 0;
00726
00727 tilt_list->list[i]->specres = lambdac/fabs(lambda1 - lambda0)*
00728 sqrt( 1+tilt*tilt);
00729 }
00730 check( cpl_array_set( a_specres, i, tilt_list->list[i]->specres));
00731 }
00732
00733 check( *specres_med = cpl_array_get_median( a_specres));
00734 check( *specres_stdev = cpl_array_get_stdev( a_specres));
00735
00736 xsh_msg("---Clipping on spectral resolution");
00737 check( xsh_array_clip_median( a_specres, kappa, niter,
00738 frac, specres_med, specres_stdev));
00739
00740 for( j=0; j < tilt_list_size; j++){
00741 double val=0.0;
00742
00743
00744 val = cpl_array_get_double( a_specres, j, &status);
00745 if (status == 1){
00746 tilt_list->list[j]->flag = 2;
00747 }
00748 }
00749 cleanup:
00750 xsh_free_array( &a_specres);
00751 xsh_free_image( &wavemap_img);
00752 xsh_free_vector( &positions);
00753 xsh_dispersol_list_free( &displist);
00754 return ;
00755 }
00756
00757
00758
00759
00760 static void
00761 set_qc_parameters( cpl_propertylist *tilt_header,
00762 cpl_propertylist *shift_header,
00763 double * ypos,
00764 double * width,
00765 double * intens,
00766 int n,
00767 xsh_instrument * instrument,
00768 int nlinecat,
00769 int nb_lines,
00770 double specres_med,
00771 double specres_stdev)
00772 {
00773 cpl_vector * yvect = NULL, * wvect = NULL, * ivect = NULL ;
00774 double avg, med, std, wavg, wstd, iavg ;
00775
00776 check( yvect = cpl_vector_wrap( n, ypos ) ) ;
00777 check( avg = cpl_vector_get_mean( yvect ) ) ;
00778 check( med = cpl_vector_get_median( yvect ) ) ;
00779 check( std = cpl_vector_get_stdev( yvect ) ) ;
00780
00781 check( wvect = cpl_vector_wrap( n, width ) ) ;
00782 check( wstd = cpl_vector_get_stdev( wvect ) ) ;
00783 check( wavg = cpl_vector_get_mean( wvect ) ) ;
00784
00785 check( ivect = cpl_vector_wrap( n, intens ) ) ;
00786 check( iavg = cpl_vector_get_mean( ivect ) ) ;
00787
00788 xsh_msg_dbg_low( "FWHM Avg: %.2lf, RMS: %.2lf", wavg, wstd ) ;
00789
00790 check( xsh_pfits_set_qc( tilt_header, &avg, QC_WAVECAL_DIFFYAVG,
00791 instrument ) ) ;
00792 check( xsh_pfits_set_qc( tilt_header, &med, QC_WAVECAL_DIFFYMED,
00793 instrument ) ) ;
00794 check( xsh_pfits_set_qc( tilt_header, &std, QC_WAVECAL_DIFFYSTD,
00795 instrument ) ) ;
00796 check( xsh_pfits_set_qc( tilt_header, &iavg, QC_WAVECAL_NLININT,
00797 instrument));
00798 check( xsh_pfits_set_qc( tilt_header, &wavg, QC_WAVECAL_FWHMAVG,
00799 instrument ) ) ;
00800 check( xsh_pfits_set_qc( tilt_header, &wstd, QC_WAVECAL_FWHMRMS,
00801 instrument ) ) ;
00802 check( xsh_pfits_set_qc( tilt_header, &nlinecat, QC_WAVECAL_CATLINE,
00803 instrument ) ) ;
00804 check( xsh_pfits_set_qc( tilt_header, &nb_lines, QC_WAVECAL_MATCHLINE,
00805 instrument ) ) ;
00806 check( xsh_pfits_set_qc( tilt_header, &n, QC_WAVECAL_FOUNDLINE,
00807 instrument));
00808 check( xsh_pfits_set_qc( tilt_header, &specres_med, QC_RESOLMED, instrument));
00809 check( xsh_pfits_set_qc( tilt_header, &specres_stdev, QC_RESOLRMS, instrument));
00810
00811
00812
00813 check( xsh_pfits_set_qc( shift_header, &avg, QC_WAVECAL_DIFFYAVG,
00814 instrument ) ) ;
00815 check( xsh_pfits_set_qc( shift_header, &med, QC_WAVECAL_DIFFYMED,
00816 instrument ) ) ;
00817 check( xsh_pfits_set_qc( shift_header, &std, QC_WAVECAL_DIFFYSTD,
00818 instrument ) ) ;
00819 check( xsh_pfits_set_qc( shift_header, &iavg, QC_WAVECAL_NLININT,
00820 instrument));
00821
00822 cleanup:
00823 xsh_unwrap_vector( &yvect ) ;
00824 xsh_unwrap_vector( &wvect ) ;
00825 xsh_unwrap_vector( &ivect ) ;
00826 return ;
00827 }
00828
00829
00830
00831
00832 static void
00833 clean_arclist_data( cpl_frame *wavesol_frame,
00834 cpl_frame *arclines_frame,
00835 xsh_order_list *orders,
00836 cpl_frame *config_model_frame,
00837 cpl_frame *pre_frame,
00838 cpl_frame *spectralformat_frame,
00839 double **lambda,
00840 double **n,
00841 double **x,
00842 double **y,
00843 double **xmin,
00844 double **xmax,
00845 int *size,
00846 double slit,
00847 double slit_min,
00848 double slit_max,
00849 xsh_instrument *instrument)
00850 {
00851 xsh_arclist *arclist = NULL;
00852 int arclist_size =0, global_size=0;
00853 cpl_vector** spectral_tab = NULL;
00854 xsh_wavesol * wsol = NULL;
00855 xsh_xs_3 config_model;
00856 int found_temp=true;
00857 xsh_spectralformat_list *spectralformat_list = NULL;
00858 int bad_positions=0;
00859 int i, j, index_loc = 0;
00860
00861 check( arclist = xsh_arclist_load( arclines_frame));
00862 check( spectralformat_list =
00863 xsh_spectralformat_list_load( spectralformat_frame, instrument));
00864 check( arclist_size = xsh_arclist_get_size( arclist));
00865
00866 if ( wavesol_frame != NULL) {
00867 check( wsol = xsh_wavesol_load( wavesol_frame, instrument));
00868 }
00869 else if ( config_model_frame != NULL ) {
00870
00871 check(xsh_model_temperature_update_frame( &config_model_frame, pre_frame,
00872 instrument, &found_temp));
00873 check( xsh_model_config_load_best( config_model_frame, &config_model));
00874 check( xsh_model_binxy(&config_model,instrument->binx,instrument->biny));
00875 }
00876 else{
00877 XSH_ASSURE_NOT_ILLEGAL_MSG(1==0,
00878 "Undefined solution type (POLY or MODEL).");
00879 }
00880
00881 XSH_CALLOC( spectral_tab, cpl_vector*, arclist_size);
00882
00883 for( i=0; i< arclist_size; i++){
00884 cpl_vector* res = NULL;
00885 float lambdaARC;
00886 int res_size;
00887
00888 check( lambdaARC = xsh_arclist_get_wavelength( arclist, i));
00889 check( res = xsh_spectralformat_list_get_orders( spectralformat_list,
00890 lambdaARC));
00891
00892 if ( res != NULL){
00893 check( res_size = cpl_vector_get_size( res));
00894 }
00895 else{
00896 res_size = 0;
00897 check( xsh_arclist_reject(arclist,i));
00898 }
00899 global_size += res_size;
00900 spectral_tab[i] = res;
00901 }
00902 xsh_msg (" Arc List x Order size = %d", global_size);
00903
00904 XSH_MALLOC( *lambda, double, global_size);
00905 XSH_MALLOC( *n, double, global_size);
00906 XSH_MALLOC( *x, double, global_size);
00907 XSH_MALLOC( *xmin, double, global_size);
00908 XSH_MALLOC( *xmax, double, global_size);
00909 XSH_MALLOC( *y, double, global_size);
00910
00911 for( i=0; i< arclist_size; i++){
00912 double comp_x=0.0, comp_y=0.0, comp_xmin=0.0, comp_ymin=0.0;
00913 double comp_xmax=0.0, comp_ymax=0.0;
00914 cpl_vector *spectral_res = NULL;
00915 int spectral_res_size=0;
00916 float lambdaARC;
00917
00918 check( lambdaARC = xsh_arclist_get_wavelength(arclist, i));
00919 check( spectral_res = spectral_tab[i]);
00920
00921 if (spectral_res != NULL){
00922 check( spectral_res_size = cpl_vector_get_size( spectral_res));
00923 for( j=0; j< spectral_res_size; j++){
00924 int absorder = 0;
00925 int oidx;
00926
00927 check( absorder = (int) cpl_vector_get( spectral_res, j));
00928 check( oidx = xsh_order_list_get_index_by_absorder( orders, absorder));
00929 if (wsol != NULL){
00930 check( comp_x = xsh_wavesol_eval_polx( wsol, lambdaARC, absorder,
00931 slit));
00932 check( comp_y = xsh_wavesol_eval_poly( wsol, lambdaARC, absorder,
00933 slit));
00934 check( comp_xmin = xsh_wavesol_eval_polx( wsol, lambdaARC, absorder,
00935 slit_min));
00936 check( comp_xmax = xsh_wavesol_eval_polx( wsol, lambdaARC, absorder,
00937 slit_max));
00938 }
00939 else{
00940 check( xsh_model_get_xy( &config_model, instrument,
00941 lambdaARC, absorder, slit, &comp_x, &comp_y));
00942 check( xsh_model_get_xy( &config_model, instrument,
00943 lambdaARC, absorder, slit_min, &comp_xmin, &comp_ymin));
00944 check( xsh_model_get_xy( &config_model, instrument,
00945 lambdaARC, absorder, slit_max, &comp_xmax, &comp_ymax));
00946 }
00947
00948 if ( (comp_y >= xsh_order_list_get_starty( orders, oidx )) &&
00949 (comp_y <= xsh_order_list_get_endy( orders, oidx))) {
00950 (*lambda)[index_loc] = lambdaARC;
00951 (*n)[index_loc] = absorder;
00952 (*x)[index_loc] = comp_x;
00953 (*y)[index_loc] = comp_y;
00954 if ( comp_xmin < comp_xmax){
00955 (*xmin)[index_loc] = comp_xmin;
00956 (*xmax)[index_loc] = comp_xmax;
00957 xsh_msg_dbg_medium("The relation f(s)->X is increasing, X and s axes have same direction.");
00958 }
00959 else{
00960 (*xmin)[index_loc] = comp_xmax;
00961 (*xmax)[index_loc] = comp_xmin;
00962 xsh_msg_dbg_medium("The relation f(s)->X is decreasing, X and s axes have opposite directions");
00963 }
00964 xsh_msg_dbg_medium(
00965 "lambda %f order %d slit %f smin %f smax %f x %f y %f xmin %f xmax %f",
00966 lambdaARC, absorder, slit, slit_min, slit_max, comp_x, comp_y, comp_xmin, comp_xmax);
00967 index_loc++;
00968 }
00969 else{
00970 xsh_msg_dbg_low( "Ypix out of Order" ) ;
00971 bad_positions++ ;
00972 }
00973 }
00974 }
00975 }
00976 xsh_msg("Clean size %d (%d bad positions)", index_loc, bad_positions);
00977 *size = index_loc;
00978
00979 cleanup:
00980 xsh_arclist_free( &arclist);
00981 xsh_wavesol_free( &wsol);
00982 xsh_spectralformat_list_free( &spectralformat_list);
00983
00984 if ( spectral_tab != NULL){
00985 for(i=0; i< arclist_size; i++){
00986 xsh_free_vector( &spectral_tab[i]);
00987 }
00988 XSH_FREE( spectral_tab);
00989 }
00990 if ( cpl_error_get_code() != CPL_ERROR_NONE){
00991 XSH_FREE( *lambda);
00992 XSH_FREE( *n);
00993 XSH_FREE( *x);
00994 XSH_FREE( *xmin);
00995 XSH_FREE( *xmax);
00996 XSH_FREE( *y);
00997 }
00998 return;
00999 }
01000
01001
01002
01003 void
01004 xsh_follow_arclines_slit( cpl_frame *pre_frame,
01005 cpl_frame *arclines_frame,
01006 cpl_frame *wavesol_frame,
01007 cpl_frame *order_frame,
01008 cpl_frame *spectralformat_frame,
01009 cpl_frame * config_model_frame,
01010 cpl_frame *wavemap_frame,
01011 cpl_frame *slitmap_frame,
01012 cpl_frame *disptab_frame,
01013 xsh_follow_arclines_param *follow_param,
01014 xsh_instrument * instrument,
01015 cpl_frame **tilt_frame,
01016 cpl_frame **shift_frame)
01017 {
01018 double smin=-6.0, smax=6.0;
01019
01020
01021
01022
01023
01024 check( xsh_follow_arclines( pre_frame, arclines_frame, wavesol_frame,
01025 order_frame, spectralformat_frame, config_model_frame, wavemap_frame,
01026 disptab_frame,
01027 follow_param, 0.0, smin, smax, "SLIT", CENTER_SLIT, instrument,
01028 tilt_frame,
01029 shift_frame));
01030 cleanup:
01031 return;
01032 }
01033
01034
01062
01063 void xsh_follow_arclines( cpl_frame *pre_frame,
01064 cpl_frame *arclines_frame,
01065 cpl_frame *wavesol_frame,
01066 cpl_frame *order_frame,
01067 cpl_frame *spectralformat_frame,
01068 cpl_frame * config_model_frame,
01069 cpl_frame *wavemap_frame,
01070 cpl_frame *disptab_frame,
01071 xsh_follow_arclines_param *follow_param,
01072 double slit,
01073 double slit_min,
01074 double slit_max,
01075 const char* tag_id,
01076 int ifu_flag,
01077 xsh_instrument * instrument,
01078 cpl_frame **tilt_frame,
01079 cpl_frame **shift_frame)
01080 {
01081 xsh_pre * pre = NULL;
01082 xsh_order_list *orders = NULL;
01083 double * vlambdadata = NULL, *vorderdata = NULL;
01084 double * vxthedata = NULL, * vythedata = NULL;
01085 double *vxmindata = NULL, * vxmaxdata = NULL;
01086 int sol_size = 0;
01087 const char* arclines_name = NULL;
01088 int s_n_low = 0, no_centroid = 0, bad_position = 0 , no_tilt=0;
01089
01090 XSH_GAUSSIAN_FIT fit_res ;
01091 xsh_shift_tab *shift_tab = NULL ;
01092 xsh_linetilt_list *tilt_list = NULL ;
01093 cpl_propertylist *tilt_header = NULL ;
01094 double *ydelta = NULL, *width = NULL, *intensity = NULL;
01095 int goodlines = 0 ;
01096
01097 int i;
01098
01099 const char * shift_tag = NULL ;
01100 char tag[80];
01101 char fname[256];
01102 int specres_niter=0;
01103 double specres_kappa = 0, specres_frac = 1;
01104 double specres_med = 0., specres_stdev = 0 ;
01105 cpl_vector *svect = NULL;
01106 int cat_lines, match_lines, found_lines;
01107
01108 XSH_ASSURE_NOT_NULL( pre_frame);
01109 XSH_ASSURE_NOT_NULL( arclines_frame);
01110 XSH_ASSURE_NOT_NULL( order_frame);
01111
01112 XSH_ASSURE_NOT_NULL( follow_param);
01113 XSH_ASSURE_NOT_NULL( instrument);
01114 XSH_ASSURE_NOT_NULL( spectralformat_frame);
01115 XSH_ASSURE_NOT_NULL( tag_id);
01116
01117
01118 XSH_ASSURE_NOT_NULL( follow_param->specres_clipping);
01119 specres_niter = follow_param->specres_clipping->niter;
01120 specres_kappa = follow_param->specres_clipping->sigma;
01121 specres_frac = follow_param->specres_clipping->frac;
01122
01123 check( pre = xsh_pre_load( pre_frame, instrument));
01124 check( orders = xsh_order_list_load( order_frame, instrument));
01125
01126 xsh_set_image_cpl_bpmap ( pre->data, pre->qual, pre->nx, pre->ny);
01127
01128
01129 check( clean_arclist_data( wavesol_frame, arclines_frame, orders,
01130 config_model_frame, pre_frame, spectralformat_frame,
01131 &vlambdadata, &vorderdata,
01132 &vxthedata, &vythedata, &vxmindata, &vxmaxdata,
01133 &sol_size, slit, slit_min, slit_max, instrument));
01134
01135
01136 check( shift_tab = xsh_shift_tab_create( instrument));
01137
01138 XSH_CALLOC( ydelta, double, sol_size);
01139 XSH_CALLOC( width, double, sol_size);
01140 XSH_CALLOC( intensity, double, sol_size);
01141
01142 check( arclines_name = cpl_frame_get_filename( arclines_frame));
01143 check( tilt_header = cpl_propertylist_load( arclines_name, 0));
01144 check( tilt_list = xsh_linetilt_list_new( sol_size, tilt_header));
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 for ( i = 0 ; i < sol_size ; i++ ) {
01161 double lambda, order;
01162 double xpix, ypix;
01163 int ok, ret, rej;
01164 int nt = 0, ng = 0 ;
01165 double s_n =0;
01166
01167 lambda = vlambdadata[i];
01168 order = vorderdata[i];
01169 xpix = vxthedata[i];
01170 ypix = vythedata[i];
01171
01172 xsh_msg_dbg_low( "LAMBDA %f, ORDER %f, SLIT %f, X %lf, Y %lf", lambda,
01173 order, slit, xpix, ypix );
01174
01175 check( ok = detect_centroid( pre, lambda, order, xpix, ypix,
01176 follow_param, instrument, 1, &fit_res));
01177
01178 if ( ok != 0 ) {
01179 xsh_msg_dbg_low( " ******* Could NOT Fit Centroid" ) ;
01180 xsh_msg_dbg_low( "Lambda: %f, Order: %f - Line NOT Fitted",
01181 lambda, order);
01182 no_centroid++ ;
01183 }
01184 else{
01185
01186 if( (xpix<=pre->nx) && (xpix>0) && (ypix<=pre->ny) && (ypix>0)) {
01187 double flux_val, err_val;
01188
01189 check( flux_val = cpl_image_get( pre->data, xpix, ypix, &rej ));
01190 check( err_val = cpl_image_get( pre->data, xpix, ypix, &rej ));
01191 check(s_n = cpl_image_get( pre->data, xpix, ypix, &rej )/
01192 cpl_image_get( pre->errs, xpix, ypix, &rej));
01193
01194 if ( s_n < follow_param->s_n_min ) {
01195 xsh_msg_dbg_low( " %f/%f < %f => S/N too low, line skipped",
01196 flux_val, err_val, follow_param->s_n_min);
01197 s_n_low++;
01198 }
01199 else{
01200 double slope = 0.0, chisq = 0.0, xmin = 0.0, xmax = 0.0;
01201 double fwhm_center = 0.0;
01202 double good_center;
01203
01204
01205
01206
01207
01208
01209
01210 xmin = vxmindata[i];
01211 xmax = vxmaxdata[i];
01212 if ( (ret = find_tilt( fit_res.peakpos, xpix, lambda, order,
01213 follow_param, pre, orders,
01214 instrument, &slope, &chisq,
01215 &xmin, &xmax, &nt, &ng,
01216 &fwhm_center, &good_center,
01217 ifu_flag )) == 0 ) {
01218 int rej, ix, iy;
01219 xsh_linetilt * tilt_line = NULL ;
01220
01221 ix = xsh_round_double( xpix);
01222 iy = xsh_round_double( ypix);
01223
01224
01225 ydelta[goodlines] = good_center-ypix;
01226 width[goodlines] = CPL_MATH_FWHM_SIG*fit_res.sigma;
01227 intensity[goodlines] = cpl_image_get( pre->data, ix, iy, &rej);
01228 check( tilt_line = xsh_linetilt_new());
01229 tilt_line->wavelength = lambda;
01230 tilt_line->slit = slit;
01231 tilt_line->tilt = slope ;
01232 tilt_line->chisq = chisq;
01233 tilt_line->xmin = xmin ;
01234 tilt_line->xmax = xmax ;
01235 tilt_line->ntot = nt ;
01236 tilt_line->ngood = ng ;
01237 tilt_line->deltay = fwhm_center;
01238 tilt_line->name = NULL ;
01239 tilt_line->order = order ;
01240 tilt_line->cenposx = xpix;
01241 tilt_line->pre_pos_y = ypix;
01242 tilt_line->cenposy = fit_res.peakpos ;
01243 tilt_line->tilt_y = good_center;
01244 tilt_line->shift_y = good_center-ypix;
01245 tilt_line->specres = fwhm_center;
01246 tilt_line->area = fit_res.area;
01247 tilt_line->intensity = cpl_image_get( pre->data, ix, iy, &rej);
01248 check( xsh_linetilt_list_add( tilt_list, tilt_line, goodlines));
01249 xsh_msg_dbg_low( "Lambda: %f, Order: %f - Line Fitted: %lf,%lf",
01250 lambda, order, xpix, tilt_line->cenposy);
01251 goodlines++;
01252 }
01253 else{
01254 xsh_msg_dbg_low( " Can't compute tilt, line skipped" );
01255 no_tilt++;
01256 }
01257 }
01258 }
01259 else{
01260 xsh_msg_dbg_low( " Bad position, line skipped" ) ;
01261 bad_position++;
01262 }
01263 }
01264 }
01265
01266 xsh_msg( "No centroid %d Bad Position: %d, S/N too low: %d No tilt %d",
01267 no_centroid, bad_position, s_n_low, no_tilt);
01268 if ( goodlines == 0 ){
01269 xsh_msg( "***** NO FITTED LINE !!!!" );
01270 }
01271 XSH_ASSURE_NOT_ILLEGAL( goodlines > 0 ) ;
01272 xsh_msg( " Good Fitted lines : %d/%d", goodlines, sol_size);
01273
01274
01275 if ( wavemap_frame != NULL || disptab_frame != NULL) {
01276 compute_specres( wavemap_frame, disptab_frame, instrument,
01277 tilt_list, specres_niter,
01278 specres_kappa, specres_frac,
01279 &specres_med, &specres_stdev);
01280 if ( cpl_error_get_code() != CPL_ERROR_NONE ) {
01281 xsh_msg( "ERROR while computing Spectral Resolution" ) ;
01282 cpl_error_reset() ;
01283 specres_med = 0. ;
01284 specres_stdev = 0. ;
01285 }
01286 }
01287 else {
01288 xsh_msg_error( "NO Wavemap (WAVE_MAP) or dispersion table (DISP_TAB), can't compute Spectral Resolution");
01289 }
01290
01291 cat_lines = sol_size;
01292 found_lines = goodlines;
01293 match_lines = tilt_list->size;
01294
01295 set_qc_parameters( tilt_header, shift_tab->header, ydelta, width, intensity, tilt_list->size,
01296 instrument, sol_size, goodlines, specres_med, specres_stdev);
01297
01298 sprintf( tag, "FOLLOW_LINETILT_%s_%s", tag_id,
01299 xsh_instrument_arm_tostring( instrument));
01300 sprintf(fname,"%s.fits",tag);
01301
01302 check( *tilt_frame = xsh_linetilt_list_save( tilt_list, instrument, fname, tag,
01303 specres_kappa, specres_niter));
01304
01305 sprintf( tag, "TILT_TAB_%s_%s", tag_id,
01306 xsh_instrument_arm_tostring( instrument));
01307 check( cpl_frame_set_tag( *tilt_frame, tag));
01308
01309 xsh_add_temporary_file(fname) ;
01310 xsh_msg( "Tilt Frame saved" ) ;
01311
01312
01313 xsh_msg( "Saving shift table SLIT, %d lines", tilt_list->size);
01314
01315 check( svect = cpl_vector_wrap( tilt_list->size, ydelta));
01316
01317 if ( ifu_flag == CENTER_SLIT){
01318 check( shift_tab->shift_y = cpl_vector_get_median( svect));
01319 shift_tag = XSH_GET_TAG_FROM_ARM( XSH_SHIFT_TAB_SLIT, instrument);
01320 }
01321 else{
01322 check( shift_tab->shift_y_cen = cpl_vector_get_median( svect));
01323 sprintf( tag, "SHIFT_TAB_%s_%s", tag_id,
01324 xsh_instrument_arm_tostring( instrument));
01325 shift_tag = tag;
01326 }
01327
01328 check( xsh_pfits_set_qc( shift_tab->header, &cat_lines, QC_WAVECAL_CATLINE,
01329 instrument ) ) ;
01330 check( xsh_pfits_set_qc( shift_tab->header, &match_lines, QC_WAVECAL_MATCHLINE,
01331 instrument ) ) ;
01332 check( xsh_pfits_set_qc( shift_tab->header, &found_lines, QC_WAVECAL_FOUNDLINE,
01333 instrument ) ) ;
01334 check( *shift_frame = xsh_shift_tab_save( shift_tab, shift_tag));
01335
01336 cleanup:
01337 xsh_pre_free( &pre);
01338 xsh_order_list_free( &orders);
01339 xsh_linetilt_list_free( &tilt_list);
01340 xsh_shift_tab_free( &shift_tab);
01341 xsh_unwrap_vector( &svect);
01342
01343 XSH_FREE( vlambdadata);
01344 XSH_FREE( vorderdata);
01345 XSH_FREE( vxthedata);
01346 XSH_FREE( vxmindata);
01347 XSH_FREE( vxmaxdata);
01348 XSH_FREE( vythedata);
01349 XSH_FREE( ydelta);
01350 XSH_FREE( width);
01351 XSH_FREE( intensity);
01352 return ;
01353 }
01354
01355
01356
01379
01380 void
01381 xsh_follow_arclines_ifu( cpl_frame *pre_frame,
01382 cpl_frame *arclines_frame,
01383 cpl_frame *wavesol_frame,
01384 cpl_frame *order_frame,
01385 cpl_frame *spectralformat_frame,
01386 cpl_frame *config_model_frame,
01387 cpl_frame *wavemap_frame,
01388 cpl_frame *slitmap_frame,
01389 cpl_frame *disptab_frame,
01390 xsh_follow_arclines_param *follow_param,
01391 xsh_instrument * instrument,
01392 cpl_frameset *tilt_set,
01393 cpl_frame **shift_frame)
01394 {
01395
01396
01397 int ifu, spos=0;
01398 double slit_min=-6, slitcen_lo=-2.0, slitcen_up=2.0, slit_max=6;
01399 char tag_id[256];
01400 cpl_frameset *shift_ifu_set = NULL;
01401 cpl_frame *shift_tab_frame = NULL;
01402 xsh_shift_tab *shift_tab_low = NULL;
01403 xsh_shift_tab *shift_tab_cen = NULL;
01404 xsh_shift_tab *shift_tab_up = NULL;
01405 const char* shift_tag = NULL;
01406 double slit_pos[4];
01407 double shift_center=0, shift_lower=0, shift_upper=0;
01408
01409 XSH_ASSURE_NOT_NULL( tilt_set);
01410 XSH_ASSURE_NOT_NULL( spectralformat_frame);
01411
01412 shift_ifu_set = cpl_frameset_new();
01413
01414 check( xsh_get_slit_edges( slitmap_frame, &slit_min, &slit_max,
01415 &slitcen_lo, &slitcen_up, instrument));
01416 slit_pos[0] = slit_min;
01417 slit_pos[1] = slitcen_lo;
01418 slit_pos[2] = slitcen_up;
01419 slit_pos[3] = slit_max;
01420
01421
01422
01423 for( ifu = LOWER_IFU_SLITLET ; ifu <= UPPER_IFU_SLITLET; ifu++) {
01424 cpl_frame *tmp_tilt_frame = NULL;
01425 cpl_frame *tmp_shift_frame = NULL;
01426 double slitlet_min, slitlet_max, slitlet_center;
01427
01428 slitlet_min = slit_pos[spos];
01429 slitlet_max = slit_pos[spos+1];
01430 slitlet_center = (slitlet_min+slitlet_max)/2.0;
01431
01432 xsh_msg( "IFU Slitlet %s: center = %f arcsec; edges = [%f, %f] arcsec",
01433 SlitletName[ifu], slitlet_center, slitlet_min, slitlet_max);
01434
01435 sprintf( tag_id, "%s_IFU", SlitletName[ifu]) ;
01436
01437 check( xsh_follow_arclines( pre_frame, arclines_frame, wavesol_frame,
01438 order_frame, spectralformat_frame, config_model_frame, wavemap_frame,
01439 disptab_frame,
01440 follow_param, slitlet_center, slitlet_min, slitlet_max, tag_id, ifu, instrument,
01441 &tmp_tilt_frame, &tmp_shift_frame));
01442
01443 spos++;
01444 check( cpl_frameset_insert( tilt_set, tmp_tilt_frame));
01445 check( cpl_frameset_insert( shift_ifu_set, tmp_shift_frame));
01446 }
01447
01448 check( shift_tab_frame = cpl_frameset_get_frame( shift_ifu_set, 0));
01449 xsh_msg_dbg_medium( "Lower Shift tab frame %s",
01450 cpl_frame_get_filename( shift_tab_frame));
01451 check( shift_tab_low = xsh_shift_tab_load( shift_tab_frame, instrument));
01452
01453 check( shift_tab_frame = cpl_frameset_get_frame( shift_ifu_set, 1));
01454 xsh_msg_dbg_medium( "Center Shift tab frame %s",
01455 cpl_frame_get_filename( shift_tab_frame));
01456 check( shift_tab_cen = xsh_shift_tab_load( shift_tab_frame, instrument));
01457
01458 check( shift_tab_frame = cpl_frameset_get_frame( shift_ifu_set, 2));
01459 xsh_msg_dbg_medium( "Upper Shift tab frame %s",
01460 cpl_frame_get_filename( shift_tab_frame));
01461 check( shift_tab_up = xsh_shift_tab_load( shift_tab_frame, instrument));
01462
01463
01464 shift_lower = shift_tab_low->shift_y_cen;
01465 shift_center = shift_tab_cen->shift_y_cen;
01466 shift_upper = shift_tab_up->shift_y_cen;
01467
01468 xsh_msg_dbg_medium( "Measured shift for slitlet: LOWER %f, CENTER %f, UPPER %f",
01469 shift_lower, shift_center, shift_upper);
01470
01471 shift_tab_cen->shift_y_down = shift_lower;
01472 shift_tab_cen->shift_y_up = shift_upper;
01473
01474 shift_tag = XSH_GET_TAG_FROM_ARM( XSH_SHIFT_TAB_IFU, instrument);
01475 check( *shift_frame = xsh_shift_tab_save( shift_tab_cen, shift_tag));
01476
01477
01478 cleanup:
01479 xsh_shift_tab_free( &shift_tab_low);
01480 xsh_shift_tab_free( &shift_tab_cen);
01481 xsh_shift_tab_free( &shift_tab_up);
01482 xsh_free_frameset( &shift_ifu_set);
01483 return;
01484 }
01485