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