IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 6, 2011, 1:02:53 PM (15 years ago)
Author:
eugene
Message:
  • add concept of saddlePoints to peaks (not actually used in the end)
  • add tmp flags to mark sources for analysis or not in psphotStack
  • autocode the pmSourceIO_CMF_PS1_* functions
  • use 1D gauss approx for convolution in PCM fitting
  • added pmSourceExtFitPars (not actually used)
  • in model guess, use 1st radial moments to define size (if it exists)
  • include PSF_INST_MAG, AP_MAG, KRON_MAG in xfit output
  • fix the position for extended source fits (avoid instability)
  • Sersic-like models (incl. Exp and Dev) use Reff, not sigma; conversion tools need to respect this
  • only use a single pass on the centroid (unwindowed, but limited to 1.5 sigma radius) - this avoids moving the centroid because of nearby neighbors
  • use symmetrical averaging (geometric mean) to calculated 1st radial moment (and avoid neighbor biases), do not use symm. averaging for the flux
  • fix the integration of the sersic, pgauss, and related model functions.
  • fix the central pixel to have the full flux for sersic-like models (interpolated value)
Location:
trunk/psModules/src/objects
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/objects

    • Property svn:ignore
      •  

        old new  
        55*.la
        66*.lo
         7pmSourceIO_CMF_PS1_V1.c
         8pmSourceIO_CMF_PS1_V2.c
         9pmSourceIO_CMF_PS1_V3.c
  • trunk/psModules/src/objects/models/pmModel_DEV.c

    r31451 r32347  
    8989static bool limitsApply = true;         // Apply limits?
    9090
     91# include "pmModel_SERSIC.CP.h"
     92
    9193psF32 PM_MODEL_FUNC (psVector *deriv,
    9294                     const psVector *params,
     
    9496{
    9597    psF32 *PAR = params->data.F32;
    96 
    97     float index = 0.5 / ALPHA;
    98     float bn = 1.9992*index - 0.3271;
    99     float Io = exp(bn);
    10098
    10199    psF32 X  = pixcoord->data.F32[0] - PAR[PM_PAR_XPOS];
     
    105103    psF32 z  = (PS_SQR(px) + PS_SQR(py) + PAR[PM_PAR_SXY]*X*Y);
    106104
    107     assert (z >= 0);
     105    // If the elliptical contour is defined in a valid way, we should never trigger this
     106    // assert.  Other models (like PGAUSS) don't use fractional powers, and thus do not have
     107    // NaN values for negative values of z
     108    psAssert (z >= 0, "do not allow negative z values in model");
     109
     110    float index = 0.5 / ALPHA;
     111    float par7 = ALPHA;
     112    float bn = 1.9992*index - 0.3271;
     113    float Io = exp(bn);
    108114
    109115    psF32 f2 = bn*pow(z,ALPHA);
    110116    psF32 f1 = Io*exp(-f2);
     117
     118    psF32 radius = hypot(X, Y);
     119    if (radius < 1.0) {
     120
     121        // ** use bilinear interpolation to the given location from the 4 surrounding pixels centered on the object center
     122
     123        // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
     124        psEllipseShape shape;
     125
     126        shape.sx  = PAR[PM_PAR_SXX];
     127        shape.sy  = PAR[PM_PAR_SYY];
     128        shape.sxy = PAR[PM_PAR_SXY];
     129
     130        // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio
     131        psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     132
     133        // get the central pixel flux from the lookup table
     134        float xPix = (axes.major - centralPixelXo) / centralPixeldX;
     135        xPix = PS_MIN (PS_MAX(xPix, 0), centralPixelNX - 1);
     136        float yPix = (index - centralPixelYo) / centralPixeldY;
     137        yPix = PS_MIN (PS_MAX(yPix, 0), centralPixelNY - 1);
     138
     139        // the integral of a Sersic has an analytical form as follows:
     140        float logGamma = lgamma(2.0*index);
     141        float bnFactor = pow(bn, 2.0*index);
     142        float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
     143
     144        // XXX interpolate to get the value
     145        // XXX for the moment, just integerize
     146        // XXX I need to multiply by the integrated flux to get the flux in the central pixel
     147        float Vcenter = centralPixel[(int)yPix][(int)xPix] * norm;
     148       
     149        float px1 = 1.0 / PAR[PM_PAR_SXX];
     150        float py1 = 1.0 / PAR[PM_PAR_SYY];
     151        float z10 = PS_SQR(px1);
     152        float z01 = PS_SQR(py1);
     153
     154        // which pixels do we need for this interpolation?
     155        // (I do not keep state information, so I don't know anything about other evaluations of nearby pixels...)
     156        if ((X >= 0) && (Y >= 0)) {
     157            float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
     158            float V00 = Vcenter;
     159            float V10 = Io*exp(-bn*pow(z10,par7));
     160            float V01 = Io*exp(-bn*pow(z01,par7));
     161            float V11 = Io*exp(-bn*pow(z11,par7));
     162            f1 = interpolatePixels(V00, V10, V01, V11, X, Y);
     163        }
     164        if ((X < 0) && (Y >= 0)) {
     165            float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
     166            float V00 = Io*exp(-bn*pow(z10,par7));
     167            float V10 = Vcenter;
     168            float V01 = Io*exp(-bn*pow(z11,par7));
     169            float V11 = Io*exp(-bn*pow(z01,par7));
     170            f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), Y);
     171        }
     172        if ((X >= 0) && (Y < 0)) {
     173            float z11 = z10 + z01 - PAR[PM_PAR_SXY]; // X * Y negative
     174            float V00 = Io*exp(-bn*pow(z01,par7));
     175            float V10 = Io*exp(-bn*pow(z11,par7));
     176            float V01 = Vcenter;
     177            float V11 = Io*exp(-bn*pow(z10,par7));
     178            f1 = interpolatePixels(V00, V10, V01, V11, X, (1.0 + Y));
     179        }
     180        if ((X < 0) && (Y < 0)) {
     181            float z11 = z10 + z01 + PAR[PM_PAR_SXY]; // X * Y positive
     182            float V00 = Io*exp(-bn*pow(z11,par7));
     183            float V10 = Io*exp(-bn*pow(z10,par7));
     184            float V01 = Io*exp(-bn*pow(z01,par7));
     185            float V11 = Vcenter;
     186            f1 = interpolatePixels(V00, V10, V01, V11, (1.0 + X), (1.0 + Y));
     187        }
     188    }   
     189
    111190    psF32 z0 = PAR[PM_PAR_I0]*f1;
    112191    psF32 f0 = PAR[PM_PAR_SKY] + z0;
     
    120199        psF32 *dPAR = deriv->data.F32;
    121200
     201        dPAR[PM_PAR_SKY]  = +1.0;
     202        dPAR[PM_PAR_I0]   = +2.0*f1; // XXX extra damping..
     203
    122204        // gradient is infinite for z = 0; saturate at z = 0.01
    123205        psF32 z1 = (z < 0.01) ? z0*bn*ALPHA*pow(0.01,ALPHA - 1.0) : z0*bn*ALPHA*pow(z,ALPHA - 1.0);
    124 
    125         dPAR[PM_PAR_SKY]  = +1.0;
    126         dPAR[PM_PAR_I0]   = +2.0*f1;
    127206
    128207        assert (isfinite(z1));
     
    223302
    224303    // set the shape parameters
     304    // XXX adjust this?
    225305    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
    226306      return false;
     
    246326}
    247327
     328// A DeVaucouleur model is equivalent to a Sersic with index = 4.0
    248329psF64 PM_MODEL_FLUX (const psVector *params)
    249330{
    250     float z, norm;
    251331    psEllipseShape shape;
    252332
    253333    psF32 *PAR = params->data.F32;
    254334
    255     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    256     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
     335    shape.sx  = PAR[PM_PAR_SXX];
     336    shape.sy  = PAR[PM_PAR_SYY];
    257337    shape.sxy = PAR[PM_PAR_SXY];
    258338
    259     // Area is equivalent to 2 pi sigma^2
     339    // for a non-circular DeVaucouleur, the flux of the Rmajor equivalent is scaled by the AspectRatio
    260340    psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
    261     psF64 Area = 2.0 * M_PI * axes.major * axes.minor;
    262 
    263     // the area needs to be multiplied by the integral of f(z)
    264     norm = 0.0;
    265 
    266     # define DZ 0.25
    267 
    268     float f0 = 1.0;
    269     float f1, f2;
    270     for (z = DZ; z < 150; z += DZ) {
    271         f1 = exp(-pow(z,ALPHA));
    272         z += DZ;
    273         f2 = exp(-pow(z,ALPHA));
    274         norm += f0 + 4*f1 + f2;
    275         f0 = f2;
    276     }
    277     norm *= DZ / 3.0;
    278 
    279     psF64 Flux = PAR[PM_PAR_I0] * Area * norm;
     341    float AspectRatio = axes.minor / axes.major;
     342
     343    float index = 4.0;
     344    float bn = 1.9992*index - 0.3271;
     345
     346    // the integral of a Sersic has an analytical form as follows:
     347    float logGamma = lgamma(2.0*index);
     348    float bnFactor = pow(bn, 2.0*index);
     349    float norm = 2.0 * M_PI * PS_SQR(axes.major) * index * exp(bn) * exp(logGamma) / bnFactor;
     350   
     351    psF64 Flux = PAR[PM_PAR_I0] * norm * AspectRatio;
    280352
    281353    return(Flux);
     
    297369        return (1.0);
    298370
    299     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    300     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
     371    shape.sx  = PAR[PM_PAR_SXX];
     372    shape.sy  = PAR[PM_PAR_SYY];
    301373    shape.sxy = PAR[PM_PAR_SXY];
    302374
Note: See TracChangeset for help on using the changeset viewer.