IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Sep 21, 2009, 8:37:01 PM (17 years ago)
Author:
eugene
Message:

re-organize pmPSFtry (split into clearer files); modify 2D psf variation analysis to use psf-aper mags as the metric

File:
1 moved

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/20090715/psModules/src/objects/pmPSFtryMakePSF.c

    • Property svn:mergeinfo set to (toggle deleted branches)
      /branches/czw_branch/cleanup/psModules/src/objects/pmPSFFromPSFtry.c24713-25285
      /branches/eam_branches/20090522/psModules/src/objects/pmPSFFromPSFtry.c24238-24573
      /branches/pap/psModules/src/objects/pmPSFFromPSFtry.c25238-25382
      /branches/pap_mops/psModules/src/objects/pmPSFFromPSFtry.c25137-25255
      /trunk/psModules/src/objects/pmPSFFromPSFtry.c24799-25395
    r25455 r25476  
    11/** @file  pmPSFtry.c
    2  *
    3  *  XXX: need description of file purpose
     2 *  @brief generate a pmPSF from a collection of EXT measurments of likely PSF stars.
    43 *
    54 *  @author EAM, IfA
     
    4443Note: some of the array entries may be NULL (failed fits); ignore them.
    4544 *****************************************************************************/
    46 bool pmPSFFromPSFtry (pmPSFtry *psfTry, int Nx, int Ny)
     45bool pmPSFtryMakePSF (pmPSFtry *psfTry)
    4746{
    4847    PS_ASSERT_PTR_NON_NULL(psfTry, false);
     
    5049
    5150    pmPSF *psf = psfTry->psf;
     51    psVector *srcMask = psfTry->mask;
    5252
    5353    // construct the fit vectors from the collection of objects
    5454    psVector *x  = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);
    5555    psVector *y  = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);
    56     psVector *z  = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);
    5756
    5857    // construct the x,y terms
    5958    for (int i = 0; i < psfTry->sources->n; i++) {
     59        if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;
     60
    6061        pmSource *source = psfTry->sources->data[i];
    61         if (source->modelEXT == NULL)
    62             continue;
     62        assert (source->modelEXT); // all unmasked sources should have modelEXT
    6363
    6464        x->data.F32[i] = source->modelEXT->params->data.F32[PM_PAR_XPOS];
     
    6666    }
    6767
    68     if (!pmPSFFitShapeParams (psf, psfTry->sources, x, y, psfTry->mask)) {
     68    // fit the shape parameters (SXX, SYY, SXY) as a function of position
     69    if (!pmPSFFitShapeParams (psf, psfTry->sources, x, y, srcMask)) {
    6970        psFree(x);
    7071        psFree(y);
    71         psFree(z);
    7272        return false;
    7373    }
    7474
    75     // skip the unfitted parameters (X, Y, Io, Sky) and the shape parameters (SXX, SYY, SXY)
    76     // apply the values of Nx, Ny determined above for E0,E1,E2 to the remaining parameters
     75    // vector to store the other parameter values
     76    psVector *z  = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);
     77
     78    // skip the unfitted parameters (X, Y, Io, Sky) and the shape parameters (SXX, SYY, SXY);
     79    // fit the remaining parameters.
    7780    for (int i = 0; i < psf->params->n; i++) {
    7881        switch (i) {
     
    9194        // select the per-object fitted data for this parameter
    9295        for (int j = 0; j < psfTry->sources->n; j++) {
     96            // skip any masked sources (failed to fit one of the model steps or get a magnitude)
     97            if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;
     98
    9399            pmSource *source = psfTry->sources->data[j];
    94             if (source->modelEXT == NULL) continue;
     100            assert (source->modelEXT); // all unmasked sources should have modelEXT
     101
    95102            z->data.F32[j] = source->modelEXT->params->data.F32[i];
    96103        }
    97 
    98         psImageBinning *binning = psImageBinningAlloc();
    99         binning->nXruff = psf->trendNx;
    100         binning->nYruff = psf->trendNy;
    101         binning->nXfine = psf->fieldNx;
    102         binning->nYfine = psf->fieldNy;
    103 
    104         if (psf->psfTrendMode == PM_TREND_MAP) {
    105             psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);
    106             psImageBinningSetSkipByOffset (binning, psf->fieldXo, psf->fieldYo);
    107         }
    108 
    109         // free existing trend, re-alloc
    110         psFree (psf->params->data[i]);
    111         psf->params->data[i] = pmTrend2DNoImageAlloc (psf->psfTrendMode, binning, psf->psfTrendStats);
    112         psFree (binning);
    113104
    114105        // fit the collection of measured parameters to the PSF 2D model
    115106        // the mask is carried from previous steps and updated with this operation
    116107        // the weight is either the flux error or NULL, depending on 'psf->poissonErrorParams'
    117         if (!pmTrend2DFit (psf->params->data[i], psfTry->mask, 0xff, x, y, z, NULL)) {
     108        if (!pmTrend2DFit (psf->params->data[i], srcMask, 0xff, x, y, z, NULL)) {
    118109            psError(PS_ERR_UNKNOWN, false, "failed to build psf model for parameter %d", i);
    119110            psFree(x);
     
    154145}
    155146
     147// fit the shape parameters using the supplied order (pmPSF->trendNx,trendNy)
     148bool pmPSFFitShapeParams (pmPSF *psf, psArray *sources, psVector *x, psVector *y, psVector *srcMask) {
     149
     150    // we are doing a robust fit.  after each pass, we drop points which are more deviant than
     151    // three sigma.  the source mask (srcMask) is updated for each pass. 
     152
     153    // The shape parameters (SXX, SXY, SYY) are strongly coupled.  We have to handle them very
     154    // carefully.  First, we convert them to the Ellipse Polarization terms (E0, E1, E2) for
     155    // each source and fit this set of parameters.  These values are less tightly coupled, but
     156    // are still inter-related.  The fitted values do a good job of constraining the major axis
     157    // and the position angle, but the minor axis is weakly measured.  When we apply the PSF
     158    // model to construct a source model, we convert the fitted values of E0,E1,E2 to the shape
     159    // parameters, with the constraint that the minor axis must be greater than a minimum
     160    // threshold.
     161
     162    // XXX re-read the sextractor manual on handling 'infinitely thin' sources...
     163
     164    // storage vectors for the polarization terms & mags
     165    psVector *e0   = psVectorAlloc (sources->n, PS_TYPE_F32);
     166    psVector *e1   = psVectorAlloc (sources->n, PS_TYPE_F32);
     167    psVector *e2   = psVectorAlloc (sources->n, PS_TYPE_F32);
     168
     169    // convert the measured source shape paramters to polarization terms
     170    for (int i = 0; i < sources->n; i++) {
     171        // skip any masked sources (failed to fit one of the model steps or get a magnitude)
     172        if (srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]) continue;
     173
     174        pmSource *source = sources->data[i];
     175        assert (source->modelEXT); // all unmasked sources should have modelEXT
     176
     177        psEllipsePol pol = pmPSF_ModelToFit (source->modelEXT->params->data.F32);
     178
     179        e0->data.F32[i] = pol.e0;
     180        e1->data.F32[i] = pol.e1;
     181        e2->data.F32[i] = pol.e2;
     182    }
     183
     184    // we run 'clipIter' cycles clipping in each of x and y, with only one iteration each.
     185    // This way, the parameters masked by one of the fits will be applied to the others
     186    for (int i = 0; i < psf->psfTrendStats->clipIter; i++) {
     187        // XXX we are using the same stats structure on each pass: do we need to re-init it?
     188        // XXX we hardwire this to SAMPLE stats above (psphotChoosePSF.c), hardwire here instead?
     189        psStatsOptions meanOption = psStatsMeanOption(psf->psfTrendStats->options);
     190        psStatsOptions stdevOption = psStatsStdevOption(psf->psfTrendStats->options);
     191
     192        pmTrend2D *trend = NULL;
     193        float mean, stdev;
     194
     195        // XXX we are using the same stats structure on each pass: do we need to re-init it?
     196        bool status = true;
     197
     198        trend = psf->params->data[PM_PAR_E0];
     199        trend->stats->clipIter = 1; // in allocation, this value is set to the value of nIter, but we should use 1 here
     200        status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e0, NULL);
     201        mean = psStatsGetValue (trend->stats, meanOption);
     202        stdev = psStatsGetValue (trend->stats, stdevOption);
     203        psTrace ("psModules.objects", 4, "clipped E0 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e0->n);
     204        if (psf->psfTrendMode == PM_TREND_MAP) psImageMapCleanup (trend->map);
     205        // pmSourceVisualPSFModelResid (trend, x, y, e0, srcMask);
     206
     207        trend = psf->params->data[PM_PAR_E1];
     208        trend->stats->clipIter = 1; // in allocation, this value is set to the value of nIter, but we should use 1 here
     209        status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e1, NULL);
     210        mean = psStatsGetValue (trend->stats, meanOption);
     211        stdev = psStatsGetValue (trend->stats, stdevOption);
     212        psTrace ("psModules.objects", 4, "clipped E1 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e1->n);
     213        if (psf->psfTrendMode == PM_TREND_MAP) psImageMapCleanup (trend->map);
     214        // pmSourceVisualPSFModelResid (trend, x, y, e1, srcMask);
     215
     216        trend = psf->params->data[PM_PAR_E2];
     217        trend->stats->clipIter = 1; // in allocation, this value is set to the value of nIter, but we should use 1 here
     218        status &= pmTrend2DFit (trend, srcMask, 0xff, x, y, e2, NULL);
     219        mean = psStatsGetValue (trend->stats, meanOption);
     220        stdev = psStatsGetValue (trend->stats, stdevOption);
     221        psTrace ("psModules.objects", 4, "clipped E2 : %f +/- %f keeping %ld of %ld\n", mean, stdev, psf->psfTrendStats->clippedNvalues, e2->n);
     222        if (psf->psfTrendMode == PM_TREND_MAP) psImageMapCleanup (trend->map);
     223        // pmSourceVisualPSFModelResid (trend, x, y, e2, srcMask);
     224
     225        if (!status) {
     226            psError (PS_ERR_UNKNOWN, true, "failed to fit PSF shape params");
     227            return false;
     228        }
     229    }
     230
     231    // test dump of the psf parameters
     232    if (psTraceGetLevel("psModules.objects") >= 4) {
     233        FILE *f = fopen ("pol.dat", "w");
     234        fprintf (f, "# x y  :  e0obs e1obs e2obs  : e0fit e1fit e2fit : mask\n");
     235        for (int i = 0; i < e0->n; i++) {
     236            fprintf (f, "%f %f  :  %f %f %f  : %f %f %f  : %d\n",
     237                     x->data.F32[i], y->data.F32[i],
     238                     e0->data.F32[i], e1->data.F32[i], e2->data.F32[i],
     239                     pmTrend2DEval (psf->params->data[PM_PAR_E0], x->data.F32[i], y->data.F32[i]),
     240                     pmTrend2DEval (psf->params->data[PM_PAR_E1], x->data.F32[i], y->data.F32[i]),
     241                     pmTrend2DEval (psf->params->data[PM_PAR_E2], x->data.F32[i], y->data.F32[i]),
     242                     srcMask->data.PS_TYPE_VECTOR_MASK_DATA[i]);
     243        }
     244        fclose (f);
     245    }
     246
     247    psFree (e0);
     248    psFree (e1);
     249    psFree (e2);
     250    return true;
     251}
     252
Note: See TracChangeset for help on using the changeset viewer.