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