IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 20448


Ignore:
Timestamp:
Oct 28, 2008, 2:01:22 PM (18 years ago)
Author:
eugene
Message:

use a hard-wired 2x2 bilinear interpolation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/objects/pmModel.c

    r20307 r20448  
    66 *  @author EAM, IfA
    77 *
    8  *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2008-10-22 02:11:08 $
     8 *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2008-10-29 00:01:22 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    193193    // use the true source position for the residual model
    194194    // the PSF model has presumably already been set for this coordinate
    195     float xPos    = params->data.F32[PM_PAR_XPOS];
    196     float yPos    = params->data.F32[PM_PAR_YPOS];
     195    float XoSave  = params->data.F32[PM_PAR_XPOS];
     196    float YoSave  = params->data.F32[PM_PAR_YPOS];
    197197    float IoSave  = params->data.F32[PM_PAR_I0];
    198198    float skySave = params->data.F32[PM_PAR_SKY];
    199199
     200    // the options allow us to modify various aspects of the model
    200201    if (mode & PM_MODEL_OP_NORM) {
    201202        params->data.F32[PM_PAR_I0] = 1.0;
     
    208209        params->data.F32[PM_PAR_YPOS] = image->row0 + 0.5*image->numRows;
    209210    }
     211
     212    // apply optional relative offset
     213    params->data.F32[PM_PAR_XPOS] += dx;
     214    params->data.F32[PM_PAR_YPOS] += dy;
    210215
    211216    // use these values for this realization
     
    216221    int xBin = 1;
    217222    int yBin = 1;
    218     float xResidCenter = 0.0;
    219     float yResidCenter = 0.0;
    220 
    221     psImage *myRo = NULL;
    222     psImage *myRx = NULL;
    223     psImage *myRy = NULL;
    224     psImageInterpolation *Ro = NULL;
    225     psImageInterpolation *Rx = NULL;
    226     psImageInterpolation *Ry = NULL;
    227     if (model->residuals && (mode & (PM_MODEL_OP_RES0 | PM_MODEL_OP_RES1))) {
    228         // if the residual image and object image don't match,
    229         // supply an appropriately overlapped residual image
    230         psImage *inRo = model->residuals->Ro;
    231         psImage *inRx = model->residuals->Rx;
    232         psImage *inRy = model->residuals->Ry;
    233         xBin = model->residuals->xBin;
    234         yBin = model->residuals->yBin;
    235         xResidCenter = model->residuals->xCenter;
    236         yResidCenter = model->residuals->yCenter;
    237         if ((image->numCols != inRo->numCols) ||
    238             (image->numRows != inRo->numRows)) {
    239             myRo = psImageAlloc (image->numCols, image->numRows, PS_TYPE_F32);
    240             myRx = psImageAlloc (image->numCols, image->numRows, PS_TYPE_F32);
    241             myRy = psImageAlloc (image->numCols, image->numRows, PS_TYPE_F32);
    242             // Difference between input and desired centres
    243             int xDiff = (int)(inRo->numCols / 2) - (xPos - image->col0);
    244             int yDiff = (int)(inRo->numRows / 2) - (yPos - image->row0);
    245             xResidCenter -= xDiff;
    246             yResidCenter -= yDiff;
    247             for (int iy = 0; iy < myRo->numRows; iy++) {
    248                 int jy = iy + yDiff;
    249                 if ((jy < 0) || (jy >= inRo->numRows)) {
    250                     for (int ix = 0; ix < myRo->numCols; ix++) {
    251                         myRo->data.F32[iy][ix] = 0.0;
    252                         myRx->data.F32[iy][ix] = 0.0;
    253                         myRy->data.F32[iy][ix] = 0.0;
    254                     }
    255                     continue;
    256                 }
    257                 for (int ix = 0; ix < myRo->numCols; ix++) {
    258                     int jx = ix + xDiff;
    259                     if ((jx < 0) || (jx >= inRo->numCols)) {
    260                         myRo->data.F32[iy][ix] = 0.0;
    261                         myRx->data.F32[iy][ix] = 0.0;
    262                         myRy->data.F32[iy][ix] = 0.0;
    263                     } else {
    264                         myRo->data.F32[iy][ix] = inRo->data.F32[jy][jx];
    265                         myRx->data.F32[iy][ix] = inRx->data.F32[jy][jx];
    266                         myRy->data.F32[iy][ix] = inRy->data.F32[jy][jx];
    267                     }
    268                 }
    269             }
    270         } else {
    271             myRo = psMemIncrRefCounter (inRo);
    272             myRx = psMemIncrRefCounter (inRx);
    273             myRy = psMemIncrRefCounter (inRy);
    274         }
    275 
    276         Ro = psImageInterpolationAlloc(PS_INTERPOLATE_BILINEAR, myRo, NULL, mask, 0, 0.0, 0.0, 1, 0, 0.0, 0);
    277         Rx = psImageInterpolationAlloc(PS_INTERPOLATE_BILINEAR, myRx, NULL, NULL, 0, 0.0, 0.0, 1, 0, 0.0, 0);
    278         Ry = psImageInterpolationAlloc(PS_INTERPOLATE_BILINEAR, myRy, NULL, NULL, 0, 0.0, 0.0, 1, 0, 0.0, 0);
    279 
    280     }
     223    float DX = 0.0;
     224    float DY = 0.0;
     225    int NX = 0;
     226    int NY = 0;
     227
     228    psF32 **Ro = NULL;
     229    psF32 **Rx = NULL;
     230    psF32 **Ry = NULL;
     231    psU8  **Rm = NULL;
     232
     233    if (model->residuals) {
     234        DX = xBin*(image->col0 - xCenter) + model->residuals->xCenter + 0.5;
     235        DY = yBin*(image->row0 - yCenter) + model->residuals->yCenter + 0.5;
     236        Ro = (model->residuals->Ro)   ? model->residuals->Ro->data.F32 : NULL;
     237        Rx = (model->residuals->Rx)   ? model->residuals->Rx->data.F32 : NULL;
     238        Ry = (model->residuals->Ry)   ? model->residuals->Ry->data.F32 : NULL;
     239        Rm = (model->residuals->mask) ? model->residuals->mask->data.U8 : NULL;
     240        if (Ro) {
     241            NX = model->residuals->Ro->numCols;
     242            NY = model->residuals->Ro->numRows;
     243        }           
     244    }
     245
     246    // XXX trying to improve the speed and threadability of this function.
     247    // note: model->residuals is a view to the item on pmPSF.
    281248
    282249    for (psS32 iy = 0; iy < image->numRows; iy++) {
     
    285252                continue;
    286253
    287             // Convert i/j to image coord space:
    288254            // XXX should we use using 0.5 pixel offset?
    289             imageCol = ix + image->col0 + dx;
    290             imageRow = iy + image->row0 + dy;
     255            // Convert to coordinate in parent image, with offset (dx,dy)
     256            imageCol = ix + image->col0;
     257            imageRow = iy + image->row0;
    291258
    292259            x->data.F32[0] = (float) imageCol;
     
    301268
    302269            // get the contribution from the residual model
    303             if (Ro) {
    304                 // fractional image position
    305                 float ox = xBin*(imageCol + 0.5 - xCenter) + xResidCenter;
    306                 float oy = yBin*(imageRow + 0.5 - yCenter) + yResidCenter;
    307 
    308                 psU8 mflux = 0;
    309                 if (mode & PM_MODEL_OP_RES0) {
    310                     double Fo = 0.0;
    311                     psImageInterpolate (&Fo, NULL, &mflux, ox, oy, Ro);
    312                     if (!mflux && isfinite(Fo)) {
    313                         pixelValue += Io*Fo;
    314                     }
    315                 }
    316                 // skip Rx,Ry if Ro is masked
    317                 if (!mflux && (mode & PM_MODEL_OP_RES1)) {
    318                     double Fx = 0.0;
    319                     double Fy = 0.0;
    320                     psImageInterpolate (&Fx, NULL, &mflux, ox, oy, Rx);
    321                     psImageInterpolate (&Fy, NULL, &mflux, ox, oy, Ry);
    322                     if (!mflux && isfinite(Fx) && isfinite(Fy)) {
    323                         pixelValue += Io*(xPos*Fx + yPos*Fy);
    324                     }
    325                 }
     270            if (Ro && (mode & PM_MODEL_OP_RES0)) {
     271                // residual image position
     272                float ry = yBin*iy + DY;
     273                float rx = xBin*ix + DX;
     274
     275                int rx0 = rx - 0.5;
     276                int rx1 = rx + 0.5;
     277                int ry0 = ry - 0.5;
     278                int ry1 = ry + 0.5;
     279
     280                if (rx0 < 0) goto skip;
     281                if (ry0 < 0) goto skip;
     282                if (rx1 >= NX) goto skip;
     283                if (ry1 >= NY) goto skip;
     284
     285                // these go from 0.0 to 1.0 between the centers of the pixels
     286                float fx = rx - 0.5 - rx0;
     287                float Fx = 1.0 - fx;
     288                float fy = ry - 0.5 - ry0;
     289                float Fy = 1.0 - fy;
     290
     291                // check the residual image mask (if set). give up if any of the 4 pixels are masked.
     292                if (Rm) {
     293                    if (Rm[ry0][rx0]) goto skip;
     294                    if (Rm[ry0][rx1]) goto skip;
     295                    if (Rm[ry1][rx0]) goto skip;
     296                    if (Rm[ry1][rx1]) goto skip;
     297                }
     298
     299                // a possible further optimization if we re-use these values
     300                // XXX allow for masked pixels, and add pixel weights
     301                float V0 = (Ro[ry0][rx0]*Fx + Ro[ry0][rx1]*fx);
     302                float V1 = (Ro[ry1][rx0]*Fx + Ro[ry1][rx1]*fx);
     303                float Vo = V0*Fy + V1*fy;
     304                if (!isfinite(Vo)) goto skip;
     305
     306                float Vx = 0.0;
     307                float Vy = 0.0;
     308
     309                // skip Rx,Ry if Ro is masked
     310                if (Rx && Ry && (mode & PM_MODEL_OP_RES1)) {
     311                    V0 = (Rx[ry0][rx0]*Fx + Rx[ry0][rx1]*fx);
     312                    V1 = (Rx[ry1][rx0]*Fx + Rx[ry1][rx1]*fx);
     313                    Vx = V0*Fy + V1*fy;
     314
     315                    V0 = (Ry[ry0][rx0]*Fx + Ry[ry0][rx1]*fx);
     316                    V1 = (Ry[ry1][rx0]*Fx + Ry[ry1][rx1]*fx);
     317                    Vy = V0*Fy + V1*fy;
     318                }
     319                if (!isfinite(Vx)) goto skip;
     320                if (!isfinite(Vy)) goto skip;
     321
     322                // 2D residual variations are set for the true source position
     323                pixelValue += Io*(Vo + XoSave*Vx + XoSave*Vy);
    326324            }
    327325
     326        skip:
    328327            // add or subtract the value
    329328            if (add) {
     
    336335
    337336    // restore original values
     337    params->data.F32[PM_PAR_XPOS] = XoSave;
     338    params->data.F32[PM_PAR_YPOS] = YoSave;
    338339    params->data.F32[PM_PAR_I0]   = IoSave;
    339340    params->data.F32[PM_PAR_SKY]  = skySave;
    340     params->data.F32[PM_PAR_XPOS] = xPos;
    341     params->data.F32[PM_PAR_YPOS] = yPos;
    342341
    343342    psFree(x);
    344     psFree(Ro);
    345     psFree(Rx);
    346     psFree(Ry);
    347     psFree(myRo);
    348     psFree(myRx);
    349     psFree(myRy);
    350343    psTrace("psModules.objects", 3, "---- %s(true) end ----\n", __func__);
    351344    return(true);
Note: See TracChangeset for help on using the changeset viewer.