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
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032
00039
00042
00043
00044
00045
00046 #include <math.h>
00047
00048 #include <xsh_drl.h>
00049 #include <xsh_data_pre.h>
00050 #include <xsh_dfs.h>
00051 #include <xsh_pfits.h>
00052 #include <xsh_error.h>
00053 #include <xsh_msg.h>
00054 #include <cpl.h>
00055 #include <xsh_badpixelmap.h>
00056 #include <xsh_irplib_mkmaster.h>
00057 #include <xsh_utils_image.h>
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static int
00069 xsh_remove_cr (cpl_imagelist * datalist, cpl_imagelist * errslist,
00070 cpl_image * median,
00071 cpl_image * errs, cpl_mask * mask,
00072 xsh_clipping_param * crh_clipping)
00073 {
00074 int nx, ny, nimg, i;
00075 cpl_image **pimg = NULL;
00076 cpl_image **perrs = NULL;
00077 int ix = 0,iy = 0;
00078 int crcount = 0;
00079 float* medvals = NULL;
00080 float* mederrs = NULL;
00081 cpl_binary *bpmdata = NULL;
00082
00083
00084
00085 check(nimg = cpl_imagelist_get_size (datalist));
00086
00087
00088 pimg = cpl_malloc (nimg * sizeof (cpl_image *));
00089 assure (pimg != NULL, cpl_error_get_code (),
00090 "Cant allocate memory for image pointers");
00091 perrs = cpl_malloc (nimg * sizeof (cpl_image *));
00092 assure (pimg != NULL, cpl_error_get_code (),
00093 "Cant allocate memory for image pointers");
00094
00095 xsh_msg_dbg_low ("Nb of images: %d\n", nimg);
00096
00097
00098 for (i = 0; i < nimg; i++){
00099 *(pimg + i) = cpl_imagelist_get (datalist, i);
00100 *(perrs + i) = cpl_imagelist_get (errslist, i);
00101 }
00102
00103
00104 check(nx = cpl_image_get_size_x (*pimg));
00105 check(ny = cpl_image_get_size_y (*pimg));
00106
00107
00108 check(medvals = cpl_image_get_data_float(median));
00109 check(mederrs = cpl_image_get_data_float(errs));
00110 check(bpmdata = cpl_mask_get_data(mask));
00111
00112 for (iy = 1; iy <= ny; iy++){
00113 for (ix = 1; ix <= nx; ix++) {
00114 int k;
00115 double medval;
00116 double error;
00117 int badpix = 0;
00118
00119 error = mederrs[ix-1+(iy-1)*nx] * crh_clipping->sigma;
00120
00121 medval = medvals[ix-1+(iy-1)*nx];
00122 badpix = 0;
00123
00124
00125 for (k = 0; k < nimg; k++) {
00126
00127 if (!bpmdata[ix-1+(iy-1)*nx]) {
00128 double delta = 0.0, kvalue = 0.0;
00129 int rej = 0;
00130 kvalue = cpl_image_get (*(pimg + k), ix, iy, &rej);
00131 if (rej != 0) {
00132 xsh_msg_dbg_high ("Pixel %d,%d already bad in image %d", ix, iy, k);
00133 continue;
00134 }
00135 delta = fabs(kvalue - medval);
00136
00137
00138
00139
00140 if (delta > error) {
00141 cpl_image_reject (*(pimg + k), ix, iy);
00142 cpl_image_reject (*(perrs + k), ix, iy);
00143 if ( crcount < 10 )
00144 xsh_msg ("CR Rejected for Pixel %d,%d [%d] (%lf vs %lf)",
00145 ix, iy, k, medval, kvalue);
00146
00147 crcount++;
00148 badpix = 1;
00149 }
00150 }
00151 else {
00152 xsh_msg_dbg_high("Pixel %d,%d already known as bad pixel in image %d", ix, iy,
00153 k+1);
00154 break;
00155 }
00156 }
00157
00158 if (!badpix){
00159
00160 bpmdata[ix-1+(iy-1)*nx] = CPL_BINARY_1;
00161 }
00162 }
00163 }
00164
00165 cpl_free (pimg);
00166 cpl_free(perrs);
00167
00168 cleanup:
00169 return crcount;
00170 }
00171
00180 static void
00181 add_qc_crh (xsh_pre* pre, int nbcrh, int nframes)
00182 {
00183 double qc_crrate = 0.0;
00184 int nbcr_avg ;
00185 XSH_ASSURE_NOT_NULL(pre);
00186 XSH_ASSURE_NOT_ILLEGAL(pre->pszx >0. && pre->pszy > 0);
00187 XSH_ASSURE_NOT_ILLEGAL(pre->exptime > 0);
00188
00189
00190
00191
00192
00193
00194 xsh_msg_dbg_medium( "add_qc_crh - Exptime = %f", pre->exptime ) ;
00195 qc_crrate =
00196 (double) nbcrh / (((double) nframes) * (pre->exptime *
00197 (pre->pszx / 10000.0) * (pre->pszy /10000.0) * pre->nx * pre->ny)) ;
00198 nbcr_avg = nbcrh/nframes ;
00199
00200
00201
00202
00203 check( xsh_pfits_set_qc_crrate( pre->data_header,qc_crrate) ) ;
00204 check( xsh_pfits_set_qc_ncrh( pre->data_header, nbcrh) ) ;
00205 check( xsh_pfits_set_qc_ncrh_mean( pre->data_header,nbcr_avg) ) ;
00206
00207 check( xsh_pfits_set_qc_crrate( pre->qual_header,qc_crrate)) ;
00208 check( xsh_pfits_set_qc_ncrh( pre->qual_header,nbcrh)) ;
00209 check( xsh_pfits_set_qc_ncrh_mean( pre->qual_header,nbcr_avg) ) ;
00210 cleanup:
00211 return ;
00212 }
00213
00214 static cpl_error_code
00215 xsh_find_cosmics(cpl_frameset* rawFrames,xsh_pre* pre,xsh_clipping_param* crh_clipping,
00216 cpl_imagelist* dataList,
00217 cpl_imagelist* errsList,cpl_mask* badpix_mask,cpl_mask** crh_mask)
00218 {
00219 long int nbpixcosmic=-1;
00220 int nb_crh_total=0;
00221 int iter=0;
00222 int size=0;
00223
00224 check( size = cpl_frameset_get_size( rawFrames));
00225
00226
00227 long nbpixtotal = cpl_frameset_get_size(rawFrames) * pre->nx * pre->ny;
00228 double frac_accepted = 1;
00229
00230 while(iter < crh_clipping->niter && frac_accepted >= crh_clipping->frac
00231 && (nbpixcosmic!=0) ) {
00232
00233
00234
00235 check(nbpixcosmic = xsh_remove_cr (dataList, errsList,pre->data,
00236 pre->errs, badpix_mask, crh_clipping));
00237 if(iter==0) {
00238 *crh_mask=cpl_mask_duplicate(badpix_mask);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247 check(cpl_mask_and(*crh_mask,badpix_mask));
00248
00249
00250
00251
00252
00253 xsh_msg(" Iteration Nb %d/%d, new cosmic found %ld",
00254 iter+1, crh_clipping->niter, nbpixcosmic);
00255
00256
00257 frac_accepted -= ((double)nbpixcosmic / (double)nbpixtotal);
00258 xsh_msg_dbg_medium("accepted pixels / total pixels = %f)",frac_accepted);
00259
00260
00261 check(xsh_bpmap_collapse_median(pre->data,dataList,*crh_mask));
00262
00263
00264 check(xsh_collapse_errs(pre->errs,errsList, *crh_mask,0));
00265 iter++;
00266
00267
00268 nb_crh_total += nbpixcosmic ;
00269 }
00270
00271
00272
00273
00274
00275
00276 xsh_msg(" Nb of cosmics removed %d", nb_crh_total);
00277
00278
00279 if (pre->exptime > 0){
00280 check(add_qc_crh( pre, nb_crh_total, size));
00281 }
00282
00283 cleanup:
00284 return cpl_error_get_code();
00285 }
00286
00287 cpl_error_code
00288 xsh_flag_cosmic_debug(xsh_pre* pre,cpl_imagelist* dataList)
00289 {
00290
00291 cpl_mask* cosmic_mask = NULL;
00292 int imask=0;
00293 int jmask=0;
00294 int i=0;
00295 cpl_image* img=NULL;
00296 cpl_mask* img_mask=NULL;
00297 int size=cpl_imagelist_get_size(dataList);
00298
00299 cosmic_mask = cpl_mask_new(pre->nx, pre->ny);
00300 for(i=0;i< size; i++){
00301 img = cpl_imagelist_get( dataList, i);
00302 img_mask = cpl_image_get_bpm( img);
00303 for(jmask=1; jmask<=pre->ny; jmask++){
00304 for(imask=1; imask <= pre->nx; imask++){
00305 if (cpl_mask_get(img_mask,imask, jmask) == CPL_BINARY_1){
00306 cpl_mask_set(cosmic_mask, imask, jmask,CPL_BINARY_1);
00307 }
00308 }
00309 }
00310 }
00311
00312
00313
00314
00315
00316 cpl_mask_delete( cosmic_mask);
00317
00318 return cpl_error_get_code();
00319 }
00320
00334 static cpl_frame*
00335 xsh_remove_cosmics (cpl_frameset * rawFrames,
00336 const char *result_tag,
00337 xsh_stack_param* stack_par,
00338 xsh_clipping_param * crh_clipping,
00339 xsh_instrument* instr,
00340 cpl_imagelist ** list,
00341 cpl_image** crh_ima,
00342 int median_mean,const int save_tmp )
00343 {
00344
00345 cpl_frame* medFrame = NULL;
00346 cpl_imagelist *dataList = NULL;
00347
00348
00349 cpl_imagelist *errsList = NULL;
00350 xsh_pre* pre = NULL;
00351 cpl_mask* badpix_mask = NULL;
00352 cpl_mask* crh_mask = NULL;
00353
00354 cpl_frame *current = NULL;
00355 int i=0, size = 0;
00356
00357
00358 char name[80];
00359 char result_name[80];
00360
00361
00362 XSH_ASSURE_NOT_NULL( instr);
00363 XSH_ASSURE_NOT_NULL( rawFrames);
00364 XSH_ASSURE_NOT_NULL( result_tag);
00365 XSH_ASSURE_NOT_NULL( crh_clipping);
00366 check( size = cpl_frameset_get_size( rawFrames));
00367
00368 XSH_ASSURE_NOT_ILLEGAL( size > 0);
00369
00370
00371 check( dataList = cpl_imagelist_new());
00372 check( errsList = cpl_imagelist_new());
00373
00374
00375 for (i=0;i < size;i++){
00376
00377 check(current = cpl_frameset_get_frame(rawFrames,i));
00378
00379 check(pre = xsh_pre_load(current,instr));
00380 check_msg( cpl_imagelist_set(dataList,cpl_image_duplicate(pre->data),
00381 i),"Cant add Data Image %d to imagelist", i) ;
00382 check_msg( cpl_imagelist_set(errsList,cpl_image_duplicate(pre->errs),
00383 i),"Cant add Data Image %d to imagelist", i) ;
00384
00385
00386
00387 if (i < (size-1)) {
00388 xsh_pre_free(&pre);
00389 }
00390 }
00391
00392
00393 assure (cpl_imagelist_is_uniform (dataList) == 0, CPL_ERROR_ILLEGAL_INPUT,
00394 "Data images are not uniform");
00395 assure (cpl_imagelist_is_uniform (errsList) == 0, CPL_ERROR_ILLEGAL_INPUT,
00396 "Errs images are not uniform");
00397
00398
00399 check(badpix_mask = cpl_mask_duplicate(xsh_pre_get_bpmap(pre)));
00400
00401
00402 xsh_msg_dbg_medium ("Nb of Bad Pixels in QUAL: %" CPL_SIZE_FORMAT "",cpl_mask_count(badpix_mask));
00403
00404
00405
00406
00407 if (size == 2) {
00408 if (strcmp(stack_par->stack_method, "median") == 0) {
00409
00410 } else {
00411 xsh_free_image(&pre->data);
00412 pre->data = xsh_irplib_mkmaster_mean(dataList, 5, 5, 1.e-5,
00413 stack_par->klow, stack_par->khigh, stack_par->niter);
00414 }
00415
00416 check( xsh_collapse_errs(pre->errs,errsList, badpix_mask,1));
00417 }
00418
00419
00420 if (size >= 3) {
00421 xsh_msg( "More than 2 input frames: remove crh (method multi)");
00422 if (strcmp(stack_par->stack_method, "median") == 0) {
00423 xsh_free_image(&pre->data);
00424 pre->data = xsh_irplib_mkmaster_median(dataList, 5, 5, 1.e-5);
00425 } else {
00426 xsh_free_image(&pre->data);
00427 pre->data = xsh_irplib_mkmaster_mean(dataList, 5, 5, 1.e-5,
00428 stack_par->klow, stack_par->khigh, stack_par->niter);
00429 }
00430
00431 }
00432
00433
00434 if ( size >= 3 ) {
00435 check(xsh_find_cosmics(rawFrames,pre,crh_clipping,dataList,errsList,badpix_mask,&crh_mask));
00436 }
00437
00438
00439 if (xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM) {
00440
00441 xsh_flag_cosmic_debug(pre,dataList);
00442 }
00443
00444
00445 check( xsh_pfits_set_datancom( pre->data_header, size));
00446
00447
00448 check( cpl_propertylist_erase_regexp( pre->data_header, "PRO BIAS *", 0));
00449
00450
00451
00452
00453 sprintf(result_name, "%s.fits", result_tag);
00454 xsh_msg_dbg_high("save frame %s tag=%s", result_name, result_tag);
00455 check(medFrame = xsh_pre_save( pre, result_name, result_tag,save_tmp));
00456 check(cpl_frame_set_tag(medFrame, result_tag));
00457
00458
00459 if ((crh_mask != NULL) && ((crh_ima) != NULL)) {
00460 xsh_free_image(crh_ima);
00461 check(*crh_ima=cpl_image_new_from_mask(crh_mask));
00462 cpl_mask_not(crh_mask);
00463 xsh_bpmap_mask_bad_pixel(*crh_ima, crh_mask, QFLAG_COSMIC_RAY_REMOVED);
00464
00465
00466 cpl_image_threshold(*crh_ima, 1.1, DBL_MAX, 0, DBL_MAX);
00467 check(sprintf(name,"%s.fits",XSH_GET_TAG_FROM_ARM(XSH_CRH_MAP,instr)));
00468
00469 }
00470
00471
00472
00473
00474
00475
00476 cleanup:
00477 if (cpl_error_get_code () != CPL_ERROR_NONE) {
00478 xsh_free_imagelist(&dataList);
00479 xsh_free_frame(&medFrame);
00480 if (list != NULL){
00481 *list = NULL;
00482 }
00483 }
00484 if (list != NULL){
00485 *list = dataList;
00486 }
00487 else{
00488 xsh_free_imagelist(&dataList);
00489 }
00490
00491 xsh_free_mask(&crh_mask);
00492 xsh_free_mask(&badpix_mask);
00493 xsh_pre_free(&pre);
00494 xsh_free_imagelist(&errsList) ;
00495 return medFrame ;
00496 }
00497
00498 cpl_frame*
00499 xsh_remove_crh_multiple (cpl_frameset * rawFrames,
00500 const char *result_tag,
00501 xsh_stack_param* stack_par,
00502 xsh_clipping_param * crh_clipping,
00503 xsh_instrument* instrument,
00504 cpl_imagelist ** list,
00505 cpl_image** crh_ima,
00506 const int save_tmp)
00507 {
00508 cpl_frame * result = NULL ;
00509
00510 XSH_ASSURE_NOT_NULL( rawFrames ) ;
00511 XSH_ASSURE_NOT_NULL( result_tag ) ;
00512 XSH_ASSURE_NOT_NULL( crh_clipping ) ;
00513 XSH_ASSURE_NOT_NULL( instrument ) ;
00514 check( result = xsh_remove_cosmics( rawFrames, result_tag, stack_par, crh_clipping,
00515 instrument, list, crh_ima, 0,save_tmp ) ) ;
00516 cleanup:
00517 return result ;
00518 }
00519
00520 cpl_frame*
00521 xsh_combine_offset(cpl_frameset * rawFrames, const char * result_tag,
00522 xsh_stack_param* stack_par, xsh_clipping_param * crh_clipping,
00523 xsh_instrument * instrument, cpl_imagelist ** list, cpl_image** crh_ima,
00524 const int save_tmp)
00525 {
00526 cpl_frame * result = NULL ;
00527
00528 XSH_ASSURE_NOT_NULL( rawFrames ) ;
00529 XSH_ASSURE_NOT_NULL( result_tag ) ;
00530 XSH_ASSURE_NOT_NULL( crh_clipping ) ;
00531 XSH_ASSURE_NOT_NULL( instrument ) ;
00532
00533 check( result = xsh_remove_cosmics( rawFrames, result_tag, stack_par, crh_clipping,
00534 instrument, list, crh_ima, 1,save_tmp ) ) ;
00535 cleanup:
00536 return result ;
00537 }
00538