uves_corrbadpix.c

00001 /*                                                                              *
00002  *   This file is part of the ESO UVES Pipeline                                 *
00003  *   Copyright (C) 2004,2005 European Southern Observatory                      *
00004  *                                                                              *
00005  *   This library is free software; you can redistribute it and/or modify       *
00006  *   it under the terms of the GNU General Public License as published by       *
00007  *   the Free Software Foundation; either version 2 of the License, or          *
00008  *   (at your option) any later version.                                        *
00009  *                                                                              *
00010  *   This program is distributed in the hope that it will be useful,            *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
00013  *   GNU General Public License for more details.                               *
00014  *                                                                              *
00015  *   You should have received a copy of the GNU General Public License          *
00016  *   along with this program; if not, write to the Free Software                *
00017  *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA       *
00018  *                                                                              */
00019 
00020 /*
00021  * $Author: amodigli $
00022  * $Date: 2010/09/24 09:32:02 $
00023  * $Revision: 1.26 $
00024  * $Name: uves-5_0_0 $
00025  * $Log: uves_corrbadpix.c,v $
00026  * Revision 1.26  2010/09/24 09:32:02  amodigli
00027  * put back QFITS dependency to fix problem spot by NRI on FIBER mode (with MIDAS calibs) data
00028  *
00029  * Revision 1.24  2009/10/29 17:47:15  amodigli
00030  * set location of new red ccd's traps
00031  *
00032  * Revision 1.23  2007/08/21 13:08:26  jmlarsen
00033  * Removed irplib_access module, largely deprecated by CPL-4
00034  *
00035  * Revision 1.22  2007/07/23 06:37:44  amodigli
00036  * we now support also input data type CPL_TYPE_FLOAT
00037  *
00038  * Revision 1.21  2007/06/06 08:17:33  amodigli
00039  * replace tab with 4 spaces
00040  *
00041  * Revision 1.20  2007/04/24 12:50:29  jmlarsen
00042  * Replaced cpl_propertylist -> uves_propertylist which is much faster
00043  *
00044  * Revision 1.19  2007/01/16 10:26:52  jmlarsen
00045  * Fixed calloc -> cpl_calloc
00046  *
00047  * Revision 1.18  2007/01/15 15:10:01  jmlarsen
00048  * Fixed memory bug in deallocator
00049  *
00050  * Revision 1.17  2007/01/15 13:57:20  jmlarsen
00051  * Fixed crashing BLUE chips
00052  *
00053  * Revision 1.16  2007/01/10 12:35:59  jmlarsen
00054  * Added uves_get_badpix
00055  *
00056  * Revision 1.15  2006/11/15 15:02:14  jmlarsen
00057  * Implemented const safe workarounds for CPL functions
00058  *
00059  * Revision 1.13  2006/11/15 14:04:08  jmlarsen
00060  * Removed non-const version of parameterlist_get_first/last/next which is already
00061  * in CPL, added const-safe wrapper, unwrapper and deallocator functions
00062  *
00063  * Revision 1.12  2006/11/06 15:19:41  jmlarsen
00064  * Removed unused include directives
00065  *
00066  * Revision 1.11  2006/08/17 13:56:52  jmlarsen
00067  * Reduced max line length
00068  *
00069  * Revision 1.10  2006/08/17 09:16:30  jmlarsen
00070  * Removed CPL2 code
00071  *
00072  * Revision 1.9  2006/08/14 12:15:26  jmlarsen
00073  * Update to CPL3
00074  *
00075  * Revision 1.8  2006/08/10 10:49:06  jmlarsen
00076  * Removed workaround for cpl_image_get_bpm
00077  *
00078  * Revision 1.7  2006/08/08 11:27:18  amodigli
00079  * upgrade to CPL3
00080  *
00081  * Revision 1.6  2006/07/07 06:45:23  amodigli
00082  * added doc
00083  *
00084  * Revision 1.5  2006/07/03 14:20:39  jmlarsen
00085  * Exclude bad pixels from order tracing
00086  *
00087  * Revision 1.4  2006/07/03 12:58:34  jmlarsen
00088  * Support flagging instead of interpolating bad pixels
00089  *
00090  * Revision 1.3  2006/04/06 08:29:56  jmlarsen
00091  * Include self
00092  *
00093  * Revision 1.2  2005/12/19 16:17:56  jmlarsen
00094  * Replaced bool -> int
00095  *
00096  * Revision 1.1  2005/11/11 13:18:54  jmlarsen
00097  * Reorganized code, renamed source files
00098  *
00099  */
00100 
00101 #ifdef HAVE_CONFIG_H
00102 #  include <config.h>
00103 #endif
00104 
00105 /*----------------------------------------------------------------------------*/
00111 /*----------------------------------------------------------------------------*/
00114 /*-----------------------------------------------------------------------------
00115                                 Includes
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                             Functions prototypes
00130  -----------------------------------------------------------------------------*/
00131 static int
00132 uves_correct_badpix(cpl_image *master_bias, uves_propertylist *header, int **badmap,
00133             bool mark_bad);
00134 
00135 /*-----------------------------------------------------------------------------
00136                             Implementation
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; /* result */
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     /* The execution time is O(n*n) which is okay, due to the low number
00223        of entries */
00224     
00225     for (row = 0; !finished; row++)
00226     {
00227         map = cpl_realloc(map, (row+1)*sizeof(int *));
00228         /* First time equivalent to: malloc(sizeof(int *)) */
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             int badmap[][4] = {{1,4,2088,4},
00289                                {1,63,2282,63},
00290                                {1,176,2443,176},
00291                                {1,196,2021,196},
00292                                {1,285,1974,285},
00293                                {1,352,1942,352},
00294                                {-1,-1,-1,-1}};
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         /* Use different bad pixels maps for bias and
00411            orderpos recipes !
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         /* No blue chip bad pixels */
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;   /* Result */
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                     /* This is extremely slow with CPL2:
00667                        cpl_image_reject(master_bias, x, y);
00668                     */
00669                     image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
00670                 }
00671                 else
00672                 /* interpolate */
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                     /* Write average */
00680                     
00681                     /* This will make the bpm invalid:
00682                        cpl_image_set(master_bias, x, y, (i1+i2)/2);
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                     /* This is extremely slow with CPL2:
00703                        cpl_image_reject(master_bias, x, y);
00704                     */
00705                     image_bpm[(x-1) + (y-1)*nx] = CPL_BINARY_1;
00706                 }
00707                 else
00708                 /* interpolate */
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                     /* Write average */
00716                     
00717                     /* This will make the bpm invalid:
00718                        cpl_image_set(master_bias, x, y, (i1+i2)/2);
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     /* Update product header */
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 }

Generated on 9 Mar 2012 for UVES Pipeline Reference Manual by  doxygen 1.6.1