Changeset 6556 for branches/rel10_ifa/psModules/src/objects/pmMoments.c
- Timestamp:
- Mar 8, 2006, 5:14:23 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/rel10_ifa/psModules/src/objects/pmMoments.c
r6537 r6556 1 /** @file pm Objects.c1 /** @file pmMoments.c 2 2 * 3 * This file will ...3 * Functions defining the pmMoments structure 4 4 * 5 5 * @author GLG, MHPCC 6 * @author EAM, IfA : significant modifications.6 * @author EAM, IfA 7 7 * 8 * @version $Revision: 1.1.2. 1$ $Name: not supported by cvs2svn $9 * @date $Date: 2006-03-0 7 06:33:35$8 * @version $Revision: 1.1.2.2 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2006-03-09 03:14:23 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 13 13 */ 14 14 15 #include <stdio.h>16 #include <math.h>17 #include <string.h>18 15 #include "pslib.h" 19 #include "pmObjects.h" 20 #include "pmModelGroup.h" 16 #include "pmMoments.h" 21 17 22 18 /****************************************************************************** … … 42 38 } 43 39 44 /******************************************************************************45 pmSourceMoments(source, radius): this function takes a subImage defined in the46 pmSource data structure, along with the peak location, and determines the47 various moments associated with that peak.48 49 Requires the following to have been created:50 pmSource51 pmSource->peak52 pmSource->pixels53 pmSource->weight54 pmSource->mask55 56 XXX: The peak calculations are done in image coords, not subImage coords.57 58 XXX EAM : this version clips input pixels on S/N59 XXX EAM : this version returns false for several reasons60 *****************************************************************************/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 sky109 // 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 each111 // pixel that is not masked, AND within the radius of the peak pixel, we112 // proceed with the moments calculation. need to do two loops for a113 // numerically stable result. first loop: get the sums.114 // XXX EAM : mask == 0 is valid115 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 pixel142 // 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 retry170 // 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 + xc183 // second moment X = sqrt (X2/Sum - (X1/Sum)^2)184 // Sxy = XY / Sum185 //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 subtracted200 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 range207 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.
