IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 2719


Ignore:
Timestamp:
Dec 15, 2004, 2:46:22 PM (22 years ago)
Author:
gusciora
Message:

* empty log message *

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/pmSubtractSky.c

    r2588 r2719  
    66 *  @author GLG, MHPCC
    77 *
    8  *  @version $Revision: 1.5 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2004-12-01 21:46:06 $
     8 *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2004-12-16 00:46:22 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    1717#include "psConstants.h"
    1818
    19 // XXX: this is pmFit in pmSubtractBias.c, and psFit here.
     19// XXX: this is pmFit in pmSubtractBias.c, named psFit here.
    2020typedef enum {
    2121    PM_FIT_NONE,                              ///< No fit
     
    3838    return(numBits);
    3939}
    40 
    41 
    4240
    4341psU64 getHighestPriorityStatOption(psU64 statOptions)
     
    123121}
    124122
     123/******************************************************************************
     124buildPolyTerms(): this routine computes a 2-D array polyTerms[] that holds
     125terms for the polynomial that is used to model the sky background.  We use
     126this array primarily for convenience in many computations involving that sky
     127model polynomials.  It is defined as:
     128    polyTerms[i][0] = the power to which X is raised in the i-th term of in an
     129    poly-order sky background polynomial.
     130 
     131    polyTerms[i][1] = the power to which Y is raised in the i-th term of in an
     132    poly-order sky background polynomial.
     133 *****************************************************************************/
     134psS32 **buildPolyTerms(psS32 polyOrder)
     135{
     136    psS32 i=0;
     137    psS32 order = 0;
     138    psS32 num=0;
     139    psS32 localPolyTerms= (((polyOrder+1) * (polyOrder + 2)) / 2);
     140
     141    // We create the data structure which we hold the xy order of each coeff.
     142    psS32 **polyTerms = (psS32 **) psAlloc(localPolyTerms * sizeof(psS32 *));
     143    for (i=0; i < localPolyTerms ; i++) {
     144        polyTerms[i] = (psS32 *) psAlloc(2 * sizeof(psS32));
     145    }
     146
     147    i=0;
     148    // This code segment loops through each term i in the polynomial and
     149    // calculates the power to which x/y are raised in that i-th term.
     150    // We first do the 0-order terms, then the 1-order terms, etc.
     151    for (order=0;order<=polyOrder;order++) {
     152        for (num=0;num<=order;num++) {
     153            polyTerms[i][0] = order-num;
     154            polyTerms[i][1] = num;
     155            i++;
     156        }
     157    }
     158
     159    return(polyTerms);
     160}
     161
     162#define PS_TWENTY 20
     163
     164// XXX: Use variable size arrays for polynomial sums.
     165/** @brief This procedure calculates various combinations of powers of x and y
     166 *   and stores them in the data structure sums[][].  After it completes:
     167 *          sums[i][j] == x^i * y^j
     168 */
     169void buildSums(psF64 x,
     170               psF64 y,
     171               psF64 sums[PS_TWENTY][PS_TWENTY],
     172               psS32 polyOrder)
     173{
     174    psS32 i = 0;
     175    psS32 j = 0;
     176    psF64 xSum = 0.0;
     177    psF64 ySum = 0.0;
     178
     179    xSum = 1.0;
     180    ySum = 1.0;
     181    for(i=0;i<=polyOrder;i++) {
     182        ySum = xSum;
     183        for(j=0;j<=polyOrder;j++) {
     184            sums[i][j] = ySum;
     185            ySum*= y;
     186        }
     187        xSum*= x;
     188    }
     189}
     190
     191/******************************************************************************
     192 
     193 *****************************************************************************/
     194psPolynomial2D *ImageFitPolynomial(psPolynomial2D *myPoly,
     195                                   psImage *binnedImage,
     196                                   psImage *maskImage)
     197{
     198    PS_POLY_CHECK_NULL(myPoly, NULL);
     199    PS_POLY_CHECK_TYPE(myPoly, PS_POLYNOMIAL_ORD, NULL);
     200    PS_INT_CHECK_NON_EQUALS(myPoly->nX, myPoly->nY, NULL);
     201    PS_IMAGE_CHECK_NULL(binnedImage, NULL);
     202    PS_IMAGE_CHECK_EMPTY(binnedImage, NULL);
     203    PS_IMAGE_CHECK_TYPE(binnedImage, PS_TYPE_F32, NULL);
     204    PS_IMAGE_CHECK_NULL(maskImage, NULL);
     205    PS_IMAGE_CHECK_EMPTY(maskImage, NULL);
     206    PS_IMAGE_CHECK_TYPE(maskImage, PS_TYPE_U8, NULL);
     207    PS_IMAGE_CHECK_SIZE_EQUAL(binnedImage, maskImage, NULL);
     208    psS32 i;
     209    psS32 j;
     210    psS32 x;
     211    psS32 y;
     212    psS32 aRow;
     213    psS32 aCol;
     214    psS32 polyOrder = myPoly->nX;
     215    psS32 localPolyTerms= (((polyOrder+1) * (polyOrder + 2)) / 2);
     216    psS32 **polyTerms = buildPolyTerms(polyOrder);
     217    psF64 sums[PS_TWENTY][PS_TWENTY];
     218    psImage *A = psImageAlloc(localPolyTerms+1, localPolyTerms+1, PS_TYPE_F64);
     219    psVector *B = psVectorAlloc(localPolyTerms+1, PS_TYPE_F64);
     220    psVector *outPerm = NULL;
     221
     222    for(i=0;i<A->numRows;i++) {
     223        for(j=0;j<A->numCols;j++) {
     224            A->data.F64[i][j] = 0.0;
     225        }
     226    }
     227    for(i=0;i<B->n;i++) {
     228        B->data.F64[i] = 0.0;
     229    }
     230
     231    for (x=0;x<binnedImage->numRows;x++) {
     232        for (y=0;y<binnedImage->numCols;y++) {
     233            if (maskImage->data.U8[x][y] != 0) {
     234                buildSums((psF64) x, (psF64) y, sums, polyOrder);
     235
     236                /************************************************************
     237                Equation (7) from the ADD describes 16 linear equations.
     238                The i-th equation is simply the partial derivative of the
     239                sky background polynomial (1) w.r.t. to the i-th term in
     240                that polynomial.  The i-th equation is stored in row i of
     241                matrix A[][] (matrix A[][] has origin (1,1), not (0,0)).  To
     242                compute A[i][j] we simply multiply the j-th term of the Sky
     243                Background Polynomial (SBP) by the i-th term of SBP.
     244                ************************************************************/
     245                for (aRow=0;aRow<localPolyTerms;aRow++) {
     246                    for (aCol=0;aCol<localPolyTerms;aCol++) {
     247                        A->data.F64[aRow][aCol]+=
     248                            (sums[ polyTerms[aCol][0] ][ polyTerms[aCol][1] ] *
     249                             sums[ polyTerms[aRow][0] ][ polyTerms[aRow][1] ]);
     250                    }
     251                }
     252
     253                // Build the B[] vector, which is the right-hand side of (7).
     254                for (i=0;i<=localPolyTerms;i++) {
     255                    B->data.F64[i]+= binnedImage->data.F32[x][y] *
     256                                     sums[ polyTerms[i][0] ][ polyTerms[i][1] ];
     257                }
     258            }
     259        }
     260    }
     261    psImage *ALUD = psMatrixLUD(NULL, outPerm, A);
     262    psVector *C = psMatrixLUSolve(C, ALUD, B, outPerm);
     263
     264    for (i=0;i<localPolyTerms;i++) {
     265        myPoly->coeff[ polyTerms[i][0] ][ polyTerms[i][1] ] = C->data.F64[i];
     266    }
     267
     268    for (i=0;i<localPolyTerms;i++) {
     269        psFree(polyTerms[i]);
     270    }
     271    psFree(polyTerms);
     272    psFree(A);
     273    psFree(ALUD);
     274    psFree(B);
     275    psFree(C);
     276    psFree(outPerm);
     277
     278    return(myPoly);
     279}
     280
    125281
    126282/******************************************************************************
    127283psReadout pmSubtractSky():
    128284 
    129 XXX: use static vectors for myStats.
     285XXX: use static vectors for myStats, and the binned image
    130286 *****************************************************************************/
    131287psReadout *pmSubtractSky(psReadout *in,
     
    136292                         float clipSD)
    137293{
    138     if (fitSpec == NULL) {
     294    // Return the original input readout if the fit specs are poorly defined.
     295    if ((fitSpec == NULL) ||
     296            ((fit == PM_FIT_NONE) || (fit == PM_FIT_SPLINE))) {
    139297        return(in);
    140298    }
    141     if ((fit != PM_FIT_POLYNOMIAL) && (fit != PM_FIT_SPLINE)) {
    142         // No fit is specified.
    143         return(in);
    144     }
    145 
    146299    psImage *origImage = in->image;
    147300    psImage *maskImage = in->mask;
    148301    psImage *binnedImage = NULL;
    149302    psPolynomial2D *myPoly;
    150     psSpline1D *mySpline;
    151303
    152304    psStatsOptions statOptions = stats->options;
     
    154306        //XXX  psWarning(PS_ERR_UNKNOWN,true, "Multiple statistical options have been requested.\n");
    155307        statOptions = getHighestPriorityStatOption(statOptions);
     308        if (statOptions <= 0) {
     309            psLogMsg(__func__, PS_LOG_WARN,
     310                     "WARNING: pmSubtractSky(): unallowable stats->options was requested\n");
     311            return(in);
     312        }
    156313    }
    157314
    158315    // Bin the input image according to input parameters.
    159     if ((binFactor <= 0) ||
    160             (stats == NULL)) {
     316    if ((binFactor <= 0) || (stats == NULL)) {
     317        // Simply use the original image: no binning.
    161318        if (binFactor <= 0) {
    162319            psLogMsg(__func__, PS_LOG_WARN,
     
    169326        binnedImage = origImage;
    170327    } else {
     328        // Call a private function to do the binning.
    171329        binnedImage = binImage(origImage, binFactor, statOptions);
    172330    }
     
    175333    if (clipSD <= 0.0) {
    176334        psLogMsg(__func__, PS_LOG_WARN,
    177                  "WARNING: pmSubtractSky(): clipSD is %f\n", clipSD)
    178         ;
     335                 "WARNING: pmSubtractSky(): clipSD is %f\n", clipSD);
    179336    } else {
     337        // Determine the mean and standard deviation of the binned image.
    180338        psF64 binnedMean;
    181339        psF64 binnedStdev;
     
    189347        psFree(myStats);
    190348
     349        // Clip all pixels which are more than clipSD sigmas from the mean.
     350        // XXX: Is this correct?  We simply set the mask.
     351        // XXX: we must unset this later since we modify the image mask.
     352        // XXX: Determine which pixels, mask or image, should be clipped.
    191353        for (int row = 0; row < binnedImage->numRows ; row++) {
    192354            for (int col = 0; col < binnedImage->numCols ; col++) {
     
    201363    // XXX: fit the polynomial to the binned image
    202364    if (fit == PM_FIT_POLYNOMIAL) {
    203         // Fit a polynomial to the old overscan vector.
    204365        myPoly = (psPolynomial2D *) fitSpec;
    205         myPoly = psImageFitPolynomial(myPoly, origImage);
     366
     367        // XXX Ensure that the polynomial is of type Chebyshev.
     368        myPoly = ImageFitPolynomial(myPoly, binnedImage, maskImage);
     369
    206370        // XXX Do we need to do something with ordinate scaling if Chebyshev?
    207371        binnedImage = psImageEvalPolynomial(binnedImage, myPoly);
    208 
    209     } else if (fit == PM_FIT_SPLINE) {
    210         // Fit a spline to the old overscan vector.
    211         mySpline = (psSpline1D *) fitSpec;
    212         // XXX: What do we do?  We don't have 2-D splines.
    213         return(in);
    214372    }
    215373
    216374    //Subtract the polynomially fitted image from the original image
    217375    if (binFactor <= 0) {
     376        // The binned image is the same size as the original image.
    218377        for (int row = 0; row < origImage->numRows ; row++) {
    219378            for (int col = 0; col < origImage->numCols ; col++) {
     
    231390
    232391    }
     392
     393    if (!((binFactor <= 0) || (stats == NULL))) {
     394        psFree(binnedImage);
     395    }
     396
    233397    return(in);
    234398}
Note: See TracChangeset for help on using the changeset viewer.