IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 35768 for trunk/psModules


Ignore:
Timestamp:
Jul 3, 2013, 2:37:22 PM (13 years ago)
Author:
eugene
Message:

deprecate KiiOpen,KiiClose (now KapaOpen,etc); major rework of psEllipse translations : use common functions pmModelAxesToParams and pmModelParamsToAxes ; use new convergence method in pmPCM_MinimizeChisq; add convergence crerition options to psMinimization; threaded versions of pmPSFtryFitEXT and pmPSFtryFitPSF

Location:
trunk/psModules
Files:
43 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/psModules

  • trunk/psModules/src/astrom/pmAstrometryUtils.c

    r35561 r35768  
    7878            Alpha->data.F32[1][1] = psPolynomial2DEval (YdY, Xo, Yo);
    7979
     80            // Beta = (-L,-M) for the current guess
    8081            Beta->data.F32[0] = -1.0 * psPolynomial2DEval (trans->x, Xo, Yo);
    8182            Beta->data.F32[1] = -1.0 * psPolynomial2DEval (trans->y, Xo, Yo);
    82 
     83            // fprintf (stderr, " Beta: %f %f\n", Beta->data.F32[0], Beta->data.F32[1]);
     84
     85            // since we want (L,M) = (0,0), Beta is also the offset
    8386            if (!psMatrixGJSolve (Alpha, Beta)) {
    8487                psError(PS_ERR_UNKNOWN, false, "Unable to solve for center.");
  • trunk/psModules/src/astrom/pmAstrometryVisual.c

    r31153 r35768  
    5151bool pmAstromVisualClose(void)
    5252{
    53     if (kapa1 != -1) KiiClose(kapa1);
    54     if (kapa2 != -1) KiiClose(kapa2);
     53    if (kapa1 != -1) KapaClose(kapa1);
     54    if (kapa2 != -1) KapaClose(kapa2);
    5555    return true;
    5656}
  • trunk/psModules/src/camera/pmReadoutFake.c

    r35455 r35768  
    3535#include "pmReadoutFake.h"
    3636
    37 #define MAX_AXIS_RATIO 20.0             // Maximum axis ratio for PSF model
     37// XXX this is now hard-wired in pmModelParamsToAxes
     38// #define MAX_AXIS_RATIO 20.0             // Maximum axis ratio for PSF model
     39
    3840#define MODEL_MASK (PM_MODEL_STATUS_NONCONVERGE | PM_MODEL_STATUS_OFFIMAGE | \
    3941                    PM_MODEL_STATUS_BADARGS | PM_MODEL_STATUS_LIMITS) // Mask to apply to models
     
    5254
    5355    psF32 *params = model->params->data.F32; // Model parameters
    54     psEllipseAxes axes = pmPSF_ModelToAxes(params, MAX_AXIS_RATIO, model->type); // Ellipse axes
     56    psEllipseAxes axes = pmPSF_ModelToAxes(params, model->type); // Ellipse axes
    5557    // Curiously, the minor axis can be larger than the major axis, so need to check.
    5658    if (axes.major >= axes.minor) {
  • trunk/psModules/src/extras/Makefile.am

    r29388 r35768  
    1010        pmVisual.c \
    1111        pmVisualUtils.c \
     12        pmThreadTools.c \
    1213        ippStages.c \
    1314        pmCensor.c
     
    2021        pmVisual.h \
    2122        pmVisualUtils.h \
     23        pmThreadTools.h \
    2224        ippDiffMode.h \
    2325        ippStages.h \
  • trunk/psModules/src/imcombine/pmStackVisual.c

    r23242 r35768  
    3636{
    3737    if(kapa != -1)
    38         KiiClose(kapa);
     38        KapaClose(kapa);
    3939    if(kapa2 != -1)
    40         KiiClose(kapa2);
     40        KapaClose(kapa2);
    4141    return true;
    4242}
  • trunk/psModules/src/imcombine/pmSubtractionVisual.c

    r30737 r35768  
    5656bool pmSubtractionVisualClose(void)
    5757{
    58     if(kapa1 != -1) KiiClose(kapa1);
    59     if(kapa2 != -1) KiiClose(kapa2);
     58    if(kapa1 != -1) KapaClose(kapa1);
     59    if(kapa2 != -1) KapaClose(kapa2);
    6060    return true;
    6161}
  • trunk/psModules/src/objects/models/pmModel_DEV.c

    r35560 r35768  
    123123
    124124        // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
    125         psEllipseShape shape;
    126 
    127         shape.sx  = PAR[PM_PAR_SXX];
    128         shape.sy  = PAR[PM_PAR_SYY];
    129         shape.sxy = PAR[PM_PAR_SXY];
    130 
    131         // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio
    132         psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     125        psEllipseAxes axes;
     126        pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    133127
    134128        // get the central pixel flux from the lookup table
     
    238232        // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
    239233        // angle and let f2,f1 fight it out
    240         q2 = 0.5*sqrtf(q1);
     234        // NOTE: the factor of 2 is needed to convert par[SXX,SYY] to shape.sx,sy
     235        q2 = 2.0*0.5*sqrtf(q1);
    241236    }
    242237
     
    303298
    304299    // set the shape parameters
    305     // XXX adjust this?
    306     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
     300    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, true)) {
    307301      return false;
    308302    }
     
    330324psF64 PM_MODEL_FLUX (const psVector *params)
    331325{
    332     psEllipseShape shape;
    333 
    334326    psF32 *PAR = params->data.F32;
    335327
    336     shape.sx  = PAR[PM_PAR_SXX];
    337     shape.sy  = PAR[PM_PAR_SYY];
    338     shape.sxy = PAR[PM_PAR_SXY];
    339 
    340     // for a non-circular DeVaucouleur, the flux of the Rmajor equivalent is scaled by the AspectRatio
    341     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     328    psEllipseAxes axes;
     329    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    342330    float AspectRatio = axes.minor / axes.major;
    343331
     
    359347psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux)
    360348{
    361     psEllipseShape shape;
    362 
    363349    psF32 *PAR = params->data.F32;
    364350
     
    370356        return (1.0);
    371357
    372     shape.sx  = PAR[PM_PAR_SXX];
    373     shape.sy  = PAR[PM_PAR_SYY];
    374     shape.sxy = PAR[PM_PAR_SXY];
    375 
    376     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     358    psEllipseAxes axes;
     359    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    377360
    378361    // f = Io exp(-z^n) -> z^n = ln(Io/f)
     
    382365    psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)",
    383366              PAR[PM_PAR_I0], flux, axes.major, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY]);
    384 
    385367    return (radius);
    386368}
     
    407389    // the 2D PSF model fits polarization terms (E0,E1,E2)
    408390    // convert to shape terms (SXX,SYY,SXY)
    409     if (!pmPSF_FitToModel (out, 0.1)) {
     391    bool useReff = pmModelUseReff (modelPSF->type);
     392    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    410393        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    411394        return false;
     
    460443    // convert to shape terms (SXX,SYY,SXY)
    461444    // XXX user-defined value for limit?
    462     if (!pmPSF_FitToModel (PAR, 0.1)) {
     445    bool useReff = pmModelUseReff (model->type);
     446    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    463447        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    464448        return false;
  • trunk/psModules/src/objects/models/pmModel_EXP.c

    r35560 r35768  
    115115
    116116        // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
    117         psEllipseShape shape;
    118 
    119         shape.sx  = PAR[PM_PAR_SXX];
    120         shape.sy  = PAR[PM_PAR_SYY];
    121         shape.sxy = PAR[PM_PAR_SXY];
    122 
    123         // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio
    124         psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     117        psEllipseAxes axes;
     118        pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    125119
    126120        // get the central pixel flux from the lookup table
     
    230224        // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
    231225        // angle and let f2,f1 fight it out
    232         q2 = 0.5*sqrtf(q1);
     226        // NOTE: the factor of 2 is needed to convert par[SXX,SYY] to shape.sx,sy
     227        q2 = 2.0*0.5*sqrtf(q1);
    233228    }
    234229
     
    295290
    296291    // set the shape parameters
    297     // XXX adjust this?
    298     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
     292    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, true)) {
    299293      return false;
    300294    }
     
    316310psF64 PM_MODEL_FLUX (const psVector *params)
    317311{
    318     psEllipseShape shape;
    319 
    320312    psF32 *PAR = params->data.F32;
    321313
    322     shape.sx  = PAR[PM_PAR_SXX];
    323     shape.sy  = PAR[PM_PAR_SYY];
    324     shape.sxy = PAR[PM_PAR_SXY];
    325 
    326     // for a non-circular Exponential, the flux of the Rmajor equivalent is scaled by the AspectRatio
    327     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     314    psEllipseAxes axes;
     315    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    328316    float AspectRatio = axes.minor / axes.major;
    329317
     
    345333psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux)
    346334{
    347     psEllipseShape shape;
    348 
    349335    psF32 *PAR = params->data.F32;
    350336
     
    356342        return (1.0);
    357343
    358     shape.sx  = PAR[PM_PAR_SXX];
    359     shape.sy  = PAR[PM_PAR_SYY];
    360     shape.sxy = PAR[PM_PAR_SXY];
    361 
    362     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     344    psEllipseAxes axes;
     345    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    363346
    364347    // f = Io exp(-sqrt(z)) -> sqrt(z) = ln(Io/f)
     
    392375    // the 2D PSF model fits polarization terms (E0,E1,E2)
    393376    // convert to shape terms (SXX,SYY,SXY)
    394     if (!pmPSF_FitToModel (out, 0.1)) {
     377    bool useReff = pmModelUseReff (modelPSF->type);
     378    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    395379        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    396380        return false;
     
    445429    // convert to shape terms (SXX,SYY,SXY)
    446430    // XXX user-defined value for limit?
    447     if (!pmPSF_FitToModel (PAR, 0.1)) {
     431    bool useReff = pmModelUseReff (model->type);
     432    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    448433        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    449434        return false;
  • trunk/psModules/src/objects/models/pmModel_GAUSS.c

    r35560 r35768  
    129129    float q2 = NAN;
    130130    if (nParam == PM_PAR_SXY) {
    131         float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
    132         float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
     131        // NOTE: the factor of 2 is needed to convert par[SXX,SYY] to shape.sx,sy
     132        float f1 = 2.0 / PS_SQR(params[PM_PAR_SYY]) + 2.0 / PS_SQR(params[PM_PAR_SXX]);
     133        float f2 = 2.0 / PS_SQR(params[PM_PAR_SYY]) - 2.0 / PS_SQR(params[PM_PAR_SXX]);
    133134        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
    134135        q1 = (q1 < 0.0) ? 0.0 : q1;
     
    200201
    201202    // set the shape parameters
    202     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
     203    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, false)) {
    203204      return false;
    204205    }
     
    219220psF64 PM_MODEL_FLUX (const psVector *params)
    220221{
    221 
    222     psEllipseShape shape;
    223 
    224222    psF32 *PAR = params->data.F32;
    225223
    226     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    227     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    228     shape.sxy = PAR[PM_PAR_SXY];
     224    psEllipseAxes axes;
     225    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
    229226
    230227    // Area is equivalent to 2 pi sigma^2
    231     // axes ratio < 20
    232     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
    233228    psF64 Area = 2.0 * M_PI * axes.major * axes.minor;
    234229
     
    242237psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux)
    243238{
    244     psEllipseShape shape;
    245 
    246239    psF32 *PAR = params->data.F32;
    247240
     
    253246        return (1.0);
    254247
    255     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    256     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    257     shape.sxy = PAR[PM_PAR_SXY];
    258 
    259     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     248    psEllipseAxes axes;
     249    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
     250
    260251    psF64 radius = axes.major * sqrt (2.0 * log(PAR[PM_PAR_I0] / flux));
    261252    psAssert (isfinite(radius), "fix this code: radius should not be nan for Io = %f, flux = %f, major = %f (%f, %f, %f)",
     
    285276    }
    286277
    287     // the OLD 2D model for SXY actually fitted SXY / (SXX^-2 + SYY^-2); correct here
    288     // out[PM_PAR_SXY] = pmPSF_SXYtoModel (out);
    289 
    290278    // the 2D PSF model fits polarization terms (E0,E1,E2)
    291279    // convert to shape terms (SXX,SYY,SXY)
    292     // XXX user-defined value for limit?
    293     if (!pmPSF_FitToModel (out, 0.1)) {
    294         // psError(PM_ERR_PSF, false, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
     280    bool useReff = pmModelUseReff (modelPSF->type);
     281    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    295282        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    296283        return false;
     
    343330    // the 2D PSF model fits polarization terms (E0,E1,E2)
    344331    // convert to shape terms (SXX,SYY,SXY)
    345     // XXX user-defined value for limit?
    346     if (!pmPSF_FitToModel (PAR, 0.1)) {
     332    bool useReff = pmModelUseReff (model->type);
     333    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    347334        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    348335        return false;
  • trunk/psModules/src/objects/models/pmModel_PGAUSS.c

    r35560 r35768  
    129129    float q2 = NAN;
    130130    if (nParam == PM_PAR_SXY) {
    131         float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
    132         float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
     131        // NOTE: the factor of 2 is needed to convert par[SXX,SYY] to shape.sx,sy
     132        float f1 = 2.0 / PS_SQR(params[PM_PAR_SYY]) + 2.0 / PS_SQR(params[PM_PAR_SXX]);
     133        float f2 = 2.0 / PS_SQR(params[PM_PAR_SYY]) - 2.0 / PS_SQR(params[PM_PAR_SXX]);
    133134        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
    134135        q1 = (q1 < 0.0) ? 0.0 : q1;
     
    201202
    202203    // set the shape parameters
    203     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
     204    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, false)) {
    204205      return false;
    205206    }
     
    222223{
    223224    float z, norm;
    224     psEllipseShape shape;
    225225
    226226    psF32 *PAR = params->data.F32;
    227227
    228     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    229     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    230     shape.sxy = PAR[PM_PAR_SXY];
    231 
    232     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     228    psEllipseAxes axes;
     229    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
     230
    233231    float AspectRatio = axes.minor / axes.major;
    234232
     
    262260{
    263261    psF64 z;
    264     psEllipseShape shape;
    265262
    266263    psF32 *PAR = params->data.F32;
     
    273270        return (1.0);
    274271
    275     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    276     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    277     shape.sxy = PAR[PM_PAR_SXY];
    278 
    279     // this estimates the radius assuming f(z) is roughly exp(-z)
    280     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     272    psEllipseAxes axes;
     273    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
     274
    281275    psF64 sigma = axes.major;
    282276
     
    347341    }
    348342
    349     // the OLD 2D model for SXY actually fitted SXY / (SXX^-2 + SYY^-2); correct here
    350     // out[PM_PAR_SXY] = pmPSF_SXYtoModel (out);
    351 
    352343    // the 2D PSF model fits polarization terms (E0,E1,E2)
    353344    // convert to shape terms (SXX,SYY,SXY)
    354     if (!pmPSF_FitToModel (out, 0.1)) {
     345    bool useReff = pmModelUseReff (modelPSF->type);
     346    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    355347        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    356348        return false;
     
    403395    // the 2D PSF model fits polarization terms (E0,E1,E2)
    404396    // convert to shape terms (SXX,SYY,SXY)
    405     // XXX user-defined value for limit?
    406     if (!pmPSF_FitToModel (PAR, 0.1)) {
     397    bool useReff = pmModelUseReff (model->type);
     398    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    407399        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    408400        return false;
  • trunk/psModules/src/objects/models/pmModel_PS1_V1.c

    r35560 r35768  
    11/******************************************************************************
    2  * this file defines the PS1_V1 source shape model.  Note that these model functions are loaded
    3  * by pmModelClass.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 as a PSF representations share a few
    7  * parameters, for which # define names are listed in pmModel.h:
     2 * this file defines the PS1_V1 source shape model.  Note that these model functions are
     3 * loaded by pmModelClass.c using 'include', and thus need no 'include' statements of
     4 * their own.  The models use a psVector to represent the set of parameters, with the
     5 * 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 as a
     7 * PSF representations share a few parameters, for which # define names are listed in
     8 * pmModel.h:
    89
    910   power-law with fitted linear term
     
    148149    float q2 = NAN;
    149150    if (nParam == PM_PAR_SXY) {
    150         float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
    151         float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
     151        float f1 = 2.0 / PS_SQR(params[PM_PAR_SYY]) + 2.0 / PS_SQR(params[PM_PAR_SXX]);
     152        float f2 = 2.0 / PS_SQR(params[PM_PAR_SYY]) - 2.0 / PS_SQR(params[PM_PAR_SXX]);
    152153        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
    153154        q1 = (q1 < 0.0) ? 0.0 : q1;
     
    220221
    221222    // set the shape parameters
    222     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
     223    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, false)) {
    223224      return false;
    224225    }
     
    244245{
    245246    float z, norm;
    246     psEllipseShape shape;
    247247
    248248    psF32 *PAR = params->data.F32;
    249249
    250     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    251     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    252     shape.sxy = PAR[PM_PAR_SXY];
    253 
    254     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     250    psEllipseAxes axes;
     251    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
    255252    float AspectRatio = axes.minor / axes.major;
    256253
     
    284281{
    285282    psF64 z;
    286     psEllipseShape shape;
    287283
    288284    psF32 *PAR = params->data.F32;
     
    292288    if (flux >= PAR[PM_PAR_I0]) return 1.0;
    293289
    294     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    295     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    296     shape.sxy = PAR[PM_PAR_SXY];
    297 
    298     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     290    psEllipseAxes axes;
     291    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
    299292    psF64 sigma = axes.major;
    300293
     
    363356    // the 2D PSF model fits polarization terms (E0,E1,E2)
    364357    // convert to shape terms (SXX,SYY,SXY)
    365     if (!pmPSF_FitToModel (out, 0.1)) {
     358    bool useReff = pmModelUseReff (modelPSF->type);
     359    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    366360        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    367361        return false;
     
    416410    // convert to shape terms (SXX,SYY,SXY)
    417411    // XXX user-defined value for limit?
    418     if (!pmPSF_FitToModel (PAR, 0.1)) {
     412    bool useReff = pmModelUseReff (model->type);
     413    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    419414        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    420415        return false;
  • trunk/psModules/src/objects/models/pmModel_QGAUSS.c

    r35560 r35768  
    11/******************************************************************************
    2  * this file defines the QGAUSS source shape model (XXX need a better name!).  Note that these
    3  * model functions are loaded by pmModelClass.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:
     2 * this file defines the QGAUSS source shape model.  Note that these model functions are
     3 * loaded by pmModelClass.c using 'include', and thus need no 'include' statements of
     4 * their own.  The models use a psVector to represent the set of parameters, with the
     5 * 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 as a
     7 * PSF representations share a few parameters, for which # define names are listed in
     8 * pmModel.h:
    89
    910   power-law with fitted linear term
     
    1415   * PM_PAR_XPOS 2  - X center of object
    1516   * 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)
     17   * PM_PAR_SXX 4   - X^2 term of elliptical contour (SigmaX / sqrt(2))
     18   * PM_PAR_SYY 5   - Y^2 term of elliptical contour (SigmaY / sqrt(2))
    1819   * PM_PAR_SXY 6   - X*Y term of elliptical contour
    1920   * PM_PAR_7   7   - amplitude of the linear component (k)
     
    138139# define AR_MAX 20.0
    139140# define AR_RATIO 0.99
    140 
    141141bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
    142142{
     
    149149    float q2 = NAN;
    150150    if (nParam == PM_PAR_SXY) {
    151         float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
    152         float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
     151        // NOTE: the factor of 2 is needed to convert par[SXX,SYY] to shape.sx,sy
     152        float f1 = 2.0 / PS_SQR(params[PM_PAR_SYY]) + 2.0 / PS_SQR(params[PM_PAR_SXX]);
     153        float f2 = 2.0 / PS_SQR(params[PM_PAR_SYY]) - 2.0 / PS_SQR(params[PM_PAR_SXX]);
    153154        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
    154155        q1 = (q1 < 0.0) ? 0.0 : q1;
     
    203204          return true;
    204205      }
    205     default:
     206      default:
    206207        psAbort("invalid choice for limits");
    207208    }
     
    221222
    222223    // set the shape parameters
    223     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
     224    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, false)) {
    224225      return false;
    225226    }
     
    245246{
    246247    float z, norm;
    247     psEllipseShape shape;
    248248
    249249    psF32 *PAR = params->data.F32;
    250250
    251     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    252     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    253     shape.sxy = PAR[PM_PAR_SXY];
    254 
    255     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     251    psEllipseAxes axes;
     252    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
    256253    float AspectRatio = axes.minor / axes.major;
    257254
     
    285282{
    286283    psF64 z;
    287     psEllipseShape shape;
    288284
    289285    psF32 *PAR = params->data.F32;
     
    293289    if (flux >= PAR[PM_PAR_I0]) return 1.0;
    294290
    295     // if (PAR[PM_PAR_7] == 0.0) return powf(PAR[PM_PAR_I0] / flux - 1.0, 1.0 / ALPHA);
    296 
    297     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    298     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    299     shape.sxy = PAR[PM_PAR_SXY];
    300 
    301     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     291    psEllipseAxes axes;
     292    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
    302293    psF64 sigma = axes.major;
    303294
     
    307298        return ( sigma * sqrt (2.0 * z) );
    308299    }
    309 
    310300    psF64 limit = flux / PAR[PM_PAR_I0];
    311301
     
    367357    // the 2D PSF model fits polarization terms (E0,E1,E2)
    368358    // convert to shape terms (SXX,SYY,SXY)
    369     if (!pmPSF_FitToModel (out, 0.1)) {
     359    bool useReff = pmModelUseReff (modelPSF->type);
     360    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    370361        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    371362        return false;
     
    424415    // the 2D PSF model fits polarization terms (E0,E1,E2)
    425416    // convert to shape terms (SXX,SYY,SXY)
    426     // XXX user-defined value for limit?
    427     if (!pmPSF_FitToModel (PAR, 0.1)) {
     417    bool useReff = pmModelUseReff (model->type);
     418    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    428419        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    429420        return false;
  • trunk/psModules/src/objects/models/pmModel_RGAUSS.c

    r35560 r35768  
    138138    float q2 = NAN;
    139139    if (nParam == PM_PAR_SXY) {
    140         float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
    141         float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
     140        // NOTE: the factor of 2 is needed to convert par[SXX,SYY] to shape.sx,sy
     141        float f1 = 2.0 / PS_SQR(params[PM_PAR_SYY]) + 2.0 / PS_SQR(params[PM_PAR_SXX]);
     142        float f2 = 2.0 / PS_SQR(params[PM_PAR_SYY]) - 2.0 / PS_SQR(params[PM_PAR_SXX]);
    142143        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
    143144        q1 = (q1 < 0.0) ? 0.0 : q1;
     
    210211
    211212    // set the shape parameters
    212     if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments)) {
     213    if (!pmModelSetShape(&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], source->moments, false)) {
    213214      return false;
    214215    }
     
    234235{
    235236    float z, norm;
    236     psEllipseShape shape;
    237237
    238238    psF32 *PAR = params->data.F32;
    239239
    240     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    241     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    242     shape.sxy = PAR[PM_PAR_SXY];
    243 
    244     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     240    psEllipseAxes axes;
     241    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
    245242    float AspectRatio = axes.minor / axes.major;
    246243
     
    274271{
    275272    psF64 z;
    276     psEllipseShape shape;
    277273
    278274    psF32 *PAR = params->data.F32;
     
    285281        return (1.0);
    286282
    287     shape.sx  = PAR[PM_PAR_SXX] / M_SQRT2;
    288     shape.sy  = PAR[PM_PAR_SYY] / M_SQRT2;
    289     shape.sxy = PAR[PM_PAR_SXY];
    290 
    291     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     283    psEllipseAxes axes;
     284    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], false);
    292285    psF64 sigma = axes.major;
    293286
     
    357350    // the 2D PSF model fits polarization terms (E0,E1,E2)
    358351    // convert to shape terms (SXX,SYY,SXY)
    359     if (!pmPSF_FitToModel (out, 0.1)) {
     352    bool useReff = pmModelUseReff (modelPSF->type);
     353    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    360354        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    361355        return false;
     
    409403    // the 2D PSF model fits polarization terms (E0,E1,E2)
    410404    // convert to shape terms (SXX,SYY,SXY)
    411     // XXX user-defined value for limit?
    412     if (!pmPSF_FitToModel (PAR, 0.1)) {
     405    bool useReff = pmModelUseReff (model->type);
     406    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    413407        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    414408        return false;
  • trunk/psModules/src/objects/models/pmModel_SERSIC.c

    r35560 r35768  
    125125
    126126        // first, use Rmajor and index to find the central pixel flux (fraction of total flux)
    127         psEllipseShape shape;
    128 
    129         shape.sx  = PAR[PM_PAR_SXX];
    130         shape.sy  = PAR[PM_PAR_SYY];
    131         shape.sxy = PAR[PM_PAR_SXY];
    132 
    133         // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio
    134         psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     127        psEllipseAxes axes;
     128        pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    135129
    136130        // get the central pixel flux from the lookup table
     
    250244        // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
    251245        // angle and let f2,f1 fight it out
    252         q2 = 0.5*sqrtf(q1);
     246        // NOTE: the factor of 2 is needed to convert par[SXX,SYY] to shape.sx,sy
     247        q2 = 2.0*0.5*sqrtf(q1);
    253248    }
    254249
     
    347342    axes.major = Rmajor;
    348343    axes.minor = Rminor;
    349     psEllipseShape shape = psEllipseAxesToShape (axes);
    350 
    351     if (!isfinite(shape.sx))  return false;
    352     if (!isfinite(shape.sy))  return false;
    353     if (!isfinite(shape.sxy)) return false;
     344
     345    pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], axes, true);
    354346
    355347    float bn = 1.9992*index - 0.3271;
     
    357349    float Io = exp(0.5*bn);
    358350
    359     float Sxx = PS_MAX(0.5, shape.sx);
    360     float Syy = PS_MAX(0.5, shape.sy);
    361 
    362     PAR[PM_PAR_SXX]  = Sxx;
    363     PAR[PM_PAR_SYY]  = Syy;
    364     PAR[PM_PAR_SXY]  = shape.sxy;
    365 
    366351    // set the model normalization (adjust for Sersic best guess)
    367352    if (!pmModelSetNorm(&PAR[PM_PAR_I0], source)) {
     
    381366psF64 PM_MODEL_FLUX (const psVector *params)
    382367{
    383     psEllipseShape shape;
    384 
    385368    psF32 *PAR = params->data.F32;
    386369
    387     shape.sx  = PAR[PM_PAR_SXX];
    388     shape.sy  = PAR[PM_PAR_SYY];
    389     shape.sxy = PAR[PM_PAR_SXY];
    390 
    391     // for a non-circular Sersic, the flux of the Rmajor equivalent is scaled by the AspectRatio
    392     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     370    psEllipseAxes axes;
     371    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    393372    float AspectRatio = axes.minor / axes.major;
    394373
     
    410389psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux)
    411390{
    412     psEllipseShape shape;
    413 
    414391    psF32 *PAR = params->data.F32;
    415392
     
    421398        return (1.0);
    422399
    423     shape.sx  = PAR[PM_PAR_SXX];
    424     shape.sy  = PAR[PM_PAR_SYY];
    425     shape.sxy = PAR[PM_PAR_SXY];
    426 
    427     psEllipseAxes axes = psEllipseShapeToAxes (shape, 20.0);
     400    psEllipseAxes axes;
     401    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], true);
    428402
    429403    // f = Io exp(-z^n) -> z^n = ln(Io/f)
     
    457431    // the 2D PSF model fits polarization terms (E0,E1,E2)
    458432    // convert to shape terms (SXX,SYY,SXY)
    459     if (!pmPSF_FitToModel (out, 0.1)) {
     433    bool useReff = pmModelUseReff (modelPSF->type);
     434    if (!pmPSF_FitToModel (out, 0.1, useReff)) {
    460435        psTrace("psModules.objects", 5, "Failed to fit object at (r,c) = (%.1f,%.1f)", in[PM_PAR_YPOS], in[PM_PAR_XPOS]);
    461436        return false;
     
    510485    // convert to shape terms (SXX,SYY,SXY)
    511486    // XXX user-defined value for limit?
    512     if (!pmPSF_FitToModel (PAR, 0.1)) {
     487    bool useReff = pmModelUseReff (model->type);
     488    if (!pmPSF_FitToModel (PAR, 0.1, useReff)) {
    513489        psTrace ("psModules.objects", 3, "Failed to fit object at (r,c) = (%.1f,%.1f)", Xo, Yo);
    514490        return false;
  • trunk/psModules/src/objects/models/pmModel_TRAIL.c

    r35577 r35768  
    350350    PAR[PM_PAR_SKY]  = 0.0;
    351351
    352     // XXX test : modify the Io, SXX, SYY terms based on the psf SXX, SYY terms:
    353     psEllipseShape psfShape;
    354     psfShape.sx  = source->modelPSF->params->data.F32[PM_PAR_SXX] / M_SQRT2;
    355     psfShape.sxy = source->modelPSF->params->data.F32[PM_PAR_SXY];
    356     psfShape.sy  = source->modelPSF->params->data.F32[PM_PAR_SYY] / M_SQRT2;
    357     psEllipseAxes psfAxes = psEllipseShapeToAxes (psfShape, 20.0);
     352    psF32 *psfPAR  = source->modelPSF->params->data.F32;
     353    bool useReff = pmModelUseReff (source->modelPSF->type);
     354
     355    psEllipseAxes psfAxes;
     356    pmModelParamsToAxes (&psfAxes, psfPAR[PM_PAR_SXX], psfPAR[PM_PAR_SXY], psfPAR[PM_PAR_SYY], useReff);
    358357
    359358    psEllipseMoments emoments;
     
    369368    if (!isfinite(axes.theta)) return false;
    370369
    371     float size = (axes.major > sqrt(source->moments->Mrf)) ? axes.major : sqrt(source->moments->Mrf);
    372     //    if (size > psfAxes.major) { size -= psfAxes.major; }
    373     //else { size = psfAxes.major; }
     370    float size = NAN;
     371    if (!isfinite(source->moments->Mrf)) {
     372      size = axes.major;
     373    } else {
     374      size = (axes.major > sqrt(source->moments->Mrf)) ? axes.major : sqrt(source->moments->Mrf);
     375    }
    374376
    375377    float theta, peak;
  • trunk/psModules/src/objects/pmModelUtils.c

    r34403 r35768  
    118118}
    119119
    120 bool pmModelSetShape (float *Sxx, float *Sxy, float *Syy, pmMoments *moments) {
     120bool pmModelUseReff (pmModelType type) {
     121    bool useReff = false;
     122    useReff |= (type == pmModelClassGetType ("PS_MODEL_SERSIC"));
     123    useReff |= (type == pmModelClassGetType ("PS_MODEL_DEV"));
     124    useReff |= (type == pmModelClassGetType ("PS_MODEL_EXP"));
     125    return useReff;
     126}
     127
     128// this function and the one below handle the two cases, where the model shape is uses R_eff or Sigma
     129bool pmModelAxesToParams (float *Sxx, float *Sxy, float *Syy, psEllipseAxes axes, bool useReff)  {
     130
     131    psEllipseShape shape = psEllipseAxesToShape (axes);
     132
     133    if (!isfinite(shape.sx))  return false;
     134    if (!isfinite(shape.sy))  return false;
     135    if (!isfinite(shape.sxy)) return false;
     136
     137    // set the shape parameters
     138    if (useReff) {
     139        *Sxx  = PS_MAX(0.5, shape.sx);
     140        *Syy  = PS_MAX(0.5, shape.sy);
     141        *Sxy  = shape.sxy * 2.0;
     142    } else {
     143        *Sxx  = PS_MAX(0.5, M_SQRT2*shape.sx);
     144        *Syy  = PS_MAX(0.5, M_SQRT2*shape.sy);
     145        *Sxy  = shape.sxy;
     146    }
     147
     148    return true;
     149}
     150
     151bool pmModelParamsToAxes (psEllipseAxes *axes, float Sxx, float Sxy, float Syy, bool useReff)  {
     152
     153    psEllipseShape shape;
     154
     155    // set the shape parameters
     156    if (useReff) {
     157        shape.sx  = Sxx;
     158        shape.sy  = Syy;
     159        shape.sxy = Sxy / 2.0;
     160    } else {
     161        shape.sx  = Sxx / M_SQRT2;
     162        shape.sy  = Syy / M_SQRT2;
     163        shape.sxy = Sxy;
     164    }
     165
     166    if ((shape.sx == 0) || (shape.sy == 0)) {
     167        axes->major = 0.0;
     168        axes->minor = 0.0;
     169        axes->theta = 0.0;
     170    } else {
     171        // axes ratio < 20
     172        // replace with maxAR argument?
     173        *axes = psEllipseShapeToAxes (shape, 20.0);
     174    }
     175
     176    return true;
     177}
     178
     179// Reff says if this is a model which uses R_eff (like exp or dev) instead of Sigma
     180// set the parameter values SXX, SXY, SYY
     181bool pmModelSetShape (float *Sxx, float *Sxy, float *Syy, pmMoments *moments, bool useReff) {
    121182
    122183    psEllipseMoments emoments;
     
    137198    axes.minor *= scale;
    138199
    139     psEllipseShape shape = psEllipseAxesToShape (axes);
    140 
    141     if (!isfinite(shape.sx))  return false;
    142     if (!isfinite(shape.sy))  return false;
    143     if (!isfinite(shape.sxy)) return false;
    144 
    145     // set the shape parameters
    146     *Sxx  = PS_MAX(0.5, M_SQRT2*shape.sx);
    147     *Syy  = PS_MAX(0.5, M_SQRT2*shape.sy);
    148     *Sxy  = shape.sxy;
     200    pmModelAxesToParams (Sxx, Sxy, Syy, axes, useReff);
    149201
    150202    return true;
  • trunk/psModules/src/objects/pmModelUtils.h

    r34085 r35768  
    4444bool pmModelSetPosition (float *Xo, float *Yo, pmSource *source);
    4545bool pmModelSetNorm (float *Io, pmSource *source);
    46 bool pmModelSetShape (float *Sxx, float *Sxy, float *Syy, pmMoments *moments);
     46bool pmModelSetShape (float *Sxx, float *Sxy, float *Syy, pmMoments *moments, bool useReff);
     47
     48bool pmModelUseReff (pmModelType type);
     49bool pmModelAxesToParams (float *Sxx, float *Sxy, float *Syy, psEllipseAxes axes, bool useReff);
     50bool pmModelParamsToAxes (psEllipseAxes *axes, float Sxx, float Sxy, float Syy, bool useReff);
    4751
    4852// XXX void pmModelSetModelVarOption (bool option);
  • trunk/psModules/src/objects/pmPCM_MinimizeChisq.c

    r34403 r35768  
    8181        psAbort ("programming error: no unmasked parameters to be fit\n");
    8282    }
     83    psAssert (pcm->nPar == Beta->n, "did we set the masked parameters correctly??");
    8384
    8485    // allocate internal arrays (current vs Guess)
    85     psImage *alpha   = psImageAlloc(Alpha->numCols, Alpha->numRows, PS_TYPE_F32);
    86     psVector *beta   = psVectorAlloc(Beta->n, PS_TYPE_F32);
     86    psImage *alpha   = psImageAlloc(pcm->nPar, pcm->nPar, PS_TYPE_F32);
     87    psVector *beta   = psVectorAlloc(pcm->nPar, PS_TYPE_F32);
    8788    psVector *Params = psVectorAlloc(params->n, PS_TYPE_F32);
    8889
     
    9091    psF32 lambda = 0.001;
    9192    psF32 dLinear = 0.0;
     93    psF32 nu = 2.0;
    9294
    9395# if (USE_FFT && PRE_CONVOLVE)
     
    120122    bool done = (min->iter >= min->maxIter);
    121123    while (!done) {
    122         psTrace("psModules.objects", 5, "Iteration number %d.  (max iterations is %d).\n", min->iter, min->maxIter);
    123         psTrace("psModules.objects", 5, "Last delta is %f.  stop if < %f, accept if < %f\n", min->lastDelta, min->minTol, min->maxTol);
     124        psTrace(FACILITY, 5, "Iteration number %d.  (max iterations is %d).\n", min->iter, min->maxIter);
     125
     126        if (min->chisqConvergence) {
     127            psTrace(FACILITY, 5, "Last delta is %f.  stop if < %f, accept if < %f\n", min->lastDelta, min->minTol, min->maxTol);
     128        } else {
     129            psTrace(FACILITY, 5, "Last delta is %f.  stop if < %f, accept if < %f\n", min->rParSigma, min->minTol*pcm->nPar, min->maxTol*pcm->nPar);
     130        }
    124131
    125132        // set a new guess for Alpha, Beta, Params
     
    140147            p_psVectorPrint(psTraceGetDestination(), Params, "params guess (1)");
    141148        }
     149
     150        // calculate the parameter change (rParDelta) and error radius (rParSigma)
     151        //    rParDelta : radius of parameter change;
     152        //    rParSigma : radius of parameter error
     153       
     154        // note that (before SetABX) Alpha[i][i] is the covariance matrix and
     155        // Beta is the actual parameter change for this pass
     156
     157        // note that Alpha & Beta only represent unmasked parameters, while params and Params have all
     158
     159        // dParSigma = Alpha[i][i] : error (squared) on parameter i
     160        // dParDelta = Params->data.F32[i] - params->data.F32[i]     : change on parameter i
     161        float rParSigma = 0.0;
     162        for (int j = 0, J = 0; j < Params->n; j++) {
     163            if (paramMask && (paramMask->data.PS_TYPE_VECTOR_MASK_DATA[j])) {
     164                continue;
     165            }
     166            rParSigma += PS_SQR(Params->data.F32[j] - params->data.F32[j]) / Alpha->data.F32[J][J];
     167            J++;
     168        }
     169        rParSigma = sqrt(rParSigma);
     170        psTrace(FACILITY, 5, "rParSigma: %f, Niter: %d\n", rParSigma, min->iter);
     171        // fprintf (stderr, "rParSigma: %f, Niter: %d\n", rParSigma, min->iter);
    142172
    143173        // calculate Chisq for new guess, update Alpha & Beta
     
    164194        }
    165195
    166         /* if (Chisq < min->value) {  */
     196        // change in chisq/nDOF since last minimum
     197        min->lastDelta = (min->value - Chisq) / pcm->nDOF;
     198
     199        // rho is positive if the new chisq is smaller; allow for some insignificant change (slight negative rho)
     200
     201        // XXX the old version of lambda changes:
     202        // XXX : Madsen gives suggestion for better use of rho
     203        // rho is positive if the new chisq is smaller
    167204        if (rho >= -1e-6) {
    168             min->lastDelta = (min->value - Chisq) / (source->pixels->numCols*source->pixels->numRows - params->n);
    169205            min->value = Chisq;
    170206            alpha  = psImageCopy(alpha, Alpha, PS_TYPE_F32);
    171207            beta   = psVectorCopy(beta, Beta, PS_TYPE_F32);
    172208            params = psVectorCopy(params, Params, PS_TYPE_F32);
    173             lambda *= 0.25;
    174209
    175210            // save the new convolved model image
    176211            psFree (source->modelFlux);
    177212            source->modelFlux = pmPCMdataSaveImage(pcm);
    178         } else {
    179             lambda *= 10.0;
    180         }
     213        }
     214        switch (min->gainFactorMode) {
     215          case 0:
     216            if (rho >= -1e-6) {
     217                lambda *= 0.25;
     218            } else {
     219                lambda *= 10.0;
     220            }
     221            break;
     222
     223          case 1:
     224            // adjust the gain ratio (lambda) based on rho
     225            if (rho < 0.25) {
     226                lambda *= 2.0;
     227            }
     228            if (rho > 0.75) {
     229                lambda *= 0.333;
     230            }
     231            break;
     232
     233          case 2:
     234            if (rho > 0.0) {
     235                lambda *= PS_MAX(0.33, (1.0 - pow(2.0*rho - 1.0, 3.0)));
     236                nu = 2.0;
     237            } else {
     238                lambda *= nu;
     239                nu *= 2.0;
     240            }
     241            break;
     242        }
    181243        min->iter++;
    182244
     245        // ending conditions:
     246        // 1) hard limit : too many iterations
    183247        done = (min->iter >= min->maxIter);
    184248       
    185         // check for convergence:
     249        // 2) require deltaChi > 1e-6 (ie, chisq is decreasing, but accept an insignificant change)
     250        if (min->lastDelta < -1e-6) {
     251            continue;
     252        }
     253
     254        // save this value in case we stop iterating
     255        min->rParSigma = rParSigma;
     256
     257        // 2) require chisqDOF < maxChisqDOF (if maxChisqDOF is not NAN)
     258        // keep iterating regardless of rParSigma in this case
    186259        float chisqDOF = Chisq / pcm->nDOF;
    187         if (!isfinite(min->maxChisqDOF) || ((chisqDOF < min->maxChisqDOF) && isfinite(min->lastDelta))) {
     260        if (isfinite(min->maxChisqDOF) && (chisqDOF > min->maxChisqDOF)) {
     261            continue;
     262        }
     263
     264        // delta-chisq or rParSigma ?
     265        if (min->chisqConvergence) {
    188266            done |= (min->lastDelta < min->minTol);
     267        } else {
     268            done |= (rParSigma < min->minTol*pcm->nPar);
    189269        }
    190270    }
     
    220300
    221301    // if the last improvement was at least as good as maxTol, accept the fit:
    222     if (min->lastDelta <= min->maxTol) {
    223         psTrace(FACILITY, 6, "---- end (true) ----\n");
    224         return(true);
     302    if (min->chisqConvergence) {
     303        if (min->lastDelta <= min->maxTol) {
     304            psTrace(FACILITY, 6, "---- end (true) ----\n");
     305            return(true);
     306        }
     307    } else {
     308        if (min->rParSigma <= min->maxTol*pcm->nPar) {
     309            psTrace(FACILITY, 6, "---- end (true) ----\n");
     310            return(true);
     311        }
    225312    }
    226313    psTrace(FACILITY, 6, "---- end (false) ----\n");
  • trunk/psModules/src/objects/pmPCMdata.c

    r34854 r35768  
    291291    psAssert (modelPSF, "psf model must be defined");
    292292   
    293     psEllipseShape shape;
    294293    psEllipseAxes axes;
    295 
    296     shape.sx  = modelPSF->params->data.F32[PM_PAR_SXX];
    297     shape.sy  = modelPSF->params->data.F32[PM_PAR_SYY];
    298     shape.sxy = modelPSF->params->data.F32[PM_PAR_SXY];
    299     axes = psEllipseShapeToAxes (shape, 20.0);
     294    bool useReff = pmModelUseReff (modelPSF->type);
     295    psF32 *PAR = modelPSF->params->data.F32;
     296    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
    300297   
    301     float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*modelPSF->params->data.F32[PM_PAR_I0]);
     298    float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
    302299    float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
    303300
     
    451448        psAssert (modelPSF, "psf model must be defined");
    452449   
    453         psEllipseShape shape;
    454450        psEllipseAxes axes;
    455 
    456         shape.sx  = modelPSF->params->data.F32[PM_PAR_SXX];
    457         shape.sy  = modelPSF->params->data.F32[PM_PAR_SYY];
    458         shape.sxy = modelPSF->params->data.F32[PM_PAR_SXY];
    459         axes = psEllipseShapeToAxes (shape, 20.0);
     451        bool useReff = pmModelUseReff (modelPSF->type);
     452        psF32 *PAR = modelPSF->params->data.F32;
     453        pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
    460454   
    461         float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*modelPSF->params->data.F32[PM_PAR_I0]);
     455        float FWHM_MAJOR = 2*modelPSF->modelRadius (modelPSF->params, 0.5*PAR[PM_PAR_I0]);
    462456        float FWHM_MINOR = FWHM_MAJOR * (axes.minor / axes.major);
    463457
  • trunk/psModules/src/objects/pmPSF.c

    r35560 r35768  
    249249// Mxy = SXY * (SXX^-4 + SYY^-4 - 2 SXY ^2)
    250250
     251// XXX deprecated
    251252// input: model->param, output: psf->param[PM_PAR_SXY]
    252 double pmPSF_SXYfromModel (psF32 *modelPar)
    253 {
    254     PS_ASSERT_PTR_NON_NULL(modelPar, NAN);
    255 
    256     double SXX = modelPar[PM_PAR_SXX];
    257     double SYY = modelPar[PM_PAR_SYY];
    258     double SXY = modelPar[PM_PAR_SXY];
    259 
    260     double par = SXY / PS_SQR(1.0 / PS_SQR(SXX) + 1.0 / PS_SQR(SYY));
    261     return (par);
    262 }
    263 
     253// XXX double pmPSF_SXYfromModel (psF32 *modelPar)
     254// XXX {
     255// XXX     PS_ASSERT_PTR_NON_NULL(modelPar, NAN);
     256// XXX
     257// XXX     double SXX = modelPar[PM_PAR_SXX];
     258// XXX     double SYY = modelPar[PM_PAR_SYY];
     259// XXX     double SXY = modelPar[PM_PAR_SXY];
     260// XXX
     261// XXX     double par = SXY / PS_SQR(1.0 / PS_SQR(SXX) + 1.0 / PS_SQR(SYY));
     262// XXX     return (par);
     263// XXX }
     264
     265// XXX deprecated
    264266// input: fitted psf->param, output: model->param[PM_PAR_SXY]
    265 double pmPSF_SXYtoModel (psF32 *fittedPar)
    266 {
    267     PS_ASSERT_PTR_NON_NULL(fittedPar, NAN);
    268 
    269     double SXX = fittedPar[PM_PAR_SXX];
    270     double SYY = fittedPar[PM_PAR_SYY];
    271     double fit = fittedPar[PM_PAR_SXY];
    272 
    273     double SXY = fit * PS_SQR(1.0 / PS_SQR(SXX) + 1.0 / PS_SQR(SYY));
    274 
    275     assert (!isnan(SXY));
    276 
    277     return SXY;
    278 }
    279 
    280 // New Concept: the PSF modelling function fits the polarization terms e0, e1, e2:
    281 
    282 // convert the parameters used in the fitted source model
    283 // to the parameters used in the 2D PSF model
    284 // XXX this function may be invalid for SERSIC, DEV, EXP models (SQRT2 not used?)
    285 bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis)
     267// XXX double pmPSF_SXYtoModel (psF32 *fittedPar)
     268// XXX {
     269// XXX     PS_ASSERT_PTR_NON_NULL(fittedPar, NAN);
     270// XXX
     271// XXX     double SXX = fittedPar[PM_PAR_SXX];
     272// XXX     double SYY = fittedPar[PM_PAR_SYY];
     273// XXX     double fit = fittedPar[PM_PAR_SXY];
     274// XXX
     275// XXX     double SXY = fit * PS_SQR(1.0 / PS_SQR(SXX) + 1.0 / PS_SQR(SYY));
     276// XXX
     277// XXX     assert (!isnan(SXY));
     278// XXX
     279// XXX     return SXY;
     280// XXX }
     281
     282// The PSF modelling function fits the polarization terms e0, e1, e2:
     283
     284// the FIT is the 2D representation of the shape using polarization parameters for the elliptical contour
     285// the MODEL is the realized psf model for a given location
     286
     287// convert the parameters (in situ) used in the fitted source model to the parameters used in
     288// the 2D PSF model
     289bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis, bool useReff)
    286290{
    287291    PS_ASSERT_PTR_NON_NULL(fittedPar, false);
     
    298302        return false;
    299303    }
    300     psEllipseShape shape = psEllipseAxesToShape (axes);
    301 
    302     fittedPar[PM_PAR_SXX] = shape.sx * M_SQRT2;
    303     fittedPar[PM_PAR_SYY] = shape.sy * M_SQRT2;
    304     fittedPar[PM_PAR_SXY] = shape.sxy;
    305 
     304
     305    pmModelAxesToParams (&fittedPar[PM_PAR_SXX], &fittedPar[PM_PAR_SXY], &fittedPar[PM_PAR_SYY], axes, useReff);
    306306    return true;
    307307}
    308308
    309 // convert the PSF parameters used in the 2D PSF model fit into the
    310 // parameters used in the source model
    311 // XXX this function may be invalid for SERSIC, DEV, EXP models (SQRT2 not used?)
    312 psEllipsePol pmPSF_ModelToFit (psF32 *modelPar)
     309// convert the parameters (in situ) used in the 2D PSF model fit into the parameters used in
     310// the source model
     311psEllipsePol pmPSF_ModelToFit (psF32 *modelPar, bool useReff)
    313312{
    314313    // must assert non-NULL input parameter
     
    319318    PS_ASSERT_PTR_NON_NULL(modelPar, pol);
    320319
    321     psEllipseShape shape;
    322 
    323     shape.sx  = modelPar[PM_PAR_SXX] / M_SQRT2;
    324     shape.sy  = modelPar[PM_PAR_SYY] / M_SQRT2;
    325     shape.sxy = modelPar[PM_PAR_SXY];
    326 
    327     pol = psEllipseShapeToPol (shape);
     320    psEllipseAxes axes;
     321    pmModelParamsToAxes (&axes, modelPar[PM_PAR_SXX], modelPar[PM_PAR_SXY], modelPar[PM_PAR_SYY], useReff);
     322
     323    pol = psEllipseAxesToPol (axes);
    328324
    329325    return pol;
     
    332328// convert the parameters used in the fitted source model to the psEllipseAxes representation
    333329// (major,minor,theta)
    334 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR, pmModelType type)
    335 {
    336     psEllipseShape shape;
     330psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, pmModelType type)
     331{
    337332    psEllipseAxes axes;
    338333    axes.major = NAN;
    339334    axes.minor = NAN;
    340335    axes.theta = NAN;
    341     //   XXX: must assert non-NULL input parameter
     336
    342337    PS_ASSERT_PTR_NON_NULL(modelPar, axes);
    343338
    344     bool useReff = false;
    345     useReff |= (type == pmModelClassGetType ("PS_MODEL_SERSIC"));
    346     useReff |= (type == pmModelClassGetType ("PS_MODEL_DEV"));
    347     useReff |= (type == pmModelClassGetType ("PS_MODEL_EXP"));
    348 
    349     if (useReff) {
    350         shape.sx  = modelPar[PM_PAR_SXX];
    351         shape.sy  = modelPar[PM_PAR_SYY];
    352         shape.sxy = modelPar[PM_PAR_SXY] / 2.0;
    353         // XXX I *think* dividing by 2.0 is the right direction, but this
    354         // needs to be checked with a real test
    355     } else {
    356         shape.sx  = modelPar[PM_PAR_SXX] / M_SQRT2;
    357         shape.sy  = modelPar[PM_PAR_SYY] / M_SQRT2;
    358         shape.sxy = modelPar[PM_PAR_SXY];
    359     }
    360 
    361     if ((shape.sx == 0) || (shape.sy == 0)) {
    362         axes.major = 0.0;
    363         axes.minor = 0.0;
    364         axes.theta = 0.0;
    365     } else {
    366         // XXX this is not really consistent with the model fit range above
    367         axes = psEllipseShapeToAxes (shape, maxAR);
    368     }
    369 
     339    bool useReff = pmModelUseReff (type);
     340    pmModelParamsToAxes (&axes, modelPar[PM_PAR_SXX], modelPar[PM_PAR_SXY], modelPar[PM_PAR_SYY], useReff);
    370341    return axes;
    371342}
     
    377348    PS_ASSERT_PTR_NON_NULL(modelPar, false);
    378349
     350    modelPar[PM_PAR_SXX] = 0.0;
     351    modelPar[PM_PAR_SYY] = 0.0;
     352    modelPar[PM_PAR_SXY] = 0.0;
     353   
    379354    if ((axes.major <= 0) || (axes.minor <= 0)) {
    380         modelPar[PM_PAR_SXX] = 0.0;
    381         modelPar[PM_PAR_SYY] = 0.0;
    382         modelPar[PM_PAR_SXY] = 0.0;
    383355        return true;
    384356    }
    385 
    386     psEllipseShape shape = psEllipseAxesToShape (axes);
    387 
    388     bool useReff = false;
    389     useReff |= ( type == pmModelClassGetType ("PS_MODEL_SERSIC"));
    390     useReff |= ( type == pmModelClassGetType ("PS_MODEL_DEV"));
    391     useReff |= ( type == pmModelClassGetType ("PS_MODEL_EXP"));
    392 
    393     if (useReff) {
    394         modelPar[PM_PAR_SXX] = shape.sx;
    395         modelPar[PM_PAR_SYY] = shape.sy;
    396         modelPar[PM_PAR_SXY] = shape.sxy * 2.0; // XXX NEED factor of 2 here for correct angle conversion
    397     } else {
    398         modelPar[PM_PAR_SXX] = shape.sx * M_SQRT2;
    399         modelPar[PM_PAR_SYY] = shape.sy * M_SQRT2;
    400         modelPar[PM_PAR_SXY] = shape.sxy;
    401     }
     357   
     358    bool useReff = pmModelUseReff (type);
     359    pmModelAxesToParams (&modelPar[PM_PAR_SXX], &modelPar[PM_PAR_SXY], &modelPar[PM_PAR_SYY], axes, useReff);
    402360    return true;
    403361}
     
    423381    par->data.F32[PM_PAR_SXY] = sxy;
    424382
    425     psEllipsePol pol = pmPSF_ModelToFit(par->data.F32);
     383    bool useReff = pmModelUseReff (options->type);
     384    psEllipsePol pol = pmPSF_ModelToFit(par->data.F32, useReff);
    426385
    427386    pmTrend2D *trend = NULL;
  • trunk/psModules/src/objects/pmPSF.h

    r32347 r35768  
    107107
    108108bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes, pmModelType type);
    109 bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis);
     109bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis, bool useReff);
    110110
    111 psEllipsePol pmPSF_ModelToFit (psF32 *modelPar);
    112 psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR, pmModelType type);
     111psEllipsePol pmPSF_ModelToFit (psF32 *modelPar, bool useReff);
     112psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, pmModelType type);
    113113
    114114/// Calculate FWHM value from a PSF
  • trunk/psModules/src/objects/pmPSFtry.h

    r30044 r35768  
    9999/** fit EXT models to all possible psf sources */
    100100bool pmPSFtryFitEXT (pmPSFtry *psfTry, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal);
     101bool pmPSFtryFitEXT_Threaded (psThreadJob *job);
    101102
    102103bool pmPSFtryMakePSF (bool *pGoodFit, pmPSFtry *psfTry);
    103104
    104105bool pmPSFtryFitPSF (pmPSFtry *psfTry, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal);
     106bool pmPSFtryFitPSF_Threaded (psThreadJob *job);
     107
     108bool pmPSFThreads (void);
    105109
    106110/** pmPSFtryMetric()
  • trunk/psModules/src/objects/pmPSFtryFitEXT.c

    r35560 r35768  
    4646#include "pmSourceVisual.h"
    4747
     48bool pmPSFThreads (void) {
     49
     50    psThreadTask *task = NULL;
     51
     52    task = psThreadTaskAlloc("PSF_TRY_FIT_EXT", 6);
     53    task->function = &pmPSFtryFitEXT_Threaded;
     54    psThreadTaskAdd(task);
     55    psFree(task);
     56
     57    task = psThreadTaskAlloc("PSF_TRY_FIT_PSF", 6);
     58    task->function = &pmPSFtryFitPSF_Threaded;
     59    psThreadTaskAdd(task);
     60    psFree(task);
     61
     62    return true;
     63}
     64
     65static int Next = 0;
     66
    4867// Fit an EXT model to all candidates PSF sources.
    4968// Note: this is independent of the modeled 2D variations in the PSF.
    5069bool pmPSFtryFitEXT (pmPSFtry *psfTry, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal) {
    51 
    52     bool status;
    5370
    5471    psTimerStart ("psf.fit");
     
    6077    maskVal |= markVal;
    6178
    62     int Next = 0;
     79    Next = 0;
    6380    for (int i = 0; i < psfTry->sources->n; i++) {
    6481
    6582        pmSource *source = psfTry->sources->data[i];
    66         if (!source->moments) {
    67             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
    68             psTrace ("psModules.objects", 4, "masking %d (%d,%d) : no moments\n", i, source->peak->x, source->peak->y);
    69             continue;
    70         }
    71         if (!source->moments->nPixels) {
    72             psTrace ("psModules.objects", 4, "masking %d (%d,%d) : no pixels\n", i, source->peak->x, source->peak->y);
    73             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
    74             continue;
    75         }
    76         // If mask object does not exist, mark the source as bad.
    77         // We cannot proceed with it because psImageMaskPixels leaves an uncleared error code last which causes
    78         // psphot to exit with a fault.
    79         if (source->maskObj == NULL) {
    80             psTrace ("psModules.objects", 4, "source %d (%d,%d) : null maskObj\n", i, source->peak->x, source->peak->y);
    81             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
    82             continue;
    83         }
    8483
    85         source->modelEXT = pmSourceModelGuess (source, options->type, maskVal, markVal);
    86         if (source->modelEXT == NULL) {
    87             psTrace ("psModules.objects", 4, "masking %d (%d,%d) : failed to generate model guess\n", i, source->peak->x, source->peak->y);
    88             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
    89             continue;
    90         }
     84        if (!source->moments) {
     85            psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
     86            psTrace ("psModules.objects", 4, "masking %d (%d,%d) : no moments\n", i, source->peak->x, source->peak->y);
     87            continue;
     88        }
     89        if (!source->moments->nPixels) {
     90            psTrace ("psModules.objects", 4, "masking %d (%d,%d) : no pixels\n", i, source->peak->x, source->peak->y);
     91            psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
     92            continue;
     93        }
     94        // If mask object does not exist, mark the source as bad.
     95        // We cannot proceed with it because psImageMaskPixels leaves an uncleared error code last which causes
     96        // psphot to exit with a fault.
     97        if (source->maskObj == NULL) {
     98            psTrace ("psModules.objects", 4, "source %d (%d,%d) : null maskObj\n", i, source->peak->x, source->peak->y);
     99            psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
     100            continue;
     101        }
    91102
    92         // set object mask to define valid pixels
    93         // XXX 0.5 PIX: is the circle symmetric about the peak coordinate (given 0.5,0.5 center)?
    94         psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->fitRadius, "OR", markVal);
     103        source->modelEXT = pmSourceModelGuess (source, options->type, maskVal, markVal);
     104        if (source->modelEXT == NULL) {
     105            psTrace ("psModules.objects", 4, "masking %d (%d,%d) : failed to generate model guess\n", i, source->peak->x, source->peak->y);
     106            psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
     107            continue;
     108        }
    95109
    96         // fit model as EXT, not PSF
    97         status = pmSourceFitModel (source, source->modelEXT, options->fitOptions, maskVal);
     110        // do some actual work on this source
     111        psThreadJob *job = psThreadJobAlloc ("PSF_TRY_FIT_EXT");
     112        psArrayAdd(job->args, 1, source);
     113        psArrayAdd(job->args, 1, psfTry);
     114        psArrayAdd(job->args, 1, options);
     115       
     116        PS_ARRAY_ADD_SCALAR(job->args, i,        PS_TYPE_S32);
    98117
    99         // clear object mask to define valid pixels
    100         psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
     118        PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
     119        PS_ARRAY_ADD_SCALAR(job->args, markVal,  PS_TYPE_IMAGE_MASK);
    101120
    102         // exclude the poor fits
    103         if (!status) {
    104             psTrace ("psModules.objects", 4, "masking %d (%d,%d) : status is poor\n", i, source->peak->x, source->peak->y);
    105             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
    106             continue;
    107         }
    108         Next ++;
     121# if (1)
     122        if (!psThreadJobAddPending(job)) {
     123            psError(PS_ERR_UNKNOWN, false, "Unable to create psf model.");
     124            return false;
     125        }
     126# else
     127        if (!pmPSFtryFitEXT_Threaded(job)) {
     128            psError(PS_ERR_UNKNOWN, false, "Unable to create psf model.");
     129            return false;
     130        }
     131        psFree(job);
     132# endif
    109133    }
     134
     135    // wait for the threads to finish and manage results
     136    if (!psThreadPoolWait (false, true)) {
     137        psError(PS_ERR_UNKNOWN, false, "failure to model psf");
     138        return false;
     139    }
     140
     141    // we have only supplied one type of job, so we can assume the types here
     142    psThreadJob *job = NULL;
     143    while ((job = psThreadJobGetDone()) != NULL) {
     144        // we have no returned data from this operation
     145        if (job->args->n < 1) fprintf (stderr, "error with job\n");
     146        psFree(job);
     147    }
     148
    110149    psLogMsg ("psphot.psftry", PS_LOG_MINUTIA, "fit ext:   %f sec for %d of %ld sources\n", psTimerMark ("psf.fit"), Next, psfTry->sources->n);
    111150    psTrace ("psModules.object", 3, "keeping %d of %ld PSF candidates (EXT)\n", Next, psfTry->sources->n);
     
    118157    return true;
    119158}
     159
     160bool pmPSFtryFitEXT_Threaded (psThreadJob *job) {
     161
     162    pmSource *source =      job->args->data[0];
     163    pmPSFtry *psfTry =      job->args->data[1];
     164    pmPSFOptions *options = job->args->data[2];
     165
     166    int i = PS_SCALAR_VALUE(job->args->data[3], S32);
     167
     168    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
     169    psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA);
     170
     171    // set object mask to define valid pixels
     172    // XXX 0.5 PIX: is the circle symmetric about the peak coordinate (given 0.5,0.5 center)?
     173    psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->fitRadius, "OR", markVal);
     174
     175    // fit model as EXT, not PSF
     176    bool status = pmSourceFitModel (source, source->modelEXT, options->fitOptions, maskVal);
     177
     178    // clear object mask to define valid pixels
     179    psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
     180
     181    // exclude the poor fits
     182    if (!status) {
     183        psTrace ("psModules.objects", 4, "masking %d (%d,%d) : status is poor\n", i, source->peak->x, source->peak->y);
     184        psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_EXT_FAIL;
     185        return true;
     186    }
     187    Next ++;
     188   
     189    return true;
     190}
  • trunk/psModules/src/objects/pmPSFtryFitPSF.c

    r34403 r35768  
    4343#include "pmSourceVisual.h"
    4444
     45static int Npsf = 0;
     46
    4547// stage 3: Refit with fixed shape parameters.  This function uses the LMM fitting, but could
    4648// be re-written to use the simultaneous linear fitting (see psphotFitSourcesLinear.c)
    4749bool pmPSFtryFitPSF (pmPSFtry *psfTry, pmPSFOptions *options, psImageMaskType maskVal, psImageMaskType markVal) {
    4850
    49     bool status;
    50 
    5151    psTimerStart ("psf.fit");
    5252
     
    5757    maskVal |= markVal;
    5858
    59     // DEBUG code: save the PSF model fit data in detail
    60 # ifdef DEBUG
    61     char filename[64];
    62     snprintf (filename, 64, "psffit.%dx%d.dat", psfTry->psf->trendNx, psfTry->psf->trendNy);
    63     FILE *f = fopen (filename, "w");
    64     psAssert (f, "failed open");
    65 # endif
    66 
    67     int Npsf = 0;
     59    Npsf = 0;
    6860    for (int i = 0; i < psfTry->sources->n; i++) {
    6961
     
    7769        }
    7870
    79         // set shape for this model based on PSF
     71        // set shape for this model based on PSF
    8072        psFree (source->modelPSF);
    81         source->modelPSF = pmModelFromPSF (source->modelEXT, psfTry->psf);
    82         if (source->modelPSF == NULL) {
    83             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_BAD_MODEL;
    84             psTrace ("psModules.objects", 4, "dropping %d (%d,%d) : bad PSF fit\n", i, source->peak->x, source->peak->y);
    85             continue;
    86         }
    87         // PSF fit and aperture mags use different radii
    88         source->modelPSF->fitRadius = options->fitRadius;
    89         source->apRadius = options->apRadius;
    90 
    91         // set object mask to define valid pixels for PSF model fit
    92         psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->fitRadius, "OR", markVal);
    93 
    94         // fit the PSF model to the source
    95         status = pmSourceFitModel (source, source->modelPSF, options->fitOptions, maskVal);
    96 
    97         // skip poor fits
    98         if (!status) {
    99             psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
    100             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_PSF_FAIL;
    101             psTrace ("psModules.objects", 4, "dropping %d (%d,%d) : failed PSF fit\n", i, source->peak->x, source->peak->y);
    102             continue;
    103         }
    104 
    105         // set object mask to define valid pixels for APERTURE magnitude
    106         if (options->fitRadius != options->apRadius) {
    107             psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
    108             psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->apRadius, "OR", markVal);
     73        source->modelPSF = pmModelFromPSF (source->modelEXT, psfTry->psf);
     74        if (source->modelPSF == NULL) {
     75            psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_BAD_MODEL;
     76            psTrace ("psModules.objects", 4, "dropping %d (%d,%d) : bad PSF fit\n", i, source->peak->x, source->peak->y);
     77            return false;
    10978        }
    11079
    111         // This function calculates the psf and aperture magnitudes
    112         status = pmSourceMagnitudes (source, psfTry->psf, PM_SOURCE_PHOT_INTERP, maskVal, markVal, options->apRadius); // raw PSF mag, AP mag
    113         if (!status || isnan(source->apMag)) {
    114             psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
    115             psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_BAD_PHOT;
    116             psTrace ("psModules.objects", 4, "dropping %d (%d,%d) : poor photometry\n", i, source->peak->x, source->peak->y);
    117             continue;
    118         }
    119 
    120         // clear object mask to define valid pixels
    121         psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
    122 
    123         psfTry->fitMag->data.F32[i] = source->psfMag;
    124         psfTry->metric->data.F32[i] = source->apMag - source->psfMag;
    125         psfTry->metricErr->data.F32[i] = source->psfMagErr;
    126 
    127         // XXX this did not work: modifies shape of psf too much
    128         // psfTry->metric->data.F32[i] = -2.5*log10(source->moments->Sum) - source->psfMag;
    129 
     80        // do some actual work on this source
     81        psThreadJob *job = psThreadJobAlloc ("PSF_TRY_FIT_PSF");
     82        psArrayAdd(job->args, 1, source);
     83        psArrayAdd(job->args, 1, psfTry);
     84        psArrayAdd(job->args, 1, options);
     85       
     86        PS_ARRAY_ADD_SCALAR(job->args, i,        PS_TYPE_S32);
     87
     88        PS_ARRAY_ADD_SCALAR(job->args, maskVal,  PS_TYPE_IMAGE_MASK);
     89        PS_ARRAY_ADD_SCALAR(job->args, markVal,  PS_TYPE_IMAGE_MASK);
     90
     91# if (1)
     92        if (!psThreadJobAddPending(job)) {
     93            psError(PS_ERR_UNKNOWN, false, "Unable to create psf model.");
     94            return false;
     95        }
     96# else
     97        if (!pmPSFtryFitPSF_Threaded(job)) {
     98            psError(PS_ERR_UNKNOWN, false, "Unable to create psf model.");
     99            return false;
     100        }
     101        psFree(job);
     102# endif
     103    }
     104
     105    // wait for the threads to finish and manage results
     106    if (!psThreadPoolWait (false, true)) {
     107        psError(PS_ERR_UNKNOWN, false, "failure to model psf");
     108        return false;
     109    }
     110
     111    // we have only supplied one type of job, so we can assume the types here
     112    psThreadJob *job = NULL;
     113    while ((job = psThreadJobGetDone()) != NULL) {
     114        // we have no returned data from this operation
     115        if (job->args->n < 1) fprintf (stderr, "error with job\n");
     116        psFree(job);
     117    }
     118    psfTry->psf->nPSFstars = Npsf;
     119
     120    // DEBUG code: save the PSF model fit data in detail
    130121# ifdef DEBUG
     122
     123    char filename[64];
     124    snprintf (filename, 64, "psffit.%dx%d.dat", psfTry->psf->trendNx, psfTry->psf->trendNy);
     125    FILE *f = fopen (filename, "w");
     126    psAssert (f, "failed open");
     127
     128    for (int i = 0; i < psfTry->sources->n; i++) {
     129
     130        // skip masked sources
     131        if (psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] & PSFTRY_MASK_ALL) continue;
     132
     133        pmSource *source = psfTry->sources->data[i];
     134
    131135        fprintf (f, "%6.1f %6.1f : %6.1f %6.1f : %8.3f %8.3f %8.3f : %f : %f %f %f : %f\n",
    132136                 source->peak->xf, source->peak->yf,
     
    136140                 source->modelPSF->params->data.F32[PM_PAR_SXX], source->modelPSF->params->data.F32[PM_PAR_SXY],
    137141                 source->modelPSF->params->data.F32[PM_PAR_SYY], source->modelPSF->params->data.F32[PM_PAR_7]);
    138 # endif
    139 
    140         psTrace ("psModules.object", 6, "keeping source %d (%d) of %ld\n", i, Npsf, psfTry->sources->n);
    141         Npsf ++;
    142     }
    143     psfTry->psf->nPSFstars = Npsf;
    144 
    145 # ifdef DEBUG
     142    }
    146143    fclose (f);
    147144# endif
     
    159156    return true;
    160157}
     158
     159bool pmPSFtryFitPSF_Threaded (psThreadJob *job) {
     160
     161    pmSource *source =      job->args->data[0];
     162    pmPSFtry *psfTry =      job->args->data[1];
     163    pmPSFOptions *options = job->args->data[2];
     164
     165    int i = PS_SCALAR_VALUE(job->args->data[3], S32);
     166
     167    psImageMaskType maskVal = PS_SCALAR_VALUE(job->args->data[4],PS_TYPE_IMAGE_MASK_DATA);
     168    psImageMaskType markVal = PS_SCALAR_VALUE(job->args->data[5],PS_TYPE_IMAGE_MASK_DATA);
     169
     170    // PSF fit and aperture mags use different radii
     171    source->modelPSF->fitRadius = options->fitRadius;
     172    source->apRadius            = options->apRadius;
     173
     174    // set object mask to define valid pixels for PSF model fit
     175    psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->fitRadius, "OR", markVal);
     176
     177    // fit the PSF model to the source
     178    bool status = pmSourceFitModel (source, source->modelPSF, options->fitOptions, maskVal);
     179
     180    // skip poor fits
     181    if (!status) {
     182        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
     183        psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_PSF_FAIL;
     184        psTrace ("psModules.objects", 4, "dropping %d (%d,%d) : failed PSF fit\n", i, source->peak->x, source->peak->y);
     185        return true;
     186    }
     187
     188    // set object mask to define valid pixels for APERTURE magnitude
     189    if (options->fitRadius != options->apRadius) {
     190        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
     191        psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->apRadius, "OR", markVal);
     192    }
     193
     194    // This function calculates the psf and aperture magnitudes
     195    status = pmSourceMagnitudes (source, psfTry->psf, PM_SOURCE_PHOT_INTERP, maskVal, markVal, options->apRadius); // raw PSF mag, AP mag
     196    psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
     197
     198    if (!status || isnan(source->apMag)) {
     199        psfTry->mask->data.PS_TYPE_VECTOR_MASK_DATA[i] = PSFTRY_MASK_BAD_PHOT;
     200        psTrace ("psModules.objects", 4, "dropping %d (%d,%d) : poor photometry\n", i, source->peak->x, source->peak->y);
     201        return true;
     202    }
     203
     204    psfTry->fitMag->data.F32[i] = source->psfMag;
     205    psfTry->metric->data.F32[i] = source->apMag - source->psfMag;
     206    psfTry->metricErr->data.F32[i] = source->psfMagErr;
     207
     208    psTrace ("psModules.object", 6, "keeping source %d (%d) of %ld\n", i, Npsf, psfTry->sources->n);
     209    Npsf ++;
     210    return true;
     211}
  • trunk/psModules/src/objects/pmPSFtryMakePSF.c

    r34403 r35768  
    165165
    166166            for (int i = 0; i < psf->params->n; i++) {
    167                 if (psf->params->data[i] == NULL) {
    168                     psFree(modelPSF);
    169                     continue;
    170                 }
     167                if (psf->params->data[i] == NULL) continue;
    171168                fprintf (f, "%f %f : ", source->modelEXT->params->data.F32[i], modelPSF->params->data.F32[i]);
    172169            }
     
    214211        assert (source->modelEXT); // all unmasked sources should have modelEXT
    215212
    216         psEllipsePol pol = pmPSF_ModelToFit (source->modelEXT->params->data.F32);
     213        bool useReff = pmModelUseReff (source->modelEXT->type);
     214        psEllipsePol pol = pmPSF_ModelToFit (source->modelEXT->params->data.F32, useReff);
    217215
    218216        e0->data.F32[i] = pol.e0;
  • trunk/psModules/src/objects/pmSource.c

    r34403 r35768  
    11451145    bool status;
    11461146    psEllipseShape oldshape;
    1147     psEllipseShape newshape;
    11481147    psEllipseAxes axes;
    11491148
     
    11661165    if (!isfinite(oldI0)) return false;
    11671166
     1167    bool useReff = pmModelUseReff (model->type);
     1168    pmModelParamsToAxes (&axes, PAR[PM_PAR_SXX], PAR[PM_PAR_SXY], PAR[PM_PAR_SYY], useReff);
     1169
    11681170    // increase size and height of source
    1169     axes = psEllipseShapeToAxes (oldshape, 20.0);
    11701171    axes.major *= SIZE;
    11711172    axes.minor *= SIZE;
    1172     newshape = psEllipseAxesToShape (axes);
     1173
     1174    pmModelAxesToParams (&PAR[PM_PAR_SXX], &PAR[PM_PAR_SXY], &PAR[PM_PAR_SYY], axes, useReff);
    11731175    PAR[PM_PAR_I0]  = FACTOR*oldI0;
    1174     PAR[PM_PAR_SXX] = newshape.sx;
    1175     PAR[PM_PAR_SYY] = newshape.sy;
    1176     PAR[PM_PAR_SXY] = newshape.sxy;
    11771176
    11781177    psImage *target = source->variance;
  • trunk/psModules/src/objects/pmSourceFitModel.c

    r35560 r35768  
    6262    opt->poissonErrors = true;
    6363    opt->saveCovariance = false;
     64
     65    // we default to the old algorithm
     66    opt->gainFactorMode = 0;
     67    opt->chisqConvergence = true;
    6468
    6569    return opt;
     
    241245
    242246    psMinimization *myMin = psMinimizationAlloc (options->nIter, options->minTol, options->maxTol);
     247    myMin->gainFactorMode = options->gainFactorMode;
     248    myMin->chisqConvergence = options->chisqConvergence;
    243249
    244250    psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32);
     
    252258    }
    253259    if (options->saveCovariance) {
     260        psFree (model->covar);
    254261        model->covar = psMemIncrRefCounter(covar);
    255262    }
     
    273280    model->flags |= PM_MODEL_STATUS_FITTED;
    274281    if (!fitStatus) model->flags |= PM_MODEL_STATUS_NONCONVERGE;
    275     if (myMin->lastDelta > myMin->minTol) model->flags |= PM_MODEL_STATUS_WEAK_FIT;
     282
     283    if (myMin->chisqConvergence) {
     284      if (myMin->lastDelta > myMin->minTol) model->flags |= PM_MODEL_STATUS_WEAK_FIT;
     285    } else {
     286      if (myMin->rParSigma > myMin->minTol*nParams) model->flags |= PM_MODEL_STATUS_WEAK_FIT;
     287    }
    276288
    277289    // get the Gauss-Newton distance for fixed model parameters
  • trunk/psModules/src/objects/pmSourceFitModel.h

    r34259 r35768  
    3535    bool poissonErrors;                 ///< use poisson errors for fits?
    3636    bool saveCovariance;
     37    int gainFactorMode;
     38    bool chisqConvergence;
    3739} pmSourceFitOptions;
    3840
  • trunk/psModules/src/objects/pmSourceFitPCM.c

    r35560 r35768  
    6666    // set up the minimization process
    6767    psMinimization *myMin = psMinimizationAlloc (fitOptions->nIter, fitOptions->minTol, fitOptions->maxTol);
     68    myMin->chisqConvergence = fitOptions->chisqConvergence;
     69    myMin->gainFactorMode = fitOptions->gainFactorMode;
    6870
    6971    psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32);
     
    118120    if (!fitStatus) pcm->modelConv->flags |= PM_MODEL_STATUS_NONCONVERGE;
    119121
     122    if (myMin->chisqConvergence) {
     123      if (myMin->lastDelta > myMin->minTol) pcm->modelConv->flags |= PM_MODEL_STATUS_WEAK_FIT;
     124    } else {
     125      if (myMin->rParSigma > myMin->minTol*pcm->nPar) pcm->modelConv->flags |= PM_MODEL_STATUS_WEAK_FIT;
     126    }
     127
    120128    // once we have fitted a model, we need to record that this model is a PCM model:
    121129    pcm->modelConv->isPCM = true;
     
    145153bool pmSourceModelGuessPCM (pmPCMdata *pcm, pmSource *source, psImageMaskType maskVal, psImageMaskType markVal) {
    146154
    147   if (!pcm->modelConv->modelGuess(pcm->modelConv, source, maskVal, markVal)) {
     155    if (!pcm->modelConv->modelGuess(pcm->modelConv, source, maskVal, markVal)) {
    148156        return false;
    149157    }
    150158    return true;
    151159
     160    // the following was an attempt to make analytical modifications to the shape terms based on the psf
     161    // this has been replaced with a more empirical approach
     162# if (0)
    152163    // generate copy of the model
    153164    // XXX we could modify the parameter values or even the model
     
    196207
    197208    return true;
     209# endif
    198210}
  • trunk/psModules/src/objects/pmSourceFitSet.c

    r34403 r35768  
    568568
    569569    psMinimization *myMin = psMinimizationAlloc (options->nIter, options->minTol, options->maxTol);
     570    myMin->gainFactorMode = options->gainFactorMode;
     571    myMin->chisqConvergence = options->chisqConvergence;
    570572
    571573    psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32);
  • trunk/psModules/src/objects/pmSourceIO_CMF.c.in

    r35610 r35768  
    925925                    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_THETA_ERR",     0, "EXT angle err (SXY, isnan)", dPAR[PM_PAR_SXY]);
    926926                } else {
    927                     psEllipseAxes axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     927                    psEllipseAxes axes = pmPSF_ModelToAxes (PAR, model->type);
    928928                    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MAJ",    0, "EXT width (major axis), length for trail", axes.major);
    929929                    psMetadataAddF32 (row, PS_LIST_TAIL, "EXT_WIDTH_MIN",    0, "EXT width (minor axis), sigma for trail",  axes.minor);
  • trunk/psModules/src/objects/pmSourceIO_CMP.c

    r34403 r35768  
    135135        lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky);
    136136
    137         axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     137        axes = pmPSF_ModelToAxes (PAR, model->type);
    138138
    139139        float psfMagErr = isfinite(source->psfMagErr) ? source->psfMagErr : 999;
  • trunk/psModules/src/objects/pmSourceIO_OBJ.c

    r34403 r35768  
    9292        }
    9393
    94         axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     94        axes = pmPSF_ModelToAxes (PAR, model->type);
    9595
    9696        psLineInit (line);
  • trunk/psModules/src/objects/pmSourceIO_PS1_CAL_0.c

    r34403 r35768  
    114114            yErr = dPAR[PM_PAR_YPOS];
    115115            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
    116                 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     116                axes = pmPSF_ModelToAxes (PAR, model->type);
    117117            } else {
    118118                axes.major = NAN;
     
    623623            yErr = dPAR[PM_PAR_YPOS];
    624624
    625             axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     625            axes = pmPSF_ModelToAxes (PAR, model->type);
    626626
    627627            // generate RA,DEC
  • trunk/psModules/src/objects/pmSourceIO_PS1_DEV_0.c

    r34403 r35768  
    9090            yErr = dPAR[PM_PAR_YPOS];
    9191
    92             axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     92            axes = pmPSF_ModelToAxes (PAR, model->type);
    9393        } else {
    9494            // XXX: This code seg faults if source->peak is NULL.
  • trunk/psModules/src/objects/pmSourceIO_PS1_DEV_1.c

    r34403 r35768  
    9696            yErr = dPAR[PM_PAR_YPOS];
    9797            if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXX])) {
    98                 axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     98                axes = pmPSF_ModelToAxes (PAR, model->type);
    9999            } else {
    100100                axes.major = NAN;
     
    523523            yErr = dPAR[PM_PAR_YPOS];
    524524
    525             axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     525            axes = pmPSF_ModelToAxes (PAR, model->type);
    526526
    527527            row = psMetadataAlloc ();
  • trunk/psModules/src/objects/pmSourceIO_SMPDATA.c

    r34403 r35768  
    9292            lsky = (source->sky < 1.0) ? 0.0 : log10(source->sky);
    9393
    94             axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     94            axes = pmPSF_ModelToAxes (PAR, model->type);
    9595
    9696        } else {
  • trunk/psModules/src/objects/pmSourceIO_SX.c

    r34403 r35768  
    8181        // pmSourceSextractType (source, &type, &flags);
    8282
    83         axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     83        axes = pmPSF_ModelToAxes (PAR, model->type);
    8484
    8585        psLineInit (line);
  • trunk/psModules/src/objects/pmSourceOutputs.c

    r34515 r35768  
    107107        }
    108108        if (isfinite(PAR[PM_PAR_SXX]) && isfinite(PAR[PM_PAR_SXY]) && isfinite(PAR[PM_PAR_SYY])) {
    109             axes = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     109            axes = pmPSF_ModelToAxes (PAR, model->type);
    110110            outputs->psfMajor = axes.major;
    111111            outputs->psfMinor = axes.minor;
  • trunk/psModules/src/objects/pmSourcePlotPSFModel.c

    r34403 r35768  
    146146        // force the axis ratio to be < 20.0
    147147        psEllipseAxes axes_mnt = psEllipseMomentsToAxes (moments, 20.0);
    148         psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, 20.0, model->type);
     148        psEllipseAxes axes_psf = pmPSF_ModelToAxes (PAR, model->type);
    149149
    150150        // moments major axis
  • trunk/psModules/src/objects/pmSourceVisual.c

    r34403 r35768  
    4646bool pmSourceVisualClose() {
    4747    if (kapa1 != -1)
    48         KiiClose(kapa1);
     48        KapaClose(kapa1);
    4949    return true;
    5050}
  • trunk/psModules/src/psmodules.h

    r34403 r35768  
    158158#include <pmReadoutFake.h>
    159159#include <pmPSFEnvelope.h>
     160#include <pmThreadTools.h>
    160161
    161162#endif
Note: See TracChangeset for help on using the changeset viewer.