IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 31361


Ignore:
Timestamp:
Apr 24, 2011, 10:09:38 PM (15 years ago)
Author:
eugene
Message:

determine the min kron radius = radius for bright PSF stars; mask interpolation used index instead of pixel coordinates in psImageInterpolate; add minKronRadius to pmSource; change errMag to psfMagErr; in growth curve, avoid perfect int radii (they can be inconsistent on + and - due to float precision; add pmGrowthCurveForSources; psfMagErr is always calculated from psfModel; apply ApTrend to all source psf mags and fluxes (not just psf sources); always use the psfModel for PSF_QF,_PERFECT; use BILINEAR to interpolate for aperture mags (BIQUAD implementation is wrong; apply growth curve to apMag & apFlux for all sources; save GrowthCurve with PSF model and read from PSF model

Location:
branches/eam_branches/ipp-20110404/psModules/src
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ipp-20110404/psModules/src/camera/pmFPAMaskWeight.c

    r29544 r31361  
    587587                double imageValue, varianceValue; // Image and variance value from interpolation
    588588                psImageMaskType maskValue = 0; // Mask value from interpolation
    589                 psImageInterpolateStatus status = psImageInterpolate(&imageValue, &varianceValue, &maskValue, x, y, interp);
     589
     590                // interpolate to pixel center (index + 0.5)
     591                psImageInterpolateStatus status = psImageInterpolate(&imageValue, &varianceValue, &maskValue, x + 0.5, y + 0.5, interp);
    590592                if (status == PS_INTERPOLATE_STATUS_ERROR || status == PS_INTERPOLATE_STATUS_OFF) {
    591593                    psError(PS_ERR_UNKNOWN, false, "Unable to interpolate readout at %d,%d", x, y);
  • branches/eam_branches/ipp-20110404/psModules/src/imcombine/pmPSFEnvelope.c

    r29543 r31361  
    380380
    381381        // measure the source moments: tophat windowing, no pixel S/N cutoff
    382         if (!pmSourceMoments(source, maxRadius, 0.0, 0.0, maskVal)) {
     382        if (!pmSourceMoments(source, maxRadius, 0.0, 0.0, 0.0, maskVal)) {
    383383            // Can't do anything about it; limp along as best we can
    384384            psErrorClear();
  • branches/eam_branches/ipp-20110404/psModules/src/objects/Makefile.am

    r31153 r31361  
    114114        pmTrend2D.h \
    115115        pmGrowthCurve.h \
     116        pmGrowthCurveGenerate.h \
    116117        pmSourceMatch.h \
    117118        pmDetEff.h \
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmGrowthCurve.c

    r29004 r31361  
    8181    while (radius < Rlin) {
    8282        // fprintf (stderr, "r: %f\n", radius);
    83         psVectorAppend (growth->radius, radius);
     83        psVectorAppend (growth->radius, radius - 0.001);
    8484        radius += 1.0;
    8585    }   
    8686    while (radius < maxRadius) {
    8787        // fprintf (stderr, "r: %f\n", radius);
    88         psVectorAppend (growth->radius, radius);
     88        psVectorAppend (growth->radius, radius - 0.001);
    8989        radius *= fR;
    9090        radius = (int) (radius + 0.5);
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmGrowthCurveGenerate.c

    r31327 r31361  
    5050
    5151#include "pmSourcePhotometry.h"
    52 
    53 pmGrowthCurve *pmGrowthCurveForPosition (psImage *image, pmPSF *psf, bool ignore, psImageMaskType maskVal, psImageMaskType markVal, float xc, float yc);
     52#include "pmGrowthCurveGenerate.h"
    5453
    5554/*****************************************************************************/
     
    226225    return growth;
    227226}
     227
     228// we generate the growth curve for the center of the image with the specified psf model
     229bool pmGrowthCurveGenerateFromSources (pmReadout *readout, pmPSF *psf, psArray *sources, bool INTERPOLATE_AP, psImageMaskType maskVal, psImageMaskType markVal)
     230{
     231    PS_ASSERT_PTR_NON_NULL(readout, false);
     232    PS_ASSERT_PTR_NON_NULL(readout->image, false);
     233
     234    // maskVal is used to test for rejected pixels, and must include markVal
     235    maskVal |= markVal;
     236
     237    pmSourcePhotometryMode photMode = INTERPOLATE_AP ? PM_SOURCE_PHOT_INTERP : 0;
     238   
     239    // measure the growth curve for each PSF source and average them together
     240    psArray *growths = psArrayAllocEmpty (100);
     241
     242    for (int i = 0; i < sources->n; i++) {
     243
     244        pmSource *source = sources->data[i];
     245
     246        if (!(source->mode & PM_SOURCE_MODE_PSFSTAR)) continue;
     247
     248        pmGrowthCurve *growth = pmGrowthCurveForSource (source, psf, photMode, maskVal, markVal);
     249        if (!growth) continue;
     250       
     251        psArrayAdd (growths, 100, growth);
     252        psFree (growth);
     253    }
     254    psAssert (growths->n, "cannot build growth curve (no valid PSF stars?)");
     255
     256# if (0)
     257    FILE *f = fopen ("growth.dat", "w");
     258    assert (f);
     259
     260    for (int j = 0; j < psf->growth->radius->n; j++) {
     261
     262        fprintf (f, "%f : ", psf->growth->radius->data.F32[j]);
     263
     264        // XXX dump the growth curves:
     265        for (int i = 0; i < growths->n; i++) {
     266           
     267            pmGrowthCurve *growth = growths->data[i];
     268            if (!growth) continue;
     269
     270            fprintf (f, "%8.4f ", growth->apMag->data.F32[j]);
     271        }
     272        fprintf (f, "\n");
     273    }
     274    fclose (f);
     275# endif
     276
     277    // just use a simple sample median to get the 'best' value from each growth curve...
     278    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     279
     280    psVector *values = psVectorAlloc (growths->n, PS_DATA_F32);
     281
     282    // loop over a range of source fluxes
     283    // no need to interpolate since we have forced the object center
     284    // to 0.5, 0.5 above
     285    for (int i = 0; i < psf->growth->radius->n; i++) {
     286
     287        // median the values for each radial bin
     288        values->n = 0;
     289        for (int j = 0; j < growths->n; j++) {
     290            pmGrowthCurve *growth = growths->data[j];
     291            if (!isfinite(growth->apMag->data.F32[i])) continue;
     292            psVectorAppend (values, growth->apMag->data.F32[i] - growth->fitMag);
     293        }
     294        if (values->n == 0) {
     295            psf->growth->apMag->data.F32[i] = NAN;
     296        } else {
     297            if (!psVectorStats (stats, values, NULL, NULL, 0)) {
     298                psError(PS_ERR_UNKNOWN, false, "failure to measure stats");
     299                return false;
     300            }
     301            psf->growth->apMag->data.F32[i] = stats->sampleMedian;
     302        }
     303    }
     304
     305    psf->growth->fitMag = psf->growth->apMag->data.F32[psf->growth->radius->n-1];
     306    psf->growth->apRef = psVectorInterpolate (psf->growth->radius, psf->growth->apMag, psf->growth->refRadius);
     307    psf->growth->apLoss = psf->growth->fitMag - psf->growth->apRef;
     308
     309    psLogMsg ("psphot.growth", 4, "GrowthCurve : apLoss : %f (fitMag - apMag @ ref : %f - %f)\n", psf->growth->apLoss, psf->growth->fitMag, psf->growth->apRef);
     310
     311    psFree (growths);
     312    psFree (stats);
     313    psFree (values);
     314
     315    return true;
     316}
     317
     318pmGrowthCurve *pmGrowthCurveForSource (pmSource *source, pmPSF *psf, pmSourcePhotometryMode photMode, psImageMaskType maskVal, psImageMaskType markVal) {
     319
     320    float radius;
     321
     322    assert (psf->growth);
     323
     324    float minRadius = psf->growth->radius->data.F32[0];
     325    pmGrowthCurve *growth = pmGrowthCurveAlloc (minRadius, psf->growth->maxRadius, psf->growth->refRadius);
     326
     327    // measure the fitMag for this source (for normalization)
     328    // pmSourcePhotometryModel (&fitMag, NULL, source->psfModel);
     329    growth->fitMag = source->psfMag;
     330
     331    float xc = source->peak->xf;
     332    float yc = source->peak->yf;
     333
     334    // Loop over the range of radii
     335    for (int i = 0; i < growth->radius->n; i++) {
     336
     337        radius = growth->radius->data.F32[i];
     338
     339        // mask the given aperture and measure the apMag
     340        psImageKeepCircle (source->maskObj, xc, yc, radius, "OR", markVal);
     341
     342        if (!pmSourceMagnitudes (source, psf, photMode, maskVal, markVal, radius)) {
     343            psFree (growth);
     344            return NULL;
     345        }
     346
     347        // if (!pmSourcePhotometryAper (NULL, &apMag, NULL, NULL, NULL, source->pixels, NULL, source->maskObj, maskVal)) {
     348        //     psFree (growth);
     349        //     return NULL;
     350        // }
     351
     352        psImageMaskPixels (source->maskObj, "AND", PS_NOT_IMAGE_MASK(markVal)); // clear the circular mask
     353
     354        growth->apMag->data.F32[i] = source->apMag;
     355    }
     356    return growth;
     357}
     358
     359# if (0)
     360    // solve for the best growth and the offsets per star to minimize the scatter
     361
     362    // generate the per-star and per-radius sums
     363    int Nradius = psf->growth->radius->n;
     364    int Nstar = growths->n;
     365
     366    psVector *Mstar   = psVectorAlloc (Nstar, PS_DATA_F32);
     367    psVector *Mradius = psVectorAlloc (Nradius, PS_DATA_F32);
     368
     369    psVectorInit (Mstar, 0.0);
     370    psVectorInit (Mradius, 0.0);
     371
     372    for (int i = 0; i < Nstar; i++) {
     373        pmGrowthCurve *growth = growths->data[i];
     374        for (int j = 0; j < Nradius; j++) {
     375            Mstar->data.F32[i] += growth->apMag->data.F32[j];
     376            Mradius->data.F32[j] += growth->apMag->data.F32[j];
     377        }
     378    }
     379
     380    psImage *A = psImageAlloc(Nstar + Nradius, Nstar + Nradius, PS_DATA_F32);
     381    psVector *B = psVectorAlloc(Nstar + Nradius, PS_DATA_F32);
     382
     383    psImageInit (A, 0.0);
     384    psVectorInit (B, 0.0);
     385
     386    for (int i = 0; i < Nstar; i++) {
     387        A->data.F32[i][i] = Nradius;
     388        B->data.F32[i] = Mstar->data.F32[i];
     389    }
     390    for (int i = 0; i < Nradius; i++) {
     391        int j = i + Nstar;
     392        A->data.F32[j][j] = Nstar;
     393        B->data.F32[j] = Mradius->data.F32[i];
     394    }
     395   
     396    if (!psMatrixGJSolve(A, B)) {
     397        psAbort("GJ failure");
     398    }
     399
     400    for (int i = 0; i < Nradius; i++) {
     401        psf->growth->apMag->data.F32[i] = B->data.F32[Nstar+i];
     402    }
     403
     404    // XXX this analysis produces a biased growth curve: points with small radius are more
     405    // likely to err on the side of being too faint (bacause of mis-aligned aperture), while on
     406    // the bright side the tend to be too bright (because of contaminating neighbors).  Bright
     407    // stars are less likely to be biased,
     408
     409    // XXX at this point, we could iterate and exclude some of the stars with low data quality
     410    // XXX we could also weight the above by flux or something
     411
     412# endif
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmPSF.h

    r29004 r31361  
    9494double pmPSF_SXYtoModel (psF32 *fittedPar);
    9595
    96 bool pmGrowthCurveGenerate (pmReadout *readout, pmPSF *psf, bool ignore, psImageMaskType maskVal, psImageMaskType mark);
    9796pmPSF *pmPSFBuildSimple (char *typeName, float sxx, float syy, float sxy, ...);
    9897
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmPSF_IO.c

    r31339 r31361  
    6565bool pmPSFmodelRead_ApTrend (pmPSF *psf, pmFPAfile *file);
    6666bool pmPSFmodelWrite_ApTrend (pmFPAfile *file, pmPSF *psf);
     67
     68bool pmPSFmodelRead_GrowthCurve (pmPSF *psf, pmFPAfile *file);
     69bool pmPSFmodelWrite_GrowthCurve (pmFPAfile *file, pmPSF *psf);
    6770
    6871bool pmPSFmodelCheckDataStatusForView (const pmFPAview *view, const pmFPAfile *file)
     
    600603    if (!pmPSFmodelWrite_ApTrend(file, psf)) {
    601604        psError(psErrorCodeLast(), false, "Unable to write PSF ApTrend");
     605        return false;
     606    }
     607
     608    if (!pmPSFmodelWrite_GrowthCurve(file, psf)) {
     609        psError(psErrorCodeLast(), false, "Unable to write PSF Growth Curve");
    602610        return false;
    603611    }
     
    11041112    }
    11051113
     1114    if (!pmPSFmodelRead_GrowthCurve(psf, file)) {
     1115        psError(psErrorCodeLast(), false, "Unable to read PSF Growth Curve");
     1116        return false;
     1117    }
     1118
    11061119    psMetadataAdd (chipAnalysis, PS_LIST_TAIL, "PSPHOT.PSF",     PS_DATA_UNKNOWN,  "psphot psf", psf);
    11071120    psFree (psf);
     
    12301243}
    12311244
     1245// write aperture trend to a FITS table
     1246bool pmPSFmodelWrite_GrowthCurve (pmFPAfile *file, pmPSF *psf) {
     1247
     1248    pmGrowthCurve *growth = psf->growth;
     1249    if (growth == NULL) {
     1250        psWarning ("no PSF Growth Curve to write out, skipping");
     1251        return true;
     1252    }
     1253
     1254    // we need to write a header for the table,
     1255    psMetadata *header = psMetadataAlloc();
     1256
     1257    psMetadataAddF32 (header, PS_LIST_TAIL, "GROWTH_MIN_RAD", 0, "", growth->radius->data.F32[0]);
     1258    psMetadataAddF32 (header, PS_LIST_TAIL, "GROWTH_MAX_RAD", 0, "", growth->maxRadius);
     1259    psMetadataAddF32 (header, PS_LIST_TAIL, "GROWTH_REF_RAD", 0, "", growth->refRadius);
     1260    psMetadataAddF32 (header, PS_LIST_TAIL, "GROWTH_AP_LOSS", 0, "", growth->apLoss);
     1261    psMetadataAddF32 (header, PS_LIST_TAIL, "GROWTH_AP_REF",  0, "", growth->apRef);
     1262    psMetadataAddF32 (header, PS_LIST_TAIL, "GROWTH_FIT_MAG", 0, "", growth->fitMag);
     1263
     1264    // build a FITS table of the ApTrend (only 1)
     1265    psArray *table = psArrayAllocEmpty (100);
     1266    for (int i = 0; i < growth->apMag->n; i++) {
     1267        psMetadata *row = psMetadataAlloc ();
     1268        psMetadataAddF32 (row, PS_LIST_TAIL, "RADIUS", 0, "", growth->radius->data.F32[i]);
     1269        psMetadataAddF32 (row, PS_LIST_TAIL, "AP_MAG", 0, "", growth->apMag->data.F32[i]);
     1270        psArrayAdd (table, 100, row);
     1271        psFree (row);
     1272    }
     1273
     1274    // write an empty FITS segment if we have no PSF information
     1275    if (table->n == 0) {
     1276        psError(PM_ERR_PROG, true, "No PSF data to write.");
     1277        psFree(table);
     1278        psFree(header);
     1279        return false;
     1280    }
     1281
     1282    psTrace ("pmFPAfile", 5, "writing psf Growth Curve data %s\n", "GROWTH_CURVE");
     1283    if (!psFitsWriteTable(file->fits, header, table, "GROWTH_CURVE")) {
     1284        psError(psErrorCodeLast(), false, "Error writing psf table data %s\n", "GROWTH_CURVE");
     1285        psFree(table);
     1286        psFree(header);
     1287        return false;
     1288    }
     1289
     1290    psFree (table);
     1291    psFree (header);
     1292    return true;
     1293}
     1294
     1295// read aperture trend to a FITS table
     1296bool pmPSFmodelRead_GrowthCurve (pmPSF *psf, pmFPAfile *file) {
     1297
     1298    bool status;
     1299
     1300    // move fits pointer to AP_TREND section
     1301    // advance to the table data extension
     1302    if (!psFitsMoveExtNameClean (file->fits, "GROWTH_CURVE")) {
     1303        psWarning ("no Growth Curve data in PSF file, skipping");
     1304        return true;
     1305    }
     1306
     1307    psMetadata *header = psFitsReadHeader (NULL, file->fits);
     1308    if (!header) {
     1309        psError(psErrorCodeLast(), false, "Unable to read GROWTH_CURVE header.");
     1310        return false;
     1311    }
     1312       
     1313    // read the raw table data
     1314    psArray *table = psFitsReadTable (file->fits);
     1315    if (!table) {
     1316        psError(psErrorCodeLast(), false, "Unable to read GROWTH_CURVE table.");
     1317        psFree(header);
     1318        return false;
     1319    }
     1320
     1321    float minRadius = psMetadataLookupF32 (&status, header, "GROWTH_MIN_RAD"); if (!status) return false;
     1322    float maxRadius = psMetadataLookupF32 (&status, header, "GROWTH_MAX_RAD"); if (!status) return false;
     1323    float refRadius = psMetadataLookupF32 (&status, header, "GROWTH_REF_RAD"); if (!status) return false;
     1324
     1325    psf->growth = pmGrowthCurveAlloc(minRadius, maxRadius, refRadius);
     1326
     1327    psf->growth->apLoss = psMetadataLookupF32 (&status, header, "GROWTH_AP_LOSS"); if (!status) return false;
     1328    psf->growth->apRef  = psMetadataLookupF32 (&status, header, "GROWTH_AP_REF"); if (!status) return false;
     1329    psf->growth->fitMag = psMetadataLookupF32 (&status, header, "GROWTH_FIT_MAG"); if (!status) return false;
     1330
     1331    // fill in the matching psf->params entries
     1332    for (int i = 0; i < table->n; i++) {
     1333        psMetadata *row = table->data[i];
     1334        psf->growth->apMag->data.F32[i] = psMetadataLookupF32 (&status, row, "AP_MAG"); if (!status) return false;
     1335    }
     1336
     1337    psFree (header);
     1338    psFree (table);
     1339    return true;
     1340}
     1341
    12321342bool pmPSFmodelReadPSFClump (psMetadata *analysis, psMetadata *header) {
    12331343
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmSource.h

    r31153 r31361  
    8282    psArray *blends;                    ///< collection of sources thought to be confused with object
    8383    float psfMag;                       ///< calculated from flux in modelPSF
     84    float psfMagErr;                    ///< error in psfMag
    8485    float psfFlux;                      ///< calculated from flux in modelPSF
    85     float psfFluxErr;                   ///< calculated from flux in modelPSF
    86     float extMag;                       ///< calculated from flux in modelEXT
    87     float errMag;                       ///< error in psfMag OR extMag (depending on type)
     86    float psfFluxErr;                   ///< error in psfFlux
     87    float extMag;                       ///< calculated from flux in modelEXT -- NOTE this is not actually used
    8888    float apMag;                        ///< apMag corresponding to psfMag or extMag (depending on type)
    8989    float apMagRaw;                     ///< raw mag in given aperture
     
    254254    float sigma,      ///< size of Gaussian window function (<= 0.0 -> skip window)
    255255    float minSN,              ///< minimum pixel significance
     256    float minKronRadius,      ///< minimum pixel significance
    256257    psImageMaskType maskVal
    257258);
     
    273274  float xGuess, float yGuess);
    274275
     276float pmSourceMinKronRadius(psArray *sources, float PSF_SN_LIM);
     277
    275278pmModel *pmSourceGetModel (bool *isPSF, const pmSource *source);
    276279
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmSourceIO_CMF_PS1_V3.c

    r31153 r31361  
    116116        psMetadataAdd (row, PS_LIST_TAIL, "PLTSCALE",         PS_DATA_F32, "plate scale at source (arcsec/pixel)",       outputs.pltScale);
    117117        psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG",     PS_DATA_F32, "PSF fit instrumental magnitude",             source->psfMag);
    118         psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude",        source->errMag);
     118        psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_MAG_SIG", PS_DATA_F32, "Sigma of PSF instrumental magnitude",        source->psfMagErr);
    119119        psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX",    PS_DATA_F32, "PSF fit instrumental flux (counts)",         source->psfFlux);
    120120        psMetadataAdd (row, PS_LIST_TAIL, "PSF_INST_FLUX_SIG",PS_DATA_F32, "Sigma of PSF instrumental flux",             source->psfFluxErr);
     
    161161        psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_INNER",  PS_DATA_F32, "Kron Flux (in 2.5 R1)",                      moments.Kinner);
    162162        psMetadataAdd (row, PS_LIST_TAIL, "KRON_FLUX_OUTER",  PS_DATA_F32, "Kron Flux (in 2.5 R1)",                      moments.Kouter);
     163
     164        // Do NOT write these : not consistent with the definition of PS1_V3 in Ohana/src/libautocode/dev/cmf-ps1-v3.d
    163165        // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_FLUX",   PS_DATA_F32, "Kron Flux (in 1.0 R1)",                      moments.KronCore);
    164         // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_ERROR",  PS_DATA_F32, "Kron Error (in 1.0 R1)",                     moments.KronCoreErr);
     166        // psMetadataAdd (row, PS_LIST_TAIL, "KRON_CORE_ERROR",  PS_DATA_F32, "Kron Error (in 1.0 R1)",                     moments.KronCoreErr);
    165167        psMetadataAdd (row, PS_LIST_TAIL, "FLAGS",            PS_DATA_U32, "psphot analysis flags",                      source->mode);
    166168        psMetadataAdd (row, PS_LIST_TAIL, "FLAGS2",           PS_DATA_U32, "psphot analysis flags",                      source->mode2);
     
    270272        // XXX use these to determine PAR[PM_PAR_I0]?
    271273        source->psfMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG");
    272         source->errMag    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");
     274        source->psfMagErr    = psMetadataLookupF32 (&status, row, "PSF_INST_MAG_SIG");
    273275        source->apMag     = psMetadataLookupF32 (&status, row, "AP_MAG");
    274276
    275277        // XXX this scaling is incorrect: does not include the 2 \pi AREA factor
    276278        PAR[PM_PAR_I0]    = (isfinite(source->psfMag)) ? pow(10.0, -0.4*source->psfMag) : NAN;
    277         dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->errMag : NAN;
     279        dPAR[PM_PAR_I0]   = (isfinite(source->psfMag)) ? PAR[PM_PAR_I0] * source->psfMagErr : NAN;
    278280
    279281        pmPSF_AxesToModel (PAR, axes);
     
    292294
    293295        // we no longer sort by S/N, only flux
    294         // if (isfinite (source->errMag) && (source->errMag > 0.0)) {
    295         //   source->peak->SN = 1.0 / source->errMag;
     296        // if (isfinite (source->psfMagErr) && (source->psfMagErr > 0.0)) {
     297        //   source->peak->SN = 1.0 / source->psfMagErr;
    296298        // } else {
    297299        //   source->peak->SN = sqrt(source->peak->flux); // an alternate proxy: various functions sort by peak S/N
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmSourceMoments.c

    r31327 r31361  
    6666// if mode & EXTERNAL or mode2 & MATCHED, do not re-calculate the centroid (use peak as centroid)
    6767
    68 bool pmSourceMoments(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN, psImageMaskType maskVal)
     68bool pmSourceMoments(pmSource *source, float radius, float sigma, float minSN, float minKronRadius, psImageMaskType maskVal)
    6969{
    7070    PS_ASSERT_PTR_NON_NULL(source, false);
     
    7474
    7575    // this function assumes the sky has been well-subtracted for the image
    76     psF32 sky = 0.0;
     76    float sky = 0.0;
    7777
    7878    if (source->moments == NULL) {
     
    8080    }
    8181
    82     psF32 Sum = 0.0;
    83     psF32 Var = 0.0;
    84     psF32 SumCore = 0.0;
    85     psF32 VarCore = 0.0;
    86     psF32 R2 = PS_SQR(radius);
    87     psF32 minSN2 = PS_SQR(minSN);
    88     psF32 rsigma2 = 0.5 / PS_SQR(sigma);
     82    float Sum = 0.0;
     83    float Var = 0.0;
     84    float SumCore = 0.0;
     85    float VarCore = 0.0;
     86    float R2 = PS_SQR(radius);
     87    float minSN2 = PS_SQR(minSN);
     88    float rsigma2 = 0.5 / PS_SQR(sigma);
    8989
    9090    // a note about coordinates: coordinates of objects throughout psphot refer to the primary
     
    109109    // Xn  = SUM (x - xc)^n * (z - sky)
    110110
    111     psF32 RFW = 0.0;
    112     psF32 RHW = 0.0;
    113 
    114     psF32 RF = 0.0;
    115     psF32 RH = 0.0;
    116     psF32 RS = 0.0;
    117     psF32 XX = 0.0;
    118     psF32 XY = 0.0;
    119     psF32 YY = 0.0;
    120     psF32 XXX = 0.0;
    121     psF32 XXY = 0.0;
    122     psF32 XYY = 0.0;
    123     psF32 YYY = 0.0;
    124     psF32 XXXX = 0.0;
    125     psF32 XXXY = 0.0;
    126     psF32 XXYY = 0.0;
    127     psF32 XYYY = 0.0;
    128     psF32 YYYY = 0.0;
     111    float RFW = 0.0;
     112    float RHW = 0.0;
     113
     114    float RF = 0.0;
     115    float RH = 0.0;
     116    float RS = 0.0;
     117    float XX = 0.0;
     118    float XY = 0.0;
     119    float YY = 0.0;
     120    float XXX = 0.0;
     121    float XXY = 0.0;
     122    float XYY = 0.0;
     123    float YYY = 0.0;
     124    float XXXX = 0.0;
     125    float XXXY = 0.0;
     126    float XXYY = 0.0;
     127    float XYYY = 0.0;
     128    float YYYY = 0.0;
    129129
    130130    Sum = 0.0;  // the second pass may include slightly different pixels, re-determine Sum
     
    140140    // center of mass in subimage.  Note: the calculation below uses pixel index, so we correct
    141141    // xCM, yCM from pixel coords to pixel index here.
    142     psF32 xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage
    143     psF32 yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage
     142    float xCM = Xo - 0.5 - source->pixels->col0; // coord of peak in subimage
     143    float yCM = Yo - 0.5 - source->pixels->row0; // coord of peak in subimage
    144144
    145145    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    146146
    147         psF32 yDiff = row - yCM;
     147        float yDiff = row - yCM;
    148148        if (fabs(yDiff) > radius) continue;
    149149
    150         psF32 *vPix = source->pixels->data.F32[row];
    151         psF32 *vWgt = source->variance->data.F32[row];
     150        float *vPix = source->pixels->data.F32[row];
     151        float *vWgt = source->variance->data.F32[row];
    152152
    153153        psImageMaskType  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
     
    164164            if (isnan(*vPix)) continue;
    165165
    166             psF32 xDiff = col - xCM;
     166            float xDiff = col - xCM;
    167167            if (fabs(xDiff) > radius) continue;
    168168
    169169            // radius is just a function of (xDiff, yDiff)
    170             psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     170            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    171171            if (r2 > R2) continue;
    172172
    173             psF32 fDiff = *vPix - sky;
    174             psF32 pDiff = fDiff;
    175             psF32 wDiff = *vWgt;
     173            float fDiff = *vPix - sky;
     174            float pDiff = fDiff;
     175            float wDiff = *vWgt;
    176176
    177177            // skip pixels below specified significance level.  this is allowed, but should be
     
    184184            // weighting over weights the sky for faint sources
    185185            if (sigma > 0.0) {
    186                 psF32 z = r2 * rsigma2;
     186                float z = r2 * rsigma2;
    187187                assert (z >= 0.0);
    188                 psF32 weight  = exp(-z);
     188                float weight  = exp(-z);
    189189
    190190                wDiff *= weight;
     
    195195
    196196            // Kron Flux uses the 1st radial moment (NOT Gaussian windowed?)
    197             psF32 r = sqrt(r2);
    198             psF32 rf = r * fDiff;
    199             psF32 rh = sqrt(r) * fDiff;
    200             psF32 rs = fDiff;
    201 
    202             psF32 rfw = r * pDiff;
    203             psF32 rhw = sqrt(r) * pDiff;
    204 
    205             psF32 x = xDiff * pDiff;
    206             psF32 y = yDiff * pDiff;
    207 
    208             psF32 xx = xDiff * x;
    209             psF32 xy = xDiff * y;
    210             psF32 yy = yDiff * y;
    211 
    212             psF32 xxx = xDiff * xx / r;
    213             psF32 xxy = xDiff * xy / r;
    214             psF32 xyy = xDiff * yy / r;
    215             psF32 yyy = yDiff * yy / r;
    216 
    217             psF32 xxxx = xDiff * xxx / r2;
    218             psF32 xxxy = xDiff * xxy / r2;
    219             psF32 xxyy = xDiff * xyy / r2;
    220             psF32 xyyy = xDiff * yyy / r2;
    221             psF32 yyyy = yDiff * yyy / r2;
     197            float r = sqrt(r2);
     198            float rf = r * fDiff;
     199            float rh = sqrt(r) * fDiff;
     200            float rs = fDiff;
     201
     202            float rfw = r * pDiff;
     203            float rhw = sqrt(r) * pDiff;
     204
     205            float x = xDiff * pDiff;
     206            float y = yDiff * pDiff;
     207
     208            float xx = xDiff * x;
     209            float xy = xDiff * y;
     210            float yy = yDiff * y;
     211
     212            float xxx = xDiff * xx / r;
     213            float xxy = xDiff * xy / r;
     214            float xyy = xDiff * yy / r;
     215            float yyy = yDiff * yy / r;
     216
     217            float xxxx = xDiff * xxx / r2;
     218            float xxxy = xDiff * xxy / r2;
     219            float xxyy = xDiff * xyy / r2;
     220            float xyyy = xDiff * yyy / r2;
     221            float yyyy = yDiff * yyy / r2;
    222222
    223223            RF  += rf;
     
    245245    }
    246246
    247     // if Mrf (first radial moment) is << sigma, we are getting into low-significance
    248     // territory.  saturate at 0.75*sigma.  conversely, if Mrf is > radius, we are clearly
    249     // making an error.  saturate at radius.
    250     source->moments->Mrf = MIN(radius, MAX(0.75*sigma, RF/RS));
    251     source->moments->Mrh = MIN(radius, MAX(0.75*sigma, RH/RS));
     247    source->moments->Mrf = RF/RS;
     248    source->moments->Mrh = RH/RS;
    252249
    253250    source->moments->Mxx = XX/Sum;
     
    266263    source->moments->Myyyy = YYYY/Sum;
    267264
    268     // XXX TEST:
    269     // source->moments->KronFinner = RFW/Sum;
    270     // source->moments->KronFouter = sigma;
    271 
    272     // Calculate the Kron magnitude (make this block optional?)
    273     float radKinner = 1.0*source->moments->Mrf;
    274     float radKron   = 2.5*source->moments->Mrf;
    275     float radKouter = 4.0*source->moments->Mrf;
     265    // if Mrf (first radial moment) is very small, we are getting into low-significance
     266    // territory.  saturate at minKronRadius.  conversely, if Mrf is > radius, we are clearly
     267    // making an error.  saturate at radius.
     268    float kronRefRadius = MIN(radius, MAX(minKronRadius, source->moments->Mrf));
     269
     270    float radKinner = 1.0*kronRefRadius;
     271    float radKron   = 2.5*kronRefRadius;
     272    float radKouter = 4.0*kronRefRadius;
    276273
    277274    int nKronPix = 0;
     
    285282    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    286283
    287         psF32 yDiff = row - yCM;
     284        float yDiff = row - yCM;
    288285        if (fabs(yDiff) > radKouter) continue;
    289286
    290         psF32 *vPix = source->pixels->data.F32[row];
    291         psF32 *vWgt = source->variance->data.F32[row];
     287        float *vPix = source->pixels->data.F32[row];
     288        float *vWgt = source->variance->data.F32[row];
    292289
    293290        psImageMaskType  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
     
    304301            if (isnan(*vPix)) continue;
    305302
    306             psF32 xDiff = col - xCM;
     303            float xDiff = col - xCM;
    307304            if (fabs(xDiff) > radKouter) continue;
    308305
    309306            // radKron is just a function of (xDiff, yDiff)
    310             psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    311 
    312             psF32 pDiff = *vPix - sky;
    313             psF32 wDiff = *vWgt;
     307            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     308
     309            float pDiff = *vPix - sky;
     310            float wDiff = *vWgt;
    314311
    315312            // skip pixels below specified significance level.  this is allowed, but should be
     
    318315            if (PS_SQR(pDiff) < minSN2*wDiff) continue;
    319316
    320             psF32 r  = sqrt(r2);
     317            float r  = sqrt(r2);
    321318            if (r < radKron) {
    322319                Sum += pDiff;
     
    363360}
    364361
    365 bool pmSourceMomentsGetCentroid(pmSource *source, psF32 radius, psF32 sigma, psF32 minSN, psImageMaskType maskVal, float xGuess, float yGuess) {
     362bool pmSourceMomentsGetCentroid(pmSource *source, float radius, float sigma, float minSN, psImageMaskType maskVal, float xGuess, float yGuess) {
    366363
    367364    // First Pass: calculate the first moments (these are subtracted from the coordinates below)
     
    370367    // .. etc
    371368
    372     psF32 sky = 0.0;
    373 
    374     psF32 peakPixel = -PS_MAX_F32;
     369    float sky = 0.0;
     370
     371    float peakPixel = -PS_MAX_F32;
    375372    psS32 numPixels = 0;
    376     psF32 Sum = 0.0;
    377     psF32 Var = 0.0;
    378     psF32 X1 = 0.0;
    379     psF32 Y1 = 0.0;
    380     psF32 R2 = PS_SQR(radius);
    381     psF32 minSN2 = PS_SQR(minSN);
    382     psF32 rsigma2 = 0.5 / PS_SQR(sigma);
     373    float Sum = 0.0;
     374    float Var = 0.0;
     375    float X1 = 0.0;
     376    float Y1 = 0.0;
     377    float R2 = PS_SQR(radius);
     378    float minSN2 = PS_SQR(minSN);
     379    float rsigma2 = 0.5 / PS_SQR(sigma);
    383380
    384381    float xPeak = xGuess - source->pixels->col0; // coord of peak in subimage
     
    386383
    387384    // we are guaranteed to have a valid pixel and variance at this location (right? right?)
    388     // psF32 weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);
     385    // float weightNorm = source->pixels->data.F32[yPeak][xPeak] / sqrt (source->variance->data.F32[yPeak][xPeak]);
    389386    // psAssert (isfinite(source->pixels->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
    390387    // psAssert (isfinite(source->variance->data.F32[yPeak][xPeak]), "peak must be on valid pixel");
     
    398395    for (psS32 row = 0; row < source->pixels->numRows ; row++) {
    399396
    400         psF32 yDiff = row + 0.5 - yPeak;
     397        float yDiff = row + 0.5 - yPeak;
    401398        if (fabs(yDiff) > radius) continue;
    402399
    403         psF32 *vPix = source->pixels->data.F32[row];
    404         psF32 *vWgt = source->variance->data.F32[row];
     400        float *vPix = source->pixels->data.F32[row];
     401        float *vWgt = source->variance->data.F32[row];
    405402
    406403        psImageMaskType *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.PS_TYPE_IMAGE_MASK_DATA[row];
     
    417414            if (isnan(*vPix)) continue;
    418415
    419             psF32 xDiff = col + 0.5 - xPeak;
     416            float xDiff = col + 0.5 - xPeak;
    420417            if (fabs(xDiff) > radius) continue;
    421418
    422419            // radius is just a function of (xDiff, yDiff)
    423             psF32 r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
     420            float r2  = PS_SQR(xDiff) + PS_SQR(yDiff);
    424421            if (r2 > R2) continue;
    425422
    426             psF32 pDiff = *vPix - sky;
    427             psF32 wDiff = *vWgt;
     423            float pDiff = *vPix - sky;
     424            float wDiff = *vWgt;
    428425
    429426            // skip pixels below specified significance level.  for a PSFs, this
     
    438435            // weighting over weights the sky for faint sources
    439436            if (sigma > 0.0) {
    440                 psF32 z  = r2*rsigma2;
     437                float z  = r2*rsigma2;
    441438                assert (z >= 0.0);
    442                 psF32 weight  = exp(-z);
     439                float weight  = exp(-z);
    443440
    444441                wDiff *= weight;
     
    449446            Sum += pDiff;
    450447
    451             psF32 xWght = xDiff * pDiff;
    452             psF32 yWght = yDiff * pDiff;
     448            float xWght = xDiff * pDiff;
     449            float yWght = yDiff * pDiff;
    453450
    454451            X1  += xWght;
     
    507504    return true;
    508505}
     506
     507float pmSourceMinKronRadius(psArray *sources, float PSF_SN_LIM) {
     508
     509    psVector *radii = psVectorAllocEmpty(100, PS_TYPE_F32);
     510
     511    for (int i = 0; i < sources->n; i++) {
     512        pmSource *src = sources->data[i]; // Source of interest
     513        if (!src || !src->moments) {
     514            continue;
     515        }
     516
     517        if (src->mode & PM_SOURCE_MODE_BLEND) {
     518            continue;
     519        }
     520
     521        if (!src->moments->nPixels) continue;
     522
     523        if (src->moments->SN < PSF_SN_LIM) continue;
     524
     525        // XXX put in Mxx,Myy cut based on clump location
     526
     527        psVectorAppend(radii, src->moments->Mrf);
     528    }
     529
     530    // find the peak in this image
     531    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     532
     533    if (!psVectorStats (stats, radii, NULL, NULL, 0)) {
     534        psError(PS_ERR_UNKNOWN, false, "Unable to get image statistics.\n");
     535        psFree(stats);
     536        return NAN;
     537    }
     538
     539    float minRadius = stats->sampleMedian;
     540
     541    psFree(radii);
     542    psFree(stats);
     543    return minRadius;
     544}
     545
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmSourcePhotometry.c

    r31340 r31361  
    8282   - apMag  : only if S/N > AP_MIN_SN
    8383   : is optionally corrected for curve-of-growth if:
    84    - the source is a STAR (PSF)
    8584   - the option is selected (mode & PM_SOURCE_PHOT_GROWTH)
    8685   - psfMag : all sources with non-NULL modelPSF
    8786   : is optionally corrected for aperture residual if:
    88    - the source is a STAR (PSF)
    8987   - the option is selected (mode & PM_SOURCE_PHOT_APCORR)
    90 
    9188   - extMag : all sources with non-NULL modelEXT
    9289**/
     
    10097
    10198    int status = false;
    102     bool isPSF;
    10399    float x, y;
    104100    float SN;
    105     pmModel *model;
    106101
    107102    source->psfMag    = NAN;
    108103    source->extMag    = NAN;
    109     source->errMag    = NAN;
     104    source->psfMagErr = NAN;
    110105    source->apMag     = NAN;
    111106    source->apMagRaw  = NAN;
     
    113108    source->apFluxErr = NAN;
    114109
    115     // we must have a valid model
    116     // XXX allow aperture magnitudes for sources without a model
    117     model = pmSourceGetModel (&isPSF, source);
    118     if (model == NULL) {
    119         psTrace ("psModules.objects", 3, "fail mag : no valid model");
     110    // XXXXXX review:
     111    // Select the 'best' model -- this is used for PSF_QF,_PERFECT & ???. isPSF is true if this
     112    // object is a PSF (not extended).  We must have a valid model.  XXX NOTE: allow aperture
     113    // magnitudes for sources without a model
     114
     115    // select the psf model
     116    pmModel *modelPSF = source->modelPSF;
     117    if (modelPSF == NULL) {
     118        psTrace ("psModules.objects", 3, "fail mag : no valid PSF model");
    120119        return false;
    121120    }
    122121
    123     // XXX handle negative flux, low-significance
    124     if (model->dparams->data.F32[PM_PAR_I0] > 0) {
    125         SN = fabs(model->params->data.F32[PM_PAR_I0] / model->dparams->data.F32[PM_PAR_I0]);
    126         source->errMag = 1.0 / SN;
     122    // get the error on the PSF model magnitude
     123    if (modelPSF->dparams->data.F32[PM_PAR_I0] > 0) {
     124        SN = fabs(modelPSF->params->data.F32[PM_PAR_I0] / modelPSF->dparams->data.F32[PM_PAR_I0]);
     125        source->psfMagErr = 1.0 / SN;
    127126    } else {
    128127        SN = NAN;
    129         source->errMag = NAN;
    130     }
    131     x = model->params->data.F32[PM_PAR_XPOS];
    132     y = model->params->data.F32[PM_PAR_YPOS];
     128        source->psfMagErr = NAN;
     129    }
     130    // the source position is used to recenter the aperture for ap photometry
     131    x = modelPSF->params->data.F32[PM_PAR_XPOS];
     132    y = modelPSF->params->data.F32[PM_PAR_YPOS];
    133133
    134134    // measure PSF model photometry
    135     // XXX TEST: do not use flux scale
    136     // XXX NOTE: turn this back on?
    137     if (0 && psf->FluxScale) {
    138         // the source peak pixel is guaranteed to be on the image, and only minimally different from the source center
    139         double fluxScale = pmTrend2DEval (psf->FluxScale, (float)source->peak->x, (float)source->peak->y);
    140         psAssert (isfinite(fluxScale), "how can the flux scale be invalid? source at %d, %d\n", source->peak->x, source->peak->y);
    141         psAssert (fluxScale > 0.0, "how can the flux scale be negative? source at %d, %d\n", source->peak->x, source->peak->y);
    142         source->psfFlux = fluxScale * source->modelPSF->params->data.F32[PM_PAR_I0];
    143         source->psfFluxErr = fluxScale * source->modelPSF->dparams->data.F32[PM_PAR_I0];
    144         source->psfMag = -2.5*log10(source->psfFlux);
    145     } else {
    146         status = pmSourcePhotometryModel (&source->psfMag, &source->psfFlux, source->modelPSF);
    147         source->psfFluxErr = source->psfFlux * (source->modelPSF->dparams->data.F32[PM_PAR_I0] / source->modelPSF->params->data.F32[PM_PAR_I0]);
    148     }
     135    status = pmSourcePhotometryModel (&source->psfMag, &source->psfFlux, modelPSF);
     136    source->psfFluxErr = source->psfFlux * source->psfMagErr;
     137
     138# if (0)
     139    // XXX NOTE: old code to use the flux scale.  test & turn this back on?  if so, need to save with psf model
     140    // the source peak pixel is guaranteed to be on the image, and only minimally different from the source center
     141    double fluxScale = pmTrend2DEval (psf->FluxScale, (float)source->peak->x, (float)source->peak->y);
     142    psAssert (isfinite(fluxScale), "how can the flux scale be invalid? source at %d, %d\n", source->peak->x, source->peak->y);
     143    psAssert (fluxScale > 0.0, "how can the flux scale be negative? source at %d, %d\n", source->peak->x, source->peak->y);
     144    source->psfFlux = fluxScale * modelPSF->params->data.F32[PM_PAR_I0];
     145    source->psfFluxErr = fluxScale * modelPSF->dparams->data.F32[PM_PAR_I0];
     146    source->psfMag = -2.5*log10(source->psfFlux);
     147# endif
    149148
    150149    if (mode == PM_SOURCE_PHOT_PSFONLY) {
     
    152151    }
    153152
     153    // get the EXT model photometry (all EXT models)
    154154    // if we have a collection of model fits, check if one of them is a pointer to modelEXT
    155155    if (source->modelFits) {
     
    172172    }
    173173
    174     // for PSFs, correct both apMag and psfMag to same system, consistent with infinite flux star in aperture RADIUS
    175     // XXX add a flag for "ap_mag is corrected?"
    176     if ((mode & PM_SOURCE_PHOT_APCORR) && isPSF && psf && psf->ApTrend) {
     174    // Correct psfMag to match aperture magnitude system (NOTE : Growth curve is already applied to ApTrend)
     175    if ((mode & PM_SOURCE_PHOT_APCORR) && psf && psf->ApTrend) {
    177176        // the source peak pixel is guaranteed to be on the image, and only minimally different from the source center
    178177        double apTrend = pmTrend2DEval (psf->ApTrend, (float)source->peak->x, (float)source->peak->y);
     
    182181    }
    183182
    184     // measure the contribution of included pixels
     183    // measure the contribution of included pixels to the PSF model fit
    185184    if (mode & PM_SOURCE_PHOT_WEIGHT) {
    186         pmSourcePixelWeight (source, model, source->maskObj, maskVal, radius);
     185        pmSourcePixelWeight (source, modelPSF, source->maskObj, maskVal, radius);
    187186    }
    188187
     
    218217        y += dy;
    219218
    220         if (!psImageShiftMask(&flux, &mask, source->pixels, source->maskObj, maskVal, dx, dy,
    221                               NAN, 0xff, PS_INTERPOLATE_BIQUADRATIC)) {
     219        // if (!psImageShiftMask(&flux, &mask, source->pixels, source->maskObj, maskVal, dx, dy, NAN, 0xff, PS_INTERPOLATE_LANCZOS2)) {
     220        // if (!psImageShiftMask(&flux, &mask, source->pixels, source->maskObj, maskVal, dx, dy, NAN, 0xff, PS_INTERPOLATE_BIQUADRATIC)) {
     221        if (!psImageShiftMask(&flux, &mask, source->pixels, source->maskObj, maskVal, dx, dy, NAN, 0xff, PS_INTERPOLATE_BILINEAR)) {
    222222            // Not much we can do about it
    223223            psErrorClear();
     
    233233
    234234    // measure object aperture photometry
    235     status = pmSourcePhotometryAperSource (source, model, flux, variance, mask, maskVal);
     235    status = pmSourcePhotometryAperSource (source, modelPSF, flux, variance, mask, maskVal);
    236236    if (!status) {
    237237        psTrace ("psModules.objects", 3, "fail mag : bad Ap Mag");
     
    242242    // detection limits (esp near bright neighbors)
    243243    source->apMag = source->apMagRaw;
    244     if (isfinite (source->apMag) && isPSF && psf) {
     244    if (isfinite (source->apMag) && psf) {
    245245        if (psf->growth && (mode & PM_SOURCE_PHOT_GROWTH)) {
    246             source->apMag = source->apMagRaw + pmGrowthCurveCorrect (psf->growth, source->apRadius);
    247             // XXX correct the apFlux?
     246            float apOffset = pmGrowthCurveCorrect (psf->growth, source->apRadius);
     247            source->apMag = source->apMagRaw + apOffset;
     248            source->apFlux *= pow(10.0, -0.4*apOffset);
     249            source->apFluxErr *= pow(10.0, -0.4*apOffset);
    248250        }
    249251    }
  • branches/eam_branches/ipp-20110404/psModules/src/objects/pmSourceUtils.h

    r14652 r31361  
    3838
    3939/// @}
    40 # endif /* PM_MODEL_CLASS_H */
     40# endif /* PM_SOURCE_UTILS_H */
  • branches/eam_branches/ipp-20110404/psModules/src/psmodules.h

    r30623 r31361  
    148148#include <pmModelUtils.h>
    149149#include <pmSourcePhotometry.h>
     150#include <pmGrowthCurveGenerate.h>
    150151#include <pmSourceVisual.h>
    151152#include <pmSourceMatch.h>
Note: See TracChangeset for help on using the changeset viewer.