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
00038
00041
00042
00043
00044
00045 #include <math.h>
00046 #include <xsh_drl.h>
00047 #include <xsh_data_order.h>
00048 #include <xsh_error.h>
00049 #include <xsh_utils_wrappers.h>
00050 #include <xsh_utils.h>
00051 #include <xsh_msg.h>
00052 #include <xsh_data_pre.h>
00053 #include <xsh_pfits.h>
00054 #include <xsh_parameters.h>
00055 #include <xsh_data_order_resid_tab.h>
00056 #include <cpl.h>
00057
00058
00059
00060
00061
00062 struct gauss_res {
00063 double centroid,
00064 sigma,
00065 area,
00066 offset,
00067 mse ;
00068 } ;
00069
00070 typedef struct {
00071 int order_idx ;
00072 int absorder ;
00073 int flag;
00074 double position ;
00075 double pos_x ;
00076 double centervalue ;
00077 double sigmavalue ;
00078 double final_x ;
00079 } CENTROIDS_STRUCT ;
00080
00081
00082
00083
00084 static cpl_error_code
00085 xsh_fit_gaussian( xsh_detect_continuum_param * detect_param,
00086 int x, int y, int nx,
00087 float *data, float *p_errs,
00088 struct gauss_res *result,
00089 xsh_instrument *instrument,
00090 int order, double threshold ) ;
00091
00092
00093
00094
00095
00096 static int Nb_noflux, Nb_nofit ;
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 #define BAD_POSITION_FLAG 999999
00111 #define THRESH_POSITION_FLAG 9999999
00112
00113
00114
00115 static cpl_error_code
00116 xsh_fit_gaussian( xsh_detect_continuum_param * detect_param,
00117 int x, int y, int nx,
00118 float *data, float *p_errs,
00119 struct gauss_res * result,
00120 xsh_instrument *instrument,
00121 int order, double threshold )
00122 {
00123 cpl_vector *v_pos = NULL ;
00124 cpl_vector *v_values = NULL ;
00125 cpl_error_code err = CPL_ERROR_NONE ;
00126 int l, nelem ;
00127 int x0 ;
00128 double flux=0.0, min_flux=0.0;
00129 int search_window ;
00130 int running_window ;
00131 int fit_window ;
00132 int x1, x2 ;
00133 double *warray = NULL ;
00134 int pix_shift=(y-1)*nx-1;
00135
00136
00137 XSH_ASSURE_NOT_NULL( detect_param);
00138 XSH_ASSURE_NOT_NULL( data);
00139 XSH_ASSURE_NOT_NULL( p_errs);
00140 XSH_ASSURE_NOT_NULL( result);
00141 XSH_ASSURE_NOT_NULL( instrument);
00142
00143 search_window = detect_param->search_window ;
00144 fit_window = detect_param->fit_window ;
00145 running_window = detect_param->running_window ;
00146
00147
00148
00149
00150 x0 = x - search_window;
00151 x2 = x + search_window;
00152 if ( x0 < 1 ) x0 = 1;
00153 if ( x2 > nx ) x2 = nx;
00154 nelem = x2 - x0 +1 ;
00155 x1 = x0 ;
00156
00157
00158
00159
00160 if ( running_window != 0 ) {
00161 XSH_MALLOC( warray, double, nelem);
00162 for( l = 0 ; l<nelem ; l++, x0++ )
00163 warray[l] = data[x0+pix_shift];
00164
00165
00166 x0 = x1 + xsh_tools_running_median_1d_get_max( warray, nelem,
00167 running_window);
00168 xsh_msg_dbg_high( " Found running maximum at %d,%d (was %d)",
00169 x0, y, x );
00170 XSH_FREE(warray) ;
00171
00172
00173 nelem = (fit_window*2)+1 ;
00174 x0 -= fit_window ;
00175 }
00176
00177
00178 xsh_msg_dbg_high( " Final fit window: %d,%d %d elements", x0, y, nelem ) ;
00179 check( v_pos = cpl_vector_new( nelem ) ) ;
00180 check( v_values = cpl_vector_new( nelem ) ) ;
00181
00182
00183 for( l = 0 ; l<nelem ; l++, x0++ ) {
00184 cpl_vector_set( v_pos, l, (double)x0 ) ;
00185 cpl_vector_set( v_values, l, (double)data[x0+pix_shift] ) ;
00186 }
00187
00188 err = cpl_vector_fit_gaussian( v_pos, NULL, v_values, NULL,
00189 CPL_FIT_ALL,
00190 &result->centroid, &result->sigma,
00191 &result->area, &result->offset,
00192 &result->mse, NULL, NULL ) ;
00193 if ( err == CPL_ERROR_NONE ) {
00194 x0 = floor( result->centroid +0.5);
00195 flux = (double)data[x0+pix_shift] ;
00196
00197 min_flux = (double)p_errs[x0+pix_shift] * threshold ;
00198 if ( flux < min_flux ) {
00199 err = CPL_ERROR_UNSPECIFIED ;
00200 }
00201 }
00202
00203 if ( err != CPL_ERROR_NONE ) {
00204 int i ;
00205
00206 if ( err == CPL_ERROR_UNSPECIFIED ) {
00207 xsh_msg_dbg_medium( " NOT ENOUGH FLUX at X,Y = %d,%d (%lf < %lf)",
00208 x, y, flux, min_flux ) ;
00209 Nb_noflux++ ;
00210 }
00211 else {
00212 cpl_error_reset() ;
00213
00214 xsh_msg_dbg_medium( " CPL_FIT_GAUSSIAN ERROR at X,Y = %d,%d", x, y ) ;
00215 Nb_nofit++ ;
00216 for( i = 0 ; i<nelem ; i++ ) {
00217 xsh_msg_dbg_high( " X = %.0lf, Value = %lf",
00218 cpl_vector_get( v_pos, i ),
00219 cpl_vector_get( v_values, i ) ) ;
00220 }
00221 }
00222 }
00223 else if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM &&
00224 (y % 10) == 0 ) {
00225
00226 char dirname1[128], dirname2[128], fname[256], cmd[256] ;
00227 FILE *fout ;
00228
00229 sprintf( dirname1, "Ord_%s", xsh_instrument_arm_tostring( instrument ) ) ;
00230 if ( access( dirname1, 0 ) != 0 ) {
00231 sprintf( cmd, "mkdir %s", dirname1 ) ;
00232 system( cmd ) ;
00233 }
00234 sprintf( dirname2, "%s/O_%02d", dirname1, order ) ;
00235 if ( access( dirname2, 0 ) != 0 ) {
00236 sprintf( cmd, "mkdir %s", dirname2 ) ;
00237 system( cmd ) ;
00238 }
00239
00240 sprintf( fname, "%s/fit_%04d", dirname2, y ) ;
00241 fout = fopen( fname, "w" ) ;
00242 for( l = 0 ; l<nelem ; l++ ) {
00243 fprintf( fout, "%lf %lf %lf %lf\n", cpl_vector_get( v_pos, l ),
00244 cpl_vector_get( v_values, l ),
00245 result->centroid, result->sigma ) ;
00246 }
00247 fclose( fout ) ;
00248 }
00249
00250 cleanup:
00251 xsh_free_vector( &v_pos ) ;
00252 xsh_free_vector( &v_values ) ;
00253 return err ;
00254 }
00255
00256 static double * Deltas = NULL, * PosY = NULL, * PosX = NULL,
00257 * XorderPos = NULL ;
00258 static int * Orders = NULL ;
00259 static int DeltaSize = 0 ;
00260 static int DeltaPoints = 0 ;
00261
00262 static cpl_frame*
00263 create_resid_tab( xsh_instrument * instrument,
00264 ORDERPOS_QC_PARAM * qcparam )
00265 {
00266 int dbg_lvl ;
00267 FILE * flog = NULL ;
00268 char logname[256];
00269 int n ;
00270 cpl_frame * resid_frame = NULL ;
00271 xsh_resid_order_tab * resid_tab = NULL ;
00272 char frame_name[256] ;
00273 char tag[256];
00274
00275 XSH_ASSURE_NOT_NULL( instrument ) ;
00276
00277 if ( (dbg_lvl = xsh_debug_level_get()) >= XSH_DEBUG_LEVEL_LOW ) {
00278
00279
00280 sprintf(logname,"orderpos_%s.dat",xsh_instrument_arm_tostring(instrument));
00281 if ( (flog = fopen( logname, "w" ) ) == NULL )
00282 xsh_msg( "Cant open log file \"%s\"", logname ) ;
00283 else xsh_msg( " ASCII File '%s'", logname ) ;
00284 }
00285
00286 for ( n = 0 ; n<DeltaPoints ; n++ ) {
00287 if ( dbg_lvl >= XSH_DEBUG_LEVEL_LOW && flog != NULL )
00288 fprintf( flog, "%d %lf %lf %lf %lf\n",
00289 *(Orders+n), *(PosY+n), *(PosX+n),
00290 *(XorderPos+n), *(Deltas+n) ) ;
00291 }
00292
00293 check( resid_tab = xsh_resid_order_create( DeltaPoints, Orders, PosX, PosY,
00294 Deltas, XorderPos ) ) ;
00295 resid_tab->residmin = qcparam->residmin ;
00296 resid_tab->residmax = qcparam->residmax ;
00297 resid_tab->residavg = qcparam->residavg ;
00298 resid_tab->residrms = qcparam->residrms ;
00299
00300 sprintf(tag,"%s%s%s",XSH_ORDERPOS_RESID_TAB,"_",
00301 xsh_instrument_arm_tostring( instrument ));
00302 sprintf(frame_name,"%s.fits",tag);
00303
00304 check( resid_frame = xsh_resid_order_save( resid_tab, frame_name,
00305 instrument,qcparam,tag ) ) ;
00306
00307 cleanup:
00308 xsh_resid_order_free(&resid_tab);
00309
00310 if(cpl_error_get_code() != CPL_ERROR_NONE) {
00311 xsh_free_frame(&resid_frame);
00312 }
00313 if(flog != NULL) {
00314 fclose(flog);
00315 }
00316 return resid_frame;
00317
00318 }
00319
00320
00321 static void cumulate_qc_parameter( int order, xsh_order_list * list,
00322 CENTROIDS_STRUCT * pcent, int npts )
00323 {
00324 int j, absorder ;
00325 double diff ;
00326 double * Delta0 ;
00327 int prevSize ;
00328
00329 absorder = list->list[order].absorder ;
00330 xsh_msg_dbg_low( " Cumulate: Order %d, Nb of Points: %d", absorder, npts ) ;
00331 prevSize = DeltaSize ;
00332
00333 DeltaSize += npts ;
00334 if ( order == 0 ) {
00335 XSH_CALLOC( Deltas, double, DeltaSize ) ;
00336 XSH_CALLOC( PosX, double, DeltaSize ) ;
00337 XSH_CALLOC( PosY, double, DeltaSize ) ;
00338 XSH_CALLOC( Orders, int, DeltaSize ) ;
00339 XSH_CALLOC( XorderPos, double, DeltaSize ) ;
00340 }
00341 else {
00342
00343 Deltas = cpl_realloc( Deltas, DeltaSize*sizeof(double) ) ;
00344 PosX = cpl_realloc( PosX, DeltaSize*sizeof(double) ) ;
00345 PosY = cpl_realloc( PosY, DeltaSize*sizeof(double) ) ;
00346 Orders = cpl_realloc( Orders, DeltaSize*sizeof(int) ) ;
00347 XorderPos = cpl_realloc( XorderPos, DeltaSize*sizeof(double) ) ;
00348 }
00349 xsh_msg_dbg_low( "Cumulated points: %d", DeltaSize ) ;
00350 Delta0 = Deltas + prevSize ;
00351
00352
00353 for( j = 0 ; j<npts ; j++, pcent++ ) {
00354 double x1 ;
00355 double y ;
00356
00357 y = pcent->position ;
00358 x1 = cpl_polynomial_eval_1d( list->list[order].cenpoly, y, NULL ) ;
00359 diff= ( x1 - pcent->centervalue ) ;
00360
00361 xsh_msg_dbg_medium( " ---- Y = %lf, x0 = %lf, x1 = %lf, diff = %lf", y,
00362 pcent->centervalue, x1, diff ) ;
00363 *(Deltas+DeltaPoints) = diff ;
00364 *(PosX+DeltaPoints) = pcent->centervalue ;
00365 *(PosY+DeltaPoints) = y ;
00366 *(Orders+DeltaPoints) = absorder ;
00367 *(XorderPos+DeltaPoints) = x1 ;
00368 DeltaPoints++ ;
00369 }
00370 {
00371
00372 cpl_vector *v_avg = NULL ;
00373 double residavg, residmax, residmin, residrms ;
00374 v_avg = cpl_vector_wrap( npts, Delta0 ) ;
00375
00376 residavg = cpl_vector_get_mean( v_avg ) ;
00377 residmax = cpl_vector_get_max( v_avg ) ;
00378 residmin = cpl_vector_get_min( v_avg ) ;
00379 residrms = cpl_vector_get_stdev( v_avg ) ;
00380 xsh_msg_dbg_low( " Residuals for Order %d:", absorder ) ;
00381 xsh_msg_dbg_low( " Mean: %lf, Max: %lf, Min: %lf, Rms: %lf",
00382 residavg, residmax, residmin, residrms ) ;
00383 xsh_msg_dbg_low( " StartY: %d, Endy: %d", list->list[order].starty,
00384 list->list[order].endy ) ;
00385 cpl_vector_unwrap( v_avg ) ;
00386 }
00387
00388 cleanup:
00389 return ;
00390 }
00391
00392 static cpl_frame*
00393 calculate_qc_parameters( ORDERPOS_QC_PARAM * qcparam,
00394 xsh_instrument * instrument )
00395 {
00396 cpl_vector *v_avg = NULL ;
00397 cpl_frame* resid_frame=NULL;
00398
00399 check(v_avg = cpl_vector_wrap( DeltaPoints, Deltas )) ;
00400 assure( v_avg != NULL, cpl_error_get_code(),
00401 "Cant wrap the v_avg vector" ) ;
00402
00403 qcparam->residavg = cpl_vector_get_mean( v_avg ) ;
00404 qcparam->residmax = cpl_vector_get_max( v_avg ) ;
00405 qcparam->residmin = cpl_vector_get_min( v_avg ) ;
00406 qcparam->residrms = cpl_vector_get_stdev( v_avg ) ;
00407 check(resid_frame=create_resid_tab( instrument, qcparam ) );
00408
00409 cleanup:
00410 cpl_vector_unwrap( v_avg ) ;
00411 XSH_FREE( Deltas ) ;
00412 XSH_FREE( PosX ) ;
00413 XSH_FREE( PosY ) ;
00414 XSH_FREE( Orders ) ;
00415 XSH_FREE( XorderPos ) ;
00416 if(cpl_error_get_code() != CPL_ERROR_NONE) {
00417 xsh_free_frame(&resid_frame);
00418 }
00419 return resid_frame;
00420
00421 }
00422
00423 static int comp_pos( const void * un, const void * deux )
00424 {
00425 CENTROIDS_STRUCT * one = (CENTROIDS_STRUCT *)un ;
00426 CENTROIDS_STRUCT * two = (CENTROIDS_STRUCT *)deux ;
00427
00428 if ( one->position < two->position ) return -1 ;
00429 else if ( one->position == two->position ) return 0 ;
00430 else return 1 ;
00431 }
00432
00433 static void set_qc_parameters( xsh_order_list * list, ORDERPOS_QC_PARAM *pqc,
00434 xsh_instrument * instrument )
00435 {
00436 cpl_propertylist * header=NULL ;
00437
00438 XSH_ASSURE_NOT_NULL(list);
00439 XSH_ASSURE_NOT_NULL(pqc);
00440
00441 header = xsh_order_list_get_header( list ) ;
00442 XSH_ASSURE_NOT_NULL( header );
00443
00444 check( xsh_pfits_set_qc( header, &pqc->residmin,
00445 QC_ORD_ORDERPOS_RESIDMIN,
00446 instrument ) ) ;
00447 check( xsh_pfits_set_qc( header, &pqc->residmax,
00448 QC_ORD_ORDERPOS_RESIDMAX,
00449 instrument ) ) ;
00450 check( xsh_pfits_set_qc( header, &pqc->residavg,
00451 QC_ORD_ORDERPOS_RESIDAVG,
00452 instrument ) ) ;
00453 check( xsh_pfits_set_qc( header, &pqc->residrms,
00454 QC_ORD_ORDERPOS_RESIDRMS,
00455 instrument ) ) ;
00456 check( xsh_pfits_set_qc( header, &pqc->ndet,
00457 QC_ORD_ORDERPOS_NDET,
00458 instrument ) ) ;
00459 check( xsh_pfits_set_qc( header, &pqc->npred,
00460 QC_ORD_ORDERPOS_NPRED,
00461 instrument ) ) ;
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 cleanup:
00479
00480 return ;
00481 }
00482
00506
00507 cpl_frame* xsh_detect_continuum( cpl_frame *frame, cpl_frame *order_table,
00508 cpl_frame *spectral_frame,
00509 xsh_detect_continuum_param *detect_param,
00510 xsh_clipping_param *dcn_clipping,
00511 xsh_instrument *instr,
00512 cpl_frame** resid_frame)
00513 {
00514
00515 cpl_frame *result = NULL;
00516
00517 xsh_pre *pre = NULL;
00518 xsh_order_list *list = NULL;
00519 xsh_order_list *guess_list = NULL;
00520 CENTROIDS_STRUCT *Centroids = NULL;
00521 cpl_vector *centers = NULL ;
00522 cpl_vector *xpos = NULL ;
00523
00524
00525 float *data = NULL;
00526 float *p_errs = NULL;
00527 int y = 0;
00528 int i = 0;
00529 int ndetected = 0 ;
00530 ORDERPOS_QC_PARAM ord_qc_param ;
00531 static FILE *flog = NULL ;
00532 int step, degree;
00533 double fit_threshold ;
00534
00535
00536 XSH_ASSURE_NOT_NULL( frame);
00537 XSH_ASSURE_NOT_NULL( order_table);
00538 XSH_ASSURE_NOT_NULL( detect_param);
00539 XSH_ASSURE_NOT_NULL( dcn_clipping);
00540 XSH_ASSURE_NOT_NULL( instr);
00541
00542
00543 assure(detect_param->search_window > 0 &&
00544 detect_param->fit_window > 0, CPL_ERROR_NULL_INPUT,
00545 "Windows must be > 0" ) ;
00546
00547
00548 fit_threshold = detect_param->fit_threshold ;
00549 degree = detect_param->poly_degree ;
00550
00551
00552 xsh_msg_dbg_medium("Clipping parameters :");
00553 xsh_msg_dbg_medium(" Sigma %f Niter %d Frac %f", dcn_clipping->sigma,
00554 dcn_clipping->niter, dcn_clipping->frac);
00555
00556
00557 check( pre = xsh_pre_load( frame, instr));
00558 check( list = xsh_order_list_load (order_table, instr));
00559
00560 assure(detect_param->search_window > 0 &&
00561 detect_param->search_window < (pre->nx/list->size),
00562 CPL_ERROR_ILLEGAL_INPUT,
00563 "Search windows half size %d must be > 0 and < %d change value of "
00564 "parameter detectcontinuum-search-window-half-size",
00565 detect_param->search_window ,(pre->nx/list->size)) ;
00566
00567 check( xsh_order_list_verify( list, xsh_pre_get_ny( pre)));
00568
00569 check( guess_list = xsh_order_list_load( order_table, instr));
00570
00571
00572 xsh_free_propertylist( &(list->header));
00573 XSH_NEW_PROPERTYLIST( list->header);
00574
00575 XSH_ASSURE_NOT_NULL( guess_list);
00576
00577
00578 check( data = cpl_image_get_data_float(pre->data));
00579 check( p_errs = cpl_image_get_data_float( pre->errs));
00580
00581
00582 XSH_MALLOC( Centroids, CENTROIDS_STRUCT, pre->ny);
00583
00584
00585
00586 xsh_msg_dbg_high( "Loop over %d Orders", list->size);
00587
00588 step = detect_param->poly_step ;
00589
00590
00591 for(i=0; i< list->size; i++){
00592 int x = 0 ;
00593 double fx ;
00594 int npts = 0, totpts = 0, npos, nn, mm, niter, totnbad = 0 ;
00595 cpl_error_code err ;
00596 int low_y=0, up_y=0;
00597 int ycenter ;
00598 int absorder ;
00599
00600 Nb_nofit = 0 ;
00601 Nb_noflux = 0 ;
00602 absorder = list->list[i].absorder ;
00603
00604 ycenter = pre->ny/2;
00605
00606 if ( ycenter < list->list[i].starty ) ycenter = list->list[i].starty;
00607
00608 check( fx = cpl_polynomial_eval_1d(list->list[i].cenpoly,
00609 (double)ycenter,NULL));
00610
00611 x = floor( fx+0.5);
00612
00613
00614
00615 xsh_msg_dbg_medium( ">>>> Order #%d, At Center X,Y: %d,%d",
00616 absorder, x, ycenter ) ;
00617
00618
00619 if ( x >= 1 && x <= pre->nx) {
00620 struct gauss_res fit_result ;
00621
00622
00623 err = xsh_fit_gaussian( detect_param, x, ycenter,
00624 pre->nx, data, p_errs,
00625 &fit_result,
00626 instr, absorder,
00627 fit_threshold );
00628
00629 if ( err == CPL_ERROR_NONE ) {
00630
00631 (Centroids+npts)->position = (double) ycenter ;
00632 (Centroids+npts)->pos_x = (double) x;
00633 (Centroids+npts)->centervalue = fit_result.centroid ;
00634 (Centroids+npts)->sigmavalue = fit_result.sigma ;
00635 (Centroids+npts)->absorder = absorder ;
00636 npts++ ;
00637 }
00638 totpts++ ;
00639 }
00640
00641
00642 xsh_msg_dbg_medium( " Down Y from %d to %d",
00643 ycenter -1, list->list[i].starty ) ;
00644 low_y = ycenter ;
00645 for( y = ycenter - 1; y >= list->list[i].starty ; y-=step ) {
00646
00647 check( fx=cpl_polynomial_eval_1d(list->list[i].cenpoly,
00648 (double)y,NULL));
00649 x = floor( fx+0.5) ;
00650
00651 if ( x >= 1 && x <= pre->nx) {
00652 struct gauss_res fit_result ;
00653
00654
00655 check_msg(err = xsh_fit_gaussian( detect_param, x, y,
00656 pre->nx, data, p_errs,
00657 &fit_result,
00658 instr, list->list[i].absorder,
00659 fit_threshold ),"Try to increase detectcontinuum-fit-window-half-size") ;
00660 if ( err == CPL_ERROR_NONE ) {
00661
00662 (Centroids+npts)->position = (double)y ;
00663 (Centroids+npts)->pos_x = (double)x;
00664 (Centroids+npts)->centervalue = fit_result.centroid ;
00665 (Centroids+npts)->sigmavalue = fit_result.sigma ;
00666 (Centroids+npts)->absorder = absorder ;
00667 low_y = y ;
00668 npts++ ;
00669 } else {
00670 cpl_error_reset();
00671 }
00672 totpts++ ;
00673 }
00674 }
00675
00676 xsh_msg_dbg_medium( " --> Nb of points: %d", npts ) ;
00677
00678 xsh_msg_dbg_medium( " Up Y from %d to %d",
00679 ycenter+1, list->list[i].endy ) ;
00680 up_y = ycenter ;
00681 for( y = ycenter + 1; y <= list->list[i].endy ; y+=step ) {
00682 check( fx=cpl_polynomial_eval_1d(list->list[i].cenpoly,
00683 (double)y,NULL));
00684 x = floor( fx+0.5);
00685
00686 if ( x >= 1 && x <= pre->nx) {
00687 struct gauss_res fit_result ;
00688
00689
00690 err = xsh_fit_gaussian( detect_param, x, y,
00691 pre->nx, data, p_errs,
00692 &fit_result,
00693 instr, list->list[i].absorder,
00694 fit_threshold ) ;
00695 if ( err == CPL_ERROR_NONE ) {
00696
00697 (Centroids+npts)->position = (double)y ;
00698 (Centroids+npts)->pos_x = (double)x ;
00699 (Centroids+npts)->centervalue = fit_result.centroid ;
00700 (Centroids+npts)->sigmavalue = fit_result.sigma ;
00701 (Centroids+npts)->absorder = absorder ;
00702 up_y = y ;
00703 npts++ ;
00704
00705 } else {
00706 cpl_error_reset();
00707 }
00708 totpts++ ;
00709 }
00710 }
00711
00712 if (xsh_debug_level_get() >= XSH_DEBUG_LEVEL_HIGH) {
00713 FILE* debug_file = NULL;
00714 char debug_name[256];
00715 int idebug;
00716
00717 sprintf(debug_name, "centroid_%d.reg", list->list[i].absorder);
00718
00719 debug_file = fopen( debug_name, "w");
00720 fprintf( debug_file, "# Region file format: DS9 version 4.0\n"\
00721 "global color=red font=\"helvetica 4 normal\""\
00722 "select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 "\
00723 "source\nimage\n");
00724 for( idebug=0; idebug < npts; idebug++){
00725 fprintf( debug_file, "point(%f,%f) #point=cross color=blue\n",
00726 Centroids[idebug].pos_x, Centroids[idebug].position);
00727 fprintf( debug_file, "point(%f,%f) #point=cross color=red\n",
00728 Centroids[idebug].centervalue, Centroids[idebug].position);
00729 }
00730 fclose( debug_file);
00731 }
00732 xsh_msg_dbg_medium( " --> Nb of points: %d", npts ) ;
00733 xsh_msg_dbg_low( " No enough flux: %d, No fit: %d", Nb_noflux,
00734 Nb_nofit ) ;
00735
00736 xsh_msg_dbg_high( " Nb of correct points found: %d/%d",
00737 npts, totpts ) ;
00738 xsh_msg_dbg_high( " LowY: %d, UpY: %d", low_y, up_y ) ;
00739
00740
00741 assure(npts > 3,CPL_ERROR_ILLEGAL_OUTPUT,
00742 "can't fit polynomial solution with nb of points %d", npts );
00743
00744
00745
00746
00747
00748 qsort( Centroids, npts, sizeof( CENTROIDS_STRUCT ), comp_pos ) ;
00749
00750
00751
00752
00753
00754 xsh_msg( "Sigma Clipping on residuals over %d pts", npts ) ;
00755
00756 npos = npts ;
00757
00758 {
00759 double poly_rms ;
00760 int nthresh = 0 ;
00761
00762 list->list[i].starty = low_y ;
00763 list->list[i].endy = up_y ;
00764
00765
00766 check( xpos = cpl_vector_new( npos ) ) ;
00767 check( centers = cpl_vector_new( npos ) ) ;
00768 {
00769 int j ;
00770 for( j = 0 ; j<npos ; j++ ) {
00771 cpl_vector_set( xpos, j, (Centroids+j)->position ) ;
00772 cpl_vector_set( centers, j, (Centroids+j)->centervalue ) ;
00773 }
00774 }
00775
00776
00777 check(xsh_free_polynomial( &list->list[i].cenpoly));
00778
00779 xsh_msg_dbg_low( "Polynomial degree: %d", degree ) ;
00780 check(list->list[i].cenpoly =
00781 xsh_polynomial_fit_1d_create( xpos, centers, degree, &poly_rms));
00782 xsh_free_vector( ¢ers ) ;
00783 xsh_free_vector( &xpos ) ;
00784
00785
00786
00787
00788
00789
00790 poly_rms = sqrt( poly_rms ) ;
00791 xsh_msg_dbg_low( " Sigma Clipping - Polynomial RMS: %lf",
00792 poly_rms ) ;
00793
00794 for( nn = 0 ; nn < npos ; nn++ ) {
00795
00796
00797
00798 double xpoly, delta ;
00799
00800 xpoly = cpl_polynomial_eval_1d( list->list[i].cenpoly,
00801 (Centroids+nn)->position,
00802 NULL ) ;
00803 delta = fabs( xpoly - (Centroids+nn)->centervalue) ;
00804 if ( delta > dcn_clipping->res_max ) {
00805
00806
00807 xsh_msg_dbg_high( " Rejected at %.0lf,%.0lf (%lf > %lf)",
00808 (Centroids+nn)->centervalue,
00809 (Centroids+nn)->position,
00810 delta, poly_rms ) ;
00811 (Centroids+nn)->position = THRESH_POSITION_FLAG ;
00812 (Centroids+nn)->flag = THRESH_POSITION_FLAG ;
00813 nthresh++ ;
00814 }
00815 }
00816
00817
00818
00819 totnbad += nthresh ;
00820 xsh_msg_dbg_low( " Rejected Positions: %d (%d)", nthresh, totnbad ) ;
00821
00822
00823
00824
00825 if ( ((float)(npts-totnbad)/(float)npts) < dcn_clipping->frac ) {
00826
00827 list->list[i].starty = -1 ;
00828 list->list[i].endy = -1 ;
00829 xsh_msg_warning( "**** Too many rejected points: %d/%d (%.2f) Discard Order %d",
00830 totnbad, npts, (float)(npts-totnbad)/(float)npts, absorder ) ;
00831 xsh_msg_warning("Try to increase detectcontinuum-clip-res-max and/or decrease detectcontinuum-clip-frac and/or detectcontinuum-search-window-half-size");
00832 break ;
00833 }
00834
00835
00836 for( nn = 0, mm = 0 ; nn<npos ; nn++ ) {
00837 if ( (Centroids+nn)->position != THRESH_POSITION_FLAG ) {
00838 if ( mm != nn ) *(Centroids+mm) = *(Centroids+nn) ;
00839 mm++ ;
00840 }
00841 }
00842 npts = mm ;
00843 }
00844
00845 npos = npts ;
00846 for( niter = 0 ; niter < dcn_clipping->niter ; niter++ ) {
00847 double poly_rms ;
00848 int nbad = 0 ;
00849
00850
00851 list->list[i].starty = low_y ;
00852 list->list[i].endy = up_y ;
00853
00854 xsh_msg_dbg_low( " Iteration %d, Starty = %d, Endy = %d, Npos = %d",
00855 niter, list->list[i].starty, list->list[i].endy, npos ) ;
00856
00857 check( xpos = cpl_vector_new( npos ) ) ;
00858 check( centers = cpl_vector_new( npos ) ) ;
00859 {
00860 int j ;
00861 for( j = 0 ; j<npos ; j++ ) {
00862 cpl_vector_set( xpos, j, (Centroids+j)->position ) ;
00863 cpl_vector_set( centers, j, (Centroids+j)->centervalue ) ;
00864 }
00865 }
00866
00867
00868 check(xsh_free_polynomial( &list->list[i].cenpoly));
00869
00870 xsh_msg_dbg_low( "Polynomial degree: %d", degree ) ;
00871 check(list->list[i].cenpoly =
00872 xsh_polynomial_fit_1d_create( xpos, centers, degree, &poly_rms));
00873 xsh_free_vector( ¢ers ) ;
00874 xsh_free_vector( &xpos ) ;
00875 {
00876 double coeff0, coeff1, coeff2 ;
00877 cpl_size icoeff = 0 ;
00878
00879 coeff0 = cpl_polynomial_get_coeff( list->list[i].cenpoly, &icoeff ) ;
00880 icoeff = 1 ;
00881 coeff1 = cpl_polynomial_get_coeff( list->list[i].cenpoly, &icoeff ) ;
00882 icoeff = 2 ;
00883 coeff2 = cpl_polynomial_get_coeff( list->list[i].cenpoly, &icoeff ) ;
00884 xsh_msg_dbg_low( " Calculated Poly: %lf %lf %lf", coeff0, coeff1, coeff2 ) ;
00885 icoeff = 0 ;
00886 coeff0 = cpl_polynomial_get_coeff( guess_list->list[i].cenpoly, &icoeff ) ;
00887 icoeff = 1 ;
00888 coeff1 = cpl_polynomial_get_coeff( guess_list->list[i].cenpoly, &icoeff ) ;
00889 icoeff = 2 ;
00890 coeff2 = cpl_polynomial_get_coeff( guess_list->list[i].cenpoly, &icoeff ) ;
00891 xsh_msg_dbg_low( " Initial Poly: %lf %lf %lf", coeff0, coeff1, coeff2 ) ;
00892 }
00893
00894
00895
00896 poly_rms = sqrt( poly_rms ) ;
00897 xsh_msg_dbg_low( " Sigma Clipping - Polynomial RMS: %lf", poly_rms ) ;
00898
00899 for( nn = 0 ; nn < npos ; nn++ ) {
00900
00901
00902
00903 double xpoly, delta ;
00904
00905 xpoly = cpl_polynomial_eval_1d( list->list[i].cenpoly,
00906 (Centroids+nn)->position,
00907 NULL ) ;
00908 delta = fabs( xpoly - (Centroids+nn)->centervalue) ;
00909 if ( delta > poly_rms*dcn_clipping->sigma ) {
00910
00911
00912 xsh_msg_dbg_high( " Rejected at %.0lf,%.0lf (%lf > %lf)",
00913 (Centroids+nn)->centervalue,
00914 (Centroids+nn)->position,
00915 delta, poly_rms ) ;
00916 (Centroids+nn)->position = BAD_POSITION_FLAG ;
00917 (Centroids+nn)->flag = BAD_POSITION_FLAG ;
00918 nbad++ ;
00919 }
00920 }
00921 if ( nbad == 0 ) break ;
00922 totnbad += nbad ;
00923 xsh_msg_dbg_low( " Rejected Positions: %d (%d)", nbad, totnbad ) ;
00924
00925
00926
00927
00928 if ( ((float)(npts-totnbad)/(float)npts) < dcn_clipping->frac ) {
00929
00930 list->list[i].starty = -1 ;
00931 list->list[i].endy = -1 ;
00932 xsh_msg( "**** Too many rejected points: %d/%d (%.2f) Discard Order %d",
00933 totnbad, npts, (float)(npts-totnbad)/(float)npts, absorder ) ;
00934 break ;
00935 }
00936
00937
00938 for( nn = 0, mm = 0 ; nn<npos ; nn++ ) {
00939 if ( (Centroids+nn)->position != BAD_POSITION_FLAG ) {
00940 if ( mm != nn ) *(Centroids+mm) = *(Centroids+nn) ;
00941 mm++ ;
00942 }
00943 }
00944 npos = mm ;
00945 }
00946
00947 if ( list->list[i].starty != -1 ) {
00948 double coeff0, coeff1, coeff2 ;
00949 cpl_size icoeff = 0 ;
00950
00951 ndetected++ ;
00952 coeff0 = cpl_polynomial_get_coeff( list->list[i].cenpoly, &icoeff ) ;
00953 icoeff = 1 ;
00954 coeff1 = cpl_polynomial_get_coeff( list->list[i].cenpoly, &icoeff ) ;
00955 icoeff = 2 ;
00956 coeff2 = cpl_polynomial_get_coeff( list->list[i].cenpoly, &icoeff ) ;
00957 xsh_msg( " Polynomial Coeffs: %lf %lf %lf",
00958 coeff0, coeff1, coeff2 ) ;
00959
00960
00961
00962 cumulate_qc_parameter( i, list, Centroids, npos ) ;
00963 }
00964 }
00965
00966 xsh_msg( " ++ Nb of Detected Orders: %d", ndetected ) ;
00967 assure(ndetected > 0,CPL_ERROR_ILLEGAL_INPUT,
00968 "parameter detectcontinuum-search-window-half-size may have a too large value or detectcontinuum-ordertab-deg-y or detectcontinuum-clip-sigma or detectcontinuum-clip-res-max may have a too small value");
00969 if(DeltaPoints>0) {
00970 check(*resid_frame=calculate_qc_parameters( &ord_qc_param, instr )) ;
00971 }
00972
00973 ord_qc_param.ndet = ndetected ;
00974
00975
00976
00977
00978
00979 ord_qc_param.npred = list->size ;
00980 ord_qc_param.max_pred = 0;
00981 ord_qc_param.min_pred = 0 ;
00982 ord_qc_param.nposall = 0 ;
00983 ord_qc_param.npossel = 0 ;
00984
00985
00986
00987
00988 check(set_qc_parameters( list, &ord_qc_param, instr ) );
00989
00990
00991
00992
00993 {
00994 char frame_name[256];
00995 char tag[256];
00996 sprintf(tag,"%s",XSH_GET_TAG_FROM_ARM(XSH_ORDER_TAB_CENTR,instr));
00997 sprintf(frame_name,"%s%s",tag,".fits");
00998
00999 check(result = xsh_order_list_save(list,instr,frame_name,tag,pre->ny ));
01000
01001
01002 xsh_msg_dbg_high("%s Created", frame_name ) ;
01003 }
01004
01005
01006
01007 cleanup:
01008 if ( flog ) fclose( flog ) ;
01009
01010 xsh_free_vector( ¢ers ) ;
01011 xsh_free_vector( &xpos ) ;
01012 XSH_FREE( Centroids ) ;
01013 xsh_pre_free(&pre);
01014 xsh_order_list_free(&list);
01015 xsh_order_list_free(&guess_list);
01016
01017
01018 return result;
01019 }
01020