Changeset 9775 for trunk/psModules/src/objects/models/pmModel_ZGAUSS.c
- Timestamp:
- Oct 29, 2006, 5:02:59 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/objects/models/pmModel_ZGAUSS.c
r9621 r9775 1 #ifdef HAVE_CONFIG_H2 #include <config.h>3 #endif4 5 1 /****************************************************************************** 6 one component, two slopes: 7 1 / (1 + z^Npow + PAR8*z^4) 2 * this file defines the ZGAUSS source shape model (XXX need a better name!). Note that these 3 * model functions are loaded by pmModelGroup.c using 'include', and thus need no 'include' 4 * statements of their own. The models use a psVector to represent the set of parameters, with 5 * the sequence used to specify the meaning of the parameter. The meaning of the parameters 6 * may thus vary depending on the specifics of the model. All models which are used a PSF 7 * representations share a few parameters, for which # define names are listed in pmModel.h: 8 8 9 params->data.F32[0] = So; 10 params->data.F32[1] = Zo; 11 params->data.F32[2] = Xo; 12 params->data.F32[3] = Yo; 13 params->data.F32[4] = 1 / SigmaX; 14 params->data.F32[5] = 1 / SigmaY; 15 params->data.F32[6] = Sxy; 16 params->data.F32[7] = Npow 17 *****************************************************************************/ 18 19 # define SQ(A)((A)*(A)) 9 power-law with fitted slope and tidal cutoff 10 1 / (1 + z^N + (Az)^4) 11 12 * PM_PAR_SKY 0 - local sky : note that this is unused and may be dropped in the future 13 * PM_PAR_I0 1 - central intensity 14 * PM_PAR_XPOS 2 - X center of object 15 * PM_PAR_YPOS 3 - Y center of object 16 * PM_PAR_SXX 4 - X^2 term of elliptical contour (sqrt(2) / SigmaX) 17 * PM_PAR_SYY 5 - Y^2 term of elliptical contour (sqrt(2) / SigmaY) 18 * PM_PAR_SXY 6 - X*Y term of elliptical contour 19 * PM_PAR_7 7 - slope of power-law component (N) 20 *****************************************************************************/ 21 22 /*** 23 XXXX the model in this file needs to be tested more carefully. 24 fix up the code to follow conventions in the other model function files. 25 ***/ 26 27 XXX broken code 28 29 # define PM_MODEL_FUNC pmModelFunc_ZGAUSS 30 # define PM_MODEL_FLUX pmModelFlux_ZGAUSS 31 # define PM_MODEL_GUESS pmModelGuess_ZGAUSS 32 # define PM_MODEL_LIMITS pmModelLimits_ZGAUSS 33 # define PM_MODEL_RADIUS pmModelRadius_ZGAUSS 34 # define PM_MODEL_FROM_PSF pmModelFromPSF_ZGAUSS 35 # define PM_MODEL_FIT_STATUS pmModelFitStatus_ZGAUSS 36 20 37 # define PAR8 0.1 21 38 22 psF64 psModelFunc_ZGAUSS(psVector *deriv,23 const psVector *params,24 const psVector *x)39 psF64 PS_MODEL_FUNC (psVector *deriv, 40 const psVector *params, 41 const psVector *x) 25 42 { 26 43 psF32 *PAR = params->data.F32; … … 54 71 } 55 72 56 psF64 psModelFlux_ZGAUSS(const psVector *params) 57 { 58 float f, norm, z; 59 60 psF32 *PAR = params->data.F32; 61 62 psF64 A1 = PS_SQR(PAR[4]); 63 psF64 A2 = PS_SQR(PAR[5]); 64 psF64 A3 = PS_SQR(PAR[6]); 65 psF64 Area = 2.0 * M_PI / sqrt(A1*A2 - A3); 66 // Area is equivalent to 2 pi sigma^2 67 68 // the area needs to be multiplied by the integral of f(z) 69 norm = 0.0; 70 psF32 pr = PAR8*z; 71 for (z = 0.005; z < 50; z += 0.01) { 72 f = 1.0 / (1 + pow(z, PAR[7]) + SQ(SQ(pr))); 73 norm += f; 74 } 75 norm *= 0.01; 76 77 psF64 Flux = PAR[1] * Area * norm; 78 79 return(Flux); 80 } 81 82 // XXX need to define the radius along the major axis 83 // define this function so it never returns Inf or NaN 84 // return the radius which yields the requested flux 85 psF64 psModelRadius_ZGAUSS (const psVector *params, psF64 flux) 86 { 87 psF64 r, z, pr, f; 88 psF32 *PAR = params->data.F32; 89 90 psEllipseAxes axes; 91 psEllipseShape shape; 92 93 if (flux <= 0) 94 return (1.0); 95 if (PAR[1] <= 0) 96 return (1.0); 97 if (flux >= PAR[1]) 98 return (1.0); 99 100 // convert Sx,Sy,Sxy to major/minor axes 101 shape.sx = 1.0 / PAR[4]; 102 shape.sy = 1.0 / PAR[5]; 103 shape.sxy = PAR[6]; 104 105 axes = psEllipseShapeToAxes (shape); 106 psF64 dr = 1.0 / axes.major; 107 psF64 limit = flux / PAR[1]; 108 109 // XXX : we can do this faster with an intelligent starting choice 110 for (r = 0.0; r < 20.0; r += dr) { 111 z = SQ(r); 112 pr = PAR8*z; 113 f = 1.0 / (1 + pow(z, PAR[7]) + SQ(SQ(pr))); 114 if (f < limit) 115 break; 116 } 117 psF64 radius = 2.0 * axes.major * sqrt (z); 118 if (isnan(radius)) { 119 fprintf (stderr, "error in code\n"); 120 } 121 return (radius); 122 } 123 124 bool psModelGuess_ZGAUSS (psModel *model, psSource *source) 73 bool PM_MODEL_LIMITS (psVector **beta_lim, psVector **params_min, psVector **params_max) 74 { 75 76 *beta_lim = psVectorAlloc (8, PS_TYPE_F32); 77 *params_min = psVectorAlloc (8, PS_TYPE_F32); 78 *params_max = psVectorAlloc (8, PS_TYPE_F32); 79 80 beta_lim[0][0].data.F32[PM_PAR_SKY] = 1000; 81 beta_lim[0][0].data.F32[PM_PAR_I0] = 3e6; 82 beta_lim[0][0].data.F32[PM_PAR_XPOS] = 5; 83 beta_lim[0][0].data.F32[PM_PAR_YPOS] = 5; 84 beta_lim[0][0].data.F32[PM_PAR_SXX] = 0.5; 85 beta_lim[0][0].data.F32[PM_PAR_SYY] = 0.5; 86 beta_lim[0][0].data.F32[PM_PAR_SXY] = 0.5; 87 beta_lim[0][0].data.F32[PM_PAR_7] = 0.5; 88 89 params_min[0][0].data.F32[PM_PAR_SKY] = -1000; 90 params_min[0][0].data.F32[PM_PAR_I0] = 0; 91 params_min[0][0].data.F32[PM_PAR_XPOS] = -100; 92 params_min[0][0].data.F32[PM_PAR_YPOS] = -100; 93 params_min[0][0].data.F32[PM_PAR_SXX] = 0.5; 94 params_min[0][0].data.F32[PM_PAR_SYY] = 0.5; 95 params_min[0][0].data.F32[PM_PAR_SXY] = -5.0; 96 params_min[0][0].data.F32[PM_PAR_7] = 0.1; 97 98 params_max[0][0].data.F32[PM_PAR_SKY] = 1e5; 99 params_max[0][0].data.F32[PM_PAR_I0] = 1e8; 100 params_max[0][0].data.F32[PM_PAR_XPOS] = 1e4; // this should be set by image dimensions! 101 params_max[0][0].data.F32[PM_PAR_YPOS] = 1e4; // this should be set by image dimensions! 102 params_max[0][0].data.F32[PM_PAR_SXX] = 100.0; 103 params_max[0][0].data.F32[PM_PAR_SYY] = 100.0; 104 params_max[0][0].data.F32[PM_PAR_SXY] = +5.0; 105 params_max[0][0].data.F32[PM_PAR_7] = 10.0; 106 107 return (TRUE); 108 } 109 110 bool PS_MODEL_GUESS (psModel *model, psSource *source) 125 111 { 126 112 … … 149 135 } 150 136 151 bool psModelFromPSF_ZGAUSS (psModel *modelPSF, psModel *modelFLT, pmPSF *psf) 137 psF64 PS_MODEL_FLUX (const psVector *params) 138 { 139 float f, norm, z; 140 141 psF32 *PAR = params->data.F32; 142 143 psF64 A1 = PS_SQR(PAR[4]); 144 psF64 A2 = PS_SQR(PAR[5]); 145 psF64 A3 = PS_SQR(PAR[6]); 146 psF64 Area = 2.0 * M_PI / sqrt(A1*A2 - A3); 147 // Area is equivalent to 2 pi sigma^2 148 149 // the area needs to be multiplied by the integral of f(z) 150 norm = 0.0; 151 psF32 pr = PAR8*z; 152 for (z = 0.005; z < 50; z += 0.01) { 153 f = 1.0 / (1 + pow(z, PAR[7]) + SQ(SQ(pr))); 154 norm += f; 155 } 156 norm *= 0.01; 157 158 psF64 Flux = PAR[1] * Area * norm; 159 160 return(Flux); 161 } 162 163 // XXX need to define the radius along the major axis 164 // define this function so it never returns Inf or NaN 165 // return the radius which yields the requested flux 166 psF64 PS_MODEL_RADIUS (const psVector *params, psF64 flux) 167 { 168 psF64 r, z, pr, f; 169 psF32 *PAR = params->data.F32; 170 171 psEllipseAxes axes; 172 psEllipseShape shape; 173 174 if (flux <= 0) 175 return (1.0); 176 if (PAR[1] <= 0) 177 return (1.0); 178 if (flux >= PAR[1]) 179 return (1.0); 180 181 // convert Sx,Sy,Sxy to major/minor axes 182 shape.sx = 1.0 / PAR[4]; 183 shape.sy = 1.0 / PAR[5]; 184 shape.sxy = PAR[6]; 185 186 axes = psEllipseShapeToAxes (shape); 187 psF64 dr = 1.0 / axes.major; 188 psF64 limit = flux / PAR[1]; 189 190 // XXX : we can do this faster with an intelligent starting choice 191 for (r = 0.0; r < 20.0; r += dr) { 192 z = SQ(r); 193 pr = PAR8*z; 194 f = 1.0 / (1 + pow(z, PAR[7]) + SQ(SQ(pr))); 195 if (f < limit) 196 break; 197 } 198 psF64 radius = 2.0 * axes.major * sqrt (z); 199 if (isnan(radius)) { 200 fprintf (stderr, "error in code\n"); 201 } 202 return (radius); 203 } 204 205 bool PS_MODEL_FROM_PSF (psModel *modelPSF, psModel *modelFLT, pmPSF *psf) 152 206 { 153 207 … … 166 220 return(true); 167 221 } 222 223 bool PM_MODEL_FIT_STATUS (pmModel *model) 224 { 225 226 psF32 dP; 227 bool status; 228 229 psF32 *PAR = model->params->data.F32; 230 psF32 *dPAR = model->dparams->data.F32; 231 232 dP = 0; 233 dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]); 234 dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]); 235 dP = sqrt (dP); 236 237 status = true; 238 status &= (dP < 0.5); 239 status &= (PAR[PM_PAR_I0] > 0); 240 status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5); 241 242 return status; 243 } 244 245 # undef PM_MODEL_FUNC 246 # undef PM_MODEL_FLUX 247 # undef PM_MODEL_GUESS 248 # undef PM_MODEL_LIMITS 249 # undef PM_MODEL_RADIUS 250 # undef PM_MODEL_FROM_PSF 251 # undef PM_MODEL_FIT_STATUS
Note:
See TracChangeset
for help on using the changeset viewer.
