IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 5, 2011, 11:02:53 AM (15 years ago)
Author:
eugene
Message:

merge updates from eam branch 20110404

File:
1 edited

Legend:

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

    r31153 r31451  
    6666// if mode & EXTERNAL or mode2 & MATCHED, do not re-calculate the centroid (use peak as centroid)
    6767
    68 bool pmSourceMoments(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN, psImageMaskType maskVal)
     68bool pmSourceMoments(pmSource *source, float radius, float sigma, float minSN, float minKronRadius, psImageMaskType maskVal)
    6969{
    7070    PS_ASSERT_PTR_NON_NULL(source, false);
     
    7474
    7575    // this function assumes the sky has been well-subtracted for the image
    76     psF32 sky = 0.0;
     76    float sky = 0.0;
    7777
    7878    if (source->moments == NULL) {
     
    8080    }
    8181
    82     psF32 Sum = 0.0;
    83     psF32 Var = 0.0;
    84     psF32 SumCore = 0.0;
    85     psF32 VarCore = 0.0;
    86     psF32 R2 = PS_SQR(radius);
    87     psF32 minSN2 = PS_SQR(minSN);
    88     psF32 rsigma2 = 0.5 / PS_SQR(sigma);
     82    float Sum = 0.0;
     83    float Var = 0.0;
     84    float SumCore = 0.0;
     85    float VarCore = 0.0;
     86    float R2 = PS_SQR(radius);
     87    float minSN2 = PS_SQR(minSN);
     88    float rsigma2 = 0.5 / PS_SQR(sigma);
    8989
    9090    // a note about coordinates: coordinates of objects throughout psphot refer to the primary
     
    109109    // Xn  = SUM (x - xc)^n * (z - sky)
    110110
    111     psF32 RF = 0.0;
    112     psF32 RH = 0.0;
    113     psF32 RS = 0.0;
    114     psF32 XX = 0.0;
    115     psF32 XY = 0.0;
    116     psF32 YY = 0.0;
    117     psF32 XXX = 0.0;
    118     psF32 XXY = 0.0;
    119     psF32 XYY = 0.0;
    120     psF32 YYY = 0.0;
    121     psF32 XXXX = 0.0;
    122     psF32 XXXY = 0.0;
    123     psF32 XXYY = 0.0;
    124     psF32 XYYY = 0.0;
    125     psF32 YYYY = 0.0;
     111    float RFW = 0.0;
     112    float RHW = 0.0;
     113
     114    float RF = 0.0;
     115    float RH = 0.0;
     116    float RS = 0.0;
     117    float XX = 0.0;
     118    float XY = 0.0;
     119    float YY = 0.0;
     120    float XXX = 0.0;
     121    float XXY = 0.0;
     122    float XYY = 0.0;
     123    float YYY = 0.0;
     124    float XXXX = 0.0;
     125    float XXXY = 0.0;
     126    float XXYY = 0.0;
     127    float XYYY = 0.0;
     128    float YYYY = 0.0;
    126129
    127130    Sum = 0.0;  // the second pass may include slightly different pixels, re-determine Sum
     131
     132    // float dX = source->moments->Mx - source->peak->xf;
     133    // float dY = source->moments->My - source->peak->yf;
     134    // float dR = hypot(dX, dY);
     135    // float Xo = (dR < 2.0) ? source->moments->Mx : source->peak->xf;
     136    // float Yo = (dR < 2.0) ? source->moments->My : source->peak->yf;
     137    float Xo = source->moments->Mx;
     138    float Yo = source->moments->My;
    128139
    129140    // center of mass in subimage.  Note: the calculation below uses pixel index, so we correct
    130141    // xCM, yCM from pixel coords to pixel index here.
    131     psF32 xCM = source->moments->Mx - 0.5 - source->pixels->col0; // coord of peak in subimage
    132     psF32 yCM = source->moments->My - 0.5 - source->pixels->row0; // coord of peak in subimage
     142    float xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage
     143    float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage
    133144
    134145    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    135146
    136         psF32 yDiff = row - yCM;
     147        float yDiff = row - yCM;
    137148        if (fabs(yDiff) > radius) continue;
    138149
    139         psF32 *vPix = source->pixels->data.F32[row];
    140         psF32 *vWgt = source->variance->data.F32[row];
     150        float *vPix = source->pixels->data.F32[row];
     151        float *vWgt = source->variance->data.F32[row];
     152
    141153        psImageMaskType  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
     154        // psImageMaskType  *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];
    142155
    143156        for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
     
    151164            if (isnan(*vPix)) continue;
    152165
    153             psF32 xDiff = col - xCM;
     166            float xDiff = col - xCM;
    154167            if (fabs(xDiff) > radius) continue;
    155168
    156169            // radius is just a function of (xDiff, yDiff)
    157             psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     170            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    158171            if (r2 > R2) continue;
    159172
    160             psF32 fDiff = *vPix - sky;
    161             psF32 pDiff = fDiff;
    162             psF32 wDiff = *vWgt;
     173            float fDiff = *vPix - sky;
     174            float pDiff = fDiff;
     175            float wDiff = *vWgt;
    163176
    164177            // skip pixels below specified significance level.  this is allowed, but should be
     
    171184            // weighting over weights the sky for faint sources
    172185            if (sigma > 0.0) {
    173                 psF32 z = r2 * rsigma2;
     186                float z = r2 * rsigma2;
    174187                assert (z >= 0.0);
    175                 psF32 weight  = exp(-z);
     188                float weight  = exp(-z);
    176189
    177190                wDiff *= weight;
     
    182195
    183196            // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?)
    184             psF32 r = sqrt(r2);
    185             psF32 rf = r * fDiff;
    186             psF32 rh = sqrt(r) * fDiff;
    187             psF32 rs = fDiff;
    188 
    189             psF32 x = xDiff * pDiff;
    190             psF32 y = yDiff * pDiff;
    191 
    192             psF32 xx = xDiff * x;
    193             psF32 xy = xDiff * y;
    194             psF32 yy = yDiff * y;
    195 
    196             psF32 xxx = xDiff * xx / r;
    197             psF32 xxy = xDiff * xy / r;
    198             psF32 xyy = xDiff * yy / r;
    199             psF32 yyy = yDiff * yy / r;
    200 
    201             psF32 xxxx = xDiff * xxx / r2;
    202             psF32 xxxy = xDiff * xxy / r2;
    203             psF32 xxyy = xDiff * xyy / r2;
    204             psF32 xyyy = xDiff * yyy / r2;
    205             psF32 yyyy = yDiff * yyy / r2;
     197            float r = sqrt(r2);
     198            float rf = r * fDiff;
     199            float rh = sqrt(r) * fDiff;
     200            float rs = fDiff;
     201
     202            float rfw = r * pDiff;
     203            float rhw = sqrt(r) * pDiff;
     204
     205            float x = xDiff * pDiff;
     206            float y = yDiff * pDiff;
     207
     208            float xx = xDiff * x;
     209            float xy = xDiff * y;
     210            float yy = yDiff * y;
     211
     212            float xxx = xDiff * xx / r;
     213            float xxy = xDiff * xy / r;
     214            float xyy = xDiff * yy / r;
     215            float yyy = yDiff * yy / r;
     216
     217            float xxxx = xDiff * xxx / r2;
     218            float xxxy = xDiff * xxy / r2;
     219            float xxyy = xDiff * xyy / r2;
     220            float xyyy = xDiff * yyy / r2;
     221            float yyyy = yDiff * yyy / r2;
    206222
    207223            RF  += rf;
    208224            RH  += rh;
    209225            RS  += rs;
     226
     227            RFW  += rfw;
     228            RHW  += rhw;
    210229
    211230            XX  += xx;
     
    244263    source->moments->Myyyy = YYYY/Sum;
    245264
    246     // Calculate the Kron magnitude (make this block optional?)
    247     float radKinner = 1.0*source->moments->Mrf;
    248     float radKron   = 2.5*source->moments->Mrf;
    249     float radKouter = 4.0*source->moments->Mrf;
     265    // if Mrf (first radial moment) is very small, we are getting into low-significance
     266    // territory.  saturate at minKronRadius.  conversely, if Mrf is > radius, we are clearly
     267    // making an error.  saturate at radius.
     268    float kronRefRadius = MIN(radius, MAX(minKronRadius, source->moments->Mrf));
     269
     270    float radKinner = 1.0*kronRefRadius;
     271    float radKron   = 2.5*kronRefRadius;
     272    float radKouter = 4.0*kronRefRadius;
    250273
    251274    int nKronPix = 0;
     
    259282    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    260283
    261         psF32 yDiff = row - yCM;
     284        float yDiff = row - yCM;
    262285        if (fabs(yDiff) > radKouter) continue;
    263286
    264         psF32 *vPix = source->pixels->data.F32[row];
    265         psF32 *vWgt = source->variance->data.F32[row];
     287        float *vPix = source->pixels->data.F32[row];
     288        float *vWgt = source->variance->data.F32[row];
     289
    266290        psImageMaskType  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
     291        // psImageMaskType  *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];
    267292
    268293        for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
     
    276301            if (isnan(*vPix)) continue;
    277302
    278             psF32 xDiff = col - xCM;
     303            float xDiff = col - xCM;
    279304            if (fabs(xDiff) > radKouter) continue;
    280305
    281306            // radKron is just a function of (xDiff, yDiff)
    282             psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    283 
    284             psF32 pDiff = *vPix - sky;
    285             psF32 wDiff = *vWgt;
     307            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     308
     309            float pDiff = *vPix - sky;
     310            float wDiff = *vWgt;
    286311
    287312            // skip pixels below specified significance level.  this is allowed, but should be
     
    290315            if (PS_SQR(pDiff) < minSN2*wDiff) continue;
    291316
    292             psF32 r  = sqrt(r2);
     317            float r  = sqrt(r2);
    293318            if (r < radKron) {
    294319                Sum += pDiff;
     
    335360}
    336361
    337 bool pmSourceMomentsGetCentroid(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN, psImageMaskType maskVal, float xGuess, float yGuess) {
     362bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) {
    338363
    339364    // First Pass: calculate the first moments (these are subtracted from the coordinates below)
     
    342367    // .. etc
    343368
    344     psF32 sky = 0.0;
    345 
    346     psF32 peakPixel = -PS_MAX_F32;
     369    float sky = 0.0;
     370
     371    float peakPixel = -PS_MAX_F32;
    347372    psS32 numPixels = 0;
    348     psF32 Sum = 0.0;
    349     psF32 Var = 0.0;
    350     psF32 X1 = 0.0;
    351     psF32 Y1 = 0.0;
    352     psF32 R2 = PS_SQR(radius);
    353     psF32 minSN2 = PS_SQR(minSN);
    354     psF32 rsigma2 = 0.5 / PS_SQR(sigma);
     373    float Sum = 0.0;
     374    float Var = 0.0;
     375    float X1 = 0.0;
     376    float Y1 = 0.0;
     377    float R2 = PS_SQR(radius);
     378    float minSN2 = PS_SQR(minSN);
     379    float rsigma2 = 0.5 / PS_SQR(sigma);
    355380
    356381    float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage
     
    358383
    359384    // we are guaranteed to have a valid pixel and variance at this location (right? right?)
    360     // psF32 weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);
     385    // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);
    361386    // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
    362387    // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
     
    370395    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    371396
    372         psF32 yDiff = row + 0.5 - yPeak;
     397        float yDiff = row + 0.5 - yPeak;
    373398        if (fabs(yDiff) > radius) continue;
    374399
    375         psF32 *vPix = source->pixels->data.F32[row];
    376         psF32 *vWgt = source->variance->data.F32[row];
     400        float *vPix = source->pixels->data.F32[row];
     401        float *vWgt = source->variance->data.F32[row];
     402
    377403        psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
     404        // psImageMaskType *vMsk = (source->maskView == NULL) ? NULL : source->maskView->data.PS_TYPE_IMAGE_MASK_DATA[row];
    378405
    379406        for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
     
    387414            if (isnan(*vPix)) continue;
    388415
    389             psF32 xDiff = col + 0.5 - xPeak;
     416            float xDiff = col + 0.5 - xPeak;
    390417            if (fabs(xDiff) > radius) continue;
    391418
    392419            // radius is just a function of (xDiff, yDiff)
    393             psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     420            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    394421            if (r2 > R2) continue;
    395422
    396             psF32 pDiff = *vPix - sky;
    397             psF32 wDiff = *vWgt;
     423            float pDiff = *vPix - sky;
     424            float wDiff = *vWgt;
    398425
    399426            // skip pixels below specified significance level.  for a PSFs, this
     
    408435            // weighting over weights the sky for faint sources
    409436            if (sigma > 0.0) {
    410                 psF32 z  = r2*rsigma2;
     437                float z  = r2*rsigma2;
    411438                assert (z >= 0.0);
    412                 psF32 weight  = exp(-z);
     439                float weight  = exp(-z);
    413440
    414441                wDiff *= weight;
     
    419446            Sum += pDiff;
    420447
    421             psF32 xWght = xDiff * pDiff;
    422             psF32 yWght = yDiff * pDiff;
     448            float xWght = xDiff * pDiff;
     449            float yWght = yDiff * pDiff;
    423450
    424451            X1  += xWght;
     
    477504    return true;
    478505}
     506
     507float pmSourceMinKronRadius(psArray *sources, float PSF_SN_LIM) {
     508
     509    psVector *radii = psVectorAllocEmpty(100, PS_TYPE_F32);
     510
     511    for (int i = 0; i < sources->n; i++) {
     512        pmSource *src = sources->data[i]; // Source of interest
     513        if (!src || !src->moments) {
     514            continue;
     515        }
     516
     517        if (src->mode & PM_SOURCE_MODE_BLEND) {
     518            continue;
     519        }
     520
     521        if (!src->moments->nPixels) continue;
     522
     523        if (src->moments->SN < PSF_SN_LIM) continue;
     524
     525        // XXX put in Mxx,Myy cut based on clump location
     526
     527        psVectorAppend(radii, src->moments->Mrf);
     528    }
     529
     530    // find the peak in this image
     531    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     532
     533    if (!psVectorStats (stats, radii, NULL, NULL, 0)) {
     534        psError(PS_ERR_UNKNOWN, false, "Unable to get image statistics.\n");
     535        psFree(stats);
     536        return NAN;
     537    }
     538
     539    float minRadius = stats->sampleMedian;
     540
     541    psFree(radii);
     542    psFree(stats);
     543    return minRadius;
     544}
     545
Note: See TracChangeset for help on using the changeset viewer.