IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 23, 2006, 6:16:11 PM (20 years ago)
Author:
eugene
Message:

fixed some errors with double sources, added second-pass linear PSF fit, multiple-depths

File:
1 edited

Legend:

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

    r6427 r6481  
    11# include "psphot.h"
     2bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight);
    23
    34// 2006.02.07 : no leaks!
    45// fit all reasonable sources with the linear PSF model
    5 bool psphotEnsemblePSF (pmReadout *readout, psMetadata *config, psArray *sources, pmPSF *psf) {
     6bool psphotEnsemblePSF (pmReadout *readout, psMetadata *config, psArray *sources, pmPSF *psf, bool final) {
    67
    78    bool  status;
     
    910    float y;
    1011    float f;
     12    float r;
     13
     14    // psRegion allArray = psRegionSet (0, 0, 0, 0);
    1115
    1216    psTimerStart ("psphot");
     
    2933
    3034    // option to limit analysis to a specific region
    31     bool UseAnalysisRegion = false;
    32     psRegion AnalysisRegion = {0, 0, 0, 0};
    3335    char *region = psMetadataLookupStr (&status, config, "ANALYSIS_REGION");
    34     if (status) {
    35         UseAnalysisRegion = true;
    36         AnalysisRegion = psRegionFromString (region);
    37         psLogMsg ("psphotEnsemblePSF", 4, "using region %f,%f - %f,%f\n",
    38                   AnalysisRegion.x0, AnalysisRegion.y0,
    39                   AnalysisRegion.x1, AnalysisRegion.y1);
    40     }
     36    psRegion AnalysisRegion = psRegionFromString (region);
     37    AnalysisRegion = psRegionForImage (readout->image, AnalysisRegion);
     38    // psRegion AnalysisRegion = psRegionForImage (readout->image, psRegionFromString (region));
     39    if (psRegionIsNaN (AnalysisRegion)) psAbort ("psphot", "analysis region mis-defined");
    4140
    4241    for (int i = 0; i < sources->n; i++) {
     
    4544        // skip non-astronomical objects (very likely defects)
    4645        // XXX EAM : should we try these anyway?
    47         if (inSource->mode &  PM_SOURCE_BLEND) continue;
    4846        if (inSource->type == PM_SOURCE_DEFECT) continue;
    4947        if (inSource->type == PM_SOURCE_SATURATED) continue;
    50 
    51         if (UseAnalysisRegion) {
    52             if (inSource->moments->x < AnalysisRegion.x0) continue;
    53             if (inSource->moments->y < AnalysisRegion.y0) continue;
    54             if (inSource->moments->x > AnalysisRegion.x1) continue;
    55             if (inSource->moments->y > AnalysisRegion.y1) continue;
    56         }
     48        if (final) {
     49            if (inSource->mode &  PM_SOURCE_SUBTRACTED) continue;
     50        } else {
     51            if (inSource->mode &  PM_SOURCE_BLEND) continue;
     52        }
     53
     54        if (inSource->moments->x < AnalysisRegion.x0) continue;
     55        if (inSource->moments->y < AnalysisRegion.y0) continue;
     56        if (inSource->moments->x > AnalysisRegion.x1) continue;
     57        if (inSource->moments->y > AnalysisRegion.y1) continue;
    5758
    5859        pmSource *otSource = pmSourceAlloc ();
     
    7374            // peak-up on peak (for non-sat objects)
    7475
    75             int ix = inSource->peak->x;
    76             int iy = inSource->peak->y;
     76            // ix,iy must land on inSource->pixels
     77            int ix = PS_MAX (inSource->pixels->col0 + 1, PS_MIN (inSource->pixels->col0 + inSource->pixels->numCols - 2, inSource->peak->x));
     78            int iy = PS_MAX (inSource->pixels->row0 + 1, PS_MIN (inSource->pixels->row0 + inSource->pixels->numRows - 2, inSource->peak->y));
    7779
    7880            psPolynomial2D *bicube = psImageBicubeFit (inSource->pixels, ix, iy);
     
    104106        otSource->mask   = psImageCopy (NULL, inSource->mask,   PS_TYPE_U8);
    105107        otSource->pixels = psImageCopy (NULL, inSource->pixels, PS_TYPE_F32);
     108        otSource->weight = psImageCopy (NULL, inSource->weight, PS_TYPE_F32);
    106109
    107110        // build the model image
     
    117120        psImageKeepCircle (mask, x, y, model->radius, "OR", PSPHOT_MASK_MARKED);
    118121        pmSourceAddModel (flux, mask, model, false, false);
     122
     123        // calculate nDOF (nPix - 1)
     124        // int Nmaskpix = psImageCountPixelMask (mask, allArray, PSPHOT_MASK_SATURATED);
     125        // model->nDOF  = mask->numCols*mask->numRows - Nmaskpix - 1;
    119126
    120127        // save source in list
     
    128135    // fill out the sparse matrix
    129136    psSparse *sparse = psSparseAlloc (models->n, 100);
     137    psVector *weight = psVectorAlloc (models->n, PS_TYPE_F32);
    130138    for (int i = 0; i < models->n; i++) {
    131139        int N = index->data.U32[i];
     
    133141        pmSource *Mi = models->data[i];
    134142
    135         // diagonal element (auto-cross-product)
    136         f = pmSourceCrossProduct (Mi, Mi);
    137         psSparseMatrixElement (sparse, i, i, f);
     143        // scale by diagonal element (auto-cross-product)
     144        r = pmSourceCrossProduct (Mi, Mi);
     145        weight->data.F32[i] = r;
     146
     147        psSparseMatrixElement (sparse, i, i, 1.0);
    138148
    139149        // find the image x model value
    140150        f = pmSourceCrossProduct (Fi, Mi);
    141         psSparseVectorElement (sparse, i, f);
     151        psSparseVectorElement (sparse, i, f / r);
    142152
    143153        // loop over all other stars following this one
     
    153163            // got an overlap; calculate cross-product and add to output array
    154164            f = pmSourceCrossProduct (Mi, Mj);
    155             psSparseMatrixElement (sparse, j, i, f);
     165            psSparseMatrixElement (sparse, j, i, f / r);
    156166        }
    157167    }
    158168    psLogMsg ("psphot.emsemble", 4, "built matrix: %f (%d elements)\n", psTimerMark ("psphot"), sparse->Nelem);
     169
     170    psSparseConstraint constraint;
     171    constraint.paramMin   = 0;
     172    constraint.paramMax   = 1e8;
     173    constraint.paramDelta = 1e8;
    159174
    160175    // solve for normalization terms (need include local sky?)
    161176    psSparseResort (sparse);
    162     psVector *norm = psSparseSolve (NULL, sparse, 3);
     177    psVector *norm = psSparseSolve (NULL, constraint, sparse, 3);
    163178
    164179    // adjust models, set sources and subtract
     
    168183        pmSource *Mi = models->data[i];
    169184
     185        // if we already have a PSF model, free it.
     186        psFree (Fi->modelPSF);
     187
    170188        // need to increment counter so we can free models here and sources above
    171189        Fi->modelPSF = psMemCopy (Mi->modelPSF);
     
    173191        // assign linearly-fitted normalization
    174192        Fi->modelPSF->params->data.F32[1] = norm->data.F32[i];
     193        Fi->modelPSF->dparams->data.F32[1] = sqrt(sqrt(2) * norm->data.F32[i] / (sparse->Bfj->data.F32[i] * weight->data.F32[i]));
     194        // XXX EAM : this factor of sqrt(2) makes the errors consistent, but I don't understand it
    175195
    176196        // subtract object
    177197        pmSourceSubModel (Fi->pixels, Fi->mask, Fi->modelPSF, false, false);
    178198        Fi->mode |= PM_SOURCE_SUBTRACTED;
    179         Fi->mode |= PM_SOURCE_TEMPSUB;
    180     }
     199        if (!final) Fi->mode |= PM_SOURCE_TEMPSUB;
     200    }
     201
     202    // measure chisq for each source
     203    for (int i = 0; final && (i < models->n); i++) {
     204        int N = index->data.U32[i];
     205        pmSource *Fi = sources->data[N];
     206        pmModel *model = Fi->modelPSF;
     207
     208        x = model->params->data.F32[2];
     209        y = model->params->data.F32[3];
     210
     211        psImageKeepCircle (Fi->mask, x, y, model->radius, "OR", PSPHOT_MASK_MARKED);
     212        pmSourceChisq (model, Fi->pixels, Fi->mask, Fi->weight);
     213        psImageKeepCircle (Fi->mask, x, y, model->radius, "AND", ~PSPHOT_MASK_MARKED);
     214    }
     215
    181216    psFree (index);
    182217    psFree (sparse);
    183218    psFree (models);
    184219    psFree (norm);
     220    psFree (weight);
    185221
    186222    psLogMsg ("psphot.emsemble", 3, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot"));
    187223    return true;
    188224}
     225
     226bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight) {
     227
     228    double dC = 0.0;
     229    int Npix = 0;
     230    for (int j = 0; j < image->numRows; j++) {
     231        for (int i = 0; i < image->numCols; i++) {
     232            if (mask->data.U8[j][i]) continue;
     233            if (weight->data.F32[j][i] <= 0) continue;
     234            dC += PS_SQR (image->data.F32[j][i]) / weight->data.F32[j][i];
     235            Npix ++;
     236        }
     237    }
     238    model->nDOF = Npix - 1;
     239    model->chisq = dC;
     240
     241    return (true);
     242}
Note: See TracChangeset for help on using the changeset viewer.