IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 34380


Ignore:
Timestamp:
Sep 3, 2012, 6:30:39 AM (14 years ago)
Author:
eugene
Message:

add function to generate ID image

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20120805/psphot/src/psphotBlendFit.c

    r34378 r34380  
    11# include "psphotInternal.h"
     2bool psphotBlendFitSetSource(pmSource *source, psImage *IDimage, float sigSigma);
    23
    34// for now, let's store the detections on the readout->analysis for each readout
     
    9293    float skySig = psMetadataLookupF32(&status, recipe, "SKY_SIG");
    9394    assert (status && isfinite(skySig) && skySig > 0);
     95
     96    // **** test block : generate an ID image where pixels are set based the source models (flux > 0.1 peak && flux > 2.0 skySig)
     97    psImage *IDimage = psImageAlloc (readout->image->numCols, readout->image->numRows, PS_TYPE_S32);
     98    psImageInit (IDimage, 0);
     99
     100    // start with the currently known moments (Mxx, Myy, Mxy) and generate a window image
     101    for (int i = 0; i < sources->n; i++) {
     102        pmSource *source = sources->data[i];
     103        psphotBlendFitSetSource (source, IDimage, skySig);
     104    }
     105    psphotSaveImage (NULL, IDimage, "idimage.fits");
    94106
    95107    // Define source fitting parameters for extended source fits
     
    359371}
    360372
     373bool psphotBlendFitSetSource(pmSource *source, psImage *IDimage, float skySigma) {
     374
     375    if (!source) return false;
     376    if (!source->peak) return false; // XXX how can we have a peak-less source?
     377    if (!source->moments) return false;
     378    if (source->type == PM_SOURCE_TYPE_DEFECT) return false;
     379    if (source->type == PM_SOURCE_TYPE_SATURATED) return false;
     380    if (source->mode2 == PM_SOURCE_MODE2_MATCHED) return false;
     381    psAssert(IDimage, "need a window");
     382
     383    if (source->mode2 & PM_SOURCE_MODE2_SATSTAR_PROFILE) {
     384        // find the radius at which we hit something like 0.1*SATURATION
     385        return false;
     386    }
     387
     388    if (!isfinite(source->moments->Mrf) || source->moments->Mrf < 0 ) return false;
     389
     390    // we have a source with moments Mx, My, Mxx, Mxy, Myy.  we just need to define a Gaussian that has
     391    // these values (and peak of 1.0)
     392
     393    int Nx = IDimage->numCols;
     394    int Ny = IDimage->numRows;
     395
     396    float Xo = source->moments->Mx;
     397    float Yo = source->moments->My;
     398
     399    psEllipseMoments moments;
     400    moments.x2 = source->moments->Mxx;
     401    moments.y2 = source->moments->Myy;
     402    moments.xy = source->moments->Mxy;
     403
     404    psEllipseAxes axes = psEllipseMomentsToAxes(moments, 20.0);
     405    if (! (isfinite(axes.major) && isfinite(axes.minor) && isfinite(axes.theta)) ) {
     406        fprintf (stderr, "invalid axes found id: %4d major: %f minor: %f theta: %f\n", source->id, axes.major, axes.minor, axes.theta);
     407        return false;
     408    }
     409
     410    // Use 1st radial moment as size, not sigma.  Why this factor of 0.5 ?
     411    float scale = 0.5 * source->moments->Mrf / axes.major;
     412    axes.major *= scale;
     413    axes.minor *= scale;
     414
     415    psEllipseShape shape = psEllipseAxesToShape(axes);
     416    if (! (isfinite(shape.sx) && isfinite(shape.sy) && isfinite(shape.sxy)) ) {
     417        fprintf (stderr, "invalid shape found id: %d sx: %f sy %f sxy: %f\n", source->id, shape.sx, shape.sy, shape.sxy);
     418        return false;
     419    }
     420
     421    float Smajor = axes.major;
     422
     423    // we want to go to 2.15 sigma (0.1 Io)
     424    int minX = PS_MIN(PS_MAX(Xo - 2.15*Smajor, 0), Nx - 1);
     425    int maxX = PS_MIN(PS_MAX(Xo + 2.15*Smajor, 0), Nx - 1);
     426    int minY = PS_MIN(PS_MAX(Yo - 2.15*Smajor, 0), Ny - 1);
     427    int maxY = PS_MIN(PS_MAX(Yo + 2.15*Smajor, 0), Ny - 1);
     428
     429    float rMxx = 0.5 / PS_SQR(shape.sx);
     430    float rMyy = 0.5 / PS_SQR(shape.sy);
     431    float Sxy = -1. * shape.sxy;    // factor of -1 is included to match the previous window function
     432                                    // implementation. XXX: Is this correct?
     433
     434    int ID = source->id;
     435    float Io = source->peak->rawFlux;
     436    for (int iy = minY; iy < maxY; iy++) {
     437        for (int ix = minX; ix < maxX; ix++) {
     438
     439            float dX = (ix + 0.5 - Xo);
     440            float dY = (iy + 0.5 - Yo);
     441
     442            float z = rMxx * PS_SQR(dX) + rMyy * PS_SQR(dY) + Sxy*dX*dY;
     443
     444            float f = Io*exp(-z);
     445           
     446            if (f < 2.0*skySigma) continue;
     447            IDimage->data.S32[iy][ix] = ID;
     448        }
     449    }
     450
     451    return true;
     452}
Note: See TracChangeset for help on using the changeset viewer.