IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6947


Ignore:
Timestamp:
Apr 21, 2006, 11:33:00 AM (20 years ago)
Author:
magnier
Message:

faster calculation of radius, simpsons rule for flux integration, rational range for Sx,Sy guess

Location:
trunk/psModules/src/objects/models
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/objects/models/pmModel_GAUSS.c

    r6907 r6947  
    8484    params[2] = moments->x;
    8585    params[3] = moments->y;
    86     params[4] = 1.2 / moments->Sx;
    87     params[5] = 1.2 / moments->Sy;
     86    params[4] = (moments->Sx < (1.2 / 2.0)) ? 2.0 : (1.2 / moments->Sx);
     87    params[5] = (moments->Sy < (1.2 / 2.0)) ? 2.0 : (1.2 / moments->Sy);
    8888    params[6] = 0.0;
    8989    return(true);
  • trunk/psModules/src/objects/models/pmModel_PGAUSS.c

    r6872 r6947  
    7676}
    7777
     78// make an initial guess for parameters
     79bool pmModelGuess_PGAUSS (pmModel *model, pmSource *source)
     80{
     81
     82    pmMoments *moments = source->moments;
     83    psF32     *params  = model->params->data.F32;
     84
     85    params[0] = moments->Sky;
     86    params[1] = moments->Peak - moments->Sky;
     87    params[2] = moments->x;
     88    params[3] = moments->y;
     89    params[4] = (moments->Sx < (1.2 / 2.0)) ? 2.0 : (1.2 / moments->Sx);
     90    params[5] = (moments->Sy < (1.2 / 2.0)) ? 2.0 : (1.2 / moments->Sy);
     91    params[6] = 0.0;
     92
     93    return(true);
     94}
     95
    7896psF64 pmModelFlux_PGAUSS(const psVector *params)
    7997{
    80     float f, norm, z;
     98    float norm, z;
    8199
    82100    psF32 *PAR = params->data.F32;
     
    90108    // the area needs to be multiplied by the integral of f(z)
    91109    norm = 0.0;
    92     for (z = 0.005; z < 50; z += 0.01) {
    93         f = 1.0 / (1 + z + z*z/2 + z*z*z/6);
    94         norm += f;
     110
     111    # define DZ 0.25
     112
     113    float f0 = 1.0;
     114    float f1, f2;
     115    for (z = DZ; z < 50; z += DZ) {
     116        f1 = 1.0 / (1 + PAR[7]*z + pow(z, 2.25));
     117        z += DZ;
     118        f2 = 1.0 / (1 + PAR[7]*z + pow(z, 2.25));
     119        norm += f0 + 4*f1 + f2;
     120        f0 = f2;
    95121    }
    96     norm *= 0.01;
     122    norm *= DZ / 3.0;
    97123
    98     psF64 Flux = params->data.F32[1] * Area * norm;
     124    psF64 Flux = PAR[1] * Area * norm;
    99125
    100126    return(Flux);
     
    118144    }
    119145    return (radius);
    120 }
    121 
    122 bool pmModelGuess_PGAUSS (pmModel *model, pmSource *source)
    123 {
    124 
    125     pmMoments *moments = source->moments;
    126     psF32     *params  = model->params->data.F32;
    127 
    128     params[0] = moments->Sky;
    129     params[1] = moments->Peak - moments->Sky;
    130     params[2] = moments->x;
    131     params[3] = moments->y;
    132     params[4] = 1.2 / moments->Sx;
    133     params[5] = 1.2 / moments->Sy;
    134     params[6] = 0.0;
    135 
    136     return(true);
    137146}
    138147
  • trunk/psModules/src/objects/models/pmModel_QGAUSS.c

    r6908 r6947  
    9595
    9696// make an initial guess for parameters
    97 // XXX we could probably do better with params[6] and params[7]
    9897bool pmModelGuess_QGAUSS (pmModel *model, pmSource *source)
    9998{
     
    107106    params[2] = peak->x;
    108107    params[3] = peak->y;
    109     params[4] = 1.2 / moments->Sx;
    110     params[5] = 1.2 / moments->Sy;
     108    params[4] = (moments->Sx < (1.2 / 2.0)) ? 2.0 : (1.2 / moments->Sx);
     109    params[5] = (moments->Sy < (1.2 / 2.0)) ? 2.0 : (1.2 / moments->Sy);
    111110    params[6] = 0.0;
    112111    params[7] = 1.0;
     
    129128
    130129    // the area needs to be multiplied by the integral of f(z)
    131     // XXX this integral can be done faster and more accurately
    132130    norm = 0.0;
    133131
    134     # define DZ 0.1
    135 
    136     # if 1
    137 
    138     float f;
    139 for (z = 0.5*DZ; z < 50; z += DZ) {
    140         f = 1.0 / (1 + PAR[7]*z + pow(z, 2.25));
    141         // test: f = 1.0 / (1 + PAR[7]*z + PS_SQR(z));
    142         norm += f;
    143     }
    144     norm *= DZ;
    145     # else
    146 
    147         float f0 = 1.0;
     132    # define DZ 0.25
     133
     134    float f0 = 1.0;
    148135    float f1, f2;
    149136    for (z = DZ; z < 50; z += DZ) {
     
    155142    }
    156143    norm *= DZ / 3.0;
    157     # endif
    158144
    159145    psF64 Flux = PAR[1] * Area * norm;
     
    168154    psF64 z, f;
    169155    psF32 *PAR = params->data.F32;
     156    int Nstep = 0;
    170157
    171158    if (flux <= 0)
     
    177164
    178165    // if Sx == Sy, sigma = Sx == Sy
    179     // XXX we should return the major axis length...??
    180166    psF64 sigma = hypot (1.0 / PAR[4], 1.0 / PAR[5]) / sqrt(2.0);
     167    psF64 limit = flux / PAR[1];
     168
     169    # if 0
     170    /* test example will just use both, printing both */
    181171    psF64 dz = 1.0 / (2.0 * sigma*sigma);
    182     psF64 limit = flux / PAR[1];
    183172
    184173    // we can do this much better with intelligent choices here
    185174    for (z = 0.0; z < 30.0; z += dz) {
     175        Nstep ++;
    186176        f = 1.0 / (1 + PAR[7]*z + pow(z, 2.25));
    187177        // test: f = 1.0 / (1 + PAR[7]*z + PS_SQR(z));
     
    189179            break;
    190180    }
     181    // fprintf (stderr, "rad 1: %f, want: %f, got: %f (%d steps)\n", z, limit, f, Nstep);
     182
     183    # else
     184
     185        /* use the fact that f is monotonically decreasing */
     186        z = 0;
     187    Nstep = 0;
     188
     189    // choose a z value guaranteed to be beyond our limit
     190    float z0 = pow((1.0 / limit), (1.0 / 2.25));
     191    float z1 = (1.0 / limit) / PAR[7];
     192    z1 = PS_MAX (z0, z1);
     193    z0 = 0.0;
     194
     195    float f0 = 1.0 / (1 + PAR[7]*z0 + pow(z0, 2.25));
     196    float f1 = 1.0 / (1 + PAR[7]*z1 + pow(z1, 2.25));
     197    while ((Nstep < 10) && (fabs(z1 - z0) > 0.5)) {
     198        z = 0.5*(z0 + z1);
     199        f = 1.0 / (1 + PAR[7]*z + pow(z, 2.25));
     200        // fprintf (stderr, "%f  %f  %f   :   %f  %f  %f\n", f0, f, f1, z0, z, z1);
     201        if (f > limit) {
     202            z0 = z;
     203            f0 = f;
     204        } else {
     205            z1 = z;
     206            f1 = f;
     207        }
     208        Nstep ++;
     209    }
     210    // fprintf (stderr, "rad 2: %f, want: %f, got: %f (%d steps)\n", z, limit, f, Nstep);
     211    # endif
    191212
    192213    psF64 radius = sigma * sqrt (2.0 * z);
Note: See TracChangeset for help on using the changeset viewer.