IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 8, 2006, 5:14:23 PM (20 years ago)
Author:
magnier
Message:

major rework of objects code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/rel10_ifa/psModules/src/objects/pmMoments.c

    r6537 r6556  
    1 /** @file  pmObjects.c
     1/** @file  pmMoments.c
    22 *
    3  *  This file will ...
     3 *  Functions defining the pmMoments structure
    44 *
    55 *  @author GLG, MHPCC
    6  *  @author EAM, IfA: significant modifications.
     6 *  @author EAM, IfA
    77 *
    8  *  @version $Revision: 1.1.2.1 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2006-03-07 06:33:35 $
     8 *  @version $Revision: 1.1.2.2 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2006-03-09 03:14:23 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    1313 */
    1414
    15 #include <stdio.h>
    16 #include <math.h>
    17 #include <string.h>
    1815#include "pslib.h"
    19 #include "pmObjects.h"
    20 #include "pmModelGroup.h"
     16#include "pmMoments.h"
    2117
    2218/******************************************************************************
     
    4238}
    4339
    44 /******************************************************************************
    45 pmSourceMoments(source, radius): this function takes a subImage defined in the
    46 pmSource data structure, along with the peak location, and determines the
    47 various moments associated with that peak.
    48  
    49 Requires the following to have been created:
    50     pmSource
    51     pmSource->peak
    52     pmSource->pixels
    53     pmSource->weight
    54     pmSource->mask
    55  
    56 XXX: The peak calculations are done in image coords, not subImage coords.
    57  
    58 XXX EAM : this version clips input pixels on S/N
    59 XXX EAM : this version returns false for several reasons
    60 *****************************************************************************/
    61 # define VALID_RADIUS(X,Y,RAD2) (((RAD2) >= (PS_SQR(X) + PS_SQR(Y))) ? 1 : 0)
    62 
    63 bool pmSourceMoments(pmSource *source,
    64                      psF32 radius)
    65 {
    66     psTrace(__func__, 3, "---- %s() begin ----\n", __func__);
    67     PS_ASSERT_PTR_NON_NULL(source, false);
    68     PS_ASSERT_PTR_NON_NULL(source->peak, false);
    69     PS_ASSERT_PTR_NON_NULL(source->pixels, false);
    70     PS_ASSERT_PTR_NON_NULL(source->mask, false);
    71     PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false);
    72 
    73     //
    74     // XXX: Verify the setting for sky if source->moments == NULL.
    75     //
    76     psF32 sky = 0.0;
    77     if (source->moments == NULL) {
    78         source->moments = pmMomentsAlloc();
    79     } else {
    80         sky = source->moments->Sky;
    81     }
    82 
    83     //
    84     // Sum = SUM (z - sky)
    85     // X1  = SUM (x - xc)*(z - sky)
    86     // X2  = SUM (x - xc)^2 * (z - sky)
    87     // XY  = SUM (x - xc)*(y - yc)*(z - sky)
    88     //
    89     psF32 peakPixel = -PS_MAX_F32;
    90     psS32 numPixels = 0;
    91     psF32 Sum = 0.0;
    92     psF32 Var = 0.0;
    93     psF32 X1 = 0.0;
    94     psF32 Y1 = 0.0;
    95     psF32 X2 = 0.0;
    96     psF32 Y2 = 0.0;
    97     psF32 XY = 0.0;
    98     psF32 x  = 0;
    99     psF32 y  = 0;
    100     psF32 R2 = PS_SQR(radius);
    101 
    102     psF32 xPeak = source->peak->x;
    103     psF32 yPeak = source->peak->y;
    104     psF32 xOff = source->pixels->col0 - source->peak->x;
    105     psF32 yOff = source->pixels->row0 - source->peak->y;
    106 
    107     // XXX why do I get different results for these two methods of finding Sx?
    108     // XXX Sx, Sy would be better measured if we clip pixels close to sky
    109     // XXX Sx, Sy can still be imaginary, so we probably need to keep Sx^2?
    110     // We loop through all pixels in this subimage (source->pixels), and for each
    111     // pixel that is not masked, AND within the radius of the peak pixel, we
    112     // proceed with the moments calculation.  need to do two loops for a
    113     // numerically stable result.  first loop: get the sums.
    114     // XXX EAM : mask == 0 is valid
    115 
    116     for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    117 
    118         psF32 *vPix = source->pixels->data.F32[row];
    119         psF32 *vWgt = source->weight->data.F32[row];
    120         psU8  *vMsk = (source->mask == NULL) ? NULL : source->mask->data.U8[row];
    121 
    122         for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
    123             if ((vMsk != NULL) && *vMsk) {
    124                 vMsk++;
    125                 continue;
    126             }
    127 
    128             psF32 xDiff = col + xOff;
    129             psF32 yDiff = row + yOff;
    130 
    131             // radius is just a function of (xDiff, yDiff)
    132             if (!VALID_RADIUS(xDiff, yDiff, R2)) {
    133                 if (vMsk != NULL)
    134                     vMsk++;
    135                 continue;
    136             }
    137 
    138             psF32 pDiff = *vPix - sky;
    139             psF32 wDiff = *vWgt;
    140 
    141             // XXX EAM : check for valid S/N in pixel
    142             // XXX EAM : should this limit be user-defined?
    143             if (PS_SQR(pDiff) < wDiff) {
    144                 if (vMsk != NULL)
    145                     vMsk++;
    146                 continue;
    147             }
    148 
    149             Var += wDiff;
    150             Sum += pDiff;
    151 
    152             psF32 xWght = xDiff * pDiff;
    153             psF32 yWght = yDiff * pDiff;
    154 
    155             X1  += xWght;
    156             Y1  += yWght;
    157 
    158             XY  += xDiff * yWght;
    159             X2  += xDiff * xWght;
    160             Y2  += yDiff * yWght;
    161 
    162             peakPixel = PS_MAX (*vPix, peakPixel);
    163             numPixels++;
    164             if (vMsk != NULL)
    165                 vMsk++;
    166         }
    167     }
    168 
    169     // if we have less than (1/4) of the possible pixels, force a retry
    170     // XXX EAM - the limit is a bit arbitrary.  make it user defined?
    171     if ((numPixels < 0.75*R2) || (Sum <= 0)) {
    172         psTrace (".psModules.pmSourceMoments", 3, "no valid pixels for source\n");
    173         psTrace(__func__, 3, "---- %s(false) end ----\n", __func__);
    174         return (false);
    175     }
    176 
    177     psTrace (".psModules.pmSourceMoments", 5,
    178              "sky: %f  Sum: %f  X1: %f  Y1: %f  X2: %f  Y2: %f  XY: %f  Npix: %d\n",
    179              sky, Sum, X1, Y1, X2, Y2, XY, numPixels);
    180 
    181     //
    182     // first moment X  = X1/Sum + xc
    183     // second moment X = sqrt (X2/Sum - (X1/Sum)^2)
    184     // Sxy             = XY / Sum
    185     //
    186     x = X1/Sum;
    187     y = Y1/Sum;
    188     if ((fabs(x) > radius) || (fabs(y) > radius)) {
    189         psTrace (".psModules.pmSourceMoments", 3,
    190                  "large centroid swing; invalid peak %d, %d\n",
    191                  source->peak->x, source->peak->y);
    192         psTrace(__func__, 3, "---- %s(false) end ----\n", __func__);
    193         return (false);
    194     }
    195 
    196     source->moments->x = x + xPeak;
    197     source->moments->y = y + yPeak;
    198 
    199     // XXX EAM : Sxy needs to have x*y subtracted
    200     source->moments->Sxy = XY/Sum - x*y;
    201     source->moments->Sum = Sum;
    202     source->moments->SN  = Sum / sqrt(Var);
    203     source->moments->Peak = peakPixel;
    204     source->moments->nPixels = numPixels;
    205 
    206     // XXX EAM : these values can be negative, so we need to limit the range
    207     source->moments->Sx = sqrt(PS_MAX(X2/Sum - PS_SQR(x), 0));
    208     source->moments->Sy = sqrt(PS_MAX(Y2/Sum - PS_SQR(y), 0));
    209 
    210     psTrace (".psModules.pmSourceMoments", 4,
    211              "sky: %f  Sum: %f  x: %f  y: %f  Sx: %f  Sy: %f  Sxy: %f\n",
    212              sky, Sum, source->moments->x, source->moments->y,
    213              source->moments->Sx, source->moments->Sy, source->moments->Sxy);
    214 
    215     psTrace(__func__, 3, "---- %s(true) end ----\n", __func__);
    216     return(true);
    217 }
    218 
Note: See TracChangeset for help on using the changeset viewer.