Changeset 9770 for trunk/psModules/src/objects/models/pmModel_PGAUSS.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_PGAUSS.c
r9730 r9770 1 #ifdef HAVE_CONFIG_H2 #include <config.h>3 #endif4 5 1 /****************************************************************************** 6 params->data.F32[0] = So; 7 params->data.F32[1] = Zo; 8 params->data.F32[2] = Xo; 9 params->data.F32[3] = Yo; 10 params->data.F32[4] = sqrt(2.0) / SigmaX; 11 params->data.F32[5] = sqrt(2.0) / SigmaY; 12 params->data.F32[6] = Sxy; 13 *****************************************************************************/ 14 15 psF32 pmModelFunc_PGAUSS(psVector *deriv, 16 const psVector *params, 17 const psVector *x) 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_PGAUSS 19 # define PM_MODEL_FLUX pmModelFlux_PGAUSS 20 # define PM_MODEL_GUESS pmModelGuess_PGAUSS 21 # define PM_MODEL_LIMITS pmModelLimits_PGAUSS 22 # define PM_MODEL_RADIUS pmModelRadius_PGAUSS 23 # define PM_MODEL_FROM_PSF pmModelFromPSF_PGAUSS 24 # define PM_MODEL_FIT_STATUS pmModelFitStatus_PGAUSS 25 26 // the model is a function of the pixel coordinate (pixcoord[0,1] = x,y) 27 psF32 PM_MODEL_FUNC(psVector *deriv, 28 const psVector *params, 29 const psVector *pixcoord) 18 30 { 19 31 psF32 *PAR = params->data.F32; 20 32 21 psF32 X = x->data.F32[0] - PAR[2];22 psF32 Y = x->data.F32[1] - PAR[3];23 psF32 px = PAR[4]*X;24 psF32 py = PAR[5]*Y;25 psF32 z = 0.5*PS_SQR(px) + 0.5*PS_SQR(py) + PAR[6]*X*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; 26 38 psF32 t = 1 + z + z*z/2.0; 27 39 psF32 r = 1.0 / (t + z*z*z/6.0); /* exp (-Z) */ 28 psF32 f = PAR[ 1]*r + PAR[0];40 psF32 f = PAR[PM_PAR_I0]*r + PAR[PM_PAR_SKY]; 29 41 30 42 if (deriv != NULL) { 31 43 psF32 *dPAR = deriv->data.F32; 32 psF32 q = PAR[ 1]*r*r*t;33 dPAR[ 0] = +1.0;34 dPAR[ 1] = +r;35 dPAR[ 2] = q*(2.0*px*PAR[4] + PAR[6]*Y);36 dPAR[ 3] = q*(2.0*py*PAR[5] + PAR[6]*X);37 dPAR[ 4] = -2.0*q*px*X;38 dPAR[ 5] = -2.0*q*py*Y;39 dPAR[ 6] = -q*X*Y;44 psF32 q = PAR[PM_PAR_I0]*r*r*t; 45 dPAR[PM_PAR_SKY] = +1.0; 46 dPAR[PM_PAR_I0] = +r; 47 dPAR[PM_PAR_XPOS] = q*(2.0*px/PAR[PM_PAR_SXX] + Y*PAR[PM_PAR_SXY]); 48 dPAR[PM_PAR_YPOS] = q*(2.0*py/PAR[PM_PAR_SYY] + X*PAR[PM_PAR_SXY]); 49 dPAR[PM_PAR_SXX] = +2.0*q*px*px/PAR[PM_PAR_SXX]; 50 dPAR[PM_PAR_SYY] = +2.0*q*py*py/PAR[PM_PAR_SYY]; 51 dPAR[PM_PAR_SXY] = -q*X*Y; 40 52 } 41 53 return(f); 42 54 } 43 55 44 bool pmModelLimits_PGAUSS (psVector **beta_lim, psVector **params_min, psVector **params_max)56 bool PM_MODEL_LIMITS (psVector **beta_lim, psVector **params_min, psVector **params_max) 45 57 { 46 58 … … 49 61 *params_max = psVectorAlloc (7, PS_TYPE_F32); 50 62 51 beta_lim[0][0].data.F32[ 0] = 1000;52 beta_lim[0][0].data.F32[ 1] = 3e6;53 beta_lim[0][0].data.F32[ 2] = 5;54 beta_lim[0][0].data.F32[ 3] = 5;55 beta_lim[0][0].data.F32[ 4] = 0.5;56 beta_lim[0][0].data.F32[ 5] = 0.5;57 beta_lim[0][0].data.F32[ 6] = 0.5;58 59 params_min[0][0].data.F32[ 0] = -1000;60 params_min[0][0].data.F32[ 1] = 0;61 params_min[0][0].data.F32[ 2] = -100;62 params_min[0][0].data.F32[ 3] = -100;63 params_min[0][0].data.F32[ 4] = 0.01;64 params_min[0][0].data.F32[ 5] = 0.01;65 params_min[0][0].data.F32[ 6] = -5.0;66 67 params_max[0][0].data.F32[ 0] = 1e5;68 params_max[0][0].data.F32[ 1] = 1e8;69 params_max[0][0].data.F32[ 2] = 1e4; // this should be set by image dimensions!70 params_max[0][0].data.F32[ 3] = 1e4; // this should be set by image dimensions!71 params_max[0][0].data.F32[ 4] = 2.0;72 params_max[0][0].data.F32[ 5] = 2.0;73 params_max[0][0].data.F32[ 6] = +5.0;63 beta_lim[0][0].data.F32[PM_PAR_SKY] = 1000; 64 beta_lim[0][0].data.F32[PM_PAR_I0] = 3e6; 65 beta_lim[0][0].data.F32[PM_PAR_XPOS] = 5; 66 beta_lim[0][0].data.F32[PM_PAR_YPOS] = 5; 67 beta_lim[0][0].data.F32[PM_PAR_SXX] = 0.5; 68 beta_lim[0][0].data.F32[PM_PAR_SYY] = 0.5; 69 beta_lim[0][0].data.F32[PM_PAR_SXY] = 0.5; 70 71 params_min[0][0].data.F32[PM_PAR_SKY] = -1000; 72 params_min[0][0].data.F32[PM_PAR_I0] = 0; 73 params_min[0][0].data.F32[PM_PAR_XPOS] = -100; 74 params_min[0][0].data.F32[PM_PAR_YPOS] = -100; 75 params_min[0][0].data.F32[PM_PAR_SXX] = 0.5; 76 params_min[0][0].data.F32[PM_PAR_SYY] = 0.5; 77 params_min[0][0].data.F32[PM_PAR_SXY] = -5.0; 78 79 params_max[0][0].data.F32[PM_PAR_SKY] = 1e5; 80 params_max[0][0].data.F32[PM_PAR_I0] = 1e8; 81 params_max[0][0].data.F32[PM_PAR_XPOS] = 1e4; // this should be set by image dimensions! 82 params_max[0][0].data.F32[PM_PAR_YPOS] = 1e4; // this should be set by image dimensions! 83 params_max[0][0].data.F32[PM_PAR_SXX] = 100.0; 84 params_max[0][0].data.F32[PM_PAR_SYY] = 100.0; 85 params_max[0][0].data.F32[PM_PAR_SXY] = +5.0; 74 86 75 87 return (TRUE); … … 77 89 78 90 // make an initial guess for parameters 79 bool pmModelGuess_PGAUSS (pmModel *model, pmSource *source)91 bool PM_MODEL_GUESS (pmModel *model, pmSource *source) 80 92 { 81 93 82 94 pmMoments *moments = source->moments; 83 psF32 * params= model->params->data.F32;84 85 params[0]= moments->Sky;86 params[1]= moments->Peak - moments->Sky;87 params[2] = moments->x;88 params[3] = moments->y;89 params[4] = (moments->Sx < (1.2 / 2.0)) ? 2.0 : (1.2 /moments->Sx);90 params[5] = (moments->Sy < (1.2 / 2.0)) ? 2.0 : (1.2 /moments->Sy);91 params[6]= 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; 92 104 93 105 return(true); 94 106 } 95 107 96 psF64 pmModelFlux_PGAUSS(const psVector *params)108 psF64 PM_MODEL_FLUX(const psVector *params) 97 109 { 98 110 float norm, z; 111 psEllipseShape shape; 99 112 100 113 psF32 *PAR = params->data.F32; 101 114 102 psF64 A1 = PS_SQR(PAR[4]);103 psF64 A2 = PS_SQR(PAR[5]);104 psF64 A3 = PS_SQR(PAR[6]);105 psF64 Area = 2.0 * M_PI / sqrt(A1*A2 - A3); 115 shape.sx = PAR[PM_PAR_SXX] / sqrt(2.0); 116 shape.sy = PAR[PM_PAR_SYY] / sqrt(2.0); 117 shape.sxy = PAR[PM_PAR_SXY] / sqrt(2.0); 118 106 119 // Area is equivalent to 2 pi sigma^2 120 psEllipseAxes axes = psEllipseShapeToAxes (shape); 121 psF64 Area = 2.0 * M_PI * axes.major * axes.minor; 107 122 108 123 // the area needs to be multiplied by the integral of f(z) … … 122 137 norm *= DZ / 3.0; 123 138 124 psF64 Flux = PAR[ 1] * Area * norm;139 psF64 Flux = PAR[PM_PAR_I0] * Area * norm; 125 140 126 141 return(Flux); … … 129 144 // define this function so it never returns Inf or NaN 130 145 // return the radius which yields the requested flux 131 psF64 pmModelRadius_PGAUSS(const psVector *params, psF64 flux)146 psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux) 132 147 { 133 148 if (flux <= 0) 134 149 return (1.0); 135 if (params->data.F32[ 1] <= 0)150 if (params->data.F32[PM_PAR_I0] <= 0) 136 151 return (1.0); 137 if (flux >= params->data.F32[ 1])152 if (flux >= params->data.F32[PM_PAR_I0]) 138 153 return (1.0); 139 154 140 psF64 sigma = sqrt(2.0) * hypot (1.0 / params->data.F32[4], 1.0 / params->data.F32[5]); 141 psF64 radius = sigma * sqrt (2.0 * log(params->data.F32[1] / flux)); 142 if (isnan(radius)) { 143 fprintf (stderr, "error in code\n"); 144 } 155 psF32 *PAR = params->data.F32; 156 157 shape.sx = PAR[PM_PAR_SXX] / sqrt(2.0); 158 shape.sy = PAR[PM_PAR_SYY] / sqrt(2.0); 159 shape.sxy = PAR[PM_PAR_SXY] / sqrt(2.0); 160 161 // this estimates the radius assuming f(z) is roughly exp(-z) 162 psEllipseAxes axes = psEllipseShapeToAxes (shape); 163 psF64 radius = axes.major * sqrt (2.0 * log(params->data.F32[PM_PAR_I0] / flux)); 164 165 if (isnan(radius)) 166 psAbort ("psphot.model", "error in code: never return invalid radius"); 167 if (radius < 0) 168 psAbort ("psphot.model", "error in code: never return invalid radius"); 169 145 170 return (radius); 146 171 } 147 172 148 bool pmModelFromPSF_PGAUSS(pmModel *modelPSF, pmModel *modelFLT, pmPSF *psf)173 bool PM_MODEL_FROM_PSF (pmModel *modelPSF, pmModel *modelFLT, pmPSF *psf) 149 174 { 150 175 … … 152 177 psF32 *in = modelFLT->params->data.F32; 153 178 154 out[0] = in[0]; 155 out[1] = in[1]; 156 out[2] = in[2]; 157 out[3] = in[3]; 158 159 for (int i = 4; i < 7; i++) { 160 psPolynomial2D *poly = psf->params->data[i-4]; 161 out[i] = psPolynomial2DEval(poly, out[2], out[3]); 179 // we require these two parameters to exist 180 assert (psf->params_NEW->n > PM_PAR_YPOS); 181 assert (psf->params_NEW->n > PM_PAR_XPOS); 182 183 for (int i = 0; i < psf->params_NEW->n; i++) { 184 if (psf->params_NEW->data[i] == NULL) { 185 out[i] = in[i]; 186 } else { 187 psPolynomial2D *poly = psf->params_NEW->data[i]; 188 out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]); 189 } 162 190 } 191 192 // the 2D model for SXY actually fits SXY / (SXX^-2 + SYY^-2); correct here 193 out[PM_PAR_SXY] = pmPSF_SXYtoModel (out); 194 163 195 return(true); 164 196 } 165 197 166 bool pmModelFitStatus_PGAUSS (pmModel *model)198 bool PM_MODEL_FIT_STATUS (pmModel *model) 167 199 { 168 200 … … 174 206 175 207 dP = 0; 176 dP += PS_SQR(dPAR[ 4] / PAR[4]);177 dP += PS_SQR(dPAR[ 5] / PAR[5]);208 dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]); 209 dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]); 178 210 dP = sqrt (dP); 179 211 180 212 status = true; 181 213 status &= (dP < 0.5); 182 status &= (PAR[ 1] > 0);183 status &= ((dPAR[ 1]/PAR[1]) < 0.5);214 status &= (PAR[PM_PAR_I0] > 0); 215 status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5); 184 216 185 217 if (status) … … 187 219 return false; 188 220 } 221 222 # undef PM_MODEL_FUNC 223 # undef PM_MODEL_FLUX 224 # undef PM_MODEL_GUESS 225 # undef PM_MODEL_LIMITS 226 # undef PM_MODEL_RADIUS 227 # undef PM_MODEL_FROM_PSF 228 # undef PM_MODEL_FIT_STATUS
Note:
See TracChangeset
for help on using the changeset viewer.
