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
00029 #ifdef HAVE_CONFIG_H
00030 # include <config.h>
00031 #endif
00032
00033
00040
00043
00044
00045
00046
00047 #include <math.h>
00048
00049 #include <xsh_drl.h>
00050 #include <xsh_data_pre.h>
00051 #include <xsh_dfs.h>
00052 #include <xsh_pfits.h>
00053 #include <xsh_error.h>
00054 #include <xsh_msg.h>
00055 #include <cpl.h>
00056 #include <xsh_badpixelmap.h>
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00078 static void xsh_collapse_errs(cpl_image * errs, cpl_imagelist * list,
00079 cpl_mask* mask)
00080 {
00081 int nx = 0, ny = 0, nimg = 0, i = 0;
00082 float **pdata = NULL;
00083 cpl_binary ** pbinary = NULL;
00084 cpl_binary * binary = NULL;
00085 float* errsdata = NULL;
00086
00087 check(nimg = cpl_imagelist_get_size (list));
00088 assure(nimg > 0,CPL_ERROR_ILLEGAL_INPUT,"you must have image to collapse");
00089
00090
00091 pdata = cpl_malloc (nimg * sizeof (float *));
00092 assure (pdata != NULL, cpl_error_get_code (),
00093 "Cant allocate memory for data pointers");
00094
00095 pbinary = cpl_malloc (nimg * sizeof (cpl_binary *));
00096 assure (pbinary != NULL, cpl_error_get_code (),
00097 "Cant allocate memory for binary pointers");
00098
00099
00100 for (i = 0; i < nimg; i++) {
00101 check( pdata[i] = cpl_image_get_data_float(cpl_imagelist_get (list, i)));
00102 check( pbinary[i] = cpl_mask_get_data(cpl_image_get_bpm(
00103 cpl_imagelist_get(list, i))));
00104 }
00105
00106
00107 check(nx = cpl_image_get_size_x (cpl_imagelist_get (list, 0)));
00108 check(ny = cpl_image_get_size_y (cpl_imagelist_get (list, 0)));
00109 check(errsdata = cpl_image_get_data_float(errs));
00110
00111
00112 check(binary = cpl_mask_get_data(mask));
00113
00114
00115 for (i = 0; i < nx * ny; i++){
00116 int count = 0;
00117 int k = 0;
00118 double errval = 0.0;
00119
00120 for (count = 0, k = 0; k < nimg; k++) {
00121
00122 if ( (binary[i] == CPL_BINARY_0) && ((pbinary[k])[i] == CPL_BINARY_0)) {
00123 errval += (pdata[k])[i] * (pdata[k])[i];
00124 count++;
00125 }
00126 }
00127
00128 if (count > 1) {
00129 double eval;
00130
00131 eval = sqrt( M_PI / 2.0 * ((double) count / ((double) count- 1.))) *
00132 (1./(double)count) * sqrt (errval);
00133 errsdata[i] = eval;
00134 }
00135 }
00136 cleanup:
00137 cpl_free(pdata);
00138 cpl_free(pbinary);
00139 }
00140
00141 static int xsh_remove_cr (cpl_imagelist * datalist, cpl_imagelist * errslist,
00142 cpl_image * median,
00143 cpl_image * errs, cpl_mask * mask,
00144 xsh_clipping_param * crh_clipping)
00145 {
00146 int nx, ny, nimg, i;
00147 cpl_image **pimg = NULL;
00148 cpl_image **perrs = NULL;
00149 int ix = 0,iy = 0;
00150 int crcount = 0;
00151 float* medvals = NULL;
00152 float* mederrs = NULL;
00153 cpl_binary *bpmdata = NULL;
00154
00155
00156
00157 check(nimg = cpl_imagelist_get_size (datalist));
00158
00159
00160 pimg = cpl_malloc (nimg * sizeof (cpl_image *));
00161 assure (pimg != NULL, cpl_error_get_code (),
00162 "Cant allocate memory for image pointers");
00163 perrs = cpl_malloc (nimg * sizeof (cpl_image *));
00164 assure (pimg != NULL, cpl_error_get_code (),
00165 "Cant allocate memory for image pointers");
00166
00167 xsh_msg_dbg_low ("Nb of images: %d\n", nimg);
00168
00169
00170 for (i = 0; i < nimg; i++){
00171 *(pimg + i) = cpl_imagelist_get (datalist, i);
00172 *(perrs + i) = cpl_imagelist_get (errslist, i);
00173 }
00174
00175
00176 check(nx = cpl_image_get_size_x (*pimg));
00177 check(ny = cpl_image_get_size_y (*pimg));
00178
00179
00180 check(medvals = cpl_image_get_data_float(median));
00181 check(mederrs = cpl_image_get_data_float(errs));
00182 check(bpmdata = cpl_mask_get_data(mask));
00183
00184 for (iy = 1; iy <= ny; iy++){
00185 for (ix = 1; ix <= nx; ix++) {
00186 int k;
00187 double medval;
00188 double error;
00189 int badpix = 0;
00190
00191 error = mederrs[ix-1+(iy-1)*nx] * crh_clipping->sigma;
00192
00193 medval = medvals[ix-1+(iy-1)*nx];
00194 badpix = 0;
00195
00196
00197 for (k = 0; k < nimg; k++) {
00198
00199 if (!bpmdata[ix-1+(iy-1)*nx]) {
00200 double delta = 0.0, kvalue = 0.0;
00201 int rej = 0;
00202 kvalue = cpl_image_get (*(pimg + k), ix, iy, &rej);
00203 if (rej != 0) {
00204 xsh_msg_dbg_high ("Pixel %d,%d already bad in image %d", ix, iy, k);
00205 continue;
00206 }
00207 delta = fabs(kvalue - medval);
00208
00209
00210
00211
00212 if (delta > error) {
00213 cpl_image_reject (*(pimg + k), ix, iy);
00214 cpl_image_reject (*(perrs + k), ix, iy);
00215 if ( crcount < 10 )
00216 xsh_msg ("CR Rejected for Pixel %d,%d [%d] (%lf vs %lf)",
00217 ix, iy, k, medval, kvalue);
00218
00219 crcount++;
00220 badpix = 1;
00221 }
00222 }
00223 else {
00224 xsh_msg_dbg_high("Pixel %d,%d already known as bad pixel in image %d", ix, iy,
00225 k+1);
00226 break;
00227 }
00228 }
00229
00230 if (!badpix){
00231
00232 bpmdata[ix-1+(iy-1)*nx] = CPL_BINARY_1;
00233 }
00234 }
00235 }
00236
00237 cpl_free (pimg);
00238 cpl_free(perrs);
00239
00240 cleanup:
00241 return crcount;
00242 }
00243
00252 static void add_qc_crh (xsh_pre* pre, int nbcrh, int nframes,
00253 xsh_instrument * instrument )
00254 {
00255 double qc_crrate = 0.0;
00256 int nbcr_avg ;
00257 XSH_ASSURE_NOT_NULL(pre);
00258 XSH_ASSURE_NOT_ILLEGAL(pre->pszx >0. && pre->pszy > 0);
00259 XSH_ASSURE_NOT_ILLEGAL(pre->exptime > 0);
00260
00261
00262
00263
00264
00265
00266 xsh_msg_dbg_medium( "add_qc_crh - Exptime = %f", pre->exptime ) ;
00267 qc_crrate =
00268 (double) nbcrh / (((double) nframes) * (pre->exptime *
00269 (pre->pszx / 10000.0) * (pre->pszy /10000.0) * pre->nx * pre->ny)) ;
00270 nbcr_avg = nbcrh/nframes ;
00271
00272
00273
00274
00275 check( xsh_pfits_set_qc_crrate( pre->data_header,qc_crrate) ) ;
00276 check( xsh_pfits_set_qc_ncrh( pre->data_header, nbcrh) ) ;
00277 check( xsh_pfits_set_qc_ncrh_mean( pre->data_header,nbcr_avg) ) ;
00278
00279 check( xsh_pfits_set_qc_crrate( pre->qual_header,qc_crrate)) ;
00280 check( xsh_pfits_set_qc_ncrh( pre->qual_header,nbcrh)) ;
00281 check( xsh_pfits_set_qc_ncrh_mean( pre->qual_header,nbcr_avg) ) ;
00282 cleanup:
00283 return ;
00284 }
00285
00286
00300 static cpl_frame*
00301 xsh_remove_cosmics (cpl_frameset * rawFrames,
00302 const char *result_tag,
00303 xsh_clipping_param * crh_clipping,
00304 xsh_instrument* instr,
00305 cpl_imagelist ** list,
00306 cpl_image** crh_ima,
00307 int median_mean )
00308 {
00309
00310 cpl_frame* medFrame = NULL;
00311 cpl_imagelist *dataList = NULL;
00312
00313
00314 cpl_imagelist *errsList = NULL;
00315 xsh_pre* pre = NULL;
00316 cpl_mask* badpix_mask = NULL;
00317 cpl_mask* crh_mask = NULL;
00318
00319 cpl_frame *current = NULL;
00320 int i=0, size = 0;
00321 long nbpixcosmic = -1;
00322 int nb_crh_total = 0 ;
00323
00324 char name[80];
00325 char result_name[80];
00326
00327
00328 XSH_ASSURE_NOT_NULL( instr);
00329 XSH_ASSURE_NOT_NULL( rawFrames);
00330 XSH_ASSURE_NOT_NULL( result_tag);
00331 XSH_ASSURE_NOT_NULL( crh_clipping);
00332 check( size = cpl_frameset_get_size( rawFrames));
00333
00334 XSH_ASSURE_NOT_ILLEGAL( size > 0);
00335
00336
00337 check( dataList = cpl_imagelist_new());
00338 check( errsList = cpl_imagelist_new());
00339
00340
00341 for (i=0;i < size;i++){
00342
00343 check(current = cpl_frameset_get_frame(rawFrames,i));
00344
00345 check(pre = xsh_pre_load(current,instr));
00346 check_msg( cpl_imagelist_set(dataList,cpl_image_duplicate(pre->data),
00347 i),"Cant add Data Image %d to imagelist", i) ;
00348 check_msg( cpl_imagelist_set(errsList,cpl_image_duplicate(pre->errs),
00349 i),"Cant add Data Image %d to imagelist", i) ;
00350
00351
00352
00353 if (i < (size-1)) {
00354 xsh_pre_free(&pre);
00355 }
00356 }
00357
00358
00359 assure (cpl_imagelist_is_uniform (dataList) == 0, CPL_ERROR_ILLEGAL_INPUT,
00360 "Data images are not uniform");
00361 assure (cpl_imagelist_is_uniform (errsList) == 0, CPL_ERROR_ILLEGAL_INPUT,
00362 "Errs images are not uniform");
00363
00364
00365 check(badpix_mask = cpl_mask_duplicate(xsh_pre_get_bpmap(pre)));
00366
00367
00368 xsh_msg_dbg_medium ("Nb of Bad Pixels in QUAL: %d",cpl_mask_count(badpix_mask));
00369
00370
00371
00372
00373 if ( size == 2){
00374 check( xsh_bpmap_collapse_mean( pre->data,dataList,badpix_mask));
00375 check( xsh_collapse_errs(pre->errs,errsList, badpix_mask));
00376 }
00377
00378
00379 if ( size >= 3 ) {
00380 xsh_msg( "More than 2 input frames: remove crh (method multi)");
00381 check(xsh_bpmap_collapse_median(pre->data,dataList, badpix_mask));
00382 }
00383
00384 if ( size >= 3 ) {
00385 long nbpixtotal = cpl_frameset_get_size(rawFrames) * pre->nx * pre->ny;
00386 double frac_accepted = 1;
00387 int iter = 0;
00388
00389 while(iter < crh_clipping->niter && frac_accepted >= crh_clipping->frac
00390 && (nbpixcosmic!=0) ) {
00391
00392
00393
00394 check(nbpixcosmic = xsh_remove_cr (dataList, errsList,pre->data,
00395 pre->errs, badpix_mask, crh_clipping));
00396 if(iter==0) crh_mask=cpl_mask_duplicate(badpix_mask);
00397
00398
00399
00400
00401
00402
00403
00404 check(cpl_mask_and(crh_mask,badpix_mask));
00405
00406
00407
00408
00409
00410 xsh_msg(" Iteration Nb %d/%d, new cosmic found %ld",
00411 iter+1, crh_clipping->niter, nbpixcosmic);
00412
00413
00414 frac_accepted -= ((double)nbpixcosmic / (double)nbpixtotal);
00415 xsh_msg_dbg_medium("accepted pixels / total pixels = %f)",frac_accepted);
00416
00417
00418 check(xsh_bpmap_collapse_median(pre->data,dataList,crh_mask));
00419
00420
00421 check(xsh_collapse_errs(pre->errs,errsList, crh_mask));
00422 iter++;
00423
00424
00425 nb_crh_total += nbpixcosmic ;
00426 }
00427 }
00428
00429
00430 if ( size >= 3 ) {
00431 xsh_msg(" Nb of cosmics removed %d", nb_crh_total);
00432 }
00433
00434
00435 if (xsh_debug_level_get() >= XSH_DEBUG_LEVEL_MEDIUM) {
00436 cpl_mask* cosmic_mask = NULL;
00437 int imask, jmask;
00438
00439 cosmic_mask = cpl_mask_new(pre->nx, pre->ny);
00440 for(i=0;i< size; i++){
00441 cpl_image *img = cpl_imagelist_get( dataList, i);
00442 cpl_mask *imgmask = cpl_image_get_bpm( img);
00443 for(jmask=1; jmask<=pre->ny; jmask++){
00444 for(imask=1; imask <= pre->nx; imask++){
00445 if (cpl_mask_get(imgmask,imask, jmask) == CPL_BINARY_1){
00446 cpl_mask_set(cosmic_mask, imask, jmask,CPL_BINARY_1);
00447 }
00448 }
00449 }
00450 }
00451
00452
00453
00454
00455
00456 cpl_mask_delete( cosmic_mask);
00457 }
00458
00459
00460 check( xsh_pfits_set_datancom( pre->data_header, size));
00461
00462 if (pre->exptime > 0){
00463 check(add_qc_crh( pre, nb_crh_total, size, instr ));
00464 }
00465
00466
00467 check ( cpl_propertylist_erase_regexp( pre->data_header, "PRO BIAS *", 0));
00468
00469
00470
00471
00472 sprintf(result_name,"%s.fits",result_tag);
00473 xsh_msg_dbg_high ("save frame %s tag=%s", result_name,result_tag);
00474 check(medFrame = xsh_pre_save( pre, result_name, result_tag,1));
00475 check(cpl_frame_set_tag(medFrame, result_tag));
00476
00477
00478 if((crh_mask!=NULL) && ((crh_ima) !=NULL)) {
00479 xsh_free_image(crh_ima);
00480 check(*crh_ima=cpl_image_new_from_mask(crh_mask));
00481 cpl_mask_not(crh_mask);
00482 xsh_bpmap_mask_bad_pixel(*crh_ima, crh_mask,QFLAG_COSMIC_RAY_REMOVED);
00483
00484
00485 cpl_image_threshold(*crh_ima,1.1,DBL_MAX,0,DBL_MAX);
00486 check(sprintf(name,"%s.fits",XSH_GET_TAG_FROM_ARM(XSH_CRH_MAP,instr)));
00487 cpl_image_save (*crh_ima,name,CPL_BPP_32_SIGNED,NULL, CPL_IO_DEFAULT);
00488 }
00489
00490
00491
00492
00493
00494
00495 cleanup:
00496 if (cpl_error_get_code () != CPL_ERROR_NONE) {
00497 xsh_free_imagelist(&dataList);
00498 xsh_free_frame(&medFrame);
00499 if (list != NULL){
00500 *list = NULL;
00501 }
00502 }
00503 if (list != NULL){
00504 *list = dataList;
00505 }
00506 else{
00507 xsh_free_imagelist(&dataList);
00508 }
00509
00510 xsh_free_mask(&crh_mask);
00511 xsh_free_mask(&badpix_mask);
00512 xsh_pre_free(&pre);
00513 xsh_free_imagelist(&errsList) ;
00514 return medFrame ;
00515 }
00524 cpl_frame*
00525 xsh_create_master_bias2(cpl_frameset* rawFrames,
00526 xsh_instrument* instr,const char* result_tag)
00527 {
00528 cpl_frame* medFrame = NULL;
00529 cpl_imagelist *dataList = NULL;
00530 cpl_imagelist *errsList = NULL;
00531 int i=0;
00532 int size=0;
00533 xsh_pre* pre = NULL;
00534 cpl_frame *current = NULL;
00535 cpl_mask* badpix_mask = NULL;
00536 char result_name[80];
00537
00538
00539 XSH_ASSURE_NOT_NULL( instr);
00540 XSH_ASSURE_NOT_NULL( rawFrames);
00541 check( size = cpl_frameset_get_size( rawFrames));
00542
00543 XSH_ASSURE_NOT_ILLEGAL( size > 0);
00544
00545 check( dataList = cpl_imagelist_new());
00546 check( errsList = cpl_imagelist_new());
00547
00548
00549 for (i=0;i < size;i++){
00550
00551 check(current = cpl_frameset_get_frame(rawFrames,i));
00552
00553 check(pre = xsh_pre_load(current,instr));
00554 check_msg( cpl_imagelist_set(dataList,cpl_image_duplicate(pre->data),
00555 i),"Cant add Data Image %d to imagelist", i) ;
00556 check_msg( cpl_imagelist_set(errsList,cpl_image_duplicate(pre->errs),
00557 i),"Cant add Data Image %d to imagelist", i) ;
00558
00559
00560
00561 if (i < (size-1)) {
00562 xsh_pre_free(&pre);
00563 }
00564 }
00565
00566 assure (cpl_imagelist_is_uniform (dataList) == 0, CPL_ERROR_ILLEGAL_INPUT,
00567 "Data images are not uniform");
00568 assure (cpl_imagelist_is_uniform (errsList) == 0, CPL_ERROR_ILLEGAL_INPUT,
00569 "Errs images are not uniform");
00570
00571
00572 check(badpix_mask = cpl_mask_duplicate(xsh_pre_get_bpmap(pre)));
00573
00574 xsh_msg ("Nb of Bad Pixels in QUAL: %d",cpl_mask_count(badpix_mask));
00575
00576
00577
00578
00579 check( xsh_bpmap_collapse_median(pre->data,dataList,badpix_mask));
00580
00581 check( xsh_collapse_errs(pre->errs,errsList, badpix_mask));
00582
00583
00584
00585
00586
00587 check( xsh_pfits_set_datancom( pre->data_header, size));
00588
00589
00590 check ( cpl_propertylist_erase_regexp( pre->data_header, "PRO BIAS *", 0));
00591
00592
00593
00594
00595 sprintf(result_name,"%s.fits",result_tag);
00596 xsh_msg ("save frame %s", result_name);
00597 check(medFrame = xsh_pre_save( pre, result_name, result_tag,1));
00598
00599 check(cpl_frame_set_tag(medFrame, result_tag));
00600
00601
00602 cleanup:
00603
00604 if (cpl_error_get_code () != CPL_ERROR_NONE) {
00605 xsh_free_frame(&medFrame);
00606 }
00607 xsh_free_imagelist(&dataList);
00608
00609
00610 xsh_free_mask(&badpix_mask);
00611 xsh_pre_free(&pre);
00612 xsh_free_imagelist(&errsList) ;
00613
00614
00615 return medFrame;
00616
00617 }
00618
00619 cpl_frame*
00620 xsh_remove_crh_multiple (cpl_frameset * rawFrames,
00621 const char *result_tag,
00622 xsh_clipping_param * crh_clipping,
00623 xsh_instrument* instrument,
00624 cpl_imagelist ** list,
00625 cpl_image** crh_ima)
00626 {
00627 cpl_frame * result = NULL ;
00628
00629 XSH_ASSURE_NOT_NULL( rawFrames ) ;
00630 XSH_ASSURE_NOT_NULL( result_tag ) ;
00631 XSH_ASSURE_NOT_NULL( crh_clipping ) ;
00632 XSH_ASSURE_NOT_NULL( instrument ) ;
00633 check( result = xsh_remove_cosmics( rawFrames, result_tag, crh_clipping,
00634 instrument, list, crh_ima, 0 ) ) ;
00635 cleanup:
00636 return result ;
00637 }
00638
00639 cpl_frame*
00640 xsh_combine_offset (cpl_frameset * rawFrames,
00641 const char * result_tag,
00642 xsh_clipping_param * crh_clipping,
00643 xsh_instrument * instrument,
00644 cpl_imagelist ** list,
00645 cpl_image** crh_ima)
00646 {
00647 cpl_frame * result = NULL ;
00648
00649 XSH_ASSURE_NOT_NULL( rawFrames ) ;
00650 XSH_ASSURE_NOT_NULL( result_tag ) ;
00651 XSH_ASSURE_NOT_NULL( crh_clipping ) ;
00652 XSH_ASSURE_NOT_NULL( instrument ) ;
00653
00654 check( result = xsh_remove_cosmics( rawFrames, result_tag, crh_clipping,
00655 instrument, list, crh_ima, 1 ) ) ;
00656 cleanup:
00657 return result ;
00658 }
00659