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
00038
00041
00042
00043
00044
00045 #include <math.h>
00046
00047 #include <xsh_drl.h>
00048 #include <xsh_data_pre.h>
00049 #include <xsh_dfs.h>
00050 #include <xsh_pfits.h>
00051 #include <xsh_error.h>
00052 #include <xsh_msg.h>
00053 #include <cpl.h>
00054 #include <xsh_badpixelmap.h>
00055 #include <xsh_parameters.h>
00056 #include <xsh_utils_wrappers.h>
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 #define MAX_ITERATIONS 6
00068 #define REGDEBUG_FULL 0
00069
00070
00071
00072
00081 static void add_qc_crh (xsh_pre* pre, int nbcrh, int nframes,
00082 xsh_instrument * instrument )
00083 {
00084 double qc_crrate = 0.0;
00085 int nbcr_avg ;
00087 XSH_ASSURE_NOT_NULL(pre);
00088 XSH_ASSURE_NOT_ILLEGAL(pre->pszx >0. && pre->pszy > 0);
00089 XSH_ASSURE_NOT_ILLEGAL(pre->exptime > 0);
00090
00091
00092
00093
00094
00095
00096 xsh_msg_dbg_medium( "add_qc_crh - Exptime = %f", pre->exptime ) ;
00097 qc_crrate =
00098 (double) nbcrh / (((double) nframes) * (pre->exptime *
00099 (pre->pszx / 10000.0) * (pre->pszy /10000.0) * pre->nx * pre->ny)) ;
00100 nbcr_avg = nbcrh/nframes ;
00101
00102
00103
00104
00105 check( xsh_pfits_set_qc_crrate( pre->data_header,qc_crrate) ) ;
00106 check( xsh_pfits_set_qc_ncrh( pre->data_header,nbcrh) ) ;
00107 check( xsh_pfits_set_qc_ncrh_mean( pre->data_header,nbcr_avg) ) ;
00108
00109 check( xsh_pfits_set_qc_crrate( pre->qual_header,qc_crrate) ) ;
00110 check( xsh_pfits_set_qc_ncrh( pre->qual_header,nbcrh) ) ;
00111 check( xsh_pfits_set_qc_ncrh_mean( pre->qual_header,nbcr_avg) ) ;
00112 cleanup:
00113 return ;
00114 }
00115
00116
00117
00118
00119
00120 cpl_frame * xsh_abs_remove_crh_single( cpl_frame *sci_frame,
00121 cpl_frame* wavemap_frame,
00122 xsh_instrument * instrument,
00123 xsh_remove_crh_single_param * single_par,
00124 const char * res_tag)
00125 {
00126 cpl_frame *result_frame = NULL;
00127 cpl_frame *abs_frame = NULL;
00128 cpl_frame *sign_frame = NULL;
00129 cpl_frame *rmcrh_frame = NULL;
00130 const char* name = NULL;
00131 cpl_propertylist *header = NULL;
00132 int qc_ncrh =0;
00133
00134 XSH_ASSURE_NOT_NULL( sci_frame);
00135
00136 check( name = cpl_frame_get_filename( sci_frame));
00137 check( header = cpl_propertylist_load( name, 0));
00138 if(cpl_propertylist_has(header,XSH_QC_CRH_NUMBER)) {
00139 check( qc_ncrh = xsh_pfits_get_qc_ncrh( header));
00140 } else {
00141 qc_ncrh =0;
00142 }
00143
00144 if (qc_ncrh > 0){
00145 xsh_msg( "Not use remove crh single");
00146 check( result_frame = cpl_frame_duplicate( sci_frame));
00147 }
00148 else{
00149 check( abs_frame = xsh_frame_abs( sci_frame, instrument, &sign_frame));
00150 check( rmcrh_frame = xsh_remove_crh_single( abs_frame, wavemap_frame, instrument,
00151 single_par, res_tag));
00152 check( result_frame = xsh_frame_mult( rmcrh_frame, instrument, sign_frame));
00153 }
00154
00155 cleanup:
00156 if (cpl_error_get_code() != CPL_ERROR_NONE){
00157 xsh_free_frame( &result_frame);
00158 }
00159 xsh_free_propertylist( &header);
00160 xsh_free_frame( &abs_frame);
00161 xsh_free_frame( &sign_frame);
00162 xsh_free_frame( &rmcrh_frame);
00163 return result_frame;
00164 }
00165
00166
00183
00184 cpl_frame * xsh_remove_crh_single( cpl_frame * in_sci_frame,
00185 cpl_frame* wavemap,
00186 xsh_instrument * instrument,
00187 xsh_remove_crh_single_param * single_par,
00188 const char * res_tag )
00189 {
00190 int i,j,k,l,m;
00191 double sigma_lim, f_lim, frac_max, frac = 0.;
00192
00193 cpl_frame* res_frame = NULL ;
00194 int *qual = NULL;
00195 char* res_name=NULL;
00196
00197 cpl_image* laplacian_image = NULL;
00198 cpl_image* laplacian_redu_image = NULL;
00199 cpl_image* two_sub_sample = NULL;
00200 cpl_image* sci_median5_image = NULL;
00201 cpl_image* noise_image = NULL;
00202 cpl_image* s_image = NULL;
00203 cpl_image* s_median_image = NULL;
00204 cpl_image* s2_image = NULL;
00205 cpl_image* sci_median3_image = NULL;
00206 cpl_image* sci_median3_7_image = NULL;
00207 cpl_image* f_image = NULL;
00208 cpl_image* r_image = NULL;
00209 cpl_image* c_image = NULL;
00210 int two_sub_sample_nx = 0;
00211 int two_sub_sample_ny = 0;
00212 xsh_pre* in_sci_pre = NULL;
00213 xsh_pre* sci_pre = NULL;
00214 cpl_image* sci_image = NULL;
00215
00216 float* sci_data = NULL;
00217 float* two_sub_sample_data = NULL;
00218 float* laplacian_data = NULL;
00219 float* laplacian_redu_data = NULL;
00220 float* sci_median5_data = NULL;
00221 float* sci_median3_data = NULL;
00222 float* sci_median3_7_data = NULL;
00223 float* noise_data = NULL;
00224 float* s_data = NULL;
00225 float* s_median_data = NULL;
00226 float* s2_data = NULL;
00227 float* f_data = NULL;
00228 float* r_data = NULL;
00229 int* c_data = NULL;
00230
00231
00232 cpl_matrix* laplacian_kernel = NULL;
00233 cpl_matrix* median3_kernel = NULL;
00234 cpl_matrix* median5_kernel = NULL;
00235 cpl_matrix* median7_kernel = NULL;
00236 int new_crh =1, nb_crh = 0;
00237 int nbiter = 1, max_iter = MAX_ITERATIONS ;
00238 cpl_vector* median = NULL;
00239 cpl_image* w_image=NULL;
00240 double* w_data=NULL;
00241 const char* w_name=NULL;
00242 int fctx=1;
00243 int fcty=1;
00244 int wmap_xsize_diff=0;
00245 double ron, conad;
00246
00247
00248 XSH_ASSURE_NOT_NULL_MSG( in_sci_frame,"Null input science frame" ) ;
00249 XSH_ASSURE_NOT_NULL_MSG( single_par,"Null input parameters" ) ;
00250 XSH_ASSURE_NOT_NULL_MSG( instrument,"Null instrument setting" ) ;
00251
00252 sigma_lim = single_par->sigma_lim;
00253 f_lim = single_par->f_lim;
00254 frac_max = single_par->crh_frac_max ;
00255 max_iter = single_par->nb_iter ;
00256 xsh_msg_dbg_high( " Params: frac_max %.1f, sigma_lim %.2f f_lim %.2f, iter %d",
00257 single_par->crh_frac_max, sigma_lim, f_lim, max_iter);
00258
00259
00260 check( in_sci_pre = xsh_pre_load( in_sci_frame, instrument));
00261 ron = in_sci_pre->ron;
00262 conad = in_sci_pre->conad;
00263 check( sci_pre = xsh_pre_duplicate( in_sci_pre ) ) ;
00264 xsh_pre_free(&in_sci_pre);
00265 check( sci_image = xsh_pre_get_data( sci_pre));
00266 check ( qual = cpl_image_get_data_int( sci_pre->qual));
00267
00268 if(wavemap!=NULL) {
00269 check( w_name = cpl_frame_get_filename( wavemap));
00270 check( w_image = cpl_image_load( w_name, CPL_TYPE_DOUBLE,0, 0));
00271 } else {
00272
00273
00274 check( w_image = cpl_image_new(sci_pre->nx,sci_pre->ny,CPL_TYPE_DOUBLE));
00275 cpl_image_add_scalar(w_image,1.);
00276 }
00277
00278 fctx=cpl_image_get_size_x(w_image)/sci_pre->nx;
00279 fcty=cpl_image_get_size_y(w_image)/sci_pre->ny;
00280 if( xsh_instrument_get_arm(instrument) == XSH_ARM_NIR){
00281 fctx = (fctx<1) ? 1 : fctx;
00282 fcty = (fcty<1) ? 1 : fcty;
00283 wmap_xsize_diff=sci_pre->nx-cpl_image_get_size_x(w_image);
00284 }
00285
00286 xsh_msg_dbg_low("fctx=%d fcty=%d",fctx,fcty);
00287 xsh_msg_dbg_low("sci nx=%d ny=%d",sci_pre->nx,sci_pre->ny);
00288
00289 check(w_data=cpl_image_get_data_double(w_image));
00290
00291
00292
00293 xsh_msg_dbg_low("--remove-crh-single : Preparing kernels");
00294
00295 check( laplacian_kernel = cpl_matrix_new(3,3));
00296 cpl_matrix_set( laplacian_kernel,0,0,0.0);
00297 cpl_matrix_set( laplacian_kernel,0,1,-1.0);
00298 cpl_matrix_set( laplacian_kernel,0,2,0.0);
00299 cpl_matrix_set( laplacian_kernel,1,0,-1.0);
00300 cpl_matrix_set( laplacian_kernel,1,1,4.0);
00301 cpl_matrix_set( laplacian_kernel,1,2,-1.0);
00302 cpl_matrix_set( laplacian_kernel,2,0,0.0);
00303 cpl_matrix_set( laplacian_kernel,2,1,-1.0);
00304 cpl_matrix_set( laplacian_kernel,2,2,0.0);
00305 cpl_matrix_divide_scalar( laplacian_kernel, 4.0);
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 check( median3_kernel = cpl_matrix_new(3,3));
00320 for(j=0; j< 3; j++){
00321 for(i=0; i< 3; i++){
00322 cpl_matrix_set( median3_kernel, i,j,1.0);
00323 }
00324 }
00325
00326
00327 check( median5_kernel = cpl_matrix_new(5,5));
00328 for(j=0; j< 5; j++){
00329 for(i=0; i< 5; i++){
00330 cpl_matrix_set( median5_kernel, i,j,1.0);
00331 }
00332 }
00333
00334
00335 check( median7_kernel = cpl_matrix_new(7,7));
00336 for(j=0; j< 7; j++){
00337 for(i=0; i< 7; i++){
00338 cpl_matrix_set( median7_kernel, i,j,1.0);
00339 }
00340 }
00341
00342
00343
00344 check (sci_data = cpl_image_get_data_float( sci_image));
00345
00346 two_sub_sample_nx = sci_pre->nx*2;
00347 two_sub_sample_ny = sci_pre->ny*2;
00348 check( two_sub_sample = cpl_image_new( two_sub_sample_nx,
00349 two_sub_sample_ny, CPL_TYPE_FLOAT));
00350 check (two_sub_sample_data = cpl_image_get_data_float( two_sub_sample));
00351 check( laplacian_redu_image = cpl_image_new( sci_pre->nx,
00352 sci_pre->ny, CPL_TYPE_FLOAT));
00353 check (laplacian_redu_data = cpl_image_get_data_float(
00354 laplacian_redu_image));
00355 check( noise_image = cpl_image_new( sci_pre->nx,
00356 sci_pre->ny, CPL_TYPE_FLOAT));
00357 check ( noise_data = cpl_image_get_data_float( noise_image));
00358 check( s_image = cpl_image_new( sci_pre->nx,
00359 sci_pre->ny, CPL_TYPE_FLOAT));
00360 check ( s_data = cpl_image_get_data_float( s_image));
00361 check( s2_image = cpl_image_new( sci_pre->nx,
00362 sci_pre->ny, CPL_TYPE_FLOAT));
00363 check ( s2_data = cpl_image_get_data_float( s2_image));
00364 check( f_image = cpl_image_new( sci_pre->nx,
00365 sci_pre->ny, CPL_TYPE_FLOAT));
00366 check( f_data = cpl_image_get_data_float( f_image));
00367 check( r_image = cpl_image_new( sci_pre->nx,
00368 sci_pre->ny, CPL_TYPE_FLOAT));
00369
00370 check( r_data = cpl_image_get_data_float( r_image));
00371 check( c_image = cpl_image_new( sci_pre->nx,
00372 sci_pre->ny, CPL_TYPE_INT));
00373 check( c_data = cpl_image_get_data_int( c_image));
00374
00375
00376
00377 while( new_crh > 0 && frac < frac_max && nbiter <= max_iter ){
00378 xsh_msg_dbg_low("Iteration %d",nbiter);
00379
00380
00381
00382
00383
00384 xsh_msg_dbg_medium("Create a 2n images");
00385 for( j=0; j< sci_pre->ny; j++){
00386 for( i=0; i< sci_pre->nx; i++){
00387 float val = sci_data[i+j*sci_pre->nx];
00388
00389 if ( val < 0. ) val = 0. ;
00390 two_sub_sample_data[i*2+j*2*two_sub_sample_nx] = val;
00391 two_sub_sample_data[i*2+1+j*2*two_sub_sample_nx] = val;
00392 two_sub_sample_data[i*2+(j*2+1)*two_sub_sample_nx] = val;
00393 two_sub_sample_data[i*2+1+(j*2+1)*two_sub_sample_nx] = val;
00394 }
00395 }
00396 xsh_msg_dbg_medium("Doing laplacian convolution");
00397
00398
00399
00400
00401 check(laplacian_image = xsh_image_filter_linear( two_sub_sample,
00402 laplacian_kernel));
00403
00404
00405
00406 xsh_msg_dbg_medium("Normalize laplacian");
00407 check (laplacian_data = cpl_image_get_data_float( laplacian_image));
00408 for ( i=0; i< two_sub_sample_nx*two_sub_sample_ny; i++){
00409 if (laplacian_data[i] > 0.0){
00410 laplacian_data[i] = 2.0 * laplacian_data[i];
00411 }
00412 else{
00413 laplacian_data[i] = 0.0;
00414 }
00415 }
00416 #if REGDEBUG_FULL
00417 xsh_msg_dbg_medium("Save Lpositive");
00418 cpl_image_save(laplacian_image, "Lpositive.fits", CPL_BPP_IEEE_FLOAT, NULL,
00419 CPL_IO_DEFAULT);
00420 #endif
00421
00422
00423
00424
00425
00426
00427 xsh_msg_dbg_medium("Resample to the original size");
00428
00429 for( j=0; j< sci_pre->ny; j++){
00430 for( i=0; i< sci_pre->nx; i++){
00431 laplacian_redu_data[i+j*sci_pre->nx] =
00432 (laplacian_data[i*2+j*2*two_sub_sample_nx]+
00433 laplacian_data[i*2+1+j*2*two_sub_sample_nx]+
00434 laplacian_data[i*2+(j*2+1)*two_sub_sample_nx]+
00435 laplacian_data[i*2+1+(j*2+1)*two_sub_sample_nx])/4.0;
00436 }
00437 }
00438 #if REGDEBUG_FULL
00439 cpl_image_save(laplacian_redu_image, "Lplus.fits", CPL_BPP_IEEE_FLOAT,
00440 NULL, CPL_IO_DEFAULT);
00441 #endif
00442 xsh_msg_dbg_medium("Apply median filter");
00443
00444 check( sci_median5_image = xsh_image_filter_median( sci_image,
00445 median5_kernel));
00446 check (sci_median5_data = cpl_image_get_data_float( sci_median5_image));
00447
00448 xsh_msg_dbg_medium("Compute noise");
00449
00450 for( i=0; i< sci_pre->nx*sci_pre->ny; i++){
00451 noise_data[i] = sqrt(sci_median5_data[i]*conad+ron*ron)/ conad;
00452 }
00453
00454 xsh_msg_dbg_medium("Compute S");
00455
00456 for( i=0; i< sci_pre->nx*sci_pre->ny; i++){
00457 s_data[i] = laplacian_redu_data[i] / (2.0*noise_data[i]);
00458 }
00459
00460 xsh_msg_dbg_medium("Compute S median");
00461
00462 check( s_median_image = xsh_image_filter_median( s_image,
00463 median5_kernel));
00464
00465 check( s_median_data = cpl_image_get_data_float( s_median_image));
00466
00467 xsh_msg_dbg_medium("Compute s2");
00468
00469 for( i=0; i< sci_pre->nx*sci_pre->ny; i++){
00470 s2_data[i] = s_data[i] -s_median_data[i];
00471 }
00472 #if REGDEBUG_FULL
00473 cpl_image_save( s2_image, "S2.fits", CPL_BPP_IEEE_FLOAT, NULL,
00474 CPL_IO_DEFAULT);
00475 #endif
00476 xsh_msg_dbg_medium("Apply 3x3 filter");
00477
00478 check( sci_median3_image = xsh_image_filter_median( sci_image,
00479 median3_kernel));
00480
00481 xsh_msg_dbg_medium("Apply 7x7 filter");
00482
00483 check( sci_median3_7_image = xsh_image_filter_median( sci_median3_image,
00484 median7_kernel));
00485 xsh_msg_dbg_medium("Apply 7x7 filter ok");
00486
00487 check ( sci_median3_data = cpl_image_get_data_float( sci_median3_image));
00488 check ( sci_median3_7_data = cpl_image_get_data_float(
00489 sci_median3_7_image));
00490
00491 xsh_msg_dbg_medium("Compute F");
00492
00493 for( i=0; i< sci_pre->nx*sci_pre->ny; i++){
00494 f_data[i] = sci_median3_data[i] -sci_median3_7_data[i];
00495 if (f_data[i] < 0.01){
00496 f_data[i] = 0.01;
00497 }
00498 }
00499 #if REGDEBUG_FULL
00500 cpl_image_save( f_image, "F.fits", CPL_BPP_IEEE_FLOAT, NULL,
00501 CPL_IO_DEFAULT);
00502 #endif
00503 xsh_msg_dbg_medium("Compute R");
00504
00505 for( i=0; i< sci_pre->nx*sci_pre->ny; i++){
00506 r_data[i] = laplacian_redu_data[i]/f_data[i];
00507 }
00508 #if REGDEBUG_FULL
00509 cpl_image_save( r_image, "R.fits", CPL_BPP_IEEE_FLOAT, NULL,
00510 CPL_IO_DEFAULT);
00511 #endif
00512
00513 xsh_msg_dbg_medium("Search for cosmic");
00514 new_crh = 0;
00515 median = cpl_vector_new(24);
00516
00517 for( j=1; j< sci_pre->ny-1; j++){
00518 double *data = NULL;
00519 cpl_vector* med_vect = NULL;
00520
00521
00522 for( i=1; i< sci_pre->nx-1-wmap_xsize_diff; i++){
00523 if(w_data[i*fctx+j*fcty*(sci_pre->nx-wmap_xsize_diff)] != 0) {
00524 if ( (s2_data[i+j*sci_pre->nx] >= sigma_lim) &&
00525 (r_data[i+j*sci_pre->nx] >= f_lim)){
00526 int li,lj,ui,uj;
00527 c_data[i+j*sci_pre->nx] = 1;
00528 new_crh++;
00529 li = i-2;
00530 lj = j-2;
00531 ui = i+2;
00532 uj = j+2;
00533 m = 0;
00534 if (li < 0) li = 0;
00535 if (ui >= sci_pre->nx) ui = sci_pre->nx-1;
00536 if (lj < 0) lj = 0;
00537 if (uj >= sci_pre->ny) uj = sci_pre->ny-1;
00538 for( k=lj; k <= uj; k++){
00539 for( l=li; l <= ui; l++){
00540 if ( k < j){
00541 cpl_vector_set(median, m, sci_data[l+k*sci_pre->nx]);
00542 m++;
00543 }
00544 else if ( (k == j) && ( l < i)){
00545 cpl_vector_set(median, m, sci_data[l+k*sci_pre->nx]);
00546 m++;
00547 }
00548 else if ( l!=i && k!=j && (s2_data[l+k*sci_pre->nx] < sigma_lim)
00549 && (r_data[l+k*sci_pre->nx] < f_lim)){
00550 cpl_vector_set(median, m, sci_data[l+k*sci_pre->nx]);
00551 m++;
00552 }
00553 }
00554 }
00555 check( data = cpl_vector_get_data( median));
00556
00557 check( med_vect = cpl_vector_wrap( m, data));
00558 check( sci_data[i+j*sci_pre->nx] = cpl_vector_get_median( med_vect));
00559 cpl_vector_unwrap( med_vect);
00560 }
00561 }
00562 }
00563 }
00564 xsh_free_vector( &median ) ;
00565 nb_crh += new_crh;
00566 frac = (double)nb_crh/(double)(sci_pre->nx*sci_pre->ny) ;
00567 xsh_msg_dbg_low(" new cosmics %d, total %d, frac %.4f [%d pixels]",new_crh,nb_crh,
00568 frac, sci_pre->nx*sci_pre->ny);
00569 nbiter++;
00570 xsh_free_image( &laplacian_image);
00571 xsh_free_image( &sci_median3_7_image ) ;
00572 xsh_free_image( &sci_median3_image ) ;
00573 xsh_free_image( &s_median_image ) ;
00574 xsh_free_image( &sci_median5_image ) ;
00575 }
00576 #if REGDEBUG_FULL
00577 cpl_image_save( c_image, "CRH_SINGLE.fits", CPL_BPP_32_SIGNED, NULL,
00578 CPL_IO_DEFAULT);
00579 #endif
00580
00581 if ( xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM){
00582 FILE *debug = NULL;
00583
00584 debug = fopen("cosmic.log","w");
00585
00586 for( j=0; j< sci_pre->ny; j++){
00587 for( i=0; i< sci_pre->nx; i++){
00588 if ( c_data[i+j*sci_pre->nx] == 1){
00589 fprintf(debug,"%.1f %.1f\n",i+1.0,j+1.0);
00590 }
00591 }
00592 }
00593 fclose(debug);
00594 }
00595
00596
00597 for( j=0; j< sci_pre->ny; j++){
00598 for( i=0; i< sci_pre->nx; i++){
00599 if ( c_data[i+j*sci_pre->nx] == 1){
00600 qual[i+j*sci_pre->nx] |= QFLAG_COSMIC_RAY_REMOVED;
00601 }
00602 }
00603 }
00604
00605
00606 res_name=xsh_stringcat_any(res_tag,".fits", NULL) ;
00607 xsh_msg_dbg_high( "Saving Result Frame '%s'", res_name ) ;
00608 check( add_qc_crh( sci_pre, nb_crh, 1, instrument ) ) ;
00609 check( res_frame = xsh_pre_save( sci_pre, res_name, res_tag,1 ) ) ;
00610 check( cpl_frame_set_tag( res_frame, res_tag ) ) ;
00611 XSH_FREE( res_name);
00612
00613 cleanup:
00614 xsh_pre_free( &sci_pre);
00615
00616
00617 xsh_free_matrix( &laplacian_kernel);
00618 xsh_free_matrix( &median3_kernel);
00619 xsh_free_matrix( &median5_kernel);
00620 xsh_free_matrix( &median7_kernel);
00621
00622 xsh_free_image( &laplacian_image);
00623 xsh_free_image( &laplacian_redu_image);
00624 xsh_free_image( &two_sub_sample);
00625 xsh_free_image( &sci_median5_image);
00626 xsh_free_image( &noise_image);
00627 xsh_free_image( &s_image);
00628 xsh_free_image( &s_median_image);
00629 xsh_free_image( &s2_image);
00630 xsh_free_image( &sci_median3_image);
00631 xsh_free_image( &sci_median3_7_image);
00632 xsh_free_image( &f_image);
00633 xsh_free_image( &r_image);
00634 xsh_free_image( &c_image);
00635 xsh_free_image( &w_image);
00636
00637 xsh_free_vector( &median);
00638
00639 return res_frame;
00640 }