Changeset 9770 for trunk/psModules/src/objects/models/pmModel_GAUSS.c
- Timestamp:
- Oct 28, 2006, 10:23:51 AM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/objects/models/pmModel_GAUSS.c
r9730 r9770 1 #ifdef HAVE_CONFIG_H2 #include <config.h>3 #endif4 5 1 /****************************************************************************** 6 params->data.F32[PM_PAR_SKY] = So; 7 params->data.F32[PM_PAR_I0] = Zo; 8 params->data.F32[PM_PAR_XPOS] = Xo; 9 params->data.F32[PM_PAR_YPOS] = Yo; 10 params->data.F32[PM_PAR_SXX] = sqrt(2.0) / SigmaX; 11 params->data.F32[PM_PAR_SYY] = sqrt(2.0) / SigmaY; 12 params->data.F32[PM_PAR_SXY] = Sxy; 13 *****************************************************************************/ 14 15 psF32 pmModelFunc_GAUSS(psVector *deriv, 16 const psVector *params, 17 const psVector *x) 18 { 19 psF32 X = x->data.F32[0] - params->data.F32[PM_PAR_XPOS]; 20 psF32 Y = x->data.F32[1] - params->data.F32[PM_PAR_YPOS]; 21 psF32 px = params->data.F32[PM_PAR_SXX]*X; 22 psF32 py = params->data.F32[PM_PAR_SYY]*Y; 23 psF32 z = 0.5*PS_SQR(px) + 0.5*PS_SQR(py) + params->data.F32[PM_PAR_SXY]*X*Y; 2 * this file defines the PGAUSS source shape model. Note that these model functions are loaded 3 * by pmModelGroup.c using 'include', and thus need no 'include' statements of their own. The 4 * models use a psVector to represent the set of parameters, with the sequence used to specify 5 * the meaning of the parameter. The meaning of the parameters may thus vary depending on the 6 * specifics of the model. All models which are used a PSF representations share a few 7 * parameters, for which # define names are listed in pmModel.h: 8 9 * PM_PAR_SKY 0 - local sky : note that this is unused and may be dropped in the future 10 * PM_PAR_I0 1 - central intensity 11 * PM_PAR_XPOS 2 - X center of object 12 * PM_PAR_YPOS 3 - Y center of object 13 * PM_PAR_SXX 4 - X^2 term of elliptical contour (sqrt(2) / SigmaX) 14 * PM_PAR_SYY 5 - Y^2 term of elliptical contour (sqrt(2) / SigmaY) 15 * PM_PAR_SXY 6 - X*Y term of elliptical contour 16 *****************************************************************************/ 17 18 # define PM_MODEL_FUNC pmModelFunc_GAUSS 19 # define PM_MODEL_FLUX pmModelFlux_GAUSS 20 # define PM_MODEL_GUESS pmModelGuess_GAUSS 21 # define PM_MODEL_LIMITS pmModelLimits_GAUSS 22 # define PM_MODEL_RADIUS pmModelRadius_GAUSS 23 # define PM_MODEL_FROM_PSF pmModelFromPSF_GAUSS 24 # define PM_MODEL_FIT_STATUS pmModelFitStatus_GAUSS 25 26 psF32 PM_MODEL_FUNC(psVector *deriv, 27 const psVector *params, 28 const psVector *pixcoord) 29 { 30 psF32 *PAR = params->data.F32; 31 32 // XXX this is fitting sqrt(2)/sigma_x, sqrt(2)/sigma_y 33 psF32 X = pixcoord->data.F32[0] - PAR[PM_PAR_XPOS]; 34 psF32 Y = pixcoord->data.F32[1] - PAR[PM_PAR_YPOS]; 35 psF32 px = X / PAR[PM_PAR_SXX]; 36 psF32 py = Y / PAR[PM_PAR_SYY]; 37 psF32 z = PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y; 24 38 psF32 r = exp(-z); 25 psF32 q = params->data.F32[PM_PAR_I0]*r;26 psF32 f = q + params->data.F32[PM_PAR_SKY];39 psF32 q = PAR[PM_PAR_I0]*r; 40 psF32 f = q + PAR[PM_PAR_SKY]; 27 41 28 42 if (deriv != NULL) { 29 deriv->data.F32[PM_PAR_SKY] = +1.0; 30 deriv->data.F32[PM_PAR_I0] = +r; 31 deriv->data.F32[PM_PAR_XPOS] = q*(2*px*params->data.F32[PM_PAR_SXX] + params->data.F32[PM_PAR_SXY]*Y); 32 deriv->data.F32[PM_PAR_YPOS] = q*(2*py*params->data.F32[PM_PAR_SYY] + params->data.F32[PM_PAR_SXY]*X); 33 deriv->data.F32[PM_PAR_SXX] = -2.0*q*px*X; 34 deriv->data.F32[PM_PAR_SYY] = -2.0*q*py*Y; 35 deriv->data.F32[PM_PAR_SXY] = -q*X*Y; 43 psF32 *dPAR = deriv->data.F32; 44 dPAR[PM_PAR_SKY] = +1.0; 45 dPAR[PM_PAR_I0] = +r; 46 dPAR[PM_PAR_XPOS] = q*(2*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]); 47 dPAR[PM_PAR_YPOS] = q*(2*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]); 48 dPAR[PM_PAR_SXX] = +2.0*q*px*px/PAR[PM_PAR_SXX]; 49 dPAR[PM_PAR_SYY] = +2.0*q*py*py/PAR[PM_PAR_SYY]; 50 dPAR[PM_PAR_SXY] = -q*X*Y; 36 51 } 37 52 return(f); … … 39 54 40 55 // define the parameter limits 41 bool pmModelLimits_GAUSS (psVector **beta_lim, psVector **params_min, psVector **params_max)56 bool PM_MODEL_LIMITS (psVector **beta_lim, psVector **params_min, psVector **params_max) 42 57 { 43 58 … … 58 73 params_min[0][0].data.F32[PM_PAR_XPOS] = -100; 59 74 params_min[0][0].data.F32[PM_PAR_YPOS] = -100; 60 params_min[0][0].data.F32[PM_PAR_SXX] = 0. 01;61 params_min[0][0].data.F32[PM_PAR_SYY] = 0. 01;75 params_min[0][0].data.F32[PM_PAR_SXX] = 0.5; 76 params_min[0][0].data.F32[PM_PAR_SYY] = 0.5; 62 77 params_min[0][0].data.F32[PM_PAR_SXY] = -5.0; 63 78 … … 66 81 params_max[0][0].data.F32[PM_PAR_XPOS] = 1e4; // this should be set by image dimensions! 67 82 params_max[0][0].data.F32[PM_PAR_YPOS] = 1e4; // this should be set by image dimensions! 68 params_max[0][0].data.F32[PM_PAR_SXX] = 2.0;69 params_max[0][0].data.F32[PM_PAR_SYY] = 2.0;83 params_max[0][0].data.F32[PM_PAR_SXX] = 100.0; 84 params_max[0][0].data.F32[PM_PAR_SYY] = 100.0; 70 85 params_max[0][0].data.F32[PM_PAR_SXY] = +5.0; 71 86 … … 74 89 75 90 // make an initial guess for parameters 76 bool pmModelGuess_GAUSS (pmModel *model, pmSource *source)91 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 77 92 { 78 93 79 94 pmMoments *moments = source->moments; 80 psF32 * params= model->params->data.F32;81 82 params[PM_PAR_SKY] = moments->Sky;83 params[PM_PAR_I0] = moments->Peak - moments->Sky;84 params[PM_PAR_XPOS] = moments->x;85 params[PM_PAR_YPOS] = moments->y;86 params[PM_PAR_SXX] = (moments->Sx < (1.2 / 2.0)) ? 2.0 : (1.2 /moments->Sx);87 params[PM_PAR_SYY] = (moments->Sy < (1.2 / 2.0)) ? 2.0 : (1.2 /moments->Sy);88 params[PM_PAR_SXY] = 0.0;95 psF32 *PAR = model->params->data.F32; 96 97 PAR[PM_PAR_SKY] = moments->Sky; 98 PAR[PM_PAR_I0] = moments->Peak - moments->Sky; 99 PAR[PM_PAR_XPOS] = moments->x; 100 PAR[PM_PAR_YPOS] = moments->y; 101 PAR[PM_PAR_SXX] = PS_MAX(0.5, moments->Sx); 102 PAR[PM_PAR_SYY] = PS_MAX(0.5, moments->Sy); 103 PAR[PM_PAR_SXY] = 0.0; 89 104 return(true); 90 105 } 91 106 92 psF64 pmModelFlux_GAUSS(const psVector *params) 93 { 94 psF64 A1 = PS_SQR(params->data.F32[PM_PAR_SXX]); 95 psF64 A2 = PS_SQR(params->data.F32[PM_PAR_SYY]); 96 psF64 A3 = PS_SQR(params->data.F32[PM_PAR_SXY]); 97 psF64 Area = 2.0 * M_PI / sqrt(A1*A2 - A3); 107 psF64 PM_MODEL_FLUX (const psVector *params) 108 { 109 110 psEllipseShape shape; 111 112 psF32 *PAR = params->data.F32; 113 114 shape.sx = PAR[PM_PAR_SXX] / sqrt(2.0); 115 shape.sy = PAR[PM_PAR_SYY] / sqrt(2.0); 116 shape.sxy = PAR[PM_PAR_SXY] / sqrt(2.0); 117 98 118 // Area is equivalent to 2 pi sigma^2 119 psEllipseAxes axes = psEllipseShapeToAxes (shape); 120 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 99 121 100 122 psF64 Flux = params->data.F32[PM_PAR_I0] * Area; … … 105 127 // return the radius which yields the requested flux 106 128 // this function is never allowed to return <= 0 107 psF64 pmModelRadius_GAUSS (const psVector *params, psF64 flux) 108 { 129 psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux) 130 { 131 psEllipseShape shape; 109 132 110 133 if (flux <= 0) … … 115 138 return (1.0); 116 139 117 psF64 sigma = sqrt(2.0) * hypot (1.0 / params->data.F32[PM_PAR_SXX], 1.0 / params->data.F32[PM_PAR_SYY]); 118 psF64 radius = sigma * sqrt (2.0 * log(params->data.F32[PM_PAR_I0] / flux)); 140 psF32 *PAR = params->data.F32; 141 142 shape.sx = PAR[PM_PAR_SXX] / sqrt(2.0); 143 shape.sy = PAR[PM_PAR_SYY] / sqrt(2.0); 144 shape.sxy = PAR[PM_PAR_SXY] / sqrt(2.0); 145 146 psEllipseAxes axes = psEllipseShapeToAxes (shape); 147 psF64 radius = axes.major * sqrt (2.0 * log(params->data.F32[PM_PAR_I0] / flux)); 119 148 return (radius); 120 149 } 121 150 122 151 // construct the PSF model from the FLT model and the psf 123 bool pmModelFromPSF_GAUSS(pmModel *modelPSF, pmModel *modelFLT, pmPSF *psf)152 bool PM_MODEL_FROM_PSF (pmModel *modelPSF, pmModel *modelFLT, pmPSF *psf) 124 153 { 125 154 … … 127 156 psF32 *in = modelFLT->params->data.F32; 128 157 129 out[PM_PAR_SKY] = in[PM_PAR_SKY]; 130 out[PM_PAR_I0] = in[PM_PAR_I0]; 131 out[PM_PAR_XPOS] = in[PM_PAR_XPOS]; 132 out[PM_PAR_YPOS] = in[PM_PAR_YPOS]; 133 134 assert (PM_PAR_YPOS + 1 == 4); // so starting at 4 is correct 135 for (int i = 4; i < 7; i++) { 136 psPolynomial2D *poly = psf->params->data[i-4]; 137 out[i] = psPolynomial2DEval(poly, out[PM_PAR_XPOS], out[PM_PAR_YPOS]); 158 // we require these two parameters to exist 159 assert (psf->params_NEW->n > PM_PAR_YPOS); 160 assert (psf->params_NEW->n > PM_PAR_XPOS); 161 162 // supply the model-fitted parameters, or copy from the input 163 for (int i = 0; i < psf->params_NEW->n; i++) { 164 if (psf->params_NEW->data[i] == NULL) { 165 out[i] = in[i]; 166 } else { 167 psPolynomial2D *poly = psf->params_NEW->data[i]; 168 out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]); 169 } 138 170 } 171 172 // the 2D model for SXY actually fits SXY / (SXX^-2 + SYY^-2); correct here 173 out[PM_PAR_SXY] = pmPSF_SXYtoModel (out); 174 139 175 return(true); 140 176 } 141 177 142 178 // check the status of the fitted model 143 bool pmModelFitStatus_GAUSS (pmModel *model) 179 // this test is invalid if the parameters are derived 180 // from the PSF model 181 bool PM_MODEL_FIT_STATUS (pmModel *model) 144 182 { 145 183 … … 164 202 return false; 165 203 } 204 205 # undef PM_MODEL_FUNC 206 # undef PM_MODEL_FLUX 207 # undef PM_MODEL_GUESS 208 # undef PM_MODEL_LIMITS 209 # undef PM_MODEL_RADIUS 210 # undef PM_MODEL_FROM_PSF 211 # undef PM_MODEL_FIT_STATUS
Note:
See TracChangeset
for help on using the changeset viewer.
