IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 6957


Ignore:
Timestamp:
Apr 21, 2006, 5:21:00 PM (20 years ago)
Author:
Paul Price
Message:

Fringe subtraction is working!

Location:
trunk/psModules/src/detrend
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/detrend/pmFringeStats.c

    r6921 r6957  
    33 *  @author Eugene Magnier, IfA
    44 *
    5  *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2006-04-20 04:28:00 $
     5 *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2006-04-22 03:21:00 $
    77 *
    88 *  Copyright 2004 IfA
    99 */
    1010
     11#include <stdio.h>
     12#include <assert.h>
    1113#include "pslib.h"
    1214#include "pmFPA.h"
     
    1517#define MAX(x,y) ((x) > (y) ? (x) : (y))
    1618#define MIN(x,y) ((x) < (y) ? (x) : (y))
     19
     20
     21// Future optimisations for speed:
     22//
     23// 1. Clipping --- don't re-do the matrix setup again, but carry matrix and vector around, subtract
     24// contributions from clipped data points.
     25// 2. Faster psImageStats (use memcpy?)
     26
     27
     28
     29//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     30// pmFringeRegions
     31//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1732
    1833static void fringeRegionsFree(pmFringeRegions *fringe)
     
    4459}
    4560
    46 
    47 static void fringeStatsFree(pmFringeStats *stats)
    48 {
    49     psFree(stats->regions);
    50     psFree(stats->f);
    51     psFree(stats->df);
    52 }
    53 
    54 pmFringeStats *pmFringeStatsAlloc(pmFringeRegions *regions)
    55 {
    56     pmFringeStats *stats = psAlloc(sizeof(pmFringeStats));
    57     (void)psMemSetDeallocator(stats, (psFreeFunc)fringeStatsFree);
    58 
    59     stats->regions = psMemIncrRefCounter(regions);
    60     stats->f = psVectorAlloc(regions->x->n, PS_TYPE_F32);
    61     stats->f->n = regions->x->n;
    62     stats->df = psVectorAlloc(regions->x->n, PS_TYPE_F32);
    63     stats->df->n = regions->x->n;
    64 
    65     return stats;
    66 }
    67 
    68 
    69 static void fringeScaleFree(pmFringeScale *scale)
    70 {
    71     psFree(scale->coeff);
    72     psFree(scale->coeffErr);
    73     return;
    74 }
    75 
    76 pmFringeScale *pmFringeScaleAlloc(int nFringeFrames)
    77 {
    78     pmFringeScale *scale = psAlloc(sizeof(pmFringeScale));
    79     (void)psMemSetDeallocator(scale, (psFreeFunc)fringeScaleFree);
    80 
    81     scale->nFringeFrames = nFringeFrames;
    82     scale->coeff = psVectorAlloc(nFringeFrames + 1, PS_TYPE_F32);
    83     scale->coeffErr = psVectorAlloc(nFringeFrames + 1, PS_TYPE_F32);
    84     scale->coeff->n = nFringeFrames + 1;
    85     scale->coeff->n = nFringeFrames + 1;
    86 
    87     return scale;
    88 }
    89 
    90 bool pmFringeRegionsCreatePoints(pmFringeRegions *fringe, psImage *image)
     61bool pmFringeRegionsCreatePoints(pmFringeRegions *fringe, const psImage *image)
    9162{
    9263
     
    10071    fringe->mask = psVectorRecycle(fringe->mask, fringe->nRequested, PS_TYPE_U8);
    10172    fringe->x->n = fringe->y->n = fringe->mask->n = fringe->nRequested;
     73    psVectorInit(fringe->mask, 0);
    10274
    10375    int nX = image->numCols;
     
    12092}
    12193
     94
     95//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     96// pmFringeStats
     97//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     98
     99static void fringeStatsFree(pmFringeStats *stats)
     100{
     101    psFree(stats->regions);
     102    psFree(stats->f);
     103    psFree(stats->df);
     104}
     105
     106pmFringeStats *pmFringeStatsAlloc(pmFringeRegions *regions)
     107{
     108    pmFringeStats *stats = psAlloc(sizeof(pmFringeStats));
     109    (void)psMemSetDeallocator(stats, (psFreeFunc)fringeStatsFree);
     110
     111    int numRegions = regions->x->n;     // Number of regions
     112    stats->regions = psMemIncrRefCounter(regions);
     113    stats->f = psVectorAlloc(numRegions, PS_TYPE_F32);
     114    stats->df = psVectorAlloc(numRegions, PS_TYPE_F32);
     115    stats->f->n = stats->df->n = numRegions;
     116
     117    return stats;
     118}
     119
    122120pmFringeStats *pmFringeStatsMeasure(pmFringeRegions *fringe, pmReadout *readout, psMaskType maskVal)
    123121{
     
    143141    psImage *mask  = readout->mask;
    144142
    145     psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     143    psStats *median = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN); // Median statistics only
     144    psStats *medianSd = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV); // Median and SD
     145
     146    // Measure the sky over the image
     147    psImage *sky = psImageAlloc(fringe->nX, fringe->nY, PS_TYPE_F32);
     148    for (int i = 0; i < fringe->nY; i++) {
     149        int y0 = (float)i * (float)image->numRows / (float)fringe->nY;
     150        int y1 = (float)(i + 1) * (float)image->numRows / (float)fringe->nY;
     151        for (int j = 0; j < fringe->nX; j++) {
     152            int x0 = (float)j * (float)image->numCols / (float)fringe->nX;
     153            int x1 = (float)(j + 1) * (float)image->numCols / (float)fringe->nX;
     154            psRegion region = psRegionSet(x0, x1, y0, y1);
     155            psImage *subImage = psImageSubset(image, region); // Subimage of the sky region
     156            psImage *subMask = psImageSubset(mask, region); // Subimage of the sky region
     157            psImageStats(median, subImage, subMask, maskVal);
     158            sky->data.F32[i][j] = median->sampleMedian;
     159        }
     160    }
    146161
    147162    for (int i = 0; i < fringe->x->n; i++) {
     
    150165        psImage *subImage = psImageSubset(image, region);
    151166        psImage *subMask = psImageSubset(mask, region);
    152         psImageStats(stats, subImage, subMask, maskVal);
    153 
    154         fPt[i] = stats->robustMedian;
    155         dfPt[i] = stats->robustStdev;
    156 
    157         psTrace(__func__, 7, "[%d:%d,%d:%d]: %f %f\n", region.x0, region.x1, region.y0, region.y1,
    158                 fPt[i], dfPt[i]);
     167        psImageStats(medianSd, subImage, subMask, maskVal);
     168        psFree(subImage);
     169        psFree(subMask);
     170
     171        int xSky = xPt[i] / (float)image->numCols * (float)sky->numCols;
     172        int ySky = yPt[i] / (float)image->numRows * (float)sky->numRows;
     173
     174        fPt[i] = medianSd->sampleMedian - sky->data.F32[ySky][xSky];
     175        dfPt[i] = 1.0 / medianSd->sampleStdev;
     176
     177        psTrace(__func__, 7, "[%d:%d,%d:%d]: %f %f\n", (int)region.x0, (int)region.x1,
     178                (int)region.y0, (int)region.y1, fPt[i], dfPt[i]);
    159179    }
    160180
     
    162182}
    163183
    164 // XXX include the fringe error (fringe->df) in the fit?
    165 pmFringeScale *pmFringeScaleMeasure(pmFringeStats *science, psArray *fringes)
    166 {
    167     pmFringeScale *scale = pmFringeScaleAlloc(fringes->n); // The resultant fringe scales
    168 
    169     int numCoeffs = fringes->n + 1;
    170     int numPoints = science->f->n;
    171 
    172     psImage *A = psImageAlloc(numCoeffs, numCoeffs, PS_TYPE_F64);
    173     psVector *B = psVectorAlloc(numCoeffs, PS_TYPE_F64);
     184//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     185// pmFringeScale
     186//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     187
     188static void fringeScaleFree(pmFringeScale *scale)
     189{
     190    psFree(scale->coeff);
     191    psFree(scale->coeffErr);
     192    return;
     193}
     194
     195pmFringeScale *pmFringeScaleAlloc(int nFringeFrames)
     196{
     197    pmFringeScale *scale = psAlloc(sizeof(pmFringeScale));
     198    (void)psMemSetDeallocator(scale, (psFreeFunc)fringeScaleFree);
     199
     200    scale->nFringeFrames = nFringeFrames;
     201    scale->coeff = psVectorAlloc(nFringeFrames + 1, PS_TYPE_F32);
     202    scale->coeffErr = psVectorAlloc(nFringeFrames + 1, PS_TYPE_F32);
     203    scale->coeff->n = nFringeFrames + 1;
     204    scale->coeff->n = nFringeFrames + 1;
     205
     206    return scale;
     207}
     208
     209// Determine the fringe scales through solving the least-squares problem
     210static bool scaleMeasure(pmFringeScale *scale, // Scale to return
     211                         pmFringeStats *science, // The fringe measurements for the science image
     212                         psArray *fringes // Array of fringe measurements for the templates
     213                        )
     214{
     215    assert(scale);
     216    assert(science);
     217    assert(fringes);
     218    assert(scale->nFringeFrames == fringes->n);
     219
     220    psVector *mask = science->regions->mask; // The region mask
     221
     222    int numCoeffs = fringes->n + 1;     // Number of coefficients: scales for the templates plus a background
     223    int numPoints = science->regions->nRequested; // Number of points (i.e., fringe measurements)
     224
     225    psImage *A = psImageAlloc(numCoeffs, numCoeffs, PS_TYPE_F64); // The least-squares matrix
     226    psVector *B = psVectorAlloc(numCoeffs, PS_TYPE_F64); // The least-squares vector
    174227    B->n = numCoeffs;
    175228
     229    // Generate the least-squares matrix and vector
    176230    for (int i = 0; i < numCoeffs; i++) {
    177         psVector *fringe1 = NULL;
     231        psVector *fringe1 = NULL;       // A fringe measurement
    178232        if (i != 0) {
    179233            pmFringeStats *fringe = fringes->data[i - 1];
    180234            fringe1 = fringe->f;
    181235        }
    182         for (int j = 0; j < numCoeffs; j++) {
    183             psVector *fringe2 = NULL;
     236
     237        // Fill in the upper part of the matrix
     238        for (int j = i; j < numCoeffs; j++) {
     239            psVector *fringe2 = NULL;   // Another fringe measurement
    184240            if (j != 0) {
    185241                pmFringeStats *fringe = fringes->data[j - 1];
     
    187243            }
    188244
    189             double sum = 0.0;
     245            double matrix = 0.0;        // The matrix sum
    190246            for (int k = 0; k < numPoints; k++) {
    191                 psF32 f1 = (fringe1 == NULL) ? 1.0 : fringe1->data.F32[k];
    192                 psF32 f2 = (fringe2 == NULL) ? 1.0 : fringe2->data.F32[k];
    193                 sum += f1*f2;
    194             }
    195             A->data.F64[i][j] = sum;
    196         }
    197 
    198         double sum = 0.0;
    199         for (int j = 0; j < numPoints; j++) {
    200             psF32 f1 = (fringe1 == NULL) ? 1.0 : fringe1->data.F32[j];
    201             psF32 f2 = science->f->data.F32[j];
    202             sum += f1*f2;
    203         }
    204         B->data.F64[i] = sum;
    205     }
    206 
     247                if (!mask->data.U8[k]) {
     248                    psF32 f1 = (fringe1) ? fringe1->data.F32[k] : 1.0; // Contribution from i fringe
     249                    psF32 f2 = (fringe2) ? fringe2->data.F32[k] : 1.0; // Contribution from j fringe
     250                    psF32 dsInv = science->df->data.F32[k]; // 1 / sigma
     251                    matrix += f1 * f2 * dsInv * dsInv;
     252                }
     253            }
     254            A->data.F64[i][j] = matrix;
     255        }
     256
     257        // Use symmetry to fill in the lower part of the matrix
     258        for (int j = 0; j < i; j++) {
     259            A->data.F64[i][j] = A->data.F64[j][i];
     260        }
     261
     262        double vector = 0.0;            // The vector sum
     263        for (int k = 0; k < numPoints; k++) {
     264            if (!mask->data.U8[k]) {
     265                psF32 f1 = (fringe1) ? fringe1->data.F32[k] : 1.0; // Contribution from fringe 1
     266                psF32 s = science->f->data.F32[k]; // Contribution from science measurement
     267                psF32 dsInv = science->df->data.F32[k]; // 1 / sigma
     268                vector += f1 * s * dsInv * dsInv;
     269            }
     270        }
     271        B->data.F64[i] = vector;
     272    }
     273
     274    if (psTraceGetLevel(__func__) >= 5) {
     275        printf("From %d points:\n", numPoints);
     276        for (int i = 0; i < numCoeffs; i++) {
     277            for (int j = 0; j < numCoeffs; j++) {
     278                printf("%.2e ", A->data.F64[i][j]);
     279            }
     280            printf("\n");
     281        }
     282    }
     283
     284    // Solve the least-squares equation
    207285    if (! psGaussJordan(A, B)) {
    208286        psError(PS_ERR_UNKNOWN, false, "Could not solve linear equations.  Returning NULL.\n");
    209     }
    210 
     287        return false;
     288    }
     289
     290    // Copy the results over
    211291    for (int i = 0; i < numCoeffs; i++) {
    212292        scale->coeff->data.F32[i] = B->data.F64[i];
     
    214294    }
    215295
     296    return true;
     297}
     298
     299// Measure the fringe differences for each region
     300static bool fringeScaleDiffs(psVector *diff, // Vector of differences
     301                             pmFringeStats *science, // Science fringe measurements
     302                             psArray *fringes, // Template fringe measurements
     303                             pmFringeScale *scale // Fringe scales
     304                            )
     305{
     306    assert(diff);
     307    assert(diff->type.type == PS_TYPE_F32);
     308    assert(science);
     309    assert(fringes);
     310    assert(scale);
     311    assert(diff->n == science->regions->nRequested);
     312    assert(fringes->n == scale->nFringeFrames);
     313
     314    psVector *mask = science->regions->mask; // The region mask
     315
     316    for (int i = 0; i < diff->n; i++) {
     317        if (!mask->data.U8[i]) {
     318            float difference = science->f->data.F32[i] - scale->coeff->data.F32[0];
     319            for (int j = 0; j < fringes->n; j++) {
     320                pmFringeStats *fringe = fringes->data[j]; // The fringe of interest
     321                difference -= scale->coeff->data.F32[j + 1] * fringe->f->data.F32[i];
     322            }
     323            diff->data.F32[i] = difference * difference * science->df->data.F32[i] * science->df->data.F32[i];
     324        }
     325    }
     326
     327    return true;
     328}
     329
     330// Clip regions based on the differences; return the number masked
     331static int clipRegions(psVector *diffs, // Differences
     332                       psVector *mask,  // Region mask
     333                       float rej        // Rejection limit in standard deviations
     334                      )
     335{
     336    assert(diffs);
     337    assert(diffs->type.type == PS_TYPE_F32);
     338    assert(mask);
     339    assert(mask->type.type == PS_TYPE_U8);
     340    assert(diffs->n == mask->n);
     341
     342    psStats *stats = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_QUARTILE); // Statistics
     343    psVectorStats(stats, diffs, NULL, mask, 1);
     344    float middle = stats->sampleMedian; // The middle of the distribution
     345    float thresh = rej * 0.74 * (stats->sampleUQ - stats->sampleLQ); // The rejection threshold
     346    psFree(stats);
     347
     348    int numClipped = 0;                 // Number clipped
     349    for (int i = 0; i < diffs->n; i++) {
     350        psTrace(__func__, 10, "Region %d (%d): %f\n", i, mask->data.U8[i], diffs->data.F32[i]);
     351        if (!mask->data.U8[i] && fabs(diffs->data.F32[i]) > middle + thresh) {
     352            psTrace(__func__, 5, "Masking %d: %f\n", i, diffs->data.F32[i]);
     353            mask->data.U8[i] = 1;
     354            numClipped++;
     355        }
     356    }
     357
     358    return numClipped;
     359}
     360
     361
     362// XXX include the fringe error (fringe->df) in the fit?
     363pmFringeScale *pmFringeScaleMeasure(pmFringeStats *science, psArray *fringes, float rej,
     364                                    unsigned int nIter, float keepFrac)
     365{
     366    pmFringeRegions *regions = science->regions; // The fringe regions
     367    int numRegions = regions->nRequested; // Number of regions
     368    if (!regions->mask) {
     369        regions->mask = psVectorAlloc(numRegions, PS_TYPE_U8);
     370        regions->mask->n = numRegions;
     371        psVectorInit(regions->mask, 0);
     372    }
     373
     374    psVector *mask = regions->mask;     // The region mask
     375    psStats *median = psStatsAlloc(PS_STAT_SAMPLE_MEDIAN); // Median statistics
     376    unsigned int numClipped = 0;        // Total number clipped
     377    psVector *diff = psVectorAlloc(numRegions, PS_TYPE_F32); // The differences between obs. and pred.
     378    diff->n = numRegions;
     379
     380    pmFringeScale *scale = pmFringeScaleAlloc(fringes->n); // The fringe scales
     381
     382    // Get rid of bad data points
     383    for (int i = 0; i < fringes->n; i++) {
     384        pmFringeStats *fringe = fringes->data[i]; // The fringe of interest
     385        for (int j = 0; j < numRegions; j++) {
     386            if (!finite(fringe->f->data.F32[j])) {
     387                mask->data.U8[j] = 1;
     388                psTrace(__func__, 9, "Masking region %d because not finite in fringe %d.\n", j, i);
     389            }
     390        }
     391    }
     392
     393    // Get rid of the extreme outliers by assuming most of the points are somewhat clustered
     394    psVectorStats(median, science->f, NULL, NULL, 0);
     395    scale->coeff->data.F32[0] = median->sampleMedian;
     396    for (int i = 0; i < fringes->n; i++) {
     397        pmFringeStats *fringe = fringes->data[i]; // The fringe of interest
     398        psVectorStats(median, fringe->f, NULL, NULL, 0);
     399        scale->coeff->data.F32[0] -= median->sampleMedian;
     400        scale->coeff->data.F32[i] = 0.0;
     401    }
     402    psFree(median);
     403    fringeScaleDiffs(diff, science, fringes, scale);
     404    numClipped = clipRegions(diff, mask, 3.0*rej);
     405    psTrace(__func__, 4, "%d regions clipped in initial pass.\n", numClipped);
     406
     407    unsigned int iter = 0;              // Iteration number
     408    unsigned int iterClip = 0;          // Number clipped in this iteration
     409    do {
     410        iter++;
     411        scaleMeasure(scale, science, fringes); // The scales
     412        psTrace(__func__, 1, "Fringe scales after iteration %d:\n", iter);
     413        psTrace(__func__, 1, "Background: %f %f\n", scale->coeff->data.F32[0], scale->coeffErr->data.F32[0]);
     414        for (int i = 0; i < scale->nFringeFrames; i++) {
     415            psTrace(__func__, 1, "%d: %f %f\n", i, scale->coeff->data.F32[i + 1],
     416                    scale->coeffErr->data.F32[i + 1]);
     417        }
     418
     419        fringeScaleDiffs(diff, science, fringes, scale);
     420        iterClip = clipRegions(diff, mask, rej); // Number clipped
     421        numClipped += iterClip;
     422        psTrace(__func__, 9, "Clipped: %d\tFrac: %f\n", iterClip, (float)numClipped/(float)numRegions);
     423    } while (iterClip > 0 && iter < nIter && (float)numClipped/(float)numRegions <= 1.0 - keepFrac);
     424    psFree(diff);
     425
     426    // A final iteration with the last clipping
     427    scaleMeasure(scale, science, fringes);
     428
    216429    return scale;
    217430}
    218431
     432//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     433// Fringe correction
     434//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     435
    219436// XXX note that this modifies the input fringe images
    220 psImage *pmFringeCorrect(pmReadout *readout, pmFringeRegions *fringes, psArray *fringeImages, psArray *fringeStats, psMaskType maskVal)
     437psImage *pmFringeCorrect(pmReadout *readout, pmFringeRegions *fringes, psArray *fringeImages,
     438                         psArray *fringeStats, psMaskType maskVal, float rej,
     439                         unsigned int nIter, float keepFrac)
    221440{
    222441    // measure the fringe stats for the science frame and solve for the scales
    223442    pmFringeStats *scienceStats = pmFringeStatsMeasure(fringes, readout, maskVal);
    224     pmFringeScale *scale = pmFringeScaleMeasure(scienceStats, fringeStats);
     443
     444    if (psTraceGetLevel(__func__) > 9) {
     445        for (int i = 0; i < fringes->nRequested; i++) {
     446            printf("%f", scienceStats->f->data.F32[i]);
     447            for (int j = 0; j < fringeStats->n; j++) {
     448                pmFringeStats *fringe = fringeStats->data[j];
     449                printf("\t%f", fringe->f->data.F32[i]);
     450            }
     451            printf("\n");
     452        }
     453    }
     454
     455    pmFringeScale *scale = pmFringeScaleMeasure(scienceStats, fringeStats, rej, nIter, keepFrac);
    225456    psFree(scienceStats);
    226457
    227458    psTrace(__func__, 7, "Fringe solution:\n");
    228     for (int i = 0; i < fringeImages->n; i++) {
     459    for (int i = 0; i < fringeImages->n + 1; i++) {
    229460        psTrace(__func__, 7, "%d: %f %f\n", i, scale->coeff->data.F32[i],
    230461                scale->coeffErr->data.F32[i]);
     
    234465    // XXX we could save data space by making the first image the output image
    235466    psImage *sumFringe = psImageAlloc(readout->image->numCols, readout->image->numRows, PS_TYPE_F32);
     467    //psBinaryOp(sumFringe, sumFringe, "+", psScalarAlloc(scale->coeff->data.F32[0], PS_TYPE_F32));
    236468    for (int i = 0; i < fringeImages->n; i++) {
    237469
  • trunk/psModules/src/detrend/pmFringeStats.h

    r6921 r6957  
    55 *  @author Eugene Magnier, IfA
    66 *
    7  *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
    8  *  @date $Date: 2006-04-20 04:28:00 $
     7 *  @version $Revision: 1.4 $ $Name: not supported by cvs2svn $
     8 *  @date $Date: 2006-04-22 03:21:00 $
    99 *
    1010 *  Copyright 2004 IfA, University of Hawaii
     
    1313# ifndef PM_FRINGE_STATS
    1414# define PM_FRINGE_STATS
     15
     16//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     17// pmFringeRegions
     18//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    1519
    1620/** Structure to hold the fringe measurement regions.
     
    3034pmFringeRegions;
    3135
     36/// Allocate fringe regions
    3237pmFringeRegions *pmFringeRegionsAlloc (
    3338    int nPts,     // number of points to create
     
    3742    int nY    // smoothing scale in y
    3843);
     44
     45// Generate the fringe points
     46bool pmFringeRegionsCreatePoints(pmFringeRegions *fringe, // Fringe regions
     47                                 const psImage *image // Image for the regions (defines the size)
     48                                );
     49
     50
     51//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     52// pmFringeStats
     53//////////////////////////////////////////////////////////////////////////////////////////////////////////////
    3954
    4055/** Structure to hold the fringe measurements for a particular image
     
    4863pmFringeStats;
    4964
    50 pmFringeStats *pmFringeStatsAlloc(pmFringeRegions *regions);
    51 
    52 // Generate the fringe points
    53 bool pmFringeRegionsCreatePoints(pmFringeRegions *fringe, psImage *image);
    54 
    55 /** the pmFringeScale structure defines the relationship between two fringe measurements
    56  */
    57 typedef struct
    58 {
    59     int nFringeFrames;
    60     psVector *coeff;
    61     psVector *coeffErr;
    62 }
    63 pmFringeScale;
     65/// Allocate fringe statistics
     66pmFringeStats *pmFringeStatsAlloc(pmFringeRegions *regions // The fringe regions which will be measured
     67                                 );
    6468
    6569/** Measure the fringe stats for an image
     
    7882);
    7983
     84
     85//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     86// pmFringeScale
     87//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     88
     89/** the pmFringeScale structure defines the relationship between two fringe measurements
     90 */
     91typedef struct
     92{
     93    int nFringeFrames;
     94    psVector *coeff;
     95    psVector *coeffErr;
     96}
     97pmFringeScale;
     98
     99/** Determine the scales for the fringe correction
     100 *
     101 * Given an input fringe measurement, and an array of template fringe measurements, measure the contribution
     102 * of each of the templates to the input.  Rejection is performed on the fringe regions, to weed out stars
     103 * etc.
     104 *
     105 * @return pmFringeScale*
     106 */
     107pmFringeScale *pmFringeScaleMeasure(pmFringeStats *science, // Fringe measurements from science image
     108                                    psArray *fringes, // Array of fringe measurements from templates
     109                                    float rej, // Rejection threshold (in standard deviations)
     110                                    unsigned int nIter, // Maximum number of iterations
     111                                    float keepFrac // Minimum fraction of regions to keep
     112                                   );
     113
     114/// Allocate fringe scales
     115pmFringeScale *pmFringeScaleAlloc(int nFringeFrames // Number of fringe frames
     116                                 );
     117
     118
     119//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     120// Fringe correction
     121//////////////////////////////////////////////////////////////////////////////////////////////////////////////
     122
    80123/** Fringe correct the science image
    81124 *
     
    89132                         psArray *fringeImages, // fringe images to use in correction
    90133                         psArray *fringeStats, // fringe stats to use in correction
    91                          psMaskType maskVal // Value to mask
     134                         psMaskType maskVal, // Value to mask
     135                         float rej,     // Rejection threshold, for pmFringeScaleMeasure
     136                         unsigned int nIter, // Maximum number of iterations, for pmFringeScaleMeasure
     137                         float keepFrac // Minimum fraction of regions to keep, for pmFringeScaleMeasure
    92138                        );
    93139
     140
    94141# endif
Note: See TracChangeset for help on using the changeset viewer.