IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 14907


Ignore:
Timestamp:
Sep 20, 2007, 9:17:16 AM (19 years ago)
Author:
magnier
Message:

added psImageMapFit psImageMapClipFit

Location:
branches/eam_branch_20070830/psLib/src/imageops
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branch_20070830/psLib/src/imageops/psImageMap.h

    r14864 r14907  
    77 *  @author Eugene Magnier, IfA
    88 *
    9  *  @version $Revision: 1.1.2.5 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2007-09-17 20:17:21 $
     9 *  @version $Revision: 1.1.2.6 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2007-09-20 19:17:16 $
    1111 *
    1212 *  Copyright 2007 Institute for Astronomy, University of Hawaii
     
    5050
    5151// fit the image map to a set of points
    52 bool psImageMapFit (psImageMap *map, psVector *x, psVector *y, psVector *f, psVector *df);
     52bool psImageMapFit (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df);
     53
     54// fit the image map to a set of points
     55bool psImageMapClipFit (psImageMap *map, psStats *stats, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df);
    5356
    5457/// @}
  • branches/eam_branch_20070830/psLib/src/imageops/psImageMapFit.c

    r14865 r14907  
    77 *  @author Eugene Magnier, IfA
    88 *
    9  *  @version $Revision: 1.1.2.4 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2007-09-17 20:19:36 $
     9 *  @version $Revision: 1.1.2.5 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2007-09-20 19:17:16 $
    1111 *
    1212 *  Copyright 2007 Institute for Astronomy, University of Hawaii
     
    2020#include "psError.h"
    2121#include "psAbort.h"
     22#include "psTrace.h"
    2223
    2324// XXX for testing
     
    4445
    4546// map defines the output image dimensions and scaling.
    46 bool psImageMapFit (psImageMap *map, psVector *x, psVector *y, psVector *f, psVector *df) {
     47bool psImageMapFit (psImageMap *map, psVector *mask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df) {
    4748
    4849    int I, J;
     50
     51    // XXX Add Asserts
    4952
    5053    // dimensions of the output map image
    5154    int Nx = map->binning->nXruff;
    5255    int Ny = map->binning->nYruff;
     56
     57    // no spatial information, just calculate mean & stdev
     58    if ((Nx == 1) && (Ny == 1)) {
     59        psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     60       
     61        // XXX does ROBUST_MEDIAN work with weight?
     62        psVectorStats (stats, f, NULL, mask, maskValue);
     63
     64        map->map->data.F32[0][0]   = stats->robustMedian;
     65        map->error->data.F32[0][0] = stats->robustStdev;
     66        psFree (stats);
     67        return true;
     68    }
     69
     70    if (Nx == 1) {
     71        psAbort ("un-implemented edge case");
     72        goto insert;
     73    }
     74    if (Ny == 1) {
     75        psAbort ("un-implemented edge case");
     76        goto insert;
     77    }
    5378
    5479    // set up the redirection table so we can use sA[-1][-1], etc
     
    104129            // J = (n + jn) + nX*(m + jm)
    105130            for (int i = 0; i < x->n; i++) {
     131
     132                if (mask && (mask->data.U8[i] & maskValue)) continue;
     133
    106134                // base coordinate offset for this point (x,y) relative to this map element (n,m)
    107135                // float dx = x->data.F32[i] - psImageBinningGetFineX (map->binning, n + 0.5);
     
    198226            sA[+1][ 0] = dx_rx_ry_ry + dx_rx_py_py;
    199227            sA[+1][+1] = dx_rx_dy_ry;
    200 
    201             // XXX need to add three additional edge cases:
    202             if ((Nx == 1) && (Ny == 1)) {
    203                 psAbort ("un-implemented edge case");
    204                 goto insert;
    205             }
    206             if (Nx == 1) {
    207                 psAbort ("un-implemented edge case");
    208                 goto insert;
    209             }
    210             if (Ny == 1) {
    211                 psAbort ("un-implemented edge case");
    212                 goto insert;
    213             }
    214228
    215229        insert:
     
    299313    return true;
    300314}
     315
     316// measure residuals on each pass and clip outliers based on stats
     317bool psImageMapClipFit (psImageMap *map, psStats *stats, psVector *inMask, psMaskType maskValue, psVector *x, psVector *y, psVector *f, psVector *df) {
     318
     319    // XXX add in full PS_ASSERTS
     320    assert (map);
     321    assert (stats);
     322    assert (x);
     323    assert (y);
     324    assert (f);
     325    assert (df);
     326
     327    // the user supplies one of various stats option pairs,
     328    // determine the desired mean and stdev STATS options:
     329    psStatsOptions meanOption = stats->options & (PS_STAT_SAMPLE_MEAN | PS_STAT_SAMPLE_MEDIAN | PS_STAT_ROBUST_MEDIAN | PS_STAT_CLIPPED_MEAN | PS_STAT_FITTED_MEAN | PS_STAT_FITTED_MEAN_V2 | PS_STAT_FITTED_MEAN_V3 | PS_STAT_FITTED_MEAN_V4);
     330    psStatsOptions stdevOption = stats->options & (PS_STAT_SAMPLE_STDEV | PS_STAT_ROBUST_STDEV | PS_STAT_CLIPPED_STDEV | PS_STAT_FITTED_STDEV | PS_STAT_FITTED_STDEV_V2 | PS_STAT_FITTED_STDEV_V3 | PS_STAT_FITTED_STDEV_V4);
     331    if (!meanOption) {
     332        psError(PS_ERR_UNKNOWN, true, "no valid mean stats option selected");
     333        return false;
     334    }
     335    if (!stdevOption) {
     336        psError(PS_ERR_UNKNOWN, true, "no valid stdev stats option selected");
     337        return false;
     338    }
     339
     340    // clipping range defined by min and max and/or clipSigma
     341    psF32 minClipSigma;
     342    psF32 maxClipSigma;
     343    if (isfinite(stats->max)) {
     344        maxClipSigma = fabs(stats->max);
     345    } else {
     346        maxClipSigma = fabs(stats->clipSigma);
     347    }
     348    if (isfinite(stats->min)) {
     349        minClipSigma = fabs(stats->min);
     350    } else {
     351        minClipSigma = fabs(stats->clipSigma);
     352    }
     353
     354    psVector *mask = inMask;
     355    if (!inMask) {
     356        mask = psVectorAlloc (x->n, PS_TYPE_U8);
     357    }
     358
     359    // vector to store residuals
     360    psVector *resid = psVectorAlloc(f->n, PS_TYPE_F32);
     361
     362    psTrace("psLib.imageops", 4, "stats->clipIter is %d\n", stats->clipIter);
     363    psTrace("psLib.imageops", 4, "(minClipSigma, maxClipSigma) is (%.2f, %.2f)\n", minClipSigma, maxClipSigma);
     364
     365    for (psS32 N = 0; N < stats->clipIter; N++) {
     366        psTrace("psLib.imageops", 6, "Loop iteration %d.  Calling psImageMapFit()\n", N);
     367        psS32 Nkeep = 0;
     368        if (!psImageMapFit(map, mask, maskValue, x, y, f, df)) {
     369            psError(PS_ERR_UNKNOWN, false, "Could not fit image map.\n");
     370            psFree(resid);
     371            if (!inMask) psFree (mask);
     372            return false;
     373        }
     374
     375        psVector *fit = psImageMapEvalVector(map, x, y);
     376        if (fit == NULL) {
     377            psError(PS_ERR_UNKNOWN, false, "Failure in psImageMapEvalVector().\n");
     378            psFree(resid);
     379            if (!inMask) psFree (mask);
     380            return false;
     381        }
     382        for (int i = 0 ; i < f->n ; i++) {
     383            resid->data.F32[i] = (f->data.F32[i] - fit->data.F32[i]);
     384        }
     385
     386        if (!psVectorStats(stats, resid, NULL, mask, maskValue)) {
     387            psError(PS_ERR_UNKNOWN, false, "Failure to compute statistics on the resid vector.\n");
     388            psFree(resid);
     389            psFree(fit);
     390            if (!inMask) psFree (mask);
     391            return false;
     392        }
     393
     394        double meanValue = psStatsGetValue (stats, meanOption);
     395        double stdevValue = psStatsGetValue (stats, stdevOption);
     396
     397        psTrace("psLib.imageops", 5, "Mean is %f\n", meanValue);
     398        psTrace("psLib.imageops", 5, "Stdev is %f\n", stdevValue);
     399        psF32 minClipValue = -minClipSigma*stdevValue;
     400        psF32 maxClipValue = +maxClipSigma*stdevValue;
     401
     402        // set mask if pts are not valid
     403        // we are masking out any point which is out of range
     404        // recovery is not allowed with this scheme
     405        for (psS32 i = 0; i < resid->n; i++) {
     406            // XXX this prevents recovery of previously masked values
     407            if (mask->data.U8[i] & maskValue) {
     408                continue;
     409            }
     410
     411            if ((resid->data.F32[i] - meanValue > maxClipValue) || (resid->data.F32[i] - meanValue < minClipValue)) {
     412                psTrace("psLib.imageops", 6, "Masking element %d  : %f vs %f : resid is %f\n", i, f->data.F32[i], fit->data.F32[i], resid->data.F32[i]);
     413                mask->data.U8[i] |= 0x01;
     414                continue;
     415            }
     416            Nkeep++;
     417        }
     418
     419        // We should probably exit this loop if no new elements were masked since the fit won't
     420        // change.
     421        psTrace("psLib.imageops", 6, "keeping %d of %ld pts for fit\n", Nkeep, x->n);
     422        stats->clippedNvalues = Nkeep;
     423        psFree(fit);
     424    }
     425
     426    // Free local temporary variables
     427    psFree(resid);
     428    if (!inMask) psFree (mask);
     429    return true;
     430}
Note: See TracChangeset for help on using the changeset viewer.