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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 #ifdef HAVE_CONFIG_H
00102 # include <config.h>
00103 #endif
00104
00105
00111
00114
00115
00116
00117
00118 #include "uves_corrbadpix.h"
00119
00120 #include <uves_pfits.h>
00121 #include <uves_dump.h>
00122 #include <uves_error.h>
00123 #include <uves_msg.h>
00124
00125 #include <cpl.h>
00126
00127 #include <stdbool.h>
00128
00129
00130
00131 static int
00132 uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap,
00133 bool mark_bad);
00134
00135
00136
00137
00138
00139
00140
00157
00158 int
00159 uves_correct_badpix_all(cpl_image *master_bias, uves_propertylist *mbias_header,
00160 enum uves_chip chip,
00161 int binx, int biny, int mark_bad, bool red_ccd_new)
00162 {
00163 int badpixels_cleaned = -1;
00164
00165 int **badmap = NULL;
00166
00167 check( badmap = uves_get_badpix(chip, binx, biny, mark_bad,red_ccd_new),
00168 "Could not get bad pixel map");
00169
00170 check( badpixels_cleaned =
00171 uves_correct_badpix(master_bias, mbias_header, badmap, mark_bad),
00172 "Error cleaning bad pixels");
00173
00174 cleanup:
00175 uves_badmap_free(&badmap);
00176 return badpixels_cleaned;
00177 }
00178
00179
00180
00185
00186 void
00187 uves_badmap_free(int ***badmap)
00188 {
00189 if (badmap != NULL)
00190 {
00191 if (*badmap != NULL)
00192 {
00193 int row;
00194 for (row = 0;
00195 (*badmap)[row][0] != -1;
00196 row++)
00197 {
00198 cpl_free((*badmap)[row]);
00199 }
00200 cpl_free((*badmap)[row]);
00201
00202 cpl_free(*badmap);
00203 *badmap = NULL;
00204 }
00205 }
00206 }
00207
00208
00214
00215 static int **
00216 dup_map(int badmap[][4])
00217 {
00218 int **map = NULL;
00219 int row;
00220 bool finished = false;
00221
00222
00223
00224
00225 for (row = 0; !finished; row++)
00226 {
00227 map = cpl_realloc(map, (row+1)*sizeof(int *));
00228
00229
00230 map[row] = cpl_calloc(4, sizeof(int));
00231 map[row][0] = badmap[row][0];
00232 map[row][1] = badmap[row][1];
00233 map[row][2] = badmap[row][2];
00234 map[row][3] = badmap[row][3];
00235
00236 finished = (badmap[row][0] == -1);
00237 }
00238
00239 return map;
00240 }
00241
00242
00243
00257
00258 int **
00259 uves_get_badpix(enum uves_chip chip,
00260 int binx, int biny, int mark_bad,bool red_ccd_new)
00261 {
00262 int **map = NULL;
00263
00264 if (chip == UVES_CHIP_REDL)
00265 {
00266 if (binx == 1 && biny == 1)
00267 {
00268 if(red_ccd_new) {
00269
00270 int badmap[][4] = {{1,4,2088,4},
00271 {1,63,2282,63},
00272 {1,108,1778,108},
00273 {1,176,2443,176},
00274 {1,196,2021,196},
00275 {1,285,1974,285},
00276 {1,352,1942,352},
00277 {-1,-1,-1,-1}};
00278
00279 if (!mark_bad)
00280 {
00281 badmap[2][0] = -1;
00282 badmap[2][1] = -1;
00283 badmap[2][2] = -1;
00284 badmap[2][3] = -1;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 map = dup_map(badmap);
00297
00298 } else {
00299 int badmap[][4] = {{1,4,2088,4},
00300 {1,63,2282,63},
00301 {1,108,1778,108},
00302 {1,176,2443,176},
00303 {1,196,2021,196},
00304 {1,285,1974,285},
00305 {1,352,1942,352},
00306 {-1,-1,-1,-1}};
00307 map = dup_map(badmap);
00308
00309 }
00310
00311 }
00312 else if (binx == 1 && biny == 2)
00313 {
00314
00315
00316 if(red_ccd_new) {
00317
00318 int badmap[][4] = {{1,4,1045,4},
00319 {1,63,1141,63},
00320 {1,108,894,108},
00321 {1,176,1222,176},
00322 {1,196,1011,196},
00323 {1,285,988,285},
00324 {1,352,971,352},
00325 {-1,-1,-1,-1}};
00326 map = dup_map(badmap);
00327 } else {
00328
00329 int badmap[][4] = {{1,4,1044,4},
00330 {1,63,1141,63},
00331 {1,108,894,108},
00332 {1,176,1222,176},
00333 {1,196,1011,196},
00334 {1,285,988,285},
00335 {1,352,971,352},
00336 {-1,-1,-1,-1}};
00337
00338 map = dup_map(badmap);
00339 }
00340 }
00341 else if (binx == 2 && biny == 2)
00342 {
00343 if(red_ccd_new) {
00344
00345 int badmap[][4] = {{1,4,1045,4},
00346 {1,14,1255,14},
00347 {1,33,1141,33},
00348 {1,89,1222,89},
00349 {1,99,1011,100},
00350 {1,144,988,144},
00351 {1,177,971,178},
00352 {-1,-1,-1,-1}};
00353
00354 map = dup_map(badmap);
00355 } else {
00356 int badmap[][4] = {{1,3,1044,3},
00357 {1,33,1141,33},
00358 {1,55,894,56},
00359 {1,89,1222,90},
00360 {1,99,1011,100},
00361 {1,144,988,145},
00362 {1,177,971,178},
00363 {-1,-1,-1,-1}};
00364 map = dup_map(badmap);
00365 }
00366 }
00367 else if (binx == 2 && biny == 3)
00368 {
00369
00370 if(red_ccd_new) {
00371
00372 int badmap[][4] = {{1,3,696,3},
00373 {1,14,836,15},
00374 {1,33,761,33},
00375 {1,55,596,56},
00376 {1,89,814,90},
00377 {1,97,805,90},
00378 {1,99,674,100},
00379 {1,144,658,144},
00380 {1,156,784,156},
00381 {1,168,759,168},
00382 {1,177,647,178},
00383 {1,203,826,203},
00384 {1,263,714,263},
00385 {-1,-1,-1,-1}};
00386 map = dup_map(badmap);
00387 } else {
00388
00389 int badmap[][4] = {{1,3,696,3},
00390 {1,33,761,33},
00391 {1,55,592,56},
00392 {1,89,814,90},
00393 {1,99,674,100},
00394 {1,144,658,144},
00395 {1,177,647,178},
00396 {-1,-1,-1,-1}};
00397
00398 map = dup_map(badmap);
00399 }
00400 }
00401 else
00402 {
00403 assure( false, CPL_ERROR_ILLEGAL_INPUT,
00404 "Don't know bad pixel map for %dx%d binning, red, lower chip",
00405 binx, biny);
00406 }
00407 }
00408 else if (chip == UVES_CHIP_REDU)
00409 {
00410
00411
00412
00413 if (binx == 1 && biny ==1)
00414 {
00415 if(red_ccd_new) {
00416
00417 int badmap[][4] = {
00418 {1,845,1268,845},
00419 {-1,-1,-1,-1}};
00420
00421 if (!mark_bad)
00422 {
00423 badmap[2][0] = -1;
00424 badmap[2][1] = -1;
00425 badmap[2][2] = -1;
00426 badmap[2][3] = -1;
00427 }
00428 map = dup_map(badmap);
00429 } else {
00430
00431 int badmap[][4] = {
00432 {1,2030,1268,2033},
00433 {1269,2033,4096,2033},
00434 {1201, 491, 3271, 492},
00435 {-1,-1,-1,-1}};
00436
00437 if (!mark_bad)
00438 {
00439 badmap[2][0] = -1;
00440 badmap[2][1] = -1;
00441 badmap[2][2] = -1;
00442 badmap[2][3] = -1;
00443 }
00444 map = dup_map(badmap);
00445 }
00446 }
00447 else if (binx == 1 && biny == 2)
00448 {
00449
00450 if(red_ccd_new) {
00451
00452 int badmap[][4] = {{1,1396,845,1396},
00453 {-1,-1,-1,-1}};
00454
00455 if (!mark_bad)
00456 {
00457 badmap[2][0] = -1;
00458 badmap[2][1] = -1;
00459 badmap[2][2] = -1;
00460 badmap[2][3] = -1;
00461 }
00462 map = dup_map(badmap);
00463 } else {
00464
00465 int badmap[][4] = {{1,2030,634,2033},
00466 {635,2033,2048,2033},
00467 {600, 491,1635, 492},
00468 {-1,-1,-1,-1}};
00469
00470 if (!mark_bad)
00471 {
00472 badmap[2][0] = -1;
00473 badmap[2][1] = -1;
00474 badmap[2][2] = -1;
00475 badmap[2][3] = -1;
00476 }
00477 map = dup_map(badmap);
00478 }
00479 }
00480 else if (binx == 2 && biny == 2)
00481 {
00482
00483 if(red_ccd_new) {
00484
00485 int badmap[][4] = {{1,422,1526,422},
00486 {-1,-1,-1,-1}};
00487
00488 if (!mark_bad)
00489 {
00490 badmap[2][0] = -1;
00491 badmap[2][1] = -1;
00492 badmap[2][2] = -1;
00493 badmap[2][3] = -1;
00494 }
00495 map = dup_map(badmap);
00496 } else {
00497
00498 int badmap[][4] = {{1,1013,634,1016},
00499 {635,1015,2048,1016},
00500 {600, 244,1635, 245},
00501 {-1,-1,-1,-1}};
00502
00503 if (!mark_bad)
00504 {
00505 badmap[2][0] = -1;
00506 badmap[2][1] = -1;
00507 badmap[2][2] = -1;
00508 badmap[2][3] = -1;
00509 }
00510 map = dup_map(badmap);
00511 }
00512 }
00513 else if (binx == 2 && biny == 3)
00514 {
00515
00516 if(red_ccd_new) {
00517 int badmap[][4] = {{1,61,287,62},
00518 {1,422,1051,422},
00519 {400, 872,1265, 872},
00520 {-1,-1,-1,-1}};
00521
00522 if (!mark_bad)
00523 {
00524 badmap[2][0] = -1;
00525 badmap[2][1] = -1;
00526 badmap[2][2] = -1;
00527 badmap[2][3] = -1;
00528 }
00529 map = dup_map(badmap);
00530
00531 } else {
00532
00533 int badmap[][4] = {{1,1013,423,1016},
00534 {424,1015,1365,1016},
00535 {400, 244,1090, 245},
00536 {-1,-1,-1,-1}};
00537
00538 if (!mark_bad)
00539 {
00540 badmap[2][0] = -1;
00541 badmap[2][1] = -1;
00542 badmap[2][2] = -1;
00543 badmap[2][3] = -1;
00544 }
00545 map = dup_map(badmap);
00546
00547
00548 }
00549 }
00550 else
00551 {
00552 assure( false, CPL_ERROR_ILLEGAL_INPUT,
00553 "Don't know bad pixel map for %dx%d binning, red, upper chip",
00554 binx, biny);
00555 }
00556 }
00557 else
00558 {
00559
00560 int badmap[][4] = {{-1,-1,-1,-1}};
00561
00562 map = dup_map(badmap);
00563 }
00564
00565 cleanup:
00566 return map;
00567 }
00568
00569
00570
00571
00586
00587 static int
00588 uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap,
00589 bool mark_bad)
00590 {
00591 int ncorrect = 0;
00592 int xstart, ystart, xend, yend;
00593 int row;
00594 bool finished = false;
00595 int nx, ny;
00596 cpl_mask *image_bad = NULL;
00597 cpl_binary*image_bpm = NULL;
00598 cpl_type type=0;
00599
00600 type=cpl_image_get_type(master_bias);
00601 assure( (type == CPL_TYPE_DOUBLE) || (type == CPL_TYPE_FLOAT),
00602 CPL_ERROR_UNSUPPORTED_MODE,
00603 "Image type must be float or double. It is %s",
00604 uves_tostring_cpl_type(cpl_image_get_type(master_bias)));
00605
00606 image_bad = cpl_image_get_bpm(master_bias);
00607 image_bpm = cpl_mask_get_data(image_bad);
00608
00609 nx = cpl_image_get_size_x(master_bias);
00610 ny = cpl_image_get_size_y(master_bias);
00611
00612 row = 0;
00613 while (!finished)
00614 {
00615 xstart = badmap[row][0];
00616 ystart = badmap[row][1];
00617 xend = badmap[row][2];
00618 yend = badmap[row][3];
00619
00620 if (xstart > 0)
00621 {
00622 int ylow, yhigh;
00623 int x, y;
00624
00625 assure( 1 <= xstart && xstart <= nx &&
00626 1 <= xend && xend <= nx &&
00627 1 <= ystart && ystart <= ny &&
00628 1 <= yend && yend <= ny, CPL_ERROR_ILLEGAL_INPUT,
00629 "Illegal window (%d, %d) - (%d, %d). Image size = %dx%d",
00630 xstart, ystart, xend, yend, nx, ny);
00631
00632 if ( ystart < 3 )
00633 {
00634 assure( yend + 2 <= ny, CPL_ERROR_ILLEGAL_INPUT,
00635 "Too large range in y: %d - %d", ystart, yend);
00636
00637 ylow = yend + 1;
00638 yhigh = yend + 2;
00639 }
00640 else if (yend > ny - 3 )
00641 {
00642 assure( ystart - 2 >= 1, CPL_ERROR_ILLEGAL_INPUT,
00643 "Too large range in y: %d - %d", ystart, yend);
00644
00645 ylow = ystart - 2;
00646 yhigh = ystart - 1;
00647 }
00648 else
00649 {
00650 ylow = ystart - 2;
00651 yhigh = yend + 2;
00652 }
00653
00654 uves_msg("Correcting window (%d, %d)-(%d, %d)", xstart, ystart, xend, yend);
00655
00656
00657 if(type == CPL_TYPE_DOUBLE) {
00658
00659 for (x = xstart; x <= xend; x++) {
00660 for (y = ystart; y <= yend; y++) {
00661 int pis_rejected;
00662 double i1, i2;
00663
00664 if (mark_bad)
00665 {
00666
00667
00668
00669 image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
00670 }
00671 else
00672
00673 {
00674 double *master_bias_data;
00675
00676 i1 = cpl_image_get(master_bias, x, ylow , &pis_rejected);
00677 i2 = cpl_image_get(master_bias, x, yhigh, &pis_rejected);
00678
00679
00680
00681
00682
00683
00684 master_bias_data = cpl_image_get_data_double(master_bias);
00685 master_bias_data[(x-1) + (y-1)*nx] = (i1+i2)/2;
00686 }
00687 ncorrect += 1;
00688 }
00689 }
00690
00691
00692 } else {
00693
00694
00695 for (x = xstart; x <= xend; x++) {
00696 for (y = ystart; y <= yend; y++) {
00697 int pis_rejected;
00698 float i1, i2;
00699
00700 if (mark_bad)
00701 {
00702
00703
00704
00705 image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
00706 }
00707 else
00708
00709 {
00710 float *master_bias_data;
00711
00712 i1 = cpl_image_get(master_bias, x, ylow , &pis_rejected);
00713 i2 = cpl_image_get(master_bias, x, yhigh, &pis_rejected);
00714
00715
00716
00717
00718
00719
00720 master_bias_data = cpl_image_get_data_float(master_bias);
00721 master_bias_data[(x-1) + (y-1)*nx] = (i1+i2)/2;
00722 }
00723 ncorrect += 1;
00724 }
00725 }
00726
00727
00728 }
00729
00730
00731 }
00732 else
00733 {
00734 finished = true;
00735 }
00736 row++;
00737 }
00738
00739
00740 if (ncorrect > 0)
00741 {
00742 check( uves_pfits_set_badpixcorr(header, "true"),
00743 "Error updating product header");
00744 }
00745
00746 cleanup:
00747 return ncorrect;
00748 }