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
00027 #ifdef HAVE_CONFIG_H
00028 #include <config.h>
00029 #endif
00030
00031
00037
00040
00041
00042
00043
00044 #include <math.h>
00045 #include <xsh_drl.h>
00046 #include <xsh_utils_wrappers.h>
00047 #include <xsh_data_order.h>
00048 #include <xsh_error.h>
00049 #include <xsh_utils.h>
00050 #include <xsh_utils_image.h>
00051 #include <xsh_msg.h>
00052 #include <xsh_data_pre.h>
00053 #include <cpl.h>
00054
00055
00056
00057
00058 #define HALF_SLIC_WINDOW 5
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00078 static cpl_table*
00079 xsh_compute_flat_edges(cpl_frame* frame,
00080 xsh_order_list* list,
00081 xsh_instrument* instrument,
00082 const char* method)
00083 {
00084
00085 cpl_image* mflat=NULL;
00086 const char* name=NULL;
00087 const char* name_o=NULL;
00088 char name_t[256];
00089 cpl_image* filter_x=NULL;
00090 cpl_propertylist* plist=NULL;
00091
00092 cpl_table* tbl=NULL;
00093 cpl_table* res=NULL;
00094
00095 cpl_vector* vsliclo=NULL;
00096 cpl_vector* vslicup=NULL;
00097 cpl_vector* vedgelo=NULL;
00098 cpl_vector* vedgeup=NULL;
00099 cpl_vector* vypos=NULL;
00100
00101 int* porder=NULL;
00102 int* pabsorder=NULL;
00103
00104 double* pcenterx=NULL;
00105 double* pcentery=NULL;
00106
00107
00108 double* pedgelo=NULL;
00109 double* pedgeup=NULL;
00110 double* psliceup=NULL;
00111 double* pslicelo=NULL;
00112 double* psliceup_resx=NULL;
00113 double* pslicelo_resx=NULL;
00114
00115 double* pedgeup_resx=NULL;
00116 double* pedgelo_resx=NULL;
00117
00118
00119 double* pedgelof=NULL;
00120 double* pedgeupf=NULL;
00121 double* psliceupf=NULL;
00122 double* pslicelof=NULL;
00123 double* psliceupthresf=NULL;
00124 double* pslicelothresf=NULL;
00125
00126 double* ypos=NULL;
00127
00128
00129 double* edgelo=NULL;
00130 double* edgeup=NULL;
00131 double* sliclo=NULL;
00132 double* slicup=NULL;
00133
00134 double max=0;
00135 int img_starty=0;
00136 int img_endy=0;
00137 int i=0;
00138 int is_ifu=0;
00139 int sx=0;
00140 int sy=0;
00141 int rad=6;
00142 int y=0;
00143 int llx=0;
00144 int urx=0;
00145 int nrows=0;
00146 int k=0;
00147 int num=0;
00148 int nsel=0;
00149
00150 cpl_polynomial* sliclopoly=NULL;
00151 cpl_polynomial* slicuppoly=NULL;
00152 cpl_polynomial* edgelopoly=NULL;
00153 cpl_polynomial* edgeuppoly=NULL;
00154
00155
00156 check(name=cpl_frame_get_filename(frame));
00157 check(mflat=cpl_image_load(name,CPL_TYPE_FLOAT,0,0));
00158
00159
00160
00161
00162
00163
00164 check(sx=cpl_image_get_size_x(mflat));
00165 check(sy=cpl_image_get_size_y(mflat));
00166
00167 if(strcmp(method,"sobel") == 0) {
00168 check(filter_x=xsh_sobel_lx(mflat));
00169 } else {
00170 check(filter_x=xsh_scharr_x(mflat));
00171 }
00172
00173
00174
00175 check(max=cpl_image_get_max(filter_x));
00176 check(cpl_image_divide_scalar(filter_x,max));
00177 check(cpl_image_abs(filter_x));
00178
00179 if(xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM) {
00180 if(strcmp(method,"sobel") == 0) {
00181 check(cpl_image_save(filter_x,"sobel_lx_n.fits",CPL_BPP_IEEE_FLOAT,
00182 NULL,CPL_IO_DEFAULT));
00183 } else {
00184 check(cpl_image_save(filter_x,"scharr_x_n.fits",CPL_BPP_IEEE_FLOAT,
00185 NULL,CPL_IO_DEFAULT));
00186 }
00187 }
00188
00189 nrows=sy*list->size;
00190 check(tbl=cpl_table_new(nrows));
00191 check(cpl_table_new_column(tbl,"ORDER",CPL_TYPE_INT));
00192 check(cpl_table_new_column(tbl,"ABSORDER",CPL_TYPE_INT));
00193
00194 check(cpl_table_new_column(tbl,"CENTERX",CPL_TYPE_DOUBLE));
00195 check(cpl_table_new_column(tbl,"CENTERY",CPL_TYPE_DOUBLE));
00196 check(cpl_table_new_column(tbl,"EDGELOX",CPL_TYPE_DOUBLE));
00197 check(cpl_table_new_column(tbl,"EDGEUPX",CPL_TYPE_DOUBLE));
00198
00199 check(cpl_table_fill_column_window_int(tbl,"ORDER",0,nrows,-1));
00200 check(cpl_table_fill_column_window_int(tbl,"ABSORDER",0,nrows,-1));
00201
00202 check(cpl_table_fill_column_window_double(tbl,"CENTERX",0,nrows,-1));
00203 check(cpl_table_fill_column_window_double(tbl,"CENTERY",0,nrows,-1));
00204 check(cpl_table_fill_column_window_double(tbl,"EDGELOX",0,nrows,-1));
00205 check(cpl_table_fill_column_window_double(tbl,"EDGEUPX",0,nrows,-1));
00206
00207
00208 check(porder=cpl_table_get_data_int(tbl,"ORDER"));
00209 check(pabsorder=cpl_table_get_data_int(tbl,"ABSORDER"));
00210
00211 check(pcenterx=cpl_table_get_data_double(tbl,"CENTERX"));
00212 check(pcentery=cpl_table_get_data_double(tbl,"CENTERY"));
00213 check(pedgelo=cpl_table_get_data_double(tbl,"EDGELOX"));
00214 check(pedgeup=cpl_table_get_data_double(tbl,"EDGEUPX"));
00215
00216
00217 is_ifu = xsh_instrument_get_mode( instrument ) == XSH_MODE_IFU ;
00218 if ( is_ifu){
00219 xsh_msg( "Detect Order Edges in IFU mode");
00220 check(cpl_table_new_column(tbl,"SLICELOX",CPL_TYPE_DOUBLE));
00221 check(cpl_table_new_column(tbl,"SLICEUPX",CPL_TYPE_DOUBLE));
00222 check(cpl_table_new_column(tbl,"SLICELOTHRESFX",CPL_TYPE_DOUBLE));
00223 check(cpl_table_new_column(tbl,"SLICEUPTHRESFX",CPL_TYPE_DOUBLE));
00224
00225 check(pslicelothresf=cpl_table_get_data_double(tbl,"SLICELOTHRESFX"));
00226 check(psliceupthresf=cpl_table_get_data_double(tbl,"SLICEUPTHRESFX"));
00227 check(cpl_table_fill_column_window_double(tbl,"SLICELOTHRESFX",0,nrows,-1));
00228 check(cpl_table_fill_column_window_double(tbl,"SLICEUPTHRESFX",0,nrows,-1));
00229
00230 check(pslicelo=cpl_table_get_data_double(tbl,"SLICELOX"));
00231 check(psliceup=cpl_table_get_data_double(tbl,"SLICEUPX"));
00232 check(cpl_table_fill_column_window_double(tbl,"SLICELOX",0,nrows,-1));
00233 check(cpl_table_fill_column_window_double(tbl,"SLICEUPX",0,nrows,-1));
00234
00235 }
00236 else {
00237 xsh_msg( "Detect Order Edges in SLIT mode");
00238 }
00239
00240
00241 for(i=0; i< list->size; i++){
00242 porder[k]=list->list[i].order;
00243 pabsorder[k]=list->list[i].absorder;
00244
00245 img_starty = list->list[i].starty/list->bin_y;
00246 img_endy=list->list[i].endy/list->bin_y;
00247
00248
00249
00250
00251
00252
00253 if((list->list[i].starty == -999) ||
00254 (list->list[i].endy==-999)){
00255 xsh_msg("PROBLEMS tracing order %d",list->list[i].absorder);
00256 method="fixed";
00257 break;
00258 }
00259
00260 xsh_msg_dbg_medium("start=%d end=%d",img_starty,img_endy);
00261 for(y=img_starty; y<img_endy; y++){
00262 double xl = 0, xu = 0, xc=0, xsl=0, xsu=0;
00263 cpl_size px, py;
00264 int yb=y*list->bin_y;
00265
00266 check( xu = xsh_order_list_eval_int( list, list->list[i].edguppoly, y));
00267 check( xl = xsh_order_list_eval_int( list, list->list[i].edglopoly, y));
00268
00269 llx=(int)xl-rad;
00270 urx=(int)xl+rad;
00271 if((llx>0) && (urx< sx)) {
00272
00273 check( cpl_image_get_maxpos_window( filter_x, llx, y, urx, y, &px, &py));
00274 pedgelo[k] = px;
00275 pedgelo[k]*=list->bin_x;
00276 porder[k]=list->list[i].order;
00277 pabsorder[k]=list->list[i].absorder;
00278 }
00279
00280 llx=(int)xu-rad;
00281 urx=(int)xu+rad;
00282
00283 if((llx>0) && (urx< sx)) {
00284
00285 check( cpl_image_get_maxpos_window( filter_x, llx,y,urx,y, &px, &py));
00286 pedgeup[k] = px;
00287 pedgeup[k]*=list->bin_x;
00288 porder[k]=list->list[i].order;
00289 pabsorder[k]=list->list[i].absorder;
00290 }
00291
00292
00293 check( xc = xsh_order_list_eval( list, list->list[i].cenpoly, y));
00294 pcenterx[k]=xc*list->bin_y;
00295 pcentery[k]=yb;
00296
00297
00298 if ( is_ifu) {
00299 if ( list->list[i].sliclopoly != NULL ) {
00300 check(xsl=cpl_polynomial_eval_1d(list->list[i].sliclopoly,yb,NULL));
00301
00302 xsl /= list->bin_x;
00303 pslicelothresf[k] = xsl;
00304 llx=(int)xsl-rad;
00305 urx=(int)xsl+rad;
00306
00307 if((llx>0) && (urx)< sx) {
00308
00309
00310 check( cpl_image_get_maxpos_window( filter_x, llx, y, urx, y, &px, &py));
00311 pslicelo[k]=px;
00312 pslicelo[k]*=list->bin_x;
00313 porder[k]=list->list[i].order;
00314 pabsorder[k]=list->list[i].absorder;
00315 }
00316 }
00317
00318 if ( list->list[i].slicuppoly != NULL ) {
00319 check(xsu=cpl_polynomial_eval_1d(list->list[i].slicuppoly,yb,NULL));
00320 xsu /= list->bin_x;
00321 psliceupthresf[k] = xsu;
00322 llx=(int)xsu-rad;
00323 urx=(int)xsu+rad;
00324
00325 if((llx>0) && (urx)< sx) {
00326
00327
00328 check( cpl_image_get_maxpos_window( filter_x, llx, y, urx, y, &px, &py));
00329 psliceup[k]=px;
00330 psliceup[k]*=list->bin_x;
00331 porder[k]=list->list[i].order;
00332 pabsorder[k]=list->list[i].absorder;
00333 }
00334 }
00335
00336
00337 }
00338
00339 k++;
00340 }
00341
00342 }
00343
00344
00345 check(num=cpl_table_and_selected_int(tbl,"ORDER",CPL_GREATER_THAN,-1));
00346 check(res=cpl_table_extract_selected(tbl));
00347
00348
00349 xsh_free_table(&tbl);
00350 cpl_table_select_all(res);
00351
00352
00353 check(cpl_table_new_column(res,"EDGELOFX",CPL_TYPE_DOUBLE));
00354 check(cpl_table_new_column(res,"EDGEUPFX",CPL_TYPE_DOUBLE));
00355 check(cpl_table_fill_column_window_double(res,"EDGELOFX",0,num,-1));
00356 check(cpl_table_fill_column_window_double(res,"EDGEUPFX",0,num,-1));
00357
00358 check(cpl_table_new_column(res,"EDGELO_RESX",CPL_TYPE_DOUBLE));
00359 check(cpl_table_new_column(res,"EDGEUP_RESX",CPL_TYPE_DOUBLE));
00360 check(cpl_table_fill_column_window_double(res,"EDGELO_RESX",0,num,-1));
00361 check(cpl_table_fill_column_window_double(res,"EDGEUP_RESX",0,num,-1));
00362
00363 check(pedgelof=cpl_table_get_data_double(res,"EDGELOFX"));
00364 check(pedgeupf=cpl_table_get_data_double(res,"EDGEUPFX"));
00365 check(pedgelo_resx=cpl_table_get_data_double(res,"EDGELO_RESX"));
00366 check(pedgeup_resx=cpl_table_get_data_double(res,"EDGEUP_RESX"));
00367
00368 if ( is_ifu ) {
00369 check(cpl_table_new_column(res,"SLICELOFX",CPL_TYPE_DOUBLE));
00370 check(cpl_table_new_column(res,"SLICEUPFX",CPL_TYPE_DOUBLE));
00371
00372 check(cpl_table_fill_column_window_double(res,"SLICELOFX",0,num,-1));
00373 check(cpl_table_fill_column_window_double(res,"SLICEUPFX",0,num,-1));
00374 check(pslicelof=cpl_table_get_data_double(res,"SLICELOFX"));
00375 check(psliceupf=cpl_table_get_data_double(res,"SLICEUPFX"));
00376
00377 check(cpl_table_new_column(res,"SLICELO_RESX",CPL_TYPE_DOUBLE));
00378 check(cpl_table_new_column(res,"SLICEUP_RESX",CPL_TYPE_DOUBLE));
00379 check(cpl_table_fill_column_window_double(res,"SLICELO_RESX",0,num,-1));
00380 check(cpl_table_fill_column_window_double(res,"SLICEUP_RESX",0,num,-1));
00381 check(pslicelo_resx=cpl_table_get_data_double(res,"SLICELO_RESX"));
00382 check(psliceup_resx=cpl_table_get_data_double(res,"SLICEUP_RESX"));
00383
00384
00385 }
00386
00387 k=0;
00388 for(i=0; i< list->size; i++){
00389
00390
00391
00392
00393
00394
00395 if((list->list[i].starty == -999) ||
00396 (list->list[i].endy==-999)){
00397 xsh_msg("PROBLEMS");
00398 method="fixed";
00399 break;
00400 }
00401
00402 check(nsel=cpl_table_and_selected_int(res,"ABSORDER",CPL_EQUAL_TO,
00403 list->list[i].absorder));
00404 if(nsel>0) {
00405 check(tbl=cpl_table_extract_selected(res));
00406
00407 check(ypos=cpl_table_get_data_double(tbl,"CENTERY"));
00408 check(vypos = cpl_vector_wrap( nsel, ypos ));
00409
00410
00411 check(edgelo=cpl_table_get_data_double(tbl,"EDGELOX"));
00412 check(edgeup=cpl_table_get_data_double(tbl,"EDGEUPX"));
00413
00414 check(vedgelo = cpl_vector_wrap( nsel, edgelo ));
00415 check(vedgeup = cpl_vector_wrap( nsel, edgeup ));
00416
00417 check( xsh_free_polynomial( &edgelopoly));
00418 check(edgelopoly=xsh_polynomial_fit_1d_create( vypos, vedgelo,
00419 list->list[i].pol_degree,
00420 NULL));
00421
00422 check( xsh_free_polynomial( &edgeuppoly));
00423 check(edgeuppoly=xsh_polynomial_fit_1d_create( vypos, vedgeup,
00424 list->list[i].pol_degree,
00425 NULL));
00426
00427
00428
00429
00430
00431 check( xsh_free_polynomial( &list->list[i].edglopoly));
00432 check(list->list[i].edglopoly=xsh_polynomial_fit_1d_create( vypos, vedgelo,
00433 list->list[i].pol_degree,
00434 NULL));
00435
00436 check( xsh_free_polynomial( &list->list[i].edguppoly));
00437 check(list->list[i].edguppoly=xsh_polynomial_fit_1d_create( vypos, vedgeup,
00438 list->list[i].pol_degree,
00439 NULL));
00440
00441
00442
00443 for(y=0; y< nsel; y++){
00444 check( pedgelof[k+y] = cpl_polynomial_eval_1d(edgelopoly,ypos[y],NULL));
00445 check( pedgeupf[k+y] = cpl_polynomial_eval_1d(edgeuppoly,ypos[y],NULL));
00446
00447 pedgelo_resx[k+y] = pedgelof[k+y] - edgelo[y];
00448 pedgeup_resx[k+y] = pedgeupf[k+y] - edgeup[y];
00449
00450 }
00451 check( cpl_vector_unwrap(vedgeup )) ;
00452 check( cpl_vector_unwrap(vedgelo )) ;
00453
00454
00455 if ( is_ifu ) {
00456 check(sliclo=cpl_table_get_data_double(tbl,"SLICELOX"));
00457 check(slicup=cpl_table_get_data_double(tbl,"SLICEUPX"));
00458 check( vslicup = cpl_vector_wrap( nsel, slicup )) ;
00459 check( vsliclo = cpl_vector_wrap( nsel, sliclo )) ;
00460
00461 check( xsh_free_polynomial( &sliclopoly));
00462 check(sliclopoly=xsh_polynomial_fit_1d_create( vypos, vsliclo,
00463 list->list[i].pol_degree,
00464 NULL));
00465
00466 check( xsh_free_polynomial( &slicuppoly));
00467 check(slicuppoly=xsh_polynomial_fit_1d_create( vypos, vslicup,
00468 list->list[i].pol_degree,
00469 NULL));
00470
00471
00472
00473
00474 check( xsh_free_polynomial( &list->list[i].sliclopoly));
00475 check(list->list[i].sliclopoly=xsh_polynomial_fit_1d_create( vypos, vsliclo,
00476 list->list[i].pol_degree,
00477 NULL));
00478
00479 check( xsh_free_polynomial( &list->list[i].slicuppoly));
00480 check(list->list[i].slicuppoly=xsh_polynomial_fit_1d_create( vypos, vslicup,
00481 list->list[i].pol_degree,
00482 NULL));
00483
00484
00485
00486 for(y=0; y< nsel; y++){
00487 check( pslicelof[k+y] = cpl_polynomial_eval_1d(sliclopoly,ypos[y],NULL));
00488 check( psliceupf[k+y] = cpl_polynomial_eval_1d(slicuppoly,ypos[y],NULL));
00489 pslicelo_resx[k+y] = pslicelof[k+y] - sliclo[y];
00490 psliceup_resx[k+y] = psliceupf[k+y] - slicup[y];
00491 }
00492 check( cpl_vector_unwrap(vslicup )) ;
00493 check( cpl_vector_unwrap(vsliclo )) ;
00494 }
00495 k+=nsel;
00496 xsh_free_table(&tbl);
00497 cpl_vector_unwrap(vypos );
00498
00499 }
00500 cpl_table_select_all(res);
00501 }
00502
00503 if(xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM) {
00504
00505
00506 if ( instrument->mode == XSH_MODE_IFU) {
00507 if (instrument->arm != XSH_ARM_UVB) {
00508 check(name_o=XSH_GET_TAG_FROM_ARM(XSH_MEASURE_FLAT_IFU_EDGES,instrument));
00509 } else {
00510 if(instrument->lamp == XSH_LAMP_QTH) {
00511 check(name_o=XSH_MEASURE_FLAT_QTH_IFU_EDGES_UVB);
00512 } else {
00513 check(name_o=XSH_MEASURE_FLAT_D2_IFU_EDGES_UVB);
00514 }
00515 }
00516 } else {
00517 if (instrument->arm != XSH_ARM_UVB) {
00518 check(name_o=XSH_GET_TAG_FROM_ARM(XSH_MEASURE_FLAT_SLIT_EDGES,instrument));
00519 } else {
00520 if(instrument->lamp == XSH_LAMP_QTH) {
00521 check(name_o=XSH_MEASURE_FLAT_QTH_SLIT_EDGES_UVB);
00522 } else {
00523 check(name_o=XSH_MEASURE_FLAT_D2_SLIT_EDGES_UVB);
00524 }
00525 }
00526 }
00527 sprintf(name_t,"%s%s",name_o,".fits");
00528 check(plist=cpl_propertylist_load(name,0));
00529 check(cpl_table_save(res,plist,NULL,name_t,CPL_IO_DEFAULT));
00530 }
00531
00532 cleanup:
00533 check( xsh_free_polynomial( &sliclopoly));
00534 check( xsh_free_polynomial( &slicuppoly));
00535 check( xsh_free_polynomial( &edgelopoly));
00536 check( xsh_free_polynomial( &edgeuppoly));
00537 xsh_free_propertylist(&plist);
00538 xsh_free_image(&mflat);
00539 xsh_free_image(&filter_x);
00540 xsh_free_table(&tbl);
00541 return res;
00542
00543 }
00544
00545
00546
00567 static void xsh_eval_y_avg_chunk(xsh_pre* pre, int xc, int yc,
00568 int chunk_y_hsize, int x_hsize, const int decode_bp, double *flux, double *noise)
00569 {
00570 int nx, ny;
00571 float *data = NULL, *errs = NULL;
00572 int *qual = NULL;
00573 int res_size=0;
00574 int i,j;
00575 int nb_good_pixels=0;
00576
00577
00578 XSH_ASSURE_NOT_NULL( pre);
00579 XSH_ASSURE_NOT_NULL( flux);
00580 XSH_ASSURE_NOT_NULL( noise);
00581
00582 nx = pre->nx;
00583 ny = pre->ny;
00584 res_size = x_hsize*2+1;
00585
00586 XSH_ASSURE_NOT_ILLEGAL( xc-x_hsize >= 0);
00587 XSH_ASSURE_NOT_ILLEGAL( xc+x_hsize < nx);
00588 XSH_ASSURE_NOT_ILLEGAL( yc-chunk_y_hsize >= 0);
00589 XSH_ASSURE_NOT_ILLEGAL( yc+chunk_y_hsize < ny);
00590
00591
00592 check( data = cpl_image_get_data_float( pre->data));
00593 check( errs = cpl_image_get_data_float( pre->errs));
00594 check( qual = cpl_image_get_data_int( pre->qual));
00595
00596
00597 for(i=0; i< res_size; i++){
00598 flux[i]=0;
00599 noise[i]=0;
00600
00601 }
00602
00603 for(i=xc-x_hsize; i <= (xc+x_hsize); i++){
00604 nb_good_pixels = 0;
00605 int pix_val=i-xc+x_hsize;
00606
00607 for(j=yc-chunk_y_hsize; j <= (yc+chunk_y_hsize); j++){
00608 int j_nx_plus_i=j*nx+i;
00609 if ( (qual[j_nx_plus_i] & decode_bp) == 0){
00610 flux[pix_val]+=data[j_nx_plus_i];
00611 noise[pix_val]+=errs[j_nx_plus_i]*errs[j_nx_plus_i];
00612 nb_good_pixels++;
00613 }
00614 }
00615 if(nb_good_pixels>0) {
00616 flux[pix_val] /= nb_good_pixels;
00617 noise[pix_val]= sqrt(noise[pix_val])/nb_good_pixels;
00618 } else {
00619 noise[pix_val] = 1;
00620 }
00621 }
00622
00623 cleanup:
00624 return;
00625 }
00626
00639 static void
00640 xsh_detect_max_y( xsh_order_list* list,
00641 int chunk_hsize,
00642 cpl_polynomial *cen_poly,
00643 int cen_start,
00644 int cen_end,
00645 xsh_pre *pre,
00646 const int decode_bp,
00647 int* maxy)
00648 {
00649 int y;
00650 float flux_max;
00651 int *qual = NULL;
00652
00653
00654 XSH_ASSURE_NOT_NULL( cen_poly);
00655 XSH_ASSURE_NOT_NULL( pre);
00656 XSH_ASSURE_NOT_NULL( maxy);
00657 XSH_ASSURE_NOT_ILLEGAL( cen_start >=1);
00658 XSH_ASSURE_NOT_ILLEGAL( cen_end <= pre->ny);
00659
00660 check( qual = cpl_image_get_data_int( pre->qual));
00661 flux_max = 0.0;
00662 for(y=cen_start+chunk_hsize; y<= cen_end-chunk_hsize; y++){
00663 int x;
00664 double flux, noise;
00665
00666 check( x = xsh_order_list_eval_int( list, cen_poly, y));
00667
00668
00669 check( xsh_eval_y_avg_chunk( pre, x-1, y-1, chunk_hsize, 0,decode_bp,
00670 &flux, &noise));
00671 if ( flux > flux_max ){
00672 if ( (qual[x-1+(y-1)*pre->nx] & decode_bp) == 0 ){
00673
00674 flux_max = flux;
00675 *maxy = y;
00676 }
00677 }
00678 }
00679
00680 cleanup:
00681 return;
00682 }
00706 static void
00707 xsh_detect_edges( xsh_order_list* list,
00708 int y,
00709 cpl_polynomial *cen_poly,
00710 xsh_pre* pre,
00711 int window_hsize,
00712 double* res_flux,
00713 double* res_noise,
00714 int chunk_hsize,
00715 double min_snr,
00716 double flux_frac,
00717 int min_size_x,
00718 const int decode_bp,
00719 int *x_min,
00720 float *x_cen_sdivn,
00721 int *xup,
00722 int *xlow,
00723 float *min_low,
00724 float *min_up)
00725 {
00726 int x = 0;
00727 float min = 0.0, noise = 0.0, sdivn = 0.0;
00728 float threshold = 0.0;
00729 int j = 0, xmin = 0,xmax = 0;
00730 int window_size;
00731
00732
00733
00734
00735 XSH_ASSURE_NOT_NULL( cen_poly);
00736 XSH_ASSURE_NOT_NULL( pre);
00737 XSH_ASSURE_NOT_NULL( res_flux);
00738 XSH_ASSURE_NOT_NULL( res_noise);
00739
00740 XSH_ASSURE_NOT_NULL( x_min);
00741 XSH_ASSURE_NOT_NULL( x_cen_sdivn);
00742 XSH_ASSURE_NOT_NULL( xup);
00743 XSH_ASSURE_NOT_NULL( xlow);
00744 XSH_ASSURE_NOT_NULL( min_low);
00745 XSH_ASSURE_NOT_NULL( min_up);
00746
00747 window_size = window_hsize*2+1;
00748
00749
00750 check( x = xsh_order_list_eval_int( list, cen_poly, y));
00751 xmin = x-window_hsize;
00752 *x_min= xmin;
00753 xmax = x+window_hsize;
00754
00755
00756 if (xmin >= 1 && xmax <= pre->nx) {
00757
00758
00759
00760 check( xsh_eval_y_avg_chunk( pre, x-1, y-1, chunk_hsize, window_hsize,decode_bp,
00761 res_flux, res_noise));
00762
00763 noise = res_noise[window_hsize+1];
00764 sdivn = res_flux[window_hsize+1]/noise;
00765 *x_cen_sdivn = sdivn;
00766
00767 if ( sdivn > min_snr ){
00768
00769
00770
00771 min = res_flux[window_hsize+1];
00772 for(j = window_hsize+1; j<window_size; j++) {
00773 if (min > res_flux[j]){
00774 min = res_flux[j];
00775 }
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792 threshold = (res_flux[window_hsize+1]-min) * flux_frac;
00793
00794 j = window_hsize+1;
00795 while( (j < window_size-1) && ((res_flux[j]-min) >= threshold)){
00796 j++;
00797 }
00798 *xup = j;
00799 *min_up = min;
00800
00801 if ( (res_flux[j]-min) >= threshold){
00802 xsh_msg("WARNING UP edge not detected. Increase window size");
00803 *x_cen_sdivn = -1;
00804 }
00805
00806
00807 min = res_flux[window_hsize+1];
00808
00809
00810 for(j=0; j<=window_hsize+1; j++) {
00811 if (min > res_flux[j]){
00812 min = res_flux[j];
00813
00814 }
00815 }
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834 threshold = (res_flux[window_hsize+1]-min) * flux_frac;
00835 j = window_hsize+1;
00836 while( (j > 0) && ( (res_flux[j]-min) >= threshold)){
00837 j--;
00838 }
00839 *xlow = (double)j;
00840 *min_low = min;
00841 if ( (res_flux[j]-min) >= threshold){
00842 xsh_msg("WARNING LOW edge not detected. Increase window size");
00843 *x_cen_sdivn = -1;
00844 }
00845 if ( (*xup-*xlow) < min_size_x){
00846 xsh_msg_dbg_medium("y %d : Size of order in cross dispersion "\
00847 "to small %d < %d", y, *xup-*xlow, min_size_x);
00848 *x_cen_sdivn = -1;
00849 }
00850 }
00851 else{
00852 xsh_msg_dbg_medium("y %d Invalid s/n : %f > %f", y, sdivn, min_snr);
00853 }
00854 }
00855 else{
00856 xsh_msg_dbg_medium("y %d Invalid xmin %d or xmax %d", y, xmin, xmax);
00857 *x_cen_sdivn = -1;
00858 }
00859 cleanup:
00860 return;
00861 }
00862
00863 static void xsh_detect_slitlet_ratio( double* res_flux, int window_hsize,
00864 double min_low, double min_up, int xlow, int xup,
00865 double *ratio_low, double *ratio_up)
00866 {
00867 double avg_cen = 0., avg_lo=0., avg_up=0.;
00868 int j;
00869 int size;
00870 int center;
00871
00872
00873
00874 XSH_ASSURE_NOT_NULL( res_flux);
00875 XSH_ASSURE_NOT_NULL( ratio_up);
00876 XSH_ASSURE_NOT_NULL( ratio_low);
00877
00878 size = (xup-xlow)/3;
00879
00880 center = window_hsize+1;
00881
00882
00883 for( j=center-HALF_SLIC_WINDOW;
00884 j <= center+HALF_SLIC_WINDOW ; j++ ){
00885 avg_cen += res_flux[j];
00886 }
00887 avg_cen /= (HALF_SLIC_WINDOW*2)+1;
00888
00889
00890 center = window_hsize+1-size;
00891 for( j=center-HALF_SLIC_WINDOW;
00892 j <= center+HALF_SLIC_WINDOW ; j++ ){
00893 avg_lo += res_flux[j];
00894 }
00895 avg_lo /= (HALF_SLIC_WINDOW*2)+1;
00896
00897
00898 center = window_hsize+1+size;
00899 for( j=center-HALF_SLIC_WINDOW;
00900 j <= center+HALF_SLIC_WINDOW ; j++ ){
00901 avg_up += res_flux[j];
00902 }
00903 avg_up /= (HALF_SLIC_WINDOW*2)+1;
00904
00905
00906
00907 *ratio_up = (avg_up-min_up)/(avg_cen-min_up);
00908 *ratio_low = (avg_lo-min_low)/(avg_cen-min_low);
00909 cleanup:
00910 return;
00911 }
00928 cpl_frame* xsh_detect_order_edge(cpl_frame *frame,
00929 cpl_frame *cen_order_tab_frame, xsh_detect_order_param *detectorder_par,
00930 xsh_instrument *instrument) {
00931
00932 cpl_frame * result = NULL;
00933
00934 xsh_pre* pre = NULL;
00935 xsh_order_list* list = NULL;
00936 double* positions = NULL;
00937 double* uppervalues = NULL;
00938 double* lowervalues = NULL;
00939 double * slicup = NULL;
00940 double * sliclow = NULL;
00941 cpl_vector* xpos = NULL;
00942 cpl_vector* upper = NULL;
00943 cpl_vector* lower = NULL;
00944 cpl_vector * vslicup = NULL;
00945 cpl_vector * vsliclow = NULL;
00946
00947
00948 int y = 0;
00949 int size = 0, i = 0, k = 0;
00950 int is_ifu = 0;
00951 char *fname = NULL;
00952 const char * tag = NULL;
00953
00954
00955 int window_size, min_order_size_x, chunk_hsize, window_hsize;
00956 double min_snr, slitlet_up_factor, slitlet_low_factor;
00957 double *res_flux = NULL, *res_noise = NULL;
00958 double flux_frac;
00959 int fixed_slice = 0;
00960 const char* method = NULL;
00961
00962 cpl_table* tab_edges_res = NULL;
00963 int bad_points = 0;
00964
00965
00966 XSH_ASSURE_NOT_NULL(frame);
00967 XSH_ASSURE_NOT_NULL(cen_order_tab_frame);
00968 XSH_ASSURE_NOT_NULL(detectorder_par);
00969
00970
00971 window_hsize = detectorder_par->search_window_hsize;
00972 window_size = window_hsize * 2 + 1;
00973 min_order_size_x = detectorder_par->min_order_size_x;
00974
00975 flux_frac = detectorder_par->flux_thresh;
00976 min_snr = detectorder_par->min_sn;
00977 slitlet_low_factor = detectorder_par->slitlet_low_factor;
00978 slitlet_up_factor = detectorder_par->slitlet_up_factor;
00979 chunk_hsize = detectorder_par->chunk_hsize;
00980 fixed_slice = detectorder_par->fixed_slice;
00981 method = detectorder_par->method;
00982
00983
00984 assure(window_size > 0, CPL_ERROR_ILLEGAL_INPUT,
00985 "window_size=%d (window_size=window_hsize*2+1) < 0 "
00986 "parameter detectorder-edges-search-window-half-size=%d "
00987 "may have been set to a too large value", window_size, window_hsize);
00988
00989
00990 xsh_msg_dbg_medium("Parameters");
00991 xsh_msg_dbg_medium(
00992 " Window: %d,flux-Thresh: %.2f, S/N: %.2f", window_size, flux_frac, min_snr);
00993 xsh_msg_dbg_medium(
00994 " min-size-x: %d, Slitlet-low-factor: %.2f\
00995 Slitlet-up-factor: %.2f chunk-half-size %d", min_order_size_x, slitlet_low_factor, slitlet_up_factor, chunk_hsize);
00996 xsh_msg_dbg_medium(" fixed-slice = %s", BOOLEAN_TO_STRING(fixed_slice));
00997
00998
00999 check( pre = xsh_pre_load( frame, instrument));
01000
01001 check(list = xsh_order_list_load( cen_order_tab_frame, instrument));
01002
01003 assure(
01004 min_order_size_x > 0 && min_order_size_x < (floor) (pre->nx / list->size),
01005 CPL_ERROR_ILLEGAL_INPUT, "parameter detectorder-min-order-size-x=%d "
01006 "has been set to a too small or too large value", min_order_size_x);
01007
01008
01009
01010
01011 XSH_REGDEBUG("binning %dx%d", list->bin_x, list->bin_y);
01012
01013 xsh_free_propertylist(&(list->header));
01014 XSH_NEW_PROPERTYLIST( list->header);
01015
01016
01017
01018
01019 is_ifu = xsh_instrument_get_mode(instrument) == XSH_MODE_IFU;
01020 if (is_ifu) {
01021 xsh_msg( "Detect Order Edges in IFU mode");
01022 } else {
01023 xsh_msg( "Detect Order Edges in SLIT mode");
01024 }
01025
01026
01027
01028
01029 XSH_CALLOC( positions, double, pre->ny*list->bin_y);
01030 XSH_CALLOC ( uppervalues,double,pre->ny*list->bin_y);
01031 XSH_CALLOC( lowervalues, double,pre->ny*list->bin_y);
01032 XSH_CALLOC ( res_flux, double, window_size);
01033 XSH_CALLOC( res_noise, double,window_size);
01034
01035 XSH_CALLOC ( slicup,double,pre->ny*list->bin_y);
01036 XSH_CALLOC( sliclow, double,pre->ny*list->bin_y);
01037
01038
01039 int decode_bp = instrument->decode_bp;
01040
01041 for (i = 0; i < list->size; i++) {
01042 int mean_size_up = 0;
01043 int mean_size_low = 0;
01044 int mean_size_slic_low = 0;
01045 int mean_size_slic_up = 0;
01046 double ratio_low = 0., ratio_up = 0.;
01047 int bin_starty;
01048 int bin_endy;
01049
01050 size = 0;
01051 check( bin_starty = xsh_order_list_get_starty( list, i));
01052 check( bin_endy = xsh_order_list_get_endy( list, i));
01053 xsh_msg_dbg_medium( "***** Order %d (%d-->%d)", i, bin_starty, bin_endy);
01054
01055 if (is_ifu && !fixed_slice) {
01056 int max_y = 0;
01057 float min_lo = 0.0, min_up = 0.0, sdivn = 0.0;
01058 int xmin = 0;
01059 int upperval = 0, lowval = 0;
01060
01061
01062
01063
01064 check(
01065 xsh_detect_max_y( list, chunk_hsize, list->list[i].cenpoly, bin_starty, bin_endy, pre,decode_bp, &max_y));
01066 xsh_msg("Max at %d", max_y);
01067
01068
01069 check(
01070 xsh_detect_edges( list, max_y, list->list[i].cenpoly, pre, window_hsize, res_flux, res_noise, chunk_hsize, min_snr, flux_frac, min_order_size_x,decode_bp, &xmin, &sdivn, &upperval, &lowval, &min_lo, &min_up));
01071
01072
01073 xsh_msg_dbg_medium("order size at center %d", upperval-lowval);
01074
01075
01076
01077
01078 check(
01079 xsh_detect_slitlet_ratio( res_flux, window_hsize, min_lo, min_up, lowval, upperval, &ratio_low, &ratio_up));
01080 xsh_msg_dbg_medium("ratio low %f up %f", ratio_low, ratio_up);
01081 }
01082
01083 bad_points = 0;
01084 for (y = 1 + chunk_hsize; y <= pre->ny - chunk_hsize; y++) {
01085
01086
01087 float min_lo = 0.0, min_up = 0.0, sdivn = 0.0;
01088 int j = 0, xmin = 0;
01089 int upperval = 0, lowval = 0;
01090 double xslicup = 0.;
01091 double xsliclow = 0.;
01092
01093
01094 check(
01095 xsh_detect_edges( list, y, list->list[i].cenpoly, pre, window_hsize, res_flux, res_noise, chunk_hsize, min_snr, flux_frac, min_order_size_x,decode_bp, &xmin, &sdivn, &upperval, &lowval, &min_lo, &min_up));
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106 if ((sdivn > min_snr) && is_ifu) {
01107 if (fixed_slice) {
01108 int slit_size = ceil((upperval - lowval + 1) / 3.0);
01109
01110 xsliclow = lowval + slit_size;
01111 xslicup = upperval - slit_size;
01112 } else {
01113 double avg = 0.;
01114 double max;
01115
01116 for (j = window_hsize + 1 - HALF_SLIC_WINDOW;
01117 j <= window_hsize + 1 + HALF_SLIC_WINDOW; j++) {
01118 avg += res_flux[j];
01119 }
01120 avg /= (HALF_SLIC_WINDOW * 2) + 1;
01121 max = (avg - min_up) * slitlet_up_factor * ratio_up;
01122 xslicup = 0;
01123 for (j = window_hsize + 1; j <= upperval; j++) {
01124 if ((res_flux[j] - min_up) < max) {
01125
01126 xslicup = j - 1;
01127 break;
01128 }
01129 }
01130 xsliclow = 0;
01131 max = (avg - min_lo) * slitlet_low_factor * ratio_low;
01132 for (j = window_hsize + 1; j >= lowval; j--) {
01133 if ((res_flux[j] - min_lo) < max) {
01134
01135 xsliclow = j + 1;
01136 break;
01137 }
01138 }
01139 }
01140 }
01141
01142 if ((sdivn > min_snr) && (upperval - lowval) >= min_order_size_x) {
01143 if (!is_ifu) {
01144 positions[size] = y;
01145 lowervalues[size] = lowval + xmin;
01146 uppervalues[size] = upperval + xmin;
01147 mean_size_low += window_hsize + 1 - lowval;
01148 mean_size_up += upperval - (window_hsize + 1);
01149 size++;
01150 } else if (xslicup != 0 && xsliclow != 0) {
01151
01152 positions[size] = y;
01153 lowervalues[size] = lowval + xmin;
01154 uppervalues[size] = upperval + xmin;
01155 mean_size_low += window_hsize + 1 - lowval;
01156 mean_size_up += upperval - (window_hsize + 1);
01157 slicup[size] = xslicup + xmin;
01158 sliclow[size] = xsliclow + xmin;
01159 mean_size_slic_low += window_hsize + 1 - xsliclow;
01160 mean_size_slic_up += xslicup - (window_hsize + 1);
01161 size++;
01162 }
01163 } else {
01164 xsh_msg_dbg_medium(
01165 "Order %d edge detection: sn (%g) < sn_threshold (%g) or order size (%d) < min order size min (%d)", list->list[i].absorder, sdivn, min_snr, (upperval - lowval), min_order_size_x);
01166 bad_points++;
01167 }
01168
01169
01170 }
01171 if (bad_points > 1) {
01172 xsh_msg_dbg_medium(
01173 "Order %d edge detection summary: ", list->list[i].absorder);
01174 xsh_msg_dbg_medium(
01175 "%d out of %d not matching user defined min S/N (%g), or minimum order size", bad_points, pre->ny-2*chunk_hsize, min_snr);
01176 }
01177
01178
01179 if (size <= 3 && detectorder_par->qc_mode == CPL_TRUE) {
01180
01181
01182
01183
01184
01185
01186 list->list[i].starty = -999;
01187 list->list[i].endy = -999;
01188 xsh_msg("PROBLEMS");
01189
01190 method = "fixed";
01191 xsh_msg_error(
01192 "%d out of %d not matching user defined min S/N (%g), or minimum order size", bad_points, pre->ny-2*chunk_hsize, min_snr);
01193
01194 break;
01195
01196 } else {
01197 assure(
01198 size > 3,
01199 CPL_ERROR_ILLEGAL_INPUT,
01200 "can't fit polynomial solution of degree %d to only %d data points "
01201 "parameter detectorder-edges-search-window-half-size=%d "
01202 "may have a too small value "
01203 "or parameter detectorder-min-sn value may be too big "
01204 "or parameter detectorder-chunk-half-size=%d "
01205 "may have been set to a too small or too large large value "
01206 "or parameter detectorder-edges-flux-thresh=%g "
01207 "may have been set to a too small or too large large value", list->list[i].pol_degree, size, window_hsize, chunk_hsize, flux_frac);
01208
01209 list->list[i].starty = positions[0] - chunk_hsize;
01210 list->list[i].endy = positions[size - 1] + chunk_hsize;
01211 }
01212
01213 mean_size_up = mean_size_up / size;
01214 mean_size_low = mean_size_low / size;
01215 xsh_msg_dbg_medium("mean size up %d low %d", mean_size_up, mean_size_low);
01216 if (is_ifu) {
01217 mean_size_slic_low = mean_size_slic_low / size;
01218 mean_size_slic_up = mean_size_slic_up / size;
01219 }
01220 xsh_msg_dbg_medium(
01221 "mean size Slitlets up %d low %d", mean_size_slic_up, mean_size_slic_low);
01222
01223 xsh_msg_dbg_medium(
01224 "starty %d endy %d", list->list[i].starty, list->list[i].endy);
01225
01226 for (y = 1; y < list->list[i].starty; y++) {
01227 int x_center;
01228
01229 check(
01230 x_center = xsh_order_list_eval_int( list, list->list[i].cenpoly, y));
01231 positions[size] = y;
01232 lowervalues[size] = x_center - mean_size_low;
01233 uppervalues[size] = x_center + mean_size_up;
01234 if (is_ifu) {
01235 sliclow[size] = x_center - mean_size_slic_low;
01236 slicup[size] = x_center + mean_size_slic_up;
01237 }
01238 size++;
01239 }
01240 for (y = list->list[i].endy + 1; y <= pre->ny; y++) {
01241 int x_center;
01242
01243 check(
01244 x_center = xsh_order_list_eval_int( list, list->list[i].cenpoly, y));
01245 positions[size] = y;
01246 lowervalues[size] = x_center - mean_size_low;
01247 uppervalues[size] = x_center + mean_size_up;
01248
01249 if (is_ifu) {
01250 sliclow[size] = x_center - mean_size_slic_low;
01251 slicup[size] = x_center + mean_size_slic_up;
01252 }
01253 size++;
01254 }
01255
01256
01257 if (xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM) {
01258 FILE* debug_out = NULL;
01259 int newi = 0;
01260 char openmode[2];
01261
01262 if (i == 0) {
01263 sprintf(openmode, "w");
01264 } else {
01265 sprintf(openmode, "a");
01266 }XSH_NAME_LAMP_MODE_ARM( fname, "detect_edges_points", ".log",
01267 instrument);
01268 debug_out = fopen(fname, openmode);
01269
01270 for (newi = 0; newi < size; newi++) {
01271 fprintf(debug_out, "%f %f %f\n", lowervalues[newi], uppervalues[newi],
01272 positions[newi]);
01273 }
01274 fclose(debug_out);
01275 if (is_ifu) {
01276 XSH_NAME_LAMP_MODE_ARM( fname, "orders_slic", ".log", instrument);
01277 debug_out = fopen(fname, openmode);
01278
01279 for (newi = 0; newi < size; newi++) {
01280 fprintf(debug_out, "%f %f %f\n", sliclow[newi], slicup[newi],
01281 positions[newi]);
01282 }
01283 fclose(debug_out);
01284 }
01285 }
01286
01287 list->list[i].starty *= list->bin_y;
01288 list->list[i].endy *= list->bin_y;
01289
01290 for (k = 0; k < size; k++) {
01291 lowervalues[k] *= list->bin_x;
01292 uppervalues[k] *= list->bin_x;
01293 positions[k] *= list->bin_y;
01294 if (is_ifu) {
01295 sliclow[k] *= list->bin_x;
01296 slicup[k] *= list->bin_x;
01297 }
01298 }
01299
01300 check(xpos = cpl_vector_wrap(size,positions));
01301 check(upper = cpl_vector_wrap(size,uppervalues));
01302 check(lower = cpl_vector_wrap(size,lowervalues));
01303 if (is_ifu) {
01304 check( vslicup = cpl_vector_wrap( size, slicup ));
01305 check( vsliclow = cpl_vector_wrap( size, sliclow ));
01306 }
01307
01308
01309
01310 check( xsh_free_polynomial( &list->list[i].edguppoly));
01311 check(
01312 list->list[i].edguppoly = xsh_polynomial_fit_1d_create( xpos, upper, list->list[i].pol_degree, NULL));
01313
01314 check( xsh_free_polynomial( &list->list[i].edglopoly));
01315 check(
01316 list->list[i].edglopoly = xsh_polynomial_fit_1d_create( xpos, lower, list->list[i].pol_degree, NULL));
01317
01318 if (is_ifu) {
01319 check( xsh_free_polynomial( &list->list[i].sliclopoly));
01320 check(
01321 list->list[i].sliclopoly = xsh_polynomial_fit_1d_create( xpos, vsliclow, list->list[i].pol_degree, NULL));
01322 check( xsh_free_polynomial( &list->list[i].slicuppoly));
01323 check(
01324 list->list[i].slicuppoly = xsh_polynomial_fit_1d_create( xpos, vslicup, list->list[i].pol_degree,NULL));
01325 }
01326
01327
01328
01329 check( xsh_unwrap_vector(&xpos));
01330 check( xsh_unwrap_vector(&upper));
01331 check( xsh_unwrap_vector(&lower));
01332 if (is_ifu) {
01333 check( xsh_unwrap_vector( &vslicup));
01334 check( xsh_unwrap_vector( &vsliclow));
01335 }
01336
01337 }
01338
01339 if (strcmp(method, "fixed") != 0) {
01340 check(tab_edges_res=xsh_compute_flat_edges(frame,list,instrument,method));
01341 }
01342
01343 tag = XSH_GET_TAG_FROM_LAMP( XSH_ORDER_TAB_EDGES,instrument);
01344 XSH_REGDEBUG( "tag %s", tag);
01345 XSH_NAME_LAMP_MODE_ARM( fname, XSH_ORDER_TAB_EDGES, ".fits", instrument);
01346 check ( result = xsh_order_list_save( list, instrument, fname, tag, pre->ny*list->bin_y));
01347
01348 if (strcmp(method, "fixed") != 0) {
01349 check(cpl_table_save(tab_edges_res, NULL, NULL, fname, CPL_IO_EXTEND));
01350 }
01351
01352 xsh_msg_dbg_high( " Created %s", fname);
01353
01354 cleanup: if (cpl_error_get_code() != CPL_ERROR_NONE) {
01355 xsh_unwrap_vector(&xpos);
01356 xsh_unwrap_vector(&upper);
01357 xsh_unwrap_vector(&lower);
01358 xsh_unwrap_vector(&vslicup);
01359 xsh_unwrap_vector(&vsliclow);
01360 }
01361 xsh_pre_free(&pre);
01362 xsh_free_table(&tab_edges_res);
01363
01364 xsh_order_list_free(&list);
01365 XSH_FREE( positions);
01366 XSH_FREE( uppervalues);
01367 XSH_FREE( lowervalues);
01368 XSH_FREE( res_flux);
01369 XSH_FREE( res_noise);
01370 XSH_FREE( slicup);
01371 XSH_FREE( sliclow);
01372 XSH_FREE( fname);
01373 return result;
01374 }
01375
01376
01377