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_RGAUSS.c

    r20001 r27840  
    11/******************************************************************************
    22 * this file defines the RGAUSS source shape model (XXX need a better name!).  Note that these
    3  * model functions are loaded by pmModelGroup.c using 'include', and thus need no 'include'
     3 * model functions are loaded by pmModelClass.c using 'include', and thus need no 'include'
    44 * statements of their own.  The models use a psVector to represent the set of parameters, with
    55 * 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
     6 * may thus vary depending on the specifics of the model.  All models which are used as a PSF
    77 * representations share a few parameters, for which # define names are listed in pmModel.h:
    88
     
    2020 *****************************************************************************/
    2121
     22#include <stdio.h>
     23#include <pslib.h>
     24
     25#include "pmMoments.h"
     26#include "pmPeaks.h"
     27#include "pmSource.h"
     28#include "pmModel.h"
     29#include "pmModel_RGAUSS.h"
     30
    2231# define PM_MODEL_FUNC            pmModelFunc_RGAUSS
    2332# define PM_MODEL_FLUX            pmModelFlux_RGAUSS
     
    2837# define PM_MODEL_PARAMS_FROM_PSF pmModelParamsFromPSF_RGAUSS
    2938# define PM_MODEL_FIT_STATUS      pmModelFitStatus_RGAUSS
     39# define PM_MODEL_SET_LIMITS      pmModelSetLimits_RGAUSS
     40
     41// the model is a function of the pixel coordinate (pixcoord[0,1] = x,y)
     42// 0.5 PIX: the parameters are defined in terms of pixel coords, so the incoming pixcoords
     43// values need to be pixel coords
     44
     45// Lax parameter limits
     46static float paramsMinLax[] = { -1.0e3, 1.0e-2, -100, -100, 0.5, 0.5, -1.0, 1.25 };
     47static float paramsMaxLax[] = { 1.0e5, 1.0e8, 1.0e4, 1.0e4, 100, 100, 1.0, 4.0 };
     48
     49// Moderate parameter limits
     50static float *paramsMinModerate = paramsMinLax;
     51static float *paramsMaxModerate = paramsMaxLax;
     52
     53// Strict parameter limits
     54static float *paramsMinStrict = paramsMinLax;
     55static float *paramsMaxStrict = paramsMaxLax;
     56
     57// Parameter limits to use
     58static float *paramsMinUse = paramsMinLax;
     59static float *paramsMaxUse = paramsMaxLax;
     60static float betaUse[] = { 1000, 3e6, 5, 5, 0.5, 0.5, 0.5, 0.5 };
     61
     62static bool limitsApply = true;         // Apply limits?
    3063
    3164psF32 PM_MODEL_FUNC (psVector *deriv,
     
    6295        dPAR[PM_PAR_SXY] = -q*X*Y;
    6396
    64         // this model derivative is undefined at z = 0.0, but is actually 0.0
     97        // this model derivative is undefined at z = 0.0, but the limit is zero as z -> 0.0
    6598        dPAR[PM_PAR_7] = (z == 0.0) ? 0.0 : -5.0*t*log(z)*p*z;
    6699    }
     
    73106# define AR_MAX 20.0
    74107# define AR_RATIO 0.99
     108
    75109bool PM_MODEL_LIMITS (psMinConstraintMode mode, int nParam, float *params, float *beta)
    76110{
    77     float beta_lim = 0, params_min = 0, params_max = 0;
    78     float f1 = 0, f2 = 0, q1 = 0, q2 = 0;
     111    if (!limitsApply) {
     112        return true;
     113    }
     114    psAssert(nParam >= 0 && nParam <= PM_PAR_7, "Parameter index is out of bounds");
    79115
    80116    // we need to calculate the limits for SXY specially
     117    float q2 = NAN;
    81118    if (nParam == PM_PAR_SXY) {
    82         f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
    83         f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
    84         q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
     119        float f1 = 1.0 / PS_SQR(params[PM_PAR_SYY]) + 1.0 / PS_SQR(params[PM_PAR_SXX]);
     120        float f2 = 1.0 / PS_SQR(params[PM_PAR_SYY]) - 1.0 / PS_SQR(params[PM_PAR_SXX]);
     121        float q1 = PS_SQR(f1)*AR_RATIO - PS_SQR(f2);
    85122        q1 = (q1 < 0.0) ? 0.0 : q1;
    86123        // if q1 < 0.0, f2 ~ f1, we have a very large axis ratio near 45deg..  Saturate at that
    87124        // angle and let f2,f1 fight it out
    88         q2  = 0.5*sqrt (q1);
     125        q2 = 0.5*sqrtf(q1);
    89126    }
    90127
    91128    switch (mode) {
    92     case PS_MINIMIZE_BETA_LIMIT:
    93         switch (nParam) {
    94         case PM_PAR_SKY:
    95             beta_lim = 1000;
    96             break;
    97         case PM_PAR_I0:
    98             beta_lim = 3e6;
    99             break;
    100         case PM_PAR_XPOS:
    101             beta_lim = 5;
    102             break;
    103         case PM_PAR_YPOS:
    104             beta_lim = 5;
    105             break;
    106         case PM_PAR_SXX:
    107             beta_lim = 0.5;
    108             break;
    109         case PM_PAR_SYY:
    110             beta_lim = 0.5;
    111             break;
    112         case PM_PAR_SXY:
    113             beta_lim =  0.5*q2;
    114             break;
    115         case PM_PAR_7:
    116             beta_lim = 0.5;
    117             break;
    118         default:
    119             psAbort("invalid parameter %d for beta test", nParam);
    120         }
    121         if (fabs(beta[nParam]) > fabs(beta_lim)) {
    122             beta[nParam] = (beta[nParam] > 0) ? fabs(beta_lim) : -fabs(beta_lim);
    123             psTrace ("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
    124                      nParam, beta[nParam], beta_lim);
    125             return false;
    126         }
    127         return true;
    128     case PS_MINIMIZE_PARAM_MIN:
    129         switch (nParam) {
    130         case PM_PAR_SKY:
    131             params_min = -1000;
    132             break;
    133         case PM_PAR_I0:
    134             params_min =   0.01;
    135             break;
    136         case PM_PAR_XPOS:
    137             params_min =  -100;
    138             break;
    139         case PM_PAR_YPOS:
    140             params_min =  -100;
    141             break;
    142         case PM_PAR_SXX:
    143             params_min =   0.5;
    144             break;
    145         case PM_PAR_SYY:
    146             params_min =   0.5;
    147             break;
    148         case PM_PAR_SXY:
    149             params_min =  -q2;
    150             break;
    151         case PM_PAR_7:
    152             params_min =   1.25;
    153             break;
    154         default:
    155             psAbort("invalid parameter %d for param min test", nParam);
    156         }
    157         if (params[nParam] < params_min) {
    158             params[nParam] = params_min;
    159             psTrace ("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
    160                      nParam, params[nParam], params_min);
    161             return false;
    162         }
    163         return true;
    164     case PS_MINIMIZE_PARAM_MAX:
    165         switch (nParam) {
    166         case PM_PAR_SKY:
    167             params_max =   1e5;
    168             break;
    169         case PM_PAR_I0:
    170             params_max =   1e8;
    171             break;
    172         case PM_PAR_XPOS:
    173             params_max =   1e4;
    174             break;
    175         case PM_PAR_YPOS:
    176             params_max =   1e4;
    177             break;
    178         case PM_PAR_SXX:
    179             params_max =   100;
    180             break;
    181         case PM_PAR_SYY:
    182             params_max =   100;
    183             break;
    184         case PM_PAR_SXY:
    185             params_max =  +q2;
    186             break;
    187         case PM_PAR_7:
    188             params_max =  4.0;
    189             break;
    190         default:
    191             psAbort("invalid parameter %d for param max test", nParam);
    192         }
    193         if (params[nParam] > params_max) {
    194             params[nParam] = params_max;
    195             psTrace ("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
    196                      nParam, params[nParam], params_max);
    197             return false;
    198         }
    199         return true;
    200     default:
     129      case PS_MINIMIZE_BETA_LIMIT: {
     130          psAssert(beta, "Require beta to limit beta");
     131          float limit = betaUse[nParam];
     132          if (nParam == PM_PAR_SXY) {
     133              limit *= q2;
     134          }
     135          if (fabs(beta[nParam]) > fabs(limit)) {
     136              beta[nParam] = (beta[nParam] > 0) ? fabs(limit) : -fabs(limit);
     137              psTrace("psModules.objects", 5, "|beta[nParam==%d]| > |beta_lim|; %g v. %g",
     138                      nParam, beta[nParam], limit);
     139              return false;
     140          }
     141          return true;
     142      }
     143      case PS_MINIMIZE_PARAM_MIN: {
     144          psAssert(params, "Require parameters to limit parameters");
     145          psAssert(paramsMinUse, "Require parameter limits to limit parameters");
     146          float limit = paramsMinUse[nParam];
     147          if (nParam == PM_PAR_SXY) {
     148              limit *= q2;
     149          }
     150          if (params[nParam] < limit) {
     151              params[nParam] = limit;
     152              psTrace("psModules.objects", 5, "params[nParam==%d] < params_min; %g v. %g",
     153                      nParam, params[nParam], limit);
     154              return false;
     155          }
     156          return true;
     157      }
     158      case PS_MINIMIZE_PARAM_MAX: {
     159          psAssert(params, "Require parameters to limit parameters");
     160          psAssert(paramsMaxUse, "Require parameter limits to limit parameters");
     161          float limit = paramsMaxUse[nParam];
     162          if (nParam == PM_PAR_SXY) {
     163              limit *= q2;
     164          }
     165          if (params[nParam] > limit) {
     166              params[nParam] = limit;
     167              psTrace("psModules.objects", 5, "params[nParam==%d] > params_max; %g v. %g",
     168                      nParam, params[nParam], limit);
     169              return false;
     170          }
     171          return true;
     172      }
     173      default:
    201174        psAbort("invalid choice for limits");
    202175    }
     
    205178}
    206179
     180
    207181// make an initial guess for parameters
     182// 0.5 PIX: moments and peaks are in pixel coords, thus so are model parameters
    208183bool PM_MODEL_GUESS (pmModel *model, pmSource *source)
    209184{
     
    230205    if (!isfinite(shape.sxy)) return false;
    231206
    232     PAR[PM_PAR_SKY]  = moments->Sky;
     207    PAR[PM_PAR_SKY]  = 0.0;
    233208    PAR[PM_PAR_I0]   = peak->flux;
    234209    PAR[PM_PAR_XPOS] = peak->xf;
     
    282257psF64 PM_MODEL_RADIUS (const psVector *params, psF64 flux)
    283258{
    284     psF64 z, f;
     259    psF64 z;
    285260    int Nstep = 0;
    286261    psEllipseShape shape;
     
    310285    // choose a z value guaranteed to be beyond our limit
    311286    float z0 = pow((1.0 / limit), (1.0 / PAR[PM_PAR_7]));
     287    psAssert (isfinite(z0), "fix this code: z0 should not be nan for %f", PAR[PM_PAR_7]);
    312288    float z1 = (1.0 / limit);
     289    psAssert (isfinite(z1), "fix this code: z1 should not be nan for %f", PAR[PM_PAR_7]);
    313290    z1 = PS_MAX (z0, z1);
    314291    z0 = 0.0;
    315292
    316     // perform a type of bisection to find the value
    317     float f0 = 1.0 / (1 + z0 + pow(z0, PAR[PM_PAR_7]));
    318     float f1 = 1.0 / (1 + z1 + pow(z1, PAR[PM_PAR_7]));
    319     while ((Nstep < 10) && (fabs(z1 - z0) > 0.5)) {
    320         z = 0.5*(z0 + z1);
    321         f = 1.0 / (1 + z + pow(z, PAR[PM_PAR_7]));
    322         if (f > limit) {
    323             z0 = z;
    324             f0 = f;
    325         } else {
    326             z1 = z;
    327             f1 = f;
    328         }
    329         Nstep ++;
    330     }
     293    // starting guess:
     294    z = 0.5*(z0 + z1);
     295    float dz = 1.0;
     296
     297    for (int i = 0; (i < 10) && (fabs(dz) > 0.0001); i++) {
     298        // use Newton-Raphson to minimize f(z) - limit = 0
     299        float q = (1 + z + pow(z,PAR[PM_PAR_7]));
     300        float dqdz = (1.0 + PAR[PM_PAR_7]*pow(z,PAR[PM_PAR_7] - 1.0));
     301
     302        float f = 1.0 / q;
     303        float dfdz = -dqdz * f / q;
     304
     305        dz = (f - limit) / dfdz;
     306
     307        // fprintf (stderr, "%f %f %f : %f %f\n", f, z, dz, dfdz, q);
     308        z -= dz;
     309        z = PS_MAX(z, 0.0);
     310    }
     311
    331312    psF64 radius = sigma * sqrt (2.0 * z);
    332313
     
    436417bool PM_MODEL_FIT_STATUS (pmModel *model)
    437418{
    438 
    439     psF32 dP;
    440419    bool  status;
    441420
     
    443422    psF32 *dPAR = model->dparams->data.F32;
    444423
    445     dP = 0;
    446     dP += PS_SQR(dPAR[PM_PAR_SXX] / PAR[PM_PAR_SXX]);
    447     dP += PS_SQR(dPAR[PM_PAR_SYY] / PAR[PM_PAR_SYY]);
    448     dP = sqrt (dP);
    449 
    450424    status = true;
    451     status &= (dP < 0.5);
    452425    status &= (PAR[PM_PAR_I0] > 0);
    453426    status &= ((dPAR[PM_PAR_I0]/PAR[PM_PAR_I0]) < 0.5);
    454427
    455428    return status;
     429}
     430
     431
     432void PM_MODEL_SET_LIMITS(pmModelLimitsType type)
     433{
     434    switch (type) {
     435      case PM_MODEL_LIMITS_NONE:
     436        paramsMinUse = NULL;
     437        paramsMaxUse = NULL;
     438        limitsApply = true;
     439        break;
     440      case PM_MODEL_LIMITS_IGNORE:
     441        paramsMinUse = NULL;
     442        paramsMaxUse = NULL;
     443        limitsApply = false;
     444        break;
     445      case PM_MODEL_LIMITS_LAX:
     446        paramsMinUse = paramsMinLax;
     447        paramsMaxUse = paramsMaxLax;
     448        limitsApply = true;
     449        break;
     450      case PM_MODEL_LIMITS_MODERATE:
     451        paramsMinUse = paramsMinModerate;
     452        paramsMaxUse = paramsMaxModerate;
     453        limitsApply = true;
     454        break;
     455      case PM_MODEL_LIMITS_STRICT:
     456        paramsMinUse = paramsMinStrict;
     457        paramsMaxUse = paramsMaxStrict;
     458        limitsApply = true;
     459        break;
     460      default:
     461        psAbort("Unrecognised model limits type: %x", type);
     462    }
     463    return;
    456464}
    457465
     
    464472# undef PM_MODEL_PARAMS_FROM_PSF
    465473# undef PM_MODEL_FIT_STATUS
     474# undef PM_MODEL_SET_LIMITS
Note: See TracChangeset for help on using the changeset viewer.