IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6399


Ignore:
Timestamp:
Feb 9, 2006, 9:40:40 AM (20 years ago)
Author:
eugene
Message:

added background median map

Location:
trunk/psphot/src
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/Makefile.am

    r6379 r6399  
    3939        psphotMagnitudes.c      \
    4040        psphotRadiusChecks.c    \
     41        psphotImageMedian.c     \
    4142        psLine.c                \
    4243        psSparse.c              \
  • trunk/psphot/src/psphot.h

    r6379 r6399  
    3939pmPSF          *psphotChoosePSF (psMetadata *config, psArray *sources, psStats *sky);
    4040void            psphotOutput (pmReadout *readout, psMetadata *arguments);
     41psImage        *psphotImageMedian (pmReadout *readout, psMetadata *config, psStats *sky);
    4142
    4243// optional object analysis steps
  • trunk/psphot/src/psphotImageMedian.c

    r6324 r6399  
    11# include "psphot.h"
     2double psImageClippedStats (psImage *image, psImage *mask, psU8 maskValue, double fmin, double fmax);
     3void fsort (float *value, int N);
     4
     5// random number seed to select a fraction of the image pixels
     6static psRandom *rnd;
     7
     8// use no more than MAX_SAMPLE_PIXELS pixels for each median box
     9static int MAX_SAMPLE_PIXELS;
    210
    311// generate the median in NxN boxes, clipping heavily
    4 // build a 2D clipped spline to the data (toss out the outliers?
    5 
     12// linear interpolation to generate full-scale model
    613psImage *psphotImageMedian (pmReadout *readout, psMetadata *config, psStats *sky)
    714{
    8 
     15    bool status;
    916    psRegion region;
     17
     18    rnd = psRandomAlloc (PS_RANDOM_TAUS, 0);
     19    MAX_SAMPLE_PIXELS = psMetadataLookupF32 (&status, config, "IMSTATS_NPIX");
     20    if (!status) MAX_SAMPLE_PIXELS = 1000;
    1021
    1122    // fit background to subset of image points within 3 sigma of sky
    1223    psTimerStart ("psphot");
    13     psRandom *rnd     = psRandomAlloc (PS_RANDOM_TAUS, 0);
    1424
    1525    psImage *image = readout->image;
    1626    psImage *mask  = readout->mask;
    1727
    18     bool      status  = false;
    19     int       Nx = image->numCols + image->col0;
    20     int       Ny = image->numRows + image->row0;
    21     int       xbin = psMetadataLookupS32 (&status, config, "BACKGROUND_XBIN");
    22     if (!status) {xbin = 64;}
    23     int       ybin = psMetadataLookupS32 (&status, config, "BACKGROUND_YBIN");
    24     if (!status) {ybin = 64;}
    25 
    26     // we slide the box in half-steps from -0.5 off the left edge to +0.5 off the right edge
    27     int nx = 2 + 2 * Nx / xbin;
    28     int ny = 2 + 2 * Ny / ybin;
    29 
    30     psStats *stats = psStatsAlloc (PS_STATS_CLIPPED_MEAN, PS_STATS_CLIPPED_STDEV);
    31     psImage *medimage = psImageAlloc (nx, ny, PS_TYPE_F32);
    32 
    33     psVector *xval = psVectorAlloc (nx, PS_TYPE_F32);
    34     psVector *yval = psVectorAlloc (ny, PS_TYPE_F32);
     28    // dimensions of input & output image
     29    int Nx = image->numCols;
     30    int Ny = image->numRows;
     31
     32    // scaling factor
     33    int DX = psMetadataLookupS32 (&status, config, "BACKGROUND_XBIN");
     34    if (!status) {DX = 64;}
     35    int DY = psMetadataLookupS32 (&status, config, "BACKGROUND_YBIN");
     36    if (!status) {DY = 64;}
     37
     38    // overhang : we will balance this evenly
     39    int dx = (Nx % DX) / 2;
     40    int dy = (Ny % DY) / 2;
     41
     42    // dimensions of binned image
     43    int nx = (Nx % DX) ? (int)(Nx / DX) + 1 : Nx / DX;
     44    int ny = (Ny % DY) ? (int)(Ny / DY) + 1 : Ny / DY;
     45
     46    // psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     47    psImage *model = psImageAlloc (nx, ny, PS_TYPE_F32);
    3548
    3649    // measure clipped median for subimages
    37     for (int iy = -1; iy < ny - 1; iy++) {
    38         for (int ix = -1; ix < nx - 1; ix++) {
    39             int sx = 0.5*ix*xbin;
    40             int sy = 0.5*iy*ybin;
    41             region = psRegionSet (sx, sx + xbin, sy, sy + ybin);
    42             region = psRegionForImage (readout->image, region);
    43             psImage *subset = psImageSubset (readout->image, region);
    44             stats = psImageStats (stats, subset);
    45            
    46             // XXX filter these on the clippedStdev?
    47             medimage->data.F32[iy][ix] = stats->clippedMean;
    48 
    49         }
    50     }
    51     for (int ix = -1; ix < nx - 1; ix++) {
    52         xval->data.F32[ix] = 0.5*ix*xbin + 0.5*xbin;
    53     }
    54     for (int iy = -1; iy < ny - 1; iy++) {
    55         yval->data.F32[iy] = 0.5*iy*ybin + 0.5*ybin;
    56     }
    57 
    58     // x-dir / y-dir
    59     psImage *devimage = psImageFitSpline (medimage, true);
    60     psImage *background = psImageEvalSpline (medimage, devimage, xval, yval, Nx, Ny);
    61 
    62     // this is a very inefficient way to evaluate the function..
    63     // lame, temporary step to zero masked pixels
     50    for (int iy = 0; iy < ny; iy++) {
     51        for (int ix = 0; ix < nx; ix++) {
     52            // sx, sy are in parent coords
     53            int sx = ix*DX - dx + image->col0;
     54            int sy = iy*DY - dy + image->row0;
     55            region = psRegionSet (sx, sx + 2*DX, sy, sy + 2*DY);
     56            region = psRegionForImage (image, region);
     57            psImage *subset  = psImageSubset (image, region);
     58            psImage *submask = psImageSubset (mask, region);
     59
     60            model->data.F32[iy][ix] = psImageClippedStats (subset, submask, 0xff, 0.25, 0.50);
     61
     62            psFree (subset);
     63            psFree (submask);
     64
     65            // XXX psImageStats is still very inefficient and poorly coded...
     66            // stats = psImageStats (stats, subset, maskset, 0xff);
     67            // model->data.F32[iy][ix] = stats->clippedMean;
     68        }
     69    }
     70    psLogMsg ("psphot", 3, "build median image: %f sec\n", psTimerMark ("psphot"));
     71
     72    // linear interpolation to full-scale
     73   
     74    psImage *background = psImageAlloc (Nx, Ny, PS_TYPE_F32);
     75
     76    // XXX this code skips the initial pixels
     77    for (int Iy = 0; Iy < ny-1; Iy ++) {
     78        for (int Ix = 0; Ix < nx-1; Ix ++) {
     79
     80            float V00 = model->data.F32[Iy+0][Ix+0];
     81            float V01 = model->data.F32[Iy+0][Ix+1];
     82            float V10 = model->data.F32[Iy+1][Ix+0];
     83            float V11 = model->data.F32[Iy+1][Ix+1];
     84
     85            // a single binned pixel quad
     86            // (Xs,Ys) : (Xe,Ye) : binned pixel centers in unbinned coords
     87            // corresponding to (Ix,Iy), (Ix+1,Iy+1)
     88            int Xs = (Ix + 1)*DX - dx;
     89            int Ys = (Iy + 1)*DY - dy;
     90            int Xe = Xs + DX;
     91            int Ye = Ys + DY;
     92
     93            for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) {
     94                float Vxs = (V10 - V00)*(iy - Ys) / DY + V00;
     95                float Vxe = (V11 - V01)*(iy - Ys) / DY + V01;
     96                float dV = (Vxe - Vxs) / DX;
     97                float V  = Vxs;
     98                for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) {
     99                    background->data.F32[iy][ix] = V;
     100                    V += dV;
     101                }
     102            }
     103        }
     104    }
     105
     106    // side pixels
     107    int Xs = DX - dx;
     108    int Xe = nx*DX - dx;
     109    for (int Iy = 0; Iy < ny - 1; Iy++) {
     110
     111        int Ys = (Iy + 1)*DY - dy;
     112        int Ye = Ys + DY;
     113
     114        // leading edge
     115        float V0 = model->data.F32[Iy+0][0];
     116        float V1 = model->data.F32[Iy+1][0];
     117        float dV = (V1 - V0) / DY;
     118        float V = V0;
     119        for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) {
     120            for (int ix = 0; ix < Xs; ix++) {
     121                background->data.F32[iy][ix] = V;
     122            }
     123            V += dV;
     124        }
     125
     126        // trailing edge
     127        V0 = model->data.F32[Iy+0][nx-1];
     128        V1 = model->data.F32[Iy+1][nx-1];
     129        dV = (V1 - V0) / DY;
     130        V = V0;
     131        for (int iy = Ys; (iy < Ye) && (iy < Ny); iy++) {
     132            for (int ix = Xe; ix < Nx; ix++) {
     133                background->data.F32[iy][ix] = V;
     134            }
     135            V += dV;
     136        }
     137    }
     138
     139    // top and bottom pixels
     140    int Ys = DY - dy;
     141    int Ye = ny*DY - dy;
     142    for (int Ix = 0; Ix < nx - 1; Ix++) {
     143
     144        int Xs = (Ix + 1)*DX - dx;
     145        int Xe = Xs + DX;
     146
     147        // top edge
     148        float V0 = model->data.F32[0][Ix+0];
     149        float V1 = model->data.F32[0][Ix+1];
     150        float dV = (V1 - V0) / DX;
     151        for (int iy = 0; iy < Ys; iy++) {
     152            float V = V0;
     153            for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) {
     154                background->data.F32[iy][ix] = V;
     155                V += dV;
     156            }
     157        }
     158
     159        // bottom edge
     160        V0 = model->data.F32[ny-1][Ix+0];
     161        V1 = model->data.F32[ny-1][Ix+1];
     162        dV = (V1 - V0) / DX;
     163        for (int iy = Ye; iy < Ny; iy++) {
     164            float V = V0;
     165            for (int ix = Xs; (ix < Xe) && (ix < Nx); ix++) {
     166                background->data.F32[iy][ix] = V;
     167                V += dV;
     168            }
     169        }
     170    }
     171
     172    // the four corners
     173    {
     174        float V;
     175        // 0,0
     176        V = model->data.F32[0][0];
     177        for (int iy = 0; iy < DY - dy; iy++) {
     178            for (int ix = 0; ix < DX - dx; ix++) {
     179                background->data.F32[iy][ix] = V;
     180            }
     181        }
     182        // Nx,0
     183        V = model->data.F32[0][nx-1];
     184        for (int iy = 0; iy < DY - dy; iy++) {
     185            for (int ix = nx*DX - dx; ix < Nx; ix++) {
     186                background->data.F32[iy][ix] = V;
     187            }
     188        }
     189        // 0,Ny
     190        V = model->data.F32[ny-1][0];
     191        for (int iy = ny*DY - dy; iy < Ny; iy++) {
     192            for (int ix = 0; ix < DX - dx; ix++) {
     193                background->data.F32[iy][ix] = V;
     194            }
     195        }
     196        // Nx,Ny
     197        V = model->data.F32[nx-1][ny-1];
     198        for (int iy = ny*DY - dy; iy < Ny; iy++) {
     199            for (int ix = nx*DX - dx; ix < Nx; ix++) {
     200                background->data.F32[iy][ix] = V;
     201            }
     202        }
     203    }   
     204    psLogMsg ("psphot", 3, "build resampled image: %f sec\n", psTimerMark ("psphot"));
     205
     206    // subtract the background model
    64207    for (int j = 0; j < image->numRows; j++) {
    65208        for (int i = 0; i < image->numCols; i++) {
     
    69212        }
    70213    }
    71     psFree (medimage);
    72     psFree (devimage);
    73     psFree (rnd);  // XXX should this be made available at a higher level?
    74 
    75     psLogMsg ("psphot", 3, "fit background model: %f sec\n", psTimerMark ("psphot"));
     214    psLogMsg ("psphot", 3, "subtracted background model: %f sec\n", psTimerMark ("psphot"));
     215    psFree (rnd);
    76216    return (background);
    77217}
     218
     219double psImageClippedStats (psImage *image, psImage *mask, psU8 maskValue, double fmin, double fmax) {
     220
     221    double value;
     222    int nx = image->numCols;
     223    int ny = image->numRows;
     224   
     225    if (nx*ny <= 0) return 0.0;
     226
     227    int Nsubset = PS_MIN (MAX_SAMPLE_PIXELS, nx*ny);
     228    int Npixels = nx*ny;
     229
     230    psVector *values = psVectorAlloc (Nsubset, PS_TYPE_F32);
     231
     232    float min = values->data.F32[0];
     233    float max = values->data.F32[0];
     234
     235    int n = 0;
     236    for (int i = 0; i < Nsubset; i++) {
     237        double frnd = psRandomUniform (rnd);
     238        int pixel = Npixels * frnd;
     239        int ix = pixel % nx;
     240        int iy = pixel / nx;
     241
     242        if (mask->data.U8[iy][ix] & maskValue) continue;
     243
     244        value = image->data.F32[iy][ix];
     245        min = PS_MIN (value, min);
     246        max = PS_MIN (value, max);
     247        values->data.F32[n] = value;
     248        n++;
     249    }
     250    values->n = n;
     251
     252    int imin = fmin * n;
     253    int imax = fmax * n;
     254    int npts = imax - imin + 1;
     255
     256    fsort (values->data.F32, n);
     257
     258    value = 0;
     259    for (int i = imin; (i <= imax) && (i < n); i++) {
     260        value += values->data.F32[i];
     261    }
     262    value = value / npts;
     263   
     264    psFree (values);
     265    return value;
     266}
     267
     268void fsort (float *value, int N) {
     269
     270    int l,j,ir,i;
     271    float temp;
     272 
     273    if (N < 2) return;
     274    l = N >> 1;
     275    ir = N - 1;
     276    for (;;) {
     277        if (l > 0) {
     278            temp = value[--l];
     279        }
     280        else {
     281            temp = value[ir];
     282            value[ir] = value[0];
     283            if (--ir == 0) {
     284                value[0] = temp;
     285                return;
     286            }
     287        }
     288        i = l;
     289        j = (l << 1) + 1;
     290        while (j <= ir) {
     291            if (j < ir && value[j] < value[j+1]) ++j;
     292            if (temp < value[j]) {
     293                value[i]=value[j];
     294                j += (i=j) + 1;
     295            }
     296            else j = ir + 1;
     297        }
     298        value[i] = temp;
     299    }
     300}
     301
  • trunk/psphot/src/psphotReadout.c

    r6379 r6399  
    1111    psPolynomial2D *model = NULL;
    1212
    13     psphotSaveImage (NULL, readout->mask, "mask.fits");
    14     psphotSaveImage (NULL, readout->image, "image.fits");
    15     psphotSaveImage (NULL, readout->weight, "weight.fits");
     13    psphotImageMedian (readout, config, sky);
    1614
    1715    // measure image stats for initial guess
Note: See TracChangeset for help on using the changeset viewer.