IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jan 13, 2006, 8:24:10 PM (21 years ago)
Author:
eugene
Message:

substantial work on the aperture residuals

File:
1 edited

Legend:

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

    r5952 r5980  
    11# include "psphot.h"
    22
    3 bool psphotApResid (psArray *sources, psMetadata *config, pmPSF *psf) {
     3psPolynomial4D *psVectorChiClipFitPolynomial4D(
     4    psPolynomial4D *poly,
     5    psStats *stats,
     6    const psVector *mask,
     7    psMaskType maskValue,
     8    const psVector *f,
     9    const psVector *fErr,
     10    const psVector *x,
     11    const psVector *y,
     12    const psVector *z,
     13    const psVector *t)
     14{
     15    PS_ASSERT_POLY_NON_NULL(poly, NULL);
     16    PS_ASSERT_POLY_TYPE(poly, PS_POLYNOMIAL_ORD, NULL);
     17    PS_ASSERT_PTR_NON_NULL(stats, NULL);
     18    PS_ASSERT_VECTOR_NON_NULL(f, NULL);
     19    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(f, NULL);
     20    if (mask != NULL) {
     21        PS_ASSERT_VECTORS_SIZE_EQUAL(f, mask, NULL);
     22        PS_ASSERT_VECTOR_TYPE(mask, PS_TYPE_U8, NULL);
     23    }
     24    PS_ASSERT_VECTOR_NON_NULL(x, NULL);
     25    PS_ASSERT_VECTORS_SIZE_EQUAL(f, x, NULL);
     26    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(x, NULL);
     27    PS_ASSERT_VECTOR_NON_NULL(y, NULL);
     28    PS_ASSERT_VECTORS_SIZE_EQUAL(f, y, NULL);
     29    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(y, NULL);
     30    PS_ASSERT_VECTOR_NON_NULL(z, NULL);
     31    PS_ASSERT_VECTORS_SIZE_EQUAL(f, z, NULL);
     32    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(z, NULL);
     33    PS_ASSERT_VECTOR_NON_NULL(t, NULL);
     34    PS_ASSERT_VECTORS_SIZE_EQUAL(f, t, NULL);
     35    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(t, NULL);
     36    PS_ASSERT_VECTOR_NON_NULL(fErr, NULL);
     37    PS_ASSERT_VECTORS_SIZE_EQUAL(fErr, mask, NULL);
     38    PS_ASSERT_VECTOR_TYPE_F32_OR_F64(fErr, NULL);
     39
     40    // clipping range defined by min and max and/or clipSigma
     41    float minClipSigma;
     42    float maxClipSigma;
     43    if (isfinite(stats->max)) {
     44        maxClipSigma = +fabs(stats->max);
     45    } else {
     46        maxClipSigma = +fabs(stats->clipSigma);
     47    }
     48    if (isfinite(stats->min)) {
     49        minClipSigma = -fabs(stats->min);
     50    } else {
     51        minClipSigma = -fabs(stats->clipSigma);
     52    }
     53    psVector *fit   = NULL;
     54    psVector *resid = psVectorAlloc (x->n, PS_TYPE_F64);
     55
     56    // eventual expansion: user supplies one of various stats option pairs,
     57    // eg (SAMPLE_MEAN | SAMPLE_STDEV) and the correct pair is used to
     58    // evaluate the clipping sigma
     59    // for now, for the SAMPLE_MEDIAN and SAMPLE_STDEV to be used
     60    stats->options |= (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
     61
     62    for (int N = 0; N < stats->clipIter; N++) {
     63        int Nkeep = 0;
     64
     65        poly = psVectorFitPolynomial4D (poly, mask, maskValue, f, fErr, x, y, z, t);
     66        fit = psPolynomial4DEvalVector (poly, x, y, z, t);
     67        resid = (psVector *) psBinaryOp (resid, (void *) f, "-", (void *) fit);
     68
     69        stats  = psVectorStats (stats, resid, NULL, mask, maskValue);
     70        psTrace (".psphot.VectorClipFit", 5, "resid stats: %f +/- %f\n", stats->sampleMedian, stats->sampleStdev);
     71
     72        // set mask if pts are not valid
     73        // we are masking out any point which is out of range
     74        // recovery is not allowed with this scheme
     75        for (int i = 0; i < resid->n; i++) {
     76            if ((mask != NULL) && (mask->data.U8[i] & maskValue)) {
     77                continue;
     78            }
     79            float sigma = hypot (psVectorGet (fErr, i), stats->sampleStdev);
     80            if (resid->data.F64[i] - stats->sampleMedian > sigma*maxClipSigma) {
     81                if (mask != NULL) {
     82                    mask->data.U8[i] |= 0x01;
     83                }
     84                continue;
     85            }
     86            if (resid->data.F64[i] - stats->sampleMedian < sigma*minClipSigma) {
     87                if (mask != NULL) {
     88                    mask->data.U8[i] |= 0x01;
     89                }
     90                continue;
     91            }
     92            Nkeep ++;
     93        }
     94
     95        psTrace (".psphot.VectorClipFit", 4, "keeping %d of %d pts for fit\n",
     96                 Nkeep, x->n);
     97
     98        stats->clippedNvalues = Nkeep;
     99        psFree (fit);
     100    }
     101    // Free local temporary variables
     102    psFree (resid);
     103
     104    if (poly == NULL) {
     105        psError(PS_ERR_UNKNOWN, true, "Could not fit a polynomial to the data.  Returning NULL.\n");
     106        return(NULL);
     107    }
     108    return(poly);
     109}
     110
     111// measure the aperture residual statistics
     112bool psphotApResid (eamReadout *imdata, psArray *sources, psMetadata *config, pmPSF *psf) {
    4113
    5114    int Npsf;
     
    8117    pmSource *source;
    9118
    10     // XXX EAM : check that PSF_FIT_RADIUS < SKY_OUTER_RADIUS
    11     float RADIUS = psMetadataLookupF32 (&status, config, "PSF_FIT_RADIUS");
    12 
    13119    psTimerStart ("psphot");
    14120
    15     // XXX EAM : drop this if we know the list is sorted
    16     sources = psArraySort (sources, psphotSortBySN);
    17 
     121    // measure the aperture loss as a function of radius for PSF
     122    float REF_RADIUS = psMetadataLookupF32 (&status, config, "PSF_REF_RADIUS");
     123    psf->growth = pmGrowthCurveAlloc (3.0, REF_RADIUS, 0.1);
     124    psphotGrowthCurve (imdata, psf);
     125   
    18126    psVector *mask    = psVectorAlloc (300, PS_TYPE_U8);
    19127    psVector *xPos    = psVectorAlloc (300, PS_TYPE_F64);
    20128    psVector *yPos    = psVectorAlloc (300, PS_TYPE_F64);
    21     psVector *rflux   = psVectorAlloc (300, PS_TYPE_F64);
     129    psVector *flux    = psVectorAlloc (300, PS_TYPE_F64);
     130    psVector *r2rflux = psVectorAlloc (300, PS_TYPE_F64);
    22131    psVector *apResid = psVectorAlloc (300, PS_TYPE_F64);
    23     mask->n = xPos->n = yPos->n = rflux->n = apResid->n = 0;
     132    psVector *dMag    = psVectorAlloc (300, PS_TYPE_F64);
     133    mask->n = xPos->n = yPos->n = flux->n = r2rflux->n = apResid->n = dMag->n = 0;
    24134    Npsf = 0;
    25135
    26     // select the NNN brightest, non-saturated sources, or just select PSFSTARs?
    27     for (int i = 0; (i < sources->n) && (Npsf < 300); i++) {
     136    // select all good PM_SOURCE_STAR entries
     137    for (int i = 0; i < sources->n; i++) {
    28138        source = sources->data[i];
    29139
     
    34144        if (source->mode &  PM_SOURCE_POOR) continue;
    35145
    36         // get magnitudes, uncorrected for (x, y, rflux)
    37         model = pmSourceMagnitudes (source, NULL, RADIUS);
     146        // get uncorrected magnitudes in scaled apertures
     147        model = pmSourceMagnitudes (source, NULL, 0);
    38148        if (model == NULL) continue;
    39149
     
    41151        xPos->data.F64[Npsf] = model->params->data.F32[2];
    42152        yPos->data.F64[Npsf] = model->params->data.F32[3];
    43         rflux->data.F64[Npsf] = pow(10.0, 0.4*source->fitMag);
    44         apResid->data.F64[Npsf] = source->apMag - source->fitMag;
    45 
    46         psVectorExtend (mask, 100, 1);
    47         psVectorExtend (xPos, 100, 1);
    48         psVectorExtend (yPos, 100, 1);
    49         psVectorExtend (rflux, 100, 1);
     153
     154        flux->data.F64[Npsf] = pow(10.0, -0.4*source->fitMag);
     155        r2rflux->data.F64[Npsf] = PS_SQR(model->radius) / flux->data.F64[Npsf];
     156       
     157        apResid->data.F64[Npsf] = source->apMag + pmGrowthCurveCorrect (psf->growth, model->radius) - source->fitMag ;
     158
     159        // XXX sanity clip?
     160        // XXX need to see if all data were tossed?
     161        // XXX need to subtract median?
     162        if (fabs(apResid->data.F64[Npsf]) > 0.2) continue;
     163
     164        dMag->data.F64[Npsf] = model->dparams->data.F32[1] / model->params->data.F32[1];
     165
     166        psVectorExtend (mask,    100, 1);
     167        psVectorExtend (xPos,    100, 1);
     168        psVectorExtend (yPos,    100, 1);
     169        psVectorExtend (flux,    100, 1);
     170        psVectorExtend (r2rflux, 100, 1);
     171        psVectorExtend (dMag,    100, 1);
    50172        psVectorExtend (apResid, 100, 1);
    51173        Npsf ++;
    52174    }
    53     psLogMsg ("psphot.apresid", 4, "measure aperture residuals : %f sec\n", psTimerMark ("psphot"));
     175    psLogMsg ("psphot.apresid", 4, "measure aperture residuals : %f sec for %d objects\n", psTimerMark ("psphot"), Npsf);
     176
     177    // APTREND options : NONE SKYBIAS XY_LIN XY_QUAD SKY_XY_LIN FULL
     178    char *ApTrendOption = psMetadataLookupPtr (&status, config, "APTREND");
     179    if (!status) ApTrendOption = psStringCopy ("SKYBIAS");
    54180
    55181    // 3hi/1lo sigma clipping on the rflux vs metric fit
    56182    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN | PS_STAT_SAMPLE_STDEV);
    57     stats->min = 1.0;
     183    stats->min = 3.0;
    58184    stats->max = 3.0;
    59     stats->clipIter = 3;
    60 
    61     // first clip out objects which are too far from the median
    62     stats->clipIter = 1;
    63     maskToConstant (psf->ApTrend);
    64     psf->ApTrend  = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux);
    65 
    66     // next, fit just SkyBias and clip out objects which are too far from the median
    67     stats->clipIter = 2;
    68     maskToSkyBias (psf->ApTrend);
    69     psf->ApTrend  = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux);
    70 
    71     // finally, fit x, y, SkyBias and clip out objects which are too far from the median
    72     stats->clipIter = 2;
    73     maskToDefault (psf->ApTrend);
    74     psf->ApTrend  = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux);
    75 
    76     // linear clipped fit of apResid to rflux, xPos, yPos
    77     # if (0)
    78     psf->ApTrend  = psVectorClipFitPolynomial3D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, NULL, xPos, yPos, rflux);
    79     psf->skyBias  = psf->ApTrend->coeff[0][0][1] / (M_PI * PS_SQR(RADIUS));
    80     psf->ApResid  = psf->ApTrend->coeff[0][0][0];
    81     psf->dApResid = stats->sampleStdev;
    82     psf->ApTrend->coeff[0][0][1] = 0;
    83     # endif
     185
     186    // constant only
     187    if (!strcasecmp (ApTrendOption, "CONSTANT")) {
     188        stats->clipIter = 2;
     189        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     190        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     191
     192        stats->clipIter = 3;
     193        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     194        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     195    }
     196
     197    // constant and skybias only
     198    if (!strcasecmp (ApTrendOption, "SKYBIAS")) {
     199        // first clip out objects which are too far from the median
     200        stats->clipIter = 2;
     201        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     202        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     203
     204        // apply the fit
     205        stats->clipIter = 3;
     206        pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS);
     207        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     208    }
     209
     210    if (!strcasecmp (ApTrendOption, "SKYSAT")) {
     211        // first clip out objects which are too far from the median
     212        stats->clipIter = 2;
     213        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     214        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     215
     216        // apply the fit
     217        stats->clipIter = 2;
     218        pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS);
     219        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     220
     221        // apply the fit
     222        stats->clipIter = 3;
     223        pmPSF_MaskApTrend (psf, PM_PSF_SKYSAT);
     224        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     225    }
     226
     227    // constant and linear X,Y only
     228    if (!strcasecmp (ApTrendOption, "XY_LIN")) {
     229        // first clip out objects which are too far from the median
     230        stats->clipIter = 2;
     231        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     232        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     233
     234        // apply the fit
     235        stats->clipIter = 3;
     236        pmPSF_MaskApTrend (psf, PM_PSF_XY_LIN);
     237        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     238    }
     239
     240    // constant and quadratic X,Y only
     241    if (!strcasecmp (ApTrendOption, "XY_QUAD")) {
     242        // first clip out objects which are too far from the median
     243        stats->clipIter = 2;
     244        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     245        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     246
     247        // apply the fit
     248        stats->clipIter = 3;
     249        pmPSF_MaskApTrend (psf, PM_PSF_XY_QUAD);
     250        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     251    }
     252
     253     // constant and sky, linear X,Y only
     254    if (!strcasecmp (ApTrendOption, "SKY_XY_LIN")) {
     255        // first clip out objects which are too far from the median
     256        stats->clipIter = 2;
     257        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     258        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     259
     260        // apply the fit
     261        stats->clipIter = 3;
     262        pmPSF_MaskApTrend (psf, PM_PSF_SKY_XY_LIN);
     263        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     264    }
     265
     266     // constant and sky, linear X,Y only
     267    if (!strcasecmp (ApTrendOption, "SKYSAT_XY_LIN")) {
     268        // first clip out objects which are too far from the median
     269        stats->clipIter = 2;
     270        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     271        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     272
     273        // apply the fit
     274        stats->clipIter = 3;
     275        pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS);
     276        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     277
     278        // apply the fit
     279        stats->clipIter = 3;
     280        pmPSF_MaskApTrend (psf, PM_PSF_SKYSAT_XY_LIN);
     281        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     282    }
     283
     284    if (!strcasecmp (ApTrendOption, "ALL")) {
     285        // first clip out objects which are too far from the median
     286        stats->clipIter = 2;
     287        pmPSF_MaskApTrend (psf, PM_PSF_CONSTANT);
     288        psf->ApTrend  = psVectorClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     289
     290        // fit just SkyBias and clip out objects which are too far from the median
     291        stats->clipIter = 2;
     292        pmPSF_MaskApTrend (psf, PM_PSF_SKYBIAS);
     293        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     294
     295        // finally, fit x, y, SkyBias and clip out objects which are too far from the median
     296        stats->clipIter = 3;
     297        pmPSF_MaskApTrend (psf, PM_PSF_ALL);
     298        psf->ApTrend  = psVectorChiClipFitPolynomial4D (psf->ApTrend, stats, mask, PSFTRY_MASK_ALL, apResid, dMag, xPos, yPos, r2rflux, flux);
     299    }
     300
     301# if (1)
     302    psPolynomial4D *poly = psf->ApTrend;
     303    for (int nt = 0; nt <= poly->nT; nt++) {
     304        for (int nz = 0; nz <= poly->nZ; nz++) {
     305            for (int ny = 0; ny <= poly->nY; ny++) {
     306                for (int nx = 0; nx <= poly->nX; nx++) {
     307                    if (poly->mask[nx][ny][nz][nt]) continue;
     308                    fprintf (stderr, "%d %d %d %d : %22.15g\n", nx, ny, nz, nt, poly->coeff[nx][ny][nz][nt]);
     309                }
     310            }
     311        }
     312    }
     313# endif
     314
     315    // construct the fitted values and the residuals
     316    psVector *fit   = psPolynomial4DEvalVector (psf->ApTrend, xPos, yPos, r2rflux, flux);
     317    psVector *resid = (psVector *) psBinaryOp (NULL, (void *) apResid, "-", (void *) fit);
     318
     319# if (0)
     320    FILE *fout = fopen ("resid.dat", "w");
     321    for (int i = 0; i < resid->n; i++) {
     322        fprintf (fout, "%d %f %f %f %f  %f %f %f %f %d\n",
     323                 i,
     324                 (float) psVectorGet(xPos, i), (float) psVectorGet(yPos, i), (float) psVectorGet(r2rflux, i), (float) psVectorGet(flux, i),
     325                 (float) psVectorGet(apResid, i), (float) psVectorGet(fit, i), (float) psVectorGet(resid, i), (float) psVectorGet(dMag, i),
     326                 mask->data.U8[i]);
     327    }
     328    fclose (fout);
     329# endif
     330
     331    // measure scatter for sources with dMag < 0.01 (S/N = 100)
     332    psStats *residStats = psStatsAlloc (PS_STAT_SAMPLE_STDEV);
     333    for (int i = 0; i < dMag->n; i++) {
     334        if (dMag->data.F64[i] > 0.01) {
     335            mask->data.U8[i] |= 0x02;
     336        }
     337    }
     338    residStats  = psVectorStats (residStats, resid, NULL, mask, 0x03);
     339
     340    // apply ApTrend results
     341    psf->skyBias  = psf->ApTrend->coeff[0][0][1][0];
     342    psf->skySat   = psf->ApTrend->coeff[0][0][0][1];
     343    psf->ApResid  = psf->ApTrend->coeff[0][0][0][0];
     344    psf->dApResid = residStats->sampleStdev;
     345    psf->ApTrend->coeff[0][0][1][0] = 0;
     346    psf->ApTrend->coeff[0][0][0][1] = 0;
     347    psf->nApResid = residStats->clippedNvalues;
    84348
    85349    /*
     
    89353    */
    90354
    91     # if (0)
    92     psPolynomial3D *poly = psf->ApTrend;
    93     for (int nz = 0; nz <= poly->nZ; nz++) {
    94         for (int ny = 0; ny <= poly->nY; ny++) {
    95             for (int nx = 0; nx <= poly->nX; nx++) {
    96                 fprintf (stderr, "%d %d %d : %22.15g\n", nx, ny, nz, poly->coeff[nx][ny][nz]);
    97             }
    98         }
    99     }
    100     # endif
    101 
    102355    psLogMsg ("psphot.apresid", 3, "measure full-frame aperture residual: %f sec\n", psTimerMark ("psphot"));
    103356    psLogMsg ("psphot.apresid", 4, "aperture residual: %f +/- %f : %f bias\n", psf->ApResid, psf->dApResid, psf->skyBias);
    104 
    105     psFree (stats);
    106     psFree (mask);
    107     psFree (rflux);
    108     psFree (apResid);
     357    psLogMsg ("psphot.apresid", 4, "apresid trends: %f %f %f %f %f\n",
     358              1e3*psf->ApTrend->coeff[1][0][0][0],
     359              1e6*psf->ApTrend->coeff[2][0][0][0],
     360              1e6*psf->ApTrend->coeff[1][1][0][0],
     361              1e3*psf->ApTrend->coeff[0][1][0][0],
     362              1e6*psf->ApTrend->coeff[0][2][0][0]);
     363
     364    // psFree (stats);
     365    // psFree (mask);
     366    // psFree (rflux);
     367    // psFree (apResid);
    109368
    110369    return true;
    111370}
     371
Note: See TracChangeset for help on using the changeset viewer.