IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 4630


Ignore:
Timestamp:
Jul 27, 2005, 3:26:57 PM (21 years ago)
Author:
eugene
Message:

various tests and changes

Location:
trunk/psphot/src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/psphot/src/LocalSky.c

    r4582 r4630  
    6262bool pmSourceFitModel_EAM(psSource *source,
    6363                          psModel *model,
    64                           const bool PSF,
    65                           float SOFT)
     64                          const bool PSF)
    6665{
    6766    PS_PTR_CHECK_NULL(source, false);
     
    7473    psBool onPic     = true;
    7574    psBool rc        = true;
    76     psF32  Ro;
     75    psF32  Ro, ymodel;
    7776
    7877
     
    8180
    8281    psModelFunc modelFunc = psModelFunc_GetFunction (model->type);
     82    psModelLimits modelLimits = psModelLimits_GetFunction (model->type);
    8383
    8484    psVector *params = model->params;
     
    8686    psVector *paramMask = NULL;
    8787
     88    psVector *beta_lim = NULL;
     89    psVector *params_min = NULL;
     90    psVector *params_max = NULL;
     91
    8892    int nParams = PSF ? params->n - 4 : params->n;
    89     psF32 Xo = params->data.F32[2];
    90     psF32 Yo = params->data.F32[3];
     93    psF32 So = params->data.F32[0];
    9194
    9295    // find the number of valid pixels
     
    122125                y->data.F32[tmpCnt] = source->pixels->data.F32[i][j];
    123126
    124                 // XXX just for test purposes, use the raw radius.  a better
    125                 // choice is to ask what is the value of z and scale by that
    126                 Ro = hypot ((Xo - coord->data.F32[0]), (Yo - coord->data.F32[1]));
    127 
    128                 // XXX enhance the noise (doubled if R = 10 pix, etc. note the square)
    129                 yErr->data.F32[tmpCnt] = sqrt (source->noise->data.F32[i][j] * (1 + PS_SQR(Ro/SOFT)));
     127                ymodel = modelFunc (NULL, model->params, coord);
     128               
     129                // this test enhances the noise based on deviation from the model flux
     130                Ro = 1.0 + fabs (y->data.F32[tmpCnt] - ymodel) / sqrt(PS_SQR(ymodel - So) + PS_SQR(So));
     131                yErr->data.F32[tmpCnt] = sqrt (source->noise->data.F32[i][j] * Ro);
    130132                // XXX EAM : note the wasted effort: we carry dY^2, take sqrt(), then
    131133                //           the minimization function calculates sq()
     
    147149        paramMask->data.U8[i] = 1;
    148150      }
    149     }       
    150 
    151     psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F64);
     151    } 
     152
     153    psImage *covar = psImageAlloc (params->n, 3, PS_TYPE_F64);
     154    modelLimits (&beta_lim, &params_min, &params_max);
     155    for (int i = 0; i < params->n; i++) {
     156        covar->data.F64[0][i] = beta_lim->data.F32[i];
     157        covar->data.F64[1][i] = params_min->data.F32[i];
     158        covar->data.F64[2][i] = params_max->data.F32[i];
     159    }
    152160
    153161    psTrace (".pmObjects.pmSourceFitModel", 5, "fitting function\n");
    154     fitStatus = psMinimizeLMChi2(myMin, covar, params, paramMask, x, y, yErr, modelFunc);
     162    fitStatus = psMinimizeLMChi2_EAM(myMin, covar, params, paramMask, x, y, yErr, modelFunc);
    155163    for (int i = 0; i < dparams->n; i++) {
    156164        if ((paramMask != NULL) && paramMask->data.U8[i]) continue;
     
    326334}
    327335
     336bool pmModelFitStatus (psModel *model) {
     337
     338    bool status;
     339
     340    psModelFitStatusFunc statusFunc = psModelFitStatusFunc_GetFunction (model->type);
     341    status = statusFunc (model);
     342
     343    return (status);
     344}
     345
     346// XXX EAM this implementation of MinLM includes limits on params & dparams
     347psBool psMinimizeLMChi2_EAM(psMinimization *min,
     348                            psImage *covar,
     349                            psVector *params,
     350                            const psVector *paramMask,
     351                            const psArray *x,
     352                            const psVector *y,
     353                            const psVector *yErr,
     354                            psMinimizeLMChi2Func func)
     355{
     356    PS_PTR_CHECK_NULL(min, NULL);
     357    PS_VECTOR_CHECK_NULL(params, NULL);
     358    PS_VECTOR_CHECK_EMPTY(params, NULL);
     359    PS_PTR_CHECK_NULL(x, NULL);
     360    PS_VECTOR_CHECK_NULL(y, NULL);
     361    PS_VECTOR_CHECK_EMPTY(y, NULL);
     362    PS_VECTOR_CHECK_SIZE_EQUAL(x, y, NULL);
     363    PS_PTR_CHECK_NULL(func, NULL);
     364
     365    // this function has test and current values for several things
     366    // the current best value is in lower case
     367    // the next guess value is in upper case
     368
     369    // allocate internal arrays (current vs Guess)
     370    psImage *alpha   = psImageAlloc (params->n, params->n, PS_TYPE_F64);
     371    psImage *Alpha   = psImageAlloc (params->n, params->n, PS_TYPE_F64);
     372    psVector *beta   = psVectorAlloc (params->n, PS_TYPE_F64);
     373    psVector *Beta   = psVectorAlloc (params->n, PS_TYPE_F64);
     374    psVector *Params = psVectorAlloc (params->n, PS_TYPE_F32);
     375    psVector *dy     = NULL;
     376    psF64 Chisq = 0.0;
     377    psF64 lambda = 0.001;
     378
     379    psVector *beta_lim = NULL;
     380    psVector *param_min = NULL;
     381    psVector *param_max = NULL;
     382
     383    // if we are provided a covar image, we expect to find these three vectors in first three rows
     384    if (covar != NULL) {
     385        beta_lim  = psVectorAlloc (params->n, PS_TYPE_F32);
     386        param_min = psVectorAlloc (params->n, PS_TYPE_F32);
     387        param_max = psVectorAlloc (params->n, PS_TYPE_F32);
     388        for (int i = 0; i < params->n; i++) {
     389            beta_lim->data.F32[i] = covar->data.F64[0][i];
     390            param_min->data.F32[i] = covar->data.F64[1][i];
     391            param_max->data.F32[i] = covar->data.F64[2][i];
     392        }
     393        psImageRecycle (covar, params->n, params->n, PS_TYPE_F64);
     394    }
     395       
     396
     397    // why is this needed here??? the initial guess on params is provided by the user
     398    Params = psVectorCopy (Params, params, PS_TYPE_F32);
     399
     400    // the user provides the error or NULL.  we need to convert
     401    // to appropriate weights
     402    dy = psVectorAlloc (y->n, PS_TYPE_F32);
     403    if (yErr != NULL) {
     404        for (int i = 0; i < dy->n; i++) {
     405            if (yErr->data.F32[i] == 0.0) {
     406                dy->data.F32[i] = 1.0;
     407                // mask this?  bad pixel, obviously...
     408            } else {
     409                dy->data.F32[i] = 1.0 / PS_SQR (yErr->data.F32[i]);
     410            }
     411        }
     412    } else {
     413        for (int i = 0; i < dy->n; i++) {
     414            dy->data.F32[i] = 1.0;
     415        }
     416    }
     417
     418    // calculate initial alpha and beta, set chisq (min->value)
     419    min->value = p_psMinLM_SetABX (alpha, beta, params, paramMask, x, y, dy, func);
     420    if (isnan(min->value)) {
     421        min->iter = min->maxIter;
     422        return (false);
     423    }
     424    # ifndef PS_NO_TRACE
     425    // dump some useful info if trace is defined
     426    if (psTraceGetLevel (".psLib.dataManip.psMinimizeLMChi2") >= 5) {
     427        p_psImagePrint  (psTraceGetDestination(), alpha, "alpha guess");
     428        p_psVectorPrint (psTraceGetDestination(), beta, "beta guess");
     429        p_psVectorPrint (psTraceGetDestination(), params, "params guess");
     430    }
     431    if (psTraceGetLevel (".psLib.dataManip.psMinimizeLMChi2") == 4) {
     432        p_psVectorPrintRow (psTraceGetDestination(), Params, "params guess");
     433    }
     434    # endif /* PS_NO_TRACE */
     435
     436    // iterate until the tolerance is reached, or give up
     437    while ((min->lastDelta > min->tol) && (min->iter < min->maxIter)) {
     438
     439        // set a new guess for Alpha, Beta, Params
     440        p_psMinLM_GuessABP_EAM (Alpha, Beta, Params, alpha, beta, params, paramMask, beta_lim, param_min, param_max, lambda);
     441
     442        // measure linear model prediction
     443        psF64 dLinear = p_psMinLM_dLinear (Beta, beta, lambda);
     444
     445        # ifndef PS_NO_TRACE
     446        // dump some useful info if trace is defined
     447        if (psTraceGetLevel (".psLib.dataManip.psMinimizeLMChi2") >= 5) {
     448            p_psImagePrint  (psTraceGetDestination(), Alpha, "alpha guess");
     449            p_psVectorPrint (psTraceGetDestination(), Beta, "beta guess");
     450            p_psVectorPrint (psTraceGetDestination(), Params, "params guess");
     451        }
     452        if (psTraceGetLevel (".psLib.dataManip.psMinimizeLMChi2") == 4) {
     453            p_psVectorPrintRow (psTraceGetDestination(), Params, "params guess");
     454        }
     455        # endif /* PS_NO_TRACE */
     456
     457        // calculate Chisq for new guess, update Alpha & Beta
     458        Chisq = p_psMinLM_SetABX (Alpha, Beta, Params, paramMask, x, y, dy, func);
     459
     460        // XXX EAM alternate convergence criterion:
     461        // compare the delta (min->value - Chisq) with the
     462        // expected delta from the linear model (dLinear)
     463        // accept new guess (if improvement), or increase lambda
     464        psF64 rho = (min->value - Chisq) / dLinear;
     465
     466        psTrace (".psLib.dataManip.psMinimizeLMChi2", 4, "last chisq: %f, new chisq %f, delta: %f, rho: %f\n", min->value, Chisq, min->lastDelta, rho);
     467        # ifndef PS_NO_TRACE
     468        // dump some useful info if trace is defined
     469        if (psTraceGetLevel (".psLib.dataManip.psMinimizeLMChi2") >= 5) {
     470            p_psImagePrint  (psTraceGetDestination(), Alpha, "alpha guess");
     471            p_psVectorPrint (psTraceGetDestination(), Beta, "beta guess");
     472            p_psVectorPrint (psTraceGetDestination(), Params, "params guess");
     473        }
     474        # endif /* PS_NO_TRACE */
     475
     476        /* if (Chisq < min->value) {  */
     477        if (rho > 0.0) { 
     478            min->lastDelta = (min->value - Chisq) / (dy->n - params->n);
     479            min->value = Chisq;
     480            alpha  = psImageCopy (alpha, Alpha, PS_TYPE_F64);
     481            beta   = psVectorCopy (beta, Beta, PS_TYPE_F64);
     482            params = psVectorCopy (params, Params, PS_TYPE_F32);
     483            lambda *= 0.1;
     484        } else {
     485            lambda *= 10.0;
     486        }
     487        min->iter ++;
     488    }
     489    psTrace (".psLib.dataManip.psMinimizeLMChi2", 3, "chisq: %f, last delta: %f, Niter: %d\n", min->value, min->lastDelta, min->iter);
     490
     491    // construct & return the covariance matrix (if requested)
     492    if (covar != NULL) {
     493      p_psMinLM_GuessABP_EAM (covar, Beta, Params, alpha, beta, params, paramMask, beta_lim, param_min, param_max, 0.0);
     494    }     
     495
     496    // free the internal temporary data
     497    psFree (alpha);
     498    psFree (Alpha);
     499    psFree (beta);
     500    psFree (Beta);
     501    psFree (Params);
     502    psFree (dy);
     503
     504    if (min->iter == min->maxIter) {
     505      return (false);
     506    }
     507    return (true);
     508}
     509
     510// XXX EAM : can we use static copies of LUv, LUm, A?
     511psBool p_psMinLM_GuessABP_EAM (psImage  *Alpha,
     512                               psVector *Beta,
     513                               psVector *Params,
     514                               const psImage  *alpha,
     515                               const psVector *beta,
     516                               const psVector *params,
     517                               const psVector *paramMask,
     518                               const psVector *beta_lim,
     519                               const psVector *params_min,
     520                               const psVector *params_max,
     521                               psF64 lambda)
     522{
     523
     524    # define USE_LU_DECOMP 1
     525    # if (USE_LU_DECOMP)
     526    psVector *LUv = NULL;
     527    psImage  *LUm = NULL;
     528    psImage  *A   = NULL;
     529    psF32    det;
     530
     531    // LU decomposition version
     532    psTrace (".psLib.dataManip.psMinLM_GuessABP", 5, "using LUD version\n");
     533
     534    // set new guess values (creates matrix A)
     535    A = psImageCopy (NULL, alpha, PS_TYPE_F64);
     536    for (int j = 0; j < params->n; j++) {
     537        if ((paramMask != NULL) && (paramMask->data.U8[j])) continue;
     538        A->data.F64[j][j] = alpha->data.F64[j][j] * (1.0 + lambda);
     539    }
     540
     541    // solve A*beta = Beta (Alpha = 1/A)
     542    // these operations do not modify the input values (creates LUm, LUv)
     543    LUm   = psMatrixLUD (NULL, &LUv, A);
     544    Beta  = psMatrixLUSolve (Beta, LUm, beta, LUv);
     545    Alpha = psMatrixInvert (Alpha, A, &det);
     546
     547    # else
     548    // gauss-jordan version
     549    psTrace (".psLib.dataManip.psMinLM_GuessABP", 5, "using Gauss-J version");
     550
     551    // set new guess values (creates matrix A)
     552    Beta = psVectorCopy (Beta, beta, PS_TYPE_F64);
     553    Alpha = psImageCopy (Alpha, alpha, PS_TYPE_F64);
     554    for (int j = 0; j < params->n; j++) {
     555        if ((paramMask != NULL) && (paramMask->data.U8[j])) continue;
     556        Alpha->data.F64[j][j] = alpha->data.F64[j][j] * (1.0 + lambda);
     557    }
     558
     559    psGaussJordan (Alpha, Beta);
     560    # endif
     561
     562    // apply Beta to get new Params values
     563    for (int j = 0; j < params->n; j++) {
     564        if ((paramMask != NULL) && (paramMask->data.U8[j])) continue;
     565        // Params->data.F32[j] = params->data.F32[j] - Beta->data.F64[j];
     566        // continue;
     567        // compare Beta to beta limits
     568        if (beta_lim != NULL) {
     569            if (fabs(Beta->data.F64[j]) > fabs(beta_lim->data.F32[j])) {
     570                Beta->data.F64[j] = (Beta->data.F64[j] > 0) ? fabs(beta_lim->data.F32[j]) : -fabs(beta_lim->data.F32[j]);
     571            }
     572        }
     573        Params->data.F32[j] = params->data.F32[j] - Beta->data.F64[j];
     574        // compare new params to param limits
     575        if (params_max != NULL) {
     576            Params->data.F32[j] = PS_MIN (Params->data.F32[j], params_max->data.F32[j]);
     577        }
     578        if (params_min != NULL) {
     579            Params->data.F32[j] = PS_MAX (Params->data.F32[j], params_min->data.F32[j]);
     580        }
     581    }
     582
     583    # if (USE_LU_DECOMP)
     584    psFree (A);
     585    psFree (LUm);
     586    psFree (LUv);
     587    # endif
     588
     589    return true;
     590}
     591
  • trunk/psphot/src/apply_psf_model.c

    r4582 r4630  
    2222    float shapeNsigma = psMetadataLookupF32 (&status, config, "PSF_SHAPE_NSIGMA");
    2323    float OUTER       = psMetadataLookupF32 (&status, config, "OUTER_RADIUS");
     24    float FIT_MIN_SN  = psMetadataLookupF32 (&status, config, "FIT_MIN_SN");
     25    float FIT_MAX_CHI = psMetadataLookupF32 (&status, config, "FIT_MAX_CHI");
    2426
    2527    // set the object surface-brightness limit for fitted pixels
     
    3436
    3537        // skip non-astronomical objects (very likely defects)
    36         if (source->type == PS_SOURCE_DEFECT) continue;
     38        if (source->type == PS_SOURCE_DEFECT) continue; // XX should I try these anyway?
    3739        if (source->type == PS_SOURCE_SATURATED) continue;
    3840
     41        source->modelPSF = NULL;
     42
    3943        // use the source moments, etc to guess basic model parameters
    40         psModel  *model  = pmSourceModelGuess (source, psf->type);
     44        psModel *model  = pmSourceModelGuess (source, psf->type);
    4145
    4246        // set PSF parameters for this model
     
    4448        x = model->params->data.F32[2];
    4549        y = model->params->data.F32[3];
    46         // XXX I need to check if the model center has moved too much relative to the peak
    4750
    4851        // set the fit radius based on the object flux limit and the model
     
    5053        model->radius = modelRadius (model->params, FLUX_LIMIT) + FIT_PADDING;
    5154        if (isnan(model->radius)) {
    52           fprintf (stderr, "error in radius\n");
    53           continue;
     55          psAbort ("apply_psf_model", "error in radius");
    5456        }
    5557       
     
    6567        psImageKeepCircle (source->mask, x, y, model->radius, AND, 0x7f);
    6668        if (!status || (model->params->data.F32[1] < 0)) {
    67           // if the fit fails, we need to change the classification
    6869          psLogMsg ("psphot", 3, "PSF fit failed for %f, %f (%d iterations)\n", x, y, model->nIter);
    69           source->type = PS_SOURCE_OTHER;  // better choice?
     70          source->type = PS_SOURCE_FAIL_FIT_PSF;  // better choice?
    7071          continue;
    7172        }
     
    7576        Nfit ++;
    7677
    77         mark_psf_source (source, shapeNsigma, SATURATE);
     78        mark_psf_source (source, shapeNsigma, FIT_MIN_SN, FIT_MAX_CHI, SATURATE);
    7879        if (subtract_psf_source (source)) {
    7980          Nsub ++;
  • trunk/psphot/src/choose_psf_model.c

    r4398 r4630  
    6262        if (test->mask->data.U8[i]) {
    6363          source->type = PS_SOURCE_OTHER;
    64           // XXX is this the right type to go to?
     64          source->modelPSF = NULL;
    6565        } else {
    6666          source->modelPSF = test->modelPSF->data[i];
  • trunk/psphot/src/fit_galaxies.c

    r4582 r4630  
    11# include "psphot.h"
    2 
    3 // fit selected galaxy model (GAUSS) to all bright objects of type GALAXY
    42
    53bool fit_galaxies (psImageData *imdata, psMetadata *config, psArray *sources, psStats *skyStats)
    64{
    7     bool  status;
     5    bool  status, goodfit;
    86    float x;
    97    float y;
     
    1311    int   Niter = 0;
    1412
    15     float MOMENT_R = psMetadataLookupF32 (&status, config, "GAL_MOMENTS_RADIUS");
    16     // float RADIUS   = psMetadataLookupF32 (&status, config, "FIT_RADIUS");
    17     float snFaint  = psMetadataLookupF32 (&status, config, "FAINT_SN_LIM");
    18     float OUTER    = psMetadataLookupF32 (&status, config, "OUTER_RADIUS");
    19     float FIT_NSIGMA  = psMetadataLookupF32 (&status, config, "FIT_NSIGMA");
    20     float FIT_PADDING = psMetadataLookupF32 (&status, config, "FIT_PADDING");
     13    float  MOMENT_R    = psMetadataLookupF32 (&status, config, "GAL_MOMENTS_RADIUS");
     14    float  snFaint     = psMetadataLookupF32 (&status, config, "FAINT_SN_LIM");
     15    float  OUTER       = psMetadataLookupF32 (&status, config, "OUTER_RADIUS");
     16    float  FIT_NSIGMA  = psMetadataLookupF32 (&status, config, "FIT_NSIGMA");
     17    float  FIT_PADDING = psMetadataLookupF32 (&status, config, "FIT_PADDING");
     18    char  *modelName   = psMetadataLookupPtr (&status, config, "GAL_MODEL");
    2119
    2220    float FLUX_LIMIT  = FIT_NSIGMA * skyStats->sampleStdev;
    2321
    24     psModelType   modelType   = psModelSetType ("PS_MODEL_SGAUSS");
     22    psModelType   modelType   = psModelSetType (modelName);
    2523    psModelRadius modelRadius = psModelRadius_GetFunction (modelType);
    26 
    27     psTraceSetLevel (".psModules.pmSourceMoments", 5);
    2824
    2925    psTimerStart ("psphot");
    3026    for (int i = 0; i < sources->n; i++) {
    3127        psSource *source = sources->data[i];
    32         if (source->type != PS_SOURCE_GALAXY) continue;
    33         if (source->moments->SN < snFaint) continue;
     28
     29        // sources which should not be fitted
     30        // skip all valid stars
     31        if (source->type == PS_SOURCE_PSFSTAR) continue;
     32        if (source->type == PS_SOURCE_SATSTAR) continue;
     33        if (source->type == PS_SOURCE_GOODSTAR) continue;
     34        // skip all likely defects
     35        if (source->type == PS_SOURCE_DEFECT) continue;
     36        if (source->type == PS_SOURCE_SATURATED) continue;
     37        //
     38        if (source->type == PS_SOURCE_FAINTSTAR) continue;
     39        if (source->type == PS_SOURCE_POOR_FIT_PSF) continue;
     40
     41        // XXX when do we pick these up again?
     42        if (source->moments->SN < snFaint) {
     43          source->type = PS_SOURCE_FAINT_GALAXY;  // better choice?
     44          continue;
     45        }
    3446
    3547        // recalculate the source moments using the galaxy radius (larger)
    3648        status = pmSourceMoments_EAM (source, MOMENT_R);
    3749        if (!status) {
    38           fprintf (stderr, "invalid moments, skipping\n");
     50          source->type = PS_SOURCE_DROP_GALAXY;  // better choice?
    3951          continue;
    4052        }
     
    4658        y = model->params->data.F32[3];
    4759
    48         // need a better model guess and a better radius choice
    49         // when radius is not fixed, we will need to check if new radius fits on image
    50 
    5160        // set the fit radius based on the object flux limit and the model
    5261        // FLUX_LIMIT should be set based on local sky model (not global median)
    53         // model->radius = 25.0;
    5462        model->radius = modelRadius (model->params, FLUX_LIMIT) + FIT_PADDING;
    55         if (isnan(model->radius)) {
    56           fprintf (stderr, "error in radius\n");
    57           continue;
    58         }
     63        if (isnan(model->radius)) psAbort ("fit_galaxies", "error in radius");
     64
    5965        if (model->radius > OUTER) {
    6066          // allocate image, noise, mask arrays for each peak (square of radius OUTER)
     
    6470        // fit as FLT, not PSF (skip poor fits)
    6571        psImageKeepCircle (source->mask, x, y, model->radius, OR, 0x80);
    66         status = pmSourceFitModel (source, model, false);
     72        status = pmSourceFitModel_EAM (source, model, false);
    6773        psImageKeepCircle (source->mask, x, y, model->radius, AND, 0x7f);
    68         if (!status || (model->params->data.F32[1] < 0)) {
     74        if (!status) {
    6975          // if the fit fails, we need to change the classification
    7076          psLogMsg ("psphot", 3, "GAL fit failed for %f, %f (%d iterations, %f radius)\n", x, y, model->nIter, model->radius);
    71           source->type = PS_SOURCE_OTHER;  // better choice?
     77          source->type = PS_SOURCE_FAIL_FIT_GAL;  // better choice?
     78          source->modelFLT = model;
    7279          Nfail ++;
    7380          continue;
    7481        }
    7582
     83        goodfit = pmModelFitStatus (model);
     84        if (!goodfit) {
     85          // if the fit fails, we need to change the classification
     86          psLogMsg ("psphot", 3, "GAL fit poor for %f, %f (%d iterations, %f radius)\n", x, y, model->nIter, model->radius);
     87          source->type = PS_SOURCE_POOR_FIT_GAL;  // better choice?
     88          source->modelFLT = model;
     89          Nfail ++;
     90          continue;
     91        }
     92
     93        source->type = PS_SOURCE_GALAXY;
    7694        source->modelFLT = model;
    7795        Niter += model[0].nIter;
  • trunk/psphot/src/mark_psf_source.c

    r4574 r4630  
    1515// PS_SOURCE_BRIGHTSTAR
    1616# define MIN_DS 0.01
    17 bool mark_psf_source (psSource *source, float shapeNsigma, float SATURATE)
     17bool mark_psf_source (psSource *source, float shapeNsigma, float minSN, float maxChi, float SATURATE)
    1818{
     19    int keep;
    1920    float dSX, dSY, SX, SY, SN;
    20     float nSx, nSy;
     21    float nSx, nSy, Chi;
    2122
    2223    if (source->modelPSF == NULL) return (false);
     
    2627    if (source->modelPSF->params->data.F32[1] >= SATURATE) {
    2728        if (source->type == PS_SOURCE_PSFSTAR) {
    28             psLogMsg ("psphot", 3, "PSFSTAR marked saturated\n");
     29            psLogMsg ("psphot", 3, "PSFSTAR marked SATSTAR\n");
    2930        }
    3031        source->type = PS_SOURCE_SATSTAR;
     
    3233    }
    3334    if (source->type == PS_SOURCE_SATSTAR) {
    34         psLogMsg ("psphot", 4, "SATSTAR marked bright (fitted peak below saturation)\n");
    35         source->type = PS_SOURCE_BRIGHTSTAR;
     35        psLogMsg ("psphot", 4, "SATSTAR marked GOODSTAR (fitted peak below saturation)\n");
     36        source->type = PS_SOURCE_GOODSTAR;
    3637    }
    3738
     
    4142    dSX = source->modelPSF->dparams->data.F32[4];
    4243    dSY = source->modelPSF->dparams->data.F32[5];
     44    Chi = source->modelPSF->chisq / source->modelPSF->nDOF;
    4345
    4446    nSx = dSX / hypot (MIN_DS, 1 / (SX * SN));
     
    4850    // dsx_o = hypot (1/(SX*SN), MIN_DSX)
    4951
    50     // assign PS_SOURCE_BRIGHTSTAR to bright objects within PSF region of dparams[]
    51     if ((fabs(nSx) < shapeNsigma) && (fabs(nSy) < shapeNsigma)) {
     52    // assign PS_SOURCE_GOODSTAR to bright objects within PSF region of dparams[]
     53    keep = TRUE;
     54    keep &= (fabs(nSx) < shapeNsigma);
     55    keep &= (fabs(nSy) < shapeNsigma);
     56    keep &= (SN > minSN);
     57    keep &= (Chi < maxChi);
     58    if (keep) {
    5259        if (source->type == PS_SOURCE_PSFSTAR) return (true);
    53         source->type = PS_SOURCE_BRIGHTSTAR;
     60        source->type = PS_SOURCE_GOODSTAR;
    5461        return (true);
    5562    }
    5663   
    5764    if (source->type == PS_SOURCE_PSFSTAR) {
    58         psLogMsg ("psphot", 3, "PSFSTAR demoted based on dSx, dSy\n");
     65        psLogMsg ("psphot", 3, "PSFSTAR demoted based on fit quality\n");
    5966    }
    6067
     68    // object appears to be small, suspected defect
     69    if ((nSx <= -shapeNsigma) || (nSy <= -shapeNsigma)) {
     70        source->type = PS_SOURCE_DEFECT;
     71        return (false);
     72    }
     73
     74    // object appears to be large, suspected galaxy
    6175    if ((nSx >= shapeNsigma) || (nSy >= shapeNsigma)) {
    6276        source->type = PS_SOURCE_GALAXY;
    6377        return (false);
    6478    }
    65     // replace DEFECT with COSMIC?
    66     if ((nSx <= -shapeNsigma) || (nSy <= -shapeNsigma)) {
    67         source->type = PS_SOURCE_DEFECT;
     79
     80    // object appears to be extremely faint: what is this?
     81    if (SN < minSN) {
     82        source->type = PS_SOURCE_FAINTSTAR;
    6883        return (false);
    6984    }
    70     psTrace (".psphot.mark_psf_source", 2, "unexpected result: unmarked object\n");
     85
     86    // these are pooly fitted, probable stars near other stars?
     87    source->type = PS_SOURCE_POOR_FIT_PSF;
    7188    return (false);
    7289}       
  • trunk/psphot/src/mark_psf_sources.c

    r4114 r4630  
    3737        nSy = dSY * SY * SN;
    3838
    39         // assign PS_SOURCE_BRIGHTSTAR to bright objects within PSF region of dparams[]
     39        // assign PS_SOURCE_GOODSTAR to bright objects within PSF region of dparams[]
    4040        if ((fabs(nSx) < shapeNsigma) && (fabs(nSy) < shapeNsigma)) {
    4141            if (SN > snFaint) {
    42                 source->type = PS_SOURCE_BRIGHTSTAR;
     42                source->type = PS_SOURCE_GOODSTAR;
    4343            } else {
    4444                source->type = PS_SOURCE_FAINTSTAR;
  • trunk/psphot/src/onesource.c

    r4582 r4630  
    1212    float INNER  = psMetadataLookupF32 (&status, config, "INNER_RADIUS");
    1313    float OUTER  = psMetadataLookupF32 (&status, config, "OUTER_RADIUS");
    14     float MRAD   = psMetadataLookupF32 (&status, config, "PSF_MOMENTS_RADIUS");
     14    float MRAD   = psMetadataLookupF32 (&status, config, "GAL_MOMENTS_RADIUS");
    1515    float RADIUS = psMetadataLookupF32 (&status, config, "FIT_RADIUS");
    1616    float SOFT   = psMetadataLookupF32 (&status, config, "SOFT_RADIUS");
     
    2121
    2222    status = pmSourceLocalSky_EAM (source, PS_STAT_SAMPLE_MEDIAN, INNER);
    23     status = pmSourceMoments (source, MRAD);
     23    status = pmSourceMoments_EAM (source, MRAD);
    2424    source->peak->counts = source->moments->Peak;
    2525
    2626    psModel *model = pmSourceModelGuess (source, modelType);
     27    fprintf (stderr, "guess slope: %f\n", model->params->data.F32[7]);
    2728
    2829    psImageKeepCircle (source->mask, x, y, RADIUS, OR, 0x80);
    29     status = pmSourceFitModel_EAM (source, model, false, SOFT);
     30    status = pmSourceFitModel_EAM (source, model, false);
    3031
    3132    pmSourcePhotometry (&fitMag, &obsMag, model, source->pixels, source->mask);
  • trunk/psphot/src/psphot-utils.c

    r4574 r4630  
    7979{
    8080
     81    double dP, flux;
    8182    int i, j;
    8283    FILE *f;
     
    9697        model = (psModel  *) source->modelPSF;
    9798        if (model == NULL) continue;
    98         if (source->type == PS_SOURCE_GALAXY) continue;
    99         if (source->type == PS_SOURCE_DEFECT) continue;
    100         if (source->type == PS_SOURCE_SATURATED) continue;
     99
     100        // valid source types for this function
     101        if (source->type == PS_SOURCE_SATSTAR) goto valid;
     102        if (source->type == PS_SOURCE_PSFSTAR) goto valid;
     103        if (source->type == PS_SOURCE_GOODSTAR) goto valid;
     104        continue;
     105
     106    valid:
    101107        params = model->params;
    102108        dparams = model->dparams;
    103         fprintf (f, "%7.1f %7.1f  %5.1f %7.3f  %7.4f  ",
    104                  params[0].data.F32[2], params[0].data.F32[3],
    105                  params[0].data.F32[0], -2.5*log10(params[0].data.F32[1]), (dparams[0].data.F32[1]/params[0].data.F32[1]));
     109       
     110        dP = 0;
     111        dP += PS_SQR(dparams[0].data.F32[2]);
     112        dP += PS_SQR(dparams[0].data.F32[3]);
     113        dP = sqrt (dP);
     114       
     115        psModelFlux modelFluxFunc = psModelFlux_GetFunction (model->type);
     116        flux = modelFluxFunc (params);
     117
     118        fprintf (f, "%7.1f %7.1f  %5.1f %7.3f  %7.4f %7.4f  ",
     119                 params[0].data.F32[2],
     120                 params[0].data.F32[3],
     121                 params[0].data.F32[0],
     122                 -2.5*log10(flux),
     123                 (dparams[0].data.F32[1]/params[0].data.F32[1]),
     124                 dP);
    106125        for (j = 0; j < model->params->n - 4; j++) {
    107126            fprintf (f, "%9.6f ", params[0].data.F32[j+4]);
    108127        }
     128        fprintf (f, " : ");
    109129        for (j = 0; j < model->params->n - 4; j++) {
    110130            fprintf (f, "%9.6f ", dparams[0].data.F32[j+4]);
    111131        }
    112         fprintf (f, ": %2d %7.4f %7.4f %7.2f (%d %d)\n",
    113                  source[0].type, log10(model[0].chisq), source[0].moments->SN,
    114                  model[0].radius, model[0].nDOF, model[0].nIter);
     132        fprintf (f, ": %2d %7.3f %7.3f %7.2f %4d %2d\n",
     133                 source[0].type,
     134                 log10(model[0].chisq/model[0].nDOF),
     135                 source[0].moments->SN,
     136                 model[0].radius,
     137                 model[0].nDOF,
     138                 model[0].nIter);
    115139    }
    116140    fclose (f);
     
    122146{
    123147
     148    double dP;
    124149    int i, j;
    125150    FILE *f;
     
    139164        model = (psModel  *) source->modelFLT;
    140165        if (model == NULL) continue;
     166        if (source->type == PS_SOURCE_GALAXY) goto valid;
     167        continue;
     168
     169    valid:
     170        params = model->params;
     171        dparams = model->dparams;
     172
     173        // XXX these are hardwired for SGAUSS : this should be pushed into the
     174        // model functions as an abstract function
     175        dP = 0;
     176        dP += PS_SQR(dparams[0].data.F32[4] / params[0].data.F32[4]);
     177        dP += PS_SQR(dparams[0].data.F32[5] / params[0].data.F32[5]);
     178        dP += PS_SQR(dparams[0].data.F32[7] / params[0].data.F32[7]);
     179        dP = sqrt (dP);
     180
     181        fprintf (f, "%7.1f %7.1f  %5.1f %7.3f  %7.4f %7.4f  ",
     182                 params[0].data.F32[2],
     183                 params[0].data.F32[3],
     184                 params[0].data.F32[0],
     185                 -2.5*log10(params[0].data.F32[1]),
     186                 (dparams[0].data.F32[1]/params[0].data.F32[1]),
     187                 dP);
     188
     189        for (j = 4; j < model->params->n; j++) {
     190            fprintf (f, "%9.6f ", params[0].data.F32[j]);
     191        }
     192        fprintf (f, " : ");
     193        for (j = 4; j < model->params->n; j++) {
     194            fprintf (f, "%9.6f ", dparams[0].data.F32[j]);
     195        }
     196        fprintf (f, ": %2d %7.3f %7.3f %7.2f %4d %2d\n",
     197                 source[0].type, log10(model[0].chisq/model[0].nDOF),
     198                 source[0].moments->SN,
     199                 model[0].radius,
     200                 model[0].nDOF,
     201                 model[0].nIter);
     202    }
     203    fclose (f);
     204    return true;
     205}
     206
     207// dump the sources to an output file
     208bool DumpModelNULL (psArray *sources, char *filename)
     209{
     210
     211    int i;
     212    FILE *f;
     213
     214    f = fopen (filename, "w");
     215    if (f == NULL) {
     216        psLogMsg ("DumpObjects", 3, "can't open output file for moments%s\n", filename);
     217        return false;
     218    }
     219
     220    psMoments *empty = pmMomentsAlloc ();
     221
     222    // write sources with models first
     223    for (i = 0; i < sources->n; i++) {
     224        psSource *source = (psSource *) sources->data[i];
     225
     226        // skip these sources (in PSF or FLT)
     227        if (source->type == PS_SOURCE_GALAXY) continue;
    141228        if (source->type == PS_SOURCE_PSFSTAR) continue;
    142229        if (source->type == PS_SOURCE_SATSTAR) continue;
    143         if (source->type == PS_SOURCE_BRIGHTSTAR) continue;
    144         if (source->type == PS_SOURCE_FAINTSTAR) continue;
    145         if (source->type == PS_SOURCE_OTHER) continue;
    146         if (source->type == PS_SOURCE_DEFECT) continue;
    147         if (source->type == PS_SOURCE_SATURATED) continue;
    148 
    149         params = model->params;
    150         dparams = model->dparams;
    151         fprintf (f, "%7.1f %7.1f  %5.1f %7.3f  %7.4f  ",
    152                  params[0].data.F32[2], params[0].data.F32[3],
    153                  params[0].data.F32[0], -2.5*log10(params[0].data.F32[1]), (dparams[0].data.F32[1]/params[0].data.F32[1]));
    154         for (j = 0; j < model->params->n - 4; j++) {
    155             fprintf (f, "%9.6f ", params[0].data.F32[j+4]);
    156         }
    157         for (j = 0; j < model->params->n - 4; j++) {
    158             fprintf (f, "%9.6f ", dparams[0].data.F32[j+4]);
    159         }
    160         fprintf (f, ": %2d %7.4f %7.4f %7.2f (%d %d)\n", source[0].type, log10(model[0].chisq), source[0].moments->SN, model[0].radius, model[0].nDOF, model[0].nIter);
    161     }
    162     fclose (f);
    163     return true;
    164 }
    165 
    166 // dump the sources to an output file
    167 bool DumpModelNULL (psArray *sources, char *filename)
    168 {
    169 
    170     int i;
    171     FILE *f;
    172 
    173     f = fopen (filename, "w");
    174     if (f == NULL) {
    175         psLogMsg ("DumpObjects", 3, "can't open output file for moments%s\n", filename);
    176         return false;
    177     }
    178 
    179     // write sources with models first
    180     for (i = 0; i < sources->n; i++) {
    181         psSource *source = (psSource *) sources->data[i];
    182         if (source->modelFLT != NULL) continue;
    183         if (source->modelPSF != NULL) continue;
    184         if (source->moments == NULL) continue;
    185         fprintf (f, "%5d %5d  %7.1f  %7.1f %7.1f  %6.3f %6.3f  %8.1f %7.1f %7.1f %7.1f  %4d %2d\n",
    186                  source->peak->x, source->peak->y, source->peak->counts,
    187                  source->moments->x, source->moments->y,
    188                  source->moments->Sx, source->moments->Sy,
    189                  source->moments->Sum, source->moments->Peak,
    190                  source->moments->Sky, source->moments->SN,
    191                  source->moments->nPixels, source->type);
     230        if (source->type == PS_SOURCE_GOODSTAR) continue;
     231
     232        if (source->moments == NULL) {
     233          fprintf (f, "%5d %5d  %7.1f  %7.1f %7.1f  %6.3f %6.3f  %8.1f %7.1f %7.1f %7.1f  %4d %2d\n",
     234                   source->peak->x, source->peak->y, source->peak->counts,
     235                   empty->x, empty->y,
     236                   empty->Sx, empty->Sy,
     237                   empty->Sum, empty->Peak,
     238                   empty->Sky, empty->SN,
     239                   empty->nPixels, source->type);
     240        } else {
     241          fprintf (f, "%5d %5d  %7.1f  %7.1f %7.1f  %6.3f %6.3f  %8.1f %7.1f %7.1f %7.1f  %4d %2d\n",
     242                   source->peak->x, source->peak->y, source->peak->counts,
     243                   source->moments->x, source->moments->y,
     244                   source->moments->Sx, source->moments->Sy,
     245                   source->moments->Sum, source->moments->Peak,
     246                   source->moments->Sky, source->moments->SN,
     247                   source->moments->nPixels, source->type);
     248        }
    192249    }
    193250    fclose (f);
  • trunk/psphot/src/psphot.h

    r4582 r4630  
    4949bool subtract_galaxies (psArray *sources, psMetadata *config);
    5050bool subtract_psf_source (psSource *source);
    51 bool mark_psf_source (psSource *source, float shapeNsigma, float SATURATE);
     51bool mark_psf_source (psSource *source, float shapeNsigma, float minSN, float maxChi, float SATURATE);
    5252bool find_defects (psImage *zapmask, psArray *sources, psMetadata *config, pmPSF *psf);
    5353bool basic_classes (psArray *sources, psMetadata *config);
     
    8080bool pmSourceDefinePixels(psSource *mySource, const psImageData *imdata, psF32 x, psF32 y, psF32 Radius);
    8181bool pmSourceLocalSky_EAM (psSource *source, psStatsOptions statsOptions, psF32 Radius);
    82 bool pmSourceFitModel_EAM(psSource *source, psModel *model, const bool PSF, float SOFT);
     82bool pmSourceFitModel_EAM(psSource *source, psModel *model, const bool PSF);
    8383bool pmSourceMoments_EAM(psSource *source, psF32 radius);
     84bool pmModelFitStatus (psModel *model);
     85psBool p_psMinLM_GuessABP_EAM (psImage  *Alpha, psVector *Beta, psVector *Params, const psImage  *alpha, const psVector *beta, const psVector *params, const psVector *paramMask, const psVector *beta_lim, const psVector *params_min, const psVector *params_max, psF64 lambda);
     86psBool psMinimizeLMChi2_EAM(psMinimization *min, psImage *covar, psVector *params, const psVector *paramMask, const psArray *x, const psVector *y, const psVector *yErr, psMinimizeLMChi2Func func);
     87psF64 p_psMinLM_dLinear (const psVector *Beta, const psVector *beta, psF64 lambda);
    8488
    8589// fitsource utilities
  • trunk/psphot/src/setup.c

    r4421 r4630  
    7575    }
    7676
    77     float XBORDER  = psMetadataLookupF32 (&status, config, "XBORDER");
    78     float YBORDER  = psMetadataLookupF32 (&status, config, "YBORDER");
    79     psRegion *keep = psRegionAlloc (XBORDER, -XBORDER, YBORDER, -YBORDER);
     77    float XMIN  = psMetadataLookupF32 (&status, config, "XMIN");
     78    float XMAX  = psMetadataLookupF32 (&status, config, "XMAX");
     79    float YMIN  = psMetadataLookupF32 (&status, config, "YMIN");
     80    float YMAX  = psMetadataLookupF32 (&status, config, "YMAX");
     81    psRegion *keep = psRegionAlloc (XMIN, XMAX, YMIN, YMAX);
    8082    keep           = psRegionForImage (keep, image, keep);
    8183    psImageKeepRegion (mask, keep, OR, 0x01);
  • trunk/psphot/src/subtract_psf_source.c

    r4574 r4630  
    77{
    88  float sky;
     9  psModel *model;
     10  psImage *pixels;
    911
    10   // non-stellar sources are ignored
    11   if (source->type == PS_SOURCE_OTHER) return (false);
    12   if (source->type == PS_SOURCE_GALAXY) return (false);
    13   if (source->type == PS_SOURCE_DEFECT) return (false);
    14   if (source->type == PS_SOURCE_SATURATED) return (false);
     12  // only subtract successful fits
     13  if (source->type == PS_SOURCE_SATSTAR) goto valid;
     14  if (source->type == PS_SOURCE_PSFSTAR) goto valid;
     15  if (source->type == PS_SOURCE_GOODSTAR) goto valid;
     16  return (false);
    1517
    16   psModel *model = source->modelPSF;
     18valid:
     19  model = source->modelPSF;
    1720  if (model == NULL) {
    1821    psLogMsg ("psphot.subtract_psf_source", 2, "missing model for %f, %f\n", source->moments->x, source->moments->y);
     
    2023  }         
    2124
    22   psImage *pixels = source->pixels;
     25  pixels = source->pixels;
    2326
    2427  // subtract object, leave local sky
Note: See TracChangeset for help on using the changeset viewer.