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