IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 3, 2010, 8:50:52 AM (16 years ago)
Author:
eugene
Message:

updates from trunk

Location:
branches/simtest_nebulous_branches
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/simtest_nebulous_branches

  • branches/simtest_nebulous_branches/psModules

  • branches/simtest_nebulous_branches/psModules/src/objects/models/pmModel_PGAUSS.c

    r20001 r27840  
    11/******************************************************************************
    22 * this file defines the PGAUSS source shape model.  Note that these model functions are loaded
    3  * by pmModelGroup.c using 'include', and thus need no 'include' statements of their own.  The
     3 * by pmModelClass.c using 'include', and thus need no 'include' statements of their own.  The
    44 * models use a psVector to represent the set of parameters, with the sequence used to specify
    55 * the meaning of the parameter.  The meaning of the parameters may thus vary depending on the
    6  * specifics of the model.  All models which are used a PSF representations share a few
     6 * specifics of the model.  All models which are used as a PSF representations share a few
    77 * parameters, for which # define names are listed in pmModel.h:
    88
     
    1919 *****************************************************************************/
    2020
     21#include <stdio.h>
     22#include <pslib.h>
     23
     24#include "pmMoments.h"
     25#include "pmPeaks.h"
     26#include "pmSource.h"
     27#include "pmModel.h"
     28#include "pmModel_PGAUSS.h"
     29
    2130# define PM_MODEL_FUNC            pmModelFunc_PGAUSS
    2231# define PM_MODEL_FLUX            pmModelFlux_PGAUSS
     
    2736# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_PGAUSS
    2837# define PM_MODEL_FIT_STATUS      pmModelFitStatus_PGAUSS
     38# define PM_MODEL_SET_LIMITS      pmModelSetLimits_PGAUSS
     39
     40// Lax parameter limits
     41static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0 };
     42static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0 };
     43
     44// Moderate parameter limits
     45static float *paramsMinModerate = paramsMinLax;
     46static float *paramsMaxModerate = paramsMaxLax;
     47
     48// Strict parameter limits
     49static float *paramsMinStrict = paramsMinLax;
     50static float *paramsMaxStrict = paramsMaxLax;
     51
     52// Parameter limits to use
     53static float *paramsMinUse = paramsMinLax;
     54static float *paramsMaxUse = paramsMaxLax;
     55static float betaUse[] = { 1000, 3e6, 5, 5, 2.0, 2.0, 0.5 };
     56
     57static bool limitsApply = true;         // Apply limits?
    2958
    3059// the model is a function of the pixel coordinate (pixcoord[0,1] = x,y)
     60// 0.5 PIX: the parameters are defined in terms of pixel coords, so the incoming pixcoords
     61// values need to be pixel coords
    3162psF32 PM_MODEL_FUNC(psVector *deriv,
    3263                    const psVector *params,
     
    69100bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
    70101{
    71     float beta_lim = 0, params_min = 0, params_max = 0;
    72     float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
     102    if (!limitsApply) {
     103        return true;
     104    }
     105    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
    73106
    74107    // we need to calculate the limits for SXY specially
     108    float q2 = NAN;
    75109    if (nParam == PM_PAR_SXY) {
    76         f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
    77         f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
    78         q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
    79         q1 = PS_MAX (0.0, q1);
     110        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
     111        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
     112        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
     113        q1 = (q1 < 0.0) ? 0.0 : q1;
    80114        // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
    81115        // angle and let f2,f1 fight it out
    82         q2  = 0.5*sqrt (q1);
     116        q2 = 0.5*sqrtf(q1);
    83117    }
    84118
    85119    switch (mode) {
    86     case PS_MINIMIZE_BETA_LIMIT:
    87         switch (nParam) {
    88         case PM_PAR_SKY:
    89             beta_lim = 1000;
    90             break;
    91         case PM_PAR_I0:
    92             beta_lim = 3e6;
    93             break;
    94         case PM_PAR_XPOS:
    95             beta_lim = 5;
    96             break;
    97         case PM_PAR_YPOS:
    98             beta_lim = 5;
    99             break;
    100         case PM_PAR_SXX:
    101             beta_lim = 2.0;
    102             break;
    103         case PM_PAR_SYY:
    104             beta_lim = 2.0;
    105             break;
    106         case PM_PAR_SXY:
    107             beta_lim =  0.5*q2;
    108             break;
    109         default:
    110             psAbort("invalid parameter %d for beta test", nParam);
    111         }
    112         if (fabs(beta[nParam]) > fabs(beta_lim)) {
    113             beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
    114             psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
    115                      nParam, beta[nParam], beta_lim);
    116             return false;
    117         }
    118         return true;
    119     case PS_MINIMIZE_PARAM_MIN:
    120         switch (nParam) {
    121         case PM_PAR_SKY:
    122             params_min = -1000;
    123             break;
    124         case PM_PAR_I0:
    125             params_min =  0.01;
    126             break;
    127         case PM_PAR_XPOS:
    128             params_min =  -100;
    129             break;
    130         case PM_PAR_YPOS:
    131             params_min =  -100;
    132             break;
    133         case PM_PAR_SXX:
    134             params_min =   0.5;
    135             break;
    136         case PM_PAR_SYY:
    137             params_min =   0.5;
    138             break;
    139         case PM_PAR_SXY:
    140             params_min =   -q2;
    141             break;
    142         default:
    143             psAbort("invalid parameter %d for param min test", nParam);
    144         }
    145         if (params[nParam] < params_min) {
    146             params[nParam] = params_min;
    147             psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
    148                      nParam, params[nParam], params_min);
    149             return false;
    150         }
    151         return true;
    152     case PS_MINIMIZE_PARAM_MAX:
    153         switch (nParam) {
    154         case PM_PAR_SKY:
    155             params_max =   1e5;
    156             break;
    157         case PM_PAR_I0:
    158             params_max =   1e8;
    159             break;
    160         case PM_PAR_XPOS:
    161             params_max =   1e4;
    162             break;
    163         case PM_PAR_YPOS:
    164             params_max =   1e4;
    165             break;
    166         case PM_PAR_SXX:
    167             params_max =   100;
    168             break;
    169         case PM_PAR_SYY:
    170             params_max =   100;
    171             break;
    172         case PM_PAR_SXY:
    173             params_max =   +q2;
    174             break;
    175         default:
    176             psAbort("invalid parameter %d for param max test", nParam);
    177         }
    178         if (params[nParam] > params_max) {
    179             params[nParam] = params_max;
    180             psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
    181                      nParam, params[nParam], params_max);
    182             return false;
    183         }
    184         return true;
    185     default:
     120      case PS_MINIMIZE_BETA_LIMIT: {
     121          psAssert(beta, "Require beta to limit beta");
     122          float limit = betaUse[nParam];
     123          if (nParam == PM_PAR_SXY) {
     124              limit *= q2;
     125          }
     126          if (fabs(beta[nParam]) > fabs(limit)) {
     127              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
     128              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
     129                      nParam, beta[nParam], limit);
     130              return false;
     131          }
     132          return true;
     133      }
     134      case PS_MINIMIZE_PARAM_MIN: {
     135          psAssert(params, "Require parameters to limit parameters");
     136          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
     137          float limit = paramsMinUse[nParam];
     138          if (nParam == PM_PAR_SXY) {
     139              limit *= q2;
     140          }
     141          if (params[nParam] < limit) {
     142              params[nParam] = limit;
     143              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
     144                      nParam, params[nParam], limit);
     145              return false;
     146          }
     147          return true;
     148      }
     149      case PS_MINIMIZE_PARAM_MAX: {
     150          psAssert(params, "Require parameters to limit parameters");
     151          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
     152          float limit = paramsMaxUse[nParam];
     153          if (nParam == PM_PAR_SXY) {
     154              limit *= q2;
     155          }
     156          if (params[nParam] > limit) {
     157              params[nParam] = limit;
     158              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
     159                      nParam, params[nParam], limit);
     160              return false;
     161          }
     162          return true;
     163      }
     164      default:
    186165        psAbort("invalid choice for limits");
    187166    }
     
    190169}
    191170
     171
    192172// make an initial guess for parameters
     173// 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
    193174bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
    194175{
     
    205186    psEllipseShape shape = psEllipseAxesToShape (axes);
    206187
    207     PAR[PM_PAR_SKY]  = moments->Sky;
     188    PAR[PM_PAR_SKY]  = 0.0;
    208189    PAR[PM_PAR_I0]   = peak->flux;
    209190    PAR[PM_PAR_XPOS] = peak->xf;
     
    255236psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux)
    256237{
    257     psF64 z, f;
     238    psF64 z;
    258239    int Nstep = 0;
    259240    psEllipseShape shape;
     
    284265    // choose a z value guaranteed to be beyond our limit
    285266    float z0 = pow((1.0 / limit), (1.0 / 3.0));
     267    psAssert (isfinite(z0), "fix this code: z0 should not be nan for %f", PAR[PM_PAR_I0]);
    286268    float z1 = (1.0 / limit);
     269    psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_I0]);
    287270    z1 = PS_MAX (z0, z1);
    288271    z0 = 0.0;
    289272
    290     // perform a type of bisection to find the value
    291     float f0 = 1.0 / (1 + z0 + z0*z0/2.0 + z0*z0*z0/6.0);
    292     float f1 = 1.0 / (1 + z1 + z1*z1/2.0 + z1*z1*z1/6.0);
    293     while ((Nstep < 10) && (fabs(z1 - z0) > 0.5)) {
    294         z = 0.5*(z0 + z1);
    295         f = 1.0 / (1 + z + z*z/2.0 + z*z*z/6.0);
    296         if (f > limit) {
    297             z0 = z;
    298             f0 = f;
    299         } else {
    300             z1 = z;
    301             f1 = f;
    302         }
    303         Nstep ++;
    304     }
     273    // starting guess:
     274    z = 0.5*(z0 + z1);
     275    float dz = 1.0;
     276
     277    for (int i = 0; (i < 10) && (fabs(dz) > 0.0001); i++) {
     278        // use Newton-Raphson to minimize f(z) - limit = 0
     279        float dqdz = (1.0 + z + z*z/2.0);
     280        float q = (dqdz + z*z*z/6.0);
     281
     282        float f = 1.0 / q;
     283        float dfdz = -dqdz * f / q;
     284
     285        dz = (f - limit) / dfdz;
     286
     287        // fprintf (stderr, "%f %f %f : %f %f\n", f, z, dz, dfdz, q);
     288        z -= dz;
     289        z = PS_MAX(z, 0.0);
     290    }
     291
    305292    psF64 radius = sigma * sqrt (2.0 * z);
    306293
     
    415402bool PM_MODEL_FIT_STATUS (pmModel *model)
    416403{
    417     psF32 dP;
    418404    bool  status;
    419405
     
    421407    psF32 *dPAR = model->dparams->data.F32;
    422408
    423     dP = 0;
    424     dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]);
    425     dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]);
    426     dP = sqrt (dP);
    427 
    428409    status = true;
    429     status &= (dP < 0.5);
    430410    status &= (PAR[PM_PAR_I0] > 0);
    431411    status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5);
    432412
    433413    return status;
     414}
     415
     416
     417void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
     418{
     419    switch (type) {
     420      case PM_MODEL_LIMITS_NONE:
     421        paramsMinUse = NULL;
     422        paramsMaxUse = NULL;
     423        limitsApply = true;
     424        break;
     425      case PM_MODEL_LIMITS_IGNORE:
     426        paramsMinUse = NULL;
     427        paramsMaxUse = NULL;
     428        limitsApply = false;
     429        break;
     430      case PM_MODEL_LIMITS_LAX:
     431        paramsMinUse = paramsMinLax;
     432        paramsMaxUse = paramsMaxLax;
     433        limitsApply = true;
     434        break;
     435      case PM_MODEL_LIMITS_MODERATE:
     436        paramsMinUse = paramsMinModerate;
     437        paramsMaxUse = paramsMaxModerate;
     438        limitsApply = true;
     439        break;
     440      case PM_MODEL_LIMITS_STRICT:
     441        paramsMinUse = paramsMinStrict;
     442        paramsMaxUse = paramsMaxStrict;
     443        limitsApply = true;
     444        break;
     445      default:
     446        psAbort("Unrecognised model limits type: %x", type);
     447    }
     448    return;
    434449}
    435450
     
    442457# undef PM_MODEL_PARAMS_FROM_PSF
    443458# undef PM_MODEL_FIT_STATUS
     459# undef PM_MODEL_SET_LIMITS
Note: See TracChangeset for help on using the changeset viewer.