IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 15000


Ignore:
Timestamp:
Sep 24, 2007, 11:27:58 AM (19 years ago)
Author:
eugene
Message:

update from eam_branch_20070921

Location:
trunk
Files:
1 added
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/camera/pmFPAfileIO.c

    r14938 r15000  
    774774    }
    775775    pmFPAview *thisView = pmFPAAddSourceFromHeader (file->fpa, phu, file->format);
     776    assert (thisView); // XXX we are having some trouble with input psf files not having the Cell and fpa names matching.
    776777    psFree (thisView);
    777778    psFree (phu);
  • trunk/psModules/src/objects/models/pmModel_GAUSS.c

    r14652 r15000  
    274274            out[i] = in[i];
    275275        } else {
    276             psPolynomial2D *poly = psf->params->data[i];
    277             out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
     276            pmTrend2D *trend = psf->params->data[i];
     277            out[i] = pmTrend2DEval(trend, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
    278278        }
    279279    }
     
    331331        if (i == PM_PAR_XPOS) continue;
    332332        if (i == PM_PAR_YPOS) continue;
    333         psPolynomial2D *poly = psf->params->data[i];
    334         assert (poly);
    335         PAR[i] = psPolynomial2DEval(poly, Xo, Yo);
     333        pmTrend2D *trend = psf->params->data[i];
     334        PAR[i] = pmTrend2DEval(trend, Xo, Yo);
    336335    }
    337336
  • trunk/psModules/src/objects/models/pmModel_PGAUSS.c

    r14652 r15000  
    328328            out[i] = in[i];
    329329        } else {
    330             psPolynomial2D *poly = psf->params->data[i];
    331             out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
     330            pmTrend2D *trend = psf->params->data[i];
     331            out[i] = pmTrend2DEval(trend, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
    332332        }
    333333    }
     
    384384        if (i == PM_PAR_XPOS) continue;
    385385        if (i == PM_PAR_YPOS) continue;
    386         psPolynomial2D *poly = psf->params->data[i];
    387         assert (poly);
    388         PAR[i] = psPolynomial2DEval(poly, Xo, Yo);
     386        pmTrend2D *trend = psf->params->data[i];
     387        PAR[i] = pmTrend2DEval(trend, Xo, Yo);
    389388    }
    390389
  • trunk/psModules/src/objects/models/pmModel_QGAUSS.c

    r14652 r15000  
    358358            out[i] = in[i];
    359359        } else {
    360             psPolynomial2D *poly = psf->params->data[i];
    361             out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
     360            pmTrend2D *trend = psf->params->data[i];
     361            out[i] = pmTrend2DEval(trend, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
    362362        }
    363363    }
     
    412412        if (i == PM_PAR_XPOS) continue;
    413413        if (i == PM_PAR_YPOS) continue;
    414         psPolynomial2D *poly = psf->params->data[i];
    415         assert (poly);
    416         PAR[i] = psPolynomial2DEval(poly, Xo, Yo);
     414        pmTrend2D *trend = psf->params->data[i];
     415        PAR[i] = pmTrend2DEval(trend, Xo, Yo);
    417416    }
    418417
  • trunk/psModules/src/objects/models/pmModel_RGAUSS.c

    r14652 r15000  
    351351            out[i] = in[i];
    352352        } else {
    353             psPolynomial2D *poly = psf->params->data[i];
    354             out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
     353            pmTrend2D *trend = psf->params->data[i];
     354            out[i] = pmTrend2DEval(trend, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
    355355        }
    356356    }
     
    405405        if (i == PM_PAR_XPOS) continue;
    406406        if (i == PM_PAR_YPOS) continue;
    407         psPolynomial2D *poly = psf->params->data[i];
    408         assert (poly);
    409         PAR[i] = psPolynomial2DEval(poly, Xo, Yo);
     407        pmTrend2D *trend = psf->params->data[i];
     408        PAR[i] = pmTrend2DEval(trend, Xo, Yo);
    410409    }
    411410
  • trunk/psModules/src/objects/models/pmModel_SERSIC.c

    r14669 r15000  
    343343            out[i] = in[i];
    344344        } else {
    345             psPolynomial2D *poly = psf->params->data[i];
    346             out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
     345            pmTrend2D *trend = psf->params->data[i];
     346            out[i] = pmTrend2DEval(trend, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
    347347        }
    348348    }
     
    397397        if (i == PM_PAR_XPOS) continue;
    398398        if (i == PM_PAR_YPOS) continue;
    399         psPolynomial2D *poly = psf->params->data[i];
    400         assert (poly);
    401         PAR[i] = psPolynomial2DEval(poly, Xo, Yo);
     399        pmTrend2D *trend = psf->params->data[i];
     400        PAR[i] = pmTrend2DEval(trend, Xo, Yo);
    402401    }
    403402
  • trunk/psModules/src/objects/pmPSF.c

    r14961 r15000  
    66 *  @author EAM, IfA
    77 *
    8  *  @version $Revision: 1.28 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-09-21 02:46:25 $
     8 *  @version $Revision: 1.29 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-09-24 21:27:58 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    4141
    4242/*****************************************************************************/
    43 /* DEFINE STATEMENTS                                                         */
    44 /*****************************************************************************/
    45 
    46 /*****************************************************************************/
    47 /* TYPE DEFINITIONS                                                          */
    48 /*****************************************************************************/
    49 
    50 /*****************************************************************************/
    51 /* GLOBAL VARIABLES                                                          */
    52 /*****************************************************************************/
    53 
    54 /*****************************************************************************/
    55 /* FILE STATIC VARIABLES                                                     */
    56 /*****************************************************************************/
    57 
    58 /*****************************************************************************/
    59 /* FUNCTION IMPLEMENTATION - LOCAL                                           */
    60 /*****************************************************************************/
    61 
    62 /*****************************************************************************/
    6343/* FUNCTION IMPLEMENTATION - PUBLIC                                          */
    6444/*****************************************************************************/
     45
     46static void pmPSFOptionsFree (pmPSFOptions *options) {
     47
     48    if (!options) return;
     49
     50    psFree (options->stats);
     51    return;
     52}
     53
     54pmPSFOptions *pmPSFOptionsAlloc () {
     55
     56    pmPSFOptions *options = (pmPSFOptions *) psAlloc(sizeof(pmPSFOptions));
     57    psMemSetDeallocator(options, (psFreeFunc) pmPSFOptionsFree);
     58
     59    options->type          = 0;
     60
     61    options->stats         = NULL;
     62
     63    options->psfTrendMode  = PM_TREND_NONE;
     64    options->psfTrendNx    = 0;
     65    options->psfTrendNy    = 0;
     66    options->psfFieldNx    = 0;
     67    options->psfFieldNy    = 0;
     68    options->psfFieldXo    = 0;
     69    options->psfFieldYo    = 0;
     70
     71    options->poissonErrorsPhotLMM = true;
     72    options->poissonErrorsPhotLin = false;
     73    options->poissonErrorsParams  = true;
     74
     75    return options;
     76}
    6577
    6678/*****************************************************************************
     
    7486
    7587    psFree (psf->ChiTrend);
     88    psFree (psf->psfTrendStats);
    7689    psFree (psf->ApTrend);
    7790    psFree (psf->FluxScale);
     
    94107 Object Normalization
    95108 *****************************************************************************/
    96 pmPSF *pmPSFAlloc (pmModelType type, bool poissonErrors, psPolynomial2D *psfTrendMask)
     109pmPSF *pmPSFAlloc (pmPSFOptions *options)
    97110{
    98111    int Nparams;
    99112
    100113    pmPSF *psf = (pmPSF *) psAlloc(sizeof(pmPSF));
    101 
    102     psf->type     = type;
     114    psMemSetDeallocator(psf, (psFreeFunc) pmPSFFree);
     115
     116    psf->type     = options->type;
    103117    psf->chisq    = 0.0;
    104118    psf->ApResid  = 0.0;
     
    108122    psf->nPSFstars  = 0;
    109123    psf->nApResid   = 0;
    110     psf->poissonErrors = poissonErrors;
     124
     125    psf->poissonErrorsPhotLMM = options->poissonErrorsPhotLMM;
     126    psf->poissonErrorsPhotLin = options->poissonErrorsPhotLin;
     127    psf->poissonErrorsParams = options->poissonErrorsParams;
    111128
    112129    // the ApTrend components are (x, y).  It may be represented with a polynomial or with a
     
    121138    psf->FluxScale = NULL;
    122139
    123     if (psf->poissonErrors) {
     140    if (psf->poissonErrorsPhotLMM) {
    124141        psf->ChiTrend = psPolynomial1DAlloc (PS_POLYNOMIAL_ORD, 1);
    125142    } else {
     
    133150    psf->residuals = NULL;
    134151
    135     Nparams = pmModelClassParameterCount (type);
     152    Nparams = pmModelClassParameterCount (options->type);
    136153    if (!Nparams) {
    137154        psError(PS_ERR_UNKNOWN, true, "Undefined pmModelType");
     
    139156    }
    140157    psf->params = psArrayAlloc(Nparams);
     158   
     159    // save the trend stats on the psf for use in pmPSFFromPSFtry
     160    psf->psfTrendStats = psMemIncrRefCounter (options->stats);
    141161
    142162    // the order of the PSF parameter (X,Y) fits is determined by the psfTrendMask polynomial
     
    147167    // PM_PAR_XPOS, etc)
    148168
    149     if (psfTrendMask) {
     169    psImageBinning *binning = psImageBinningAlloc();
     170    binning->nXruff = options->psfTrendNx;
     171    binning->nYruff = options->psfTrendNy;
     172    binning->nXfine = options->psfFieldNx;
     173    binning->nYfine = options->psfFieldNy;
     174    psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);
     175    psImageBinningSetSkipByOffset (binning, options->psfFieldXo, options->psfFieldYo);
     176
     177    psf->fieldNx = options->psfFieldNx;
     178    psf->fieldNy = options->psfFieldNy;
     179    psf->fieldXo = options->psfFieldXo;
     180    psf->fieldYo = options->psfFieldYo;
     181
     182    // define the parameter trends
     183    if (options->psfTrendMode != PM_TREND_NONE) {
    150184        for (int i = 0; i < psf->params->n; i++) {
    151             if (i == PM_PAR_SKY)
    152                 continue;
    153             if (i == PM_PAR_I0)
    154                 continue;
    155             if (i == PM_PAR_XPOS)
    156                 continue;
    157             if (i == PM_PAR_YPOS)
    158                 continue;
    159 
    160             psPolynomial2D *param = psPolynomial2DAlloc(PS_POLYNOMIAL_ORD, psfTrendMask->nX, psfTrendMask->nY);
    161             for (int nx = 0; nx < param->nX + 1; nx++) {
    162                 for (int ny = 0; ny < param->nY + 1; ny++) {
    163                     param->mask[nx][ny] = psfTrendMask->mask[nx][ny];
    164                 }
    165             }
    166             psf->params->data[i] = param;
     185            if (i == PM_PAR_SKY) continue;
     186            if (i == PM_PAR_I0) continue;
     187            if (i == PM_PAR_XPOS) continue;
     188            if (i == PM_PAR_YPOS) continue;
     189
     190            psf->params->data[i] = pmTrend2DNoImageAlloc (options->psfTrendMode, binning, options->stats);
    167191        }
    168192    }
    169 
    170     psMemSetDeallocator(psf, (psFreeFunc) pmPSFFree);
    171     return(psf);
     193    psFree (binning);
     194    return psf;
    172195}
    173196
     
    300323    va_start(ap, sxy);
    301324
    302     pmModelType type = pmModelClassGetType (typeName);
    303     psPolynomial2D *psfTrend = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, 0, 0);
    304     pmPSF *psf = pmPSFAlloc (type, true, psfTrend);
     325    pmPSFOptions *options = pmPSFOptionsAlloc ();
     326    options->type = pmModelClassGetType (typeName);
     327    options->psfTrendMode = PM_TREND_POLY_ORD;
     328    options->psfTrendNx = 0;
     329    options->psfTrendNy = 0;
     330
     331    pmPSF *psf = pmPSFAlloc (options);
    305332
    306333    psVector *par = psVectorAlloc (psf->params->n, PS_TYPE_F32);
     
    311338    psEllipsePol pol = pmPSF_ModelToFit(par->data.F32);
    312339
     340    pmTrend2D *trend = NULL;
     341
    313342    // set the psf shape parameters
    314     psPolynomial2D *poly = NULL;
    315     poly = psf->params->data[PM_PAR_E0];
    316     poly->coeff[0][0] = pol.e0;
    317 
    318     poly = psf->params->data[PM_PAR_E1];
    319     poly->coeff[0][0] = pol.e1;
    320 
    321     poly = psf->params->data[PM_PAR_E2];
    322     poly->coeff[0][0] = pol.e2;
     343    trend = psf->params->data[PM_PAR_E0];
     344    trend->poly->coeff[0][0] = pol.e0;
     345
     346    trend = psf->params->data[PM_PAR_E1];
     347    trend->poly->coeff[0][0] = pol.e1;
     348
     349    trend = psf->params->data[PM_PAR_E2];
     350    trend->poly->coeff[0][0] = pol.e2;
    323351
    324352    for (int i = PM_PAR_SXY + 1; i < psf->params->n; i++) {
    325         poly = psf->params->data[i];
    326         poly->coeff[0][0] = (psF32)va_arg(ap, psF64);
     353        trend = psf->params->data[i];
     354        trend->poly->coeff[0][0] = (psF32)va_arg(ap, psF64);
    327355    }
    328356    va_end(ap);
    329357
    330358    psFree (par);
    331     psFree (psfTrend);
     359    psFree (options);
    332360    return psf;
    333361}
  • trunk/psModules/src/objects/pmPSF.h

    r14936 r15000  
    66 * @author EAM, IfA
    77 *
    8  * @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2007-09-21 00:05:35 $
     8 * @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2007-09-24 21:27:58 $
    1010 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    1111 */
     
    1919// type of model carried by the pmModel structure
    2020typedef int pmModelType;
    21 
    22 typedef enum {
    23     PM_PSF_APTREND_ERROR = 0,
    24     PM_PSF_APTREND_NONE,
    25     PM_PSF_APTREND_CONSTANT,
    26     PM_PSF_APTREND_SKYBIAS,
    27     PM_PSF_APTREND_SKYSAT,
    28     PM_PSF_APTREND_XY_LIN,
    29     PM_PSF_APTREND_XY_QUAD,
    30     PM_PSF_APTREND_SKY_XY_LIN,
    31     PM_PSF_APTREND_SKYSAT_XY_LIN,
    32     PM_PSF_APTREND_ALL
    33 } pmPSFApTrendOptions;
    3421
    3522/** pmPSF data structure
     
    4936    pmModelType type;                   ///< PSF Model in use
    5037    psArray *params;                    ///< Model parameters (psPolynomial2D)
     38    psStats *psfTrendStats;             ///< psf parameter trend clipping stats
    5139    psPolynomial1D *ChiTrend;           ///< Chisq vs flux fit (correction for systematic errors)
    5240    pmTrend2D *ApTrend;                 ///< ApResid vs (x,y)
     
    5947    int nPSFstars;                      ///< number of stars used to measure PSF
    6048    int nApResid;                       ///< number of stars used to measure ApResid
    61     bool poissonErrors;
     49    int fieldNx;
     50    int fieldNy;
     51    int fieldXo;
     52    int fieldYo;
     53    bool poissonErrorsPhotLMM;          ///< use poission errors for non-linear model fitting
     54    bool poissonErrorsPhotLin;          ///< use poission errors for linear model fitting
     55    bool poissonErrorsParams;           ///< use poission errors for model parameter fitting
    6256    pmGrowthCurve *growth;              ///< apMag vs Radius
    6357    pmResiduals *residuals;             ///< normalized residual image (no spatial variation)
    6458}
    6559pmPSF;
     60
     61typedef struct {
     62    pmModelType   type;
     63    psStats      *stats;                // psfTrend clipping stats
     64    pmTrend2DMode psfTrendMode;
     65    int           psfTrendNx;
     66    int           psfTrendNy;
     67    int           psfFieldNx;
     68    int           psfFieldNy;
     69    int           psfFieldXo;
     70    int           psfFieldYo;
     71    bool          poissonErrorsPhotLMM; ///< use poission errors for non-linear model fitting
     72    bool          poissonErrorsPhotLin; ///< use poission errors for linear model fitting
     73    bool          poissonErrorsParams; ///< use poission errors for model parameter fitting
     74    float         radius;
     75} pmPSFOptions;
    6676
    6777# define PM_PAR_E0 PM_PAR_SXX
     
    7484 *
    7585 */
    76 pmPSF *pmPSFAlloc(
    77     pmModelType type,     // type of model for PSF
    78     bool poissonErrors,
    79     psPolynomial2D *psfTrendMask
    80 );
    81 
    82 bool pmPSFMaskApTrend (psPolynomial4D *trend, pmPSFApTrendOptions option);
    83 
    84 pmPSFApTrendOptions pmPSFApTrendOptionFromName (char *name);
     86pmPSF *pmPSFAlloc (pmPSFOptions *options);
     87pmPSFOptions *pmPSFOptionsAlloc ();
    8588
    8689double pmPSF_SXYfromModel (psF32 *modelPar);
     
    9194
    9295bool pmPSF_AxesToModel (psF32 *modelPar, psEllipseAxes axes);
     96bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis);
     97
     98psEllipsePol pmPSF_ModelToFit (psF32 *modelPar);
    9399psEllipseAxes pmPSF_ModelToAxes (psF32 *modelPar, double maxAR);
    94 bool pmPSF_FitToModel (psF32 *fittedPar, float minMinorAxis);
    95 psEllipsePol pmPSF_ModelToFit (psF32 *modelPar);
    96100
    97101/// @}
  • trunk/psModules/src/objects/pmPSF_IO.c

    r14936 r15000  
    66 *  @author EAM, IfA
    77 *
    8  *  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-09-21 00:05:57 $
     8 *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-09-24 21:27:58 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    148148
    149149// for a pmPSF supplied on the analysis metadata, we write out
     150// if needed:
     151//   - a PHU blank header
    150152// - image header        : FITS Image NAXIS = 0
    151 // - psf table (+header) : FITS Table
    152 // - psf resid (+header) : FITS Image
    153 // if needed, we also write out a PHU blank header
     153// if (trendMode == MAP)
     154//   - psf resid (+header) : FITS Image
     155// else
     156//   - psf table (+header) : FITS Table
    154157bool pmPSFmodelWrite (psMetadata *analysis, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    155158{
     
    159162
    160163    if (!analysis) return false;
     164
     165    // select the current recipe
     166    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, "PSPHOT");
     167    if (!recipe) {
     168        psError(PS_ERR_UNKNOWN, false, "missing recipe %s", "PSPHOT");
     169        return false;
     170    }
    161171
    162172    // write a PHU? (only if input image is MEF)
     
    215225
    216226    // write out the IMAGE header segment
    217     // this header block is new, write it to disk
     227    // if this header block is new, write it to disk
    218228    if (hdu->header != file->header) {
    219229        // add EXTNAME, EXTHEAD, EXTTYPE to header
     
    250260        psMetadataAddStr (header, PS_LIST_TAIL, "PSF_NAME", 0, "PSF model name", modelName);
    251261
    252         psMetadataAddBool (header, PS_LIST_TAIL, "POISSON",  0, "Use Poisson errors in fits?", psf->poissonErrors);
     262        psMetadataAddBool (header, PS_LIST_TAIL, "ERR_LMM",  0, "Use Poisson errors in fits?", psf->poissonErrorsPhotLMM);
     263        psMetadataAddBool (header, PS_LIST_TAIL, "ERR_LIN",  0, "Use Poisson errors in fits?", psf->poissonErrorsPhotLin);
     264        psMetadataAddBool (header, PS_LIST_TAIL, "ERR_PAR",  0, "Use Poisson errors in fits?", psf->poissonErrorsParams);
    253265
    254266        int nPar = pmModelClassParameterCount (psf->type)    ;
    255267        psMetadataAdd (header, PS_LIST_TAIL, "PSF_NPAR", PS_DATA_S32, "PSF model parameter count", nPar);
     268
     269        psMetadataAddS32 (header, PS_LIST_TAIL, "IMAXIS1", 0, "Image X Size", psf->fieldNx);
     270        psMetadataAddS32 (header, PS_LIST_TAIL, "IMAXIS2", 0, "Image Y Size", psf->fieldNy);
     271        psMetadataAddS32 (header, PS_LIST_TAIL, "IMREF1",  0, "Image X Ref",  psf->fieldXo);
     272        psMetadataAddS32 (header, PS_LIST_TAIL, "IMREF2",  0, "Image Y Ref",  psf->fieldYo);
     273
     274        // extract PSF Clump info
     275        pmPSFClump psfClump;
     276
     277        psfClump.X  = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.X");   assert (status);
     278        psfClump.Y  = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.Y");   assert (status);
     279        psfClump.dX = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DX");  assert (status);
     280        psfClump.dY = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DY");  assert (status);
     281
     282        psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLX", 0, "psf clump center", psfClump.X);
     283        psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLY", 0, "psf clump center", psfClump.Y);
     284        psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLDX", 0, "psf clump size", psfClump.dX);
     285        psMetadataAddF32 (header, PS_LIST_TAIL, "PSF_CLDY", 0, "psf clump size", psfClump.dY);
    256286
    257287        // save the dimensions of each parameter
    258288        for (int i = 0; i < nPar; i++) {
    259289            char name[9];
    260             psPolynomial2D *poly = psf->params->data[i];
    261             if (poly == NULL) continue;
     290            int nX, nY;
     291
     292            pmTrend2D *trend = psf->params->data[i];
     293            if (trend == NULL) continue;
     294
     295            if (trend->mode == PM_TREND_MAP) {
     296              nX = trend->map->map->numCols;
     297              nY = trend->map->map->numRows;
     298            } else {
     299              nX = trend->poly->nX;
     300              nY = trend->poly->nY;
     301            }
    262302            snprintf (name, 9, "PAR%02d_NX", i);
    263             psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", poly->nX);
     303            psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", nX);
    264304            snprintf (name, 9, "PAR%02d_NY", i);
    265             psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", poly->nY);
     305            psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", nY);
     306            snprintf (name, 9, "PAR%02d_MD", i);
     307            char *modeName = pmTrend2DModeToString (trend->mode);
     308            psMetadataAddStr (header, PS_LIST_TAIL, name, 0, "", modeName);
     309            psFree (modeName);
    266310        }
    267311
    268312        // other required information describing the PSF
    269         psMetadataAddF32  (header, PS_LIST_TAIL, "AP_RESID", 0, "aperture residual", psf->ApResid);
    270         psMetadataAddF32  (header, PS_LIST_TAIL, "AP_ERROR", 0, "aperture residual scatter", psf->dApResid);
    271         psMetadataAddF32  (header, PS_LIST_TAIL, "CHISQ",    0, "chi-square for fit", psf->chisq);
    272         psMetadataAddS32  (header, PS_LIST_TAIL, "NSTARS",   0, "number of stars used to measure PSF", psf->nPSFstars);
     313        psMetadataAddF32 (header, PS_LIST_TAIL, "AP_RESID", 0, "aperture residual", psf->ApResid);
     314        psMetadataAddF32 (header, PS_LIST_TAIL, "AP_ERROR", 0, "aperture residual scatter", psf->dApResid);
     315        psMetadataAddF32 (header, PS_LIST_TAIL, "CHISQ",    0, "chi-square for fit", psf->chisq);
     316        psMetadataAddS32 (header, PS_LIST_TAIL, "NSTARS",   0, "number of stars used to measure PSF", psf->nPSFstars);
    273317
    274318        // XXX can we drop this now?
     
    278322        psArray *psfTable = psArrayAllocEmpty (100);
    279323        for (int i = 0; i < nPar; i++) {
    280             psPolynomial2D *poly = psf->params->data[i];
    281             if (poly == NULL) continue; // skip unset parameters (eg, XPOS)
    282             for (int ix = 0; ix <= poly->nX; ix++) {
    283                 for (int iy = 0; iy <= poly->nY; iy++) {
    284 
    285                     psMetadata *row = psMetadataAlloc ();
    286                     psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);
    287                     psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
    288                     psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
    289                     psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", poly->coeff[ix][iy]);
    290                     psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", poly->coeffErr[ix][iy]);
    291                     psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", poly->mask[ix][iy]);
    292 
    293                     psArrayAdd (psfTable, 100, row);
    294                     psFree (row);
     324            pmTrend2D *trend = psf->params->data[i];
     325            if (trend == NULL) continue; // skip unset parameters (eg, XPOS)
     326
     327            if (trend->mode == PM_TREND_MAP) {
     328                // write the image components into a table: this is needed because they may each be a different size
     329                psImageMap *map = trend->map;
     330                for (int ix = 0; ix < map->map->numCols; ix++) {
     331                    for (int iy = 0; iy < map->map->numRows; iy++) {
     332                        psMetadata *row = psMetadataAlloc ();
     333                        psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);
     334                        psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
     335                        psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
     336                        psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", map->map->data.F32[iy][ix]);
     337                        psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", map->error->data.F32[iy][ix]);
     338                        psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", 0); // no cells are masked
     339
     340                        psArrayAdd (psfTable, 100, row);
     341                        psFree (row);
     342                    }
     343                }
     344            } else {
     345                // write the polynomial components into a table
     346                psPolynomial2D *poly = trend->poly;
     347                for (int ix = 0; ix <= poly->nX; ix++) {
     348                    for (int iy = 0; iy <= poly->nY; iy++) {
     349                        psMetadata *row = psMetadataAlloc ();
     350                        psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);
     351                        psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
     352                        psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
     353                        psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", poly->coeff[ix][iy]);
     354                        psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", poly->coeffErr[ix][iy]);
     355                        psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", poly->mask[ix][iy]);
     356
     357                        psArrayAdd (psfTable, 100, row);
     358                        psFree (row);
     359                    }
    295360                }
    296361            }
     
    356421    // XXX save the growth curve
    357422    // XXX save ApTrend (as image?)
     423    // XXX write the ApTrend with the same API as will be used for the PSF parameters above
    358424
    359425# if (0)
     
    474540    psTrace ("psModules.objects", 5, "read psf model for %s\n", file->filename);
    475541
     542    // select the current recipe
     543    psMetadata *recipe = psMetadataLookupPtr (NULL, config->recipes, "PSPHOT");
     544    if (!recipe) {
     545        psError(PS_ERR_UNKNOWN, false, "missing recipe %s", "PSPHOT");
     546        return false;
     547    }
     548
    476549    // Menu of EXTNAME rules
    477550    psMetadata *menu = psMetadataLookupMetadata(&status, file->camera, "EXTNAME.RULES");
     
    506579    if (!header) psAbort("cannot read table header");
    507580
     581    pmPSFOptions *options = pmPSFOptionsAlloc();
     582
    508583    // load the PSF model parameters from the FITS table
    509584    char *modelName = psMetadataLookupStr (&status, header, "PSF_NAME");
    510     pmModelType type = pmModelClassGetType (modelName);
    511     if (type == -1) {
     585    options->type = pmModelClassGetType (modelName);
     586    if (options->type == -1) {
    512587        psError(PS_ERR_UNKNOWN, true, "invalid model name %s in psf file %s", modelName, file->filename);
    513588        return false;
    514589    }
    515590
    516     bool poissonErrors = psMetadataLookupBool (&status, header, "POISSON");
     591    // psf clump data
     592    pmPSFClump psfClump;
     593
     594    psfClump.X  = psMetadataLookupF32 (&status, header, "PSF_CLX" );  assert(status);
     595    psfClump.Y  = psMetadataLookupF32 (&status, header, "PSF_CLY" );  assert(status);
     596    psfClump.dX = psMetadataLookupF32 (&status, header, "PSF_CLDX");  assert(status);
     597    psfClump.dY = psMetadataLookupF32 (&status, header, "PSF_CLDY");  assert(status);
     598
     599    psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.X" , 0, "psf clump center", psfClump.X);
     600    psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.Y" , 0, "psf clump center", psfClump.Y);
     601    psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.DX", 0, "psf clump size",   psfClump.dX);
     602    psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.DY", 0, "psf clump size",   psfClump.dY);
     603
     604    options->poissonErrorsPhotLMM = psMetadataLookupBool (&status, header, "ERR_LMM");
     605    options->poissonErrorsPhotLin = psMetadataLookupBool (&status, header, "ERR_LIN");
     606    options->poissonErrorsParams  = psMetadataLookupBool (&status, header, "ERR_PAR");
     607
     608    options->psfFieldNx = psMetadataLookupS32 (&status, header, "IMAXIS1");
     609    options->psfFieldNy = psMetadataLookupS32 (&status, header, "IMAXIS2");
     610    options->psfFieldXo = psMetadataLookupS32 (&status, header, "IMREF1");
     611    options->psfFieldYo = psMetadataLookupS32 (&status, header, "IMREF2");
     612
     613    psImageBinning *binning = psImageBinningAlloc();
     614    binning->nXfine = options->psfFieldNx;
     615    binning->nYfine = options->psfFieldNy;
    517616
    518617    // we determine the PSF parameter polynomials from the MD-defined polynomials
    519     pmPSF *psf = pmPSFAlloc (type, poissonErrors, NULL);
     618    pmPSF *psf = pmPSFAlloc (options);
    520619
    521620    // check the number of expected parameters
     
    524623        psAbort("mismatch model par count");
    525624
    526     // load the dimensions of each parameter
     625    // load the trend mode and dimensions of each parameter
    527626    for (int i = 0; i < nPar; i++) {
    528627        char name[9];
    529628        snprintf (name, 9, "PAR%02d_NX", i);
    530         int nXorder = psMetadataLookupS32 (&status, header, name);
     629        binning->nXruff = psMetadataLookupS32 (&status, header, name);
    531630        if (!status) continue;          // not all parameters are defined
     631
    532632        snprintf (name, 9, "PAR%02d_NY", i);
    533         int nYorder = psMetadataLookupS32 (&status, header, name);
     633        binning->nYruff = psMetadataLookupS32 (&status, header, name);
    534634        if (!status) {
    535             psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX defined for PAR %d, but no NY", i);
     635            psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX defined for PAR %d, but not NY", i);
    536636            return false;
    537637        }
    538         psf->params->data[i] = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXorder, nYorder);
    539     }
     638
     639        snprintf (name, 9, "PAR%02d_MD", i);
     640        char *modeName = psMetadataLookupStr (&status, header, name);
     641        if (!status) {
     642            psError(PS_ERR_UNKNOWN, true, "inconsistent PSF header: NX & NY defined for PAR %d, but not MD", i);
     643            return false;
     644        }
     645        pmTrend2DMode psfTrendMode = pmTrend2DModeFromString (modeName);
     646        if (psfTrendMode == PM_TREND_NONE) {
     647            psfTrendMode = PM_TREND_POLY_ORD;
     648        }
     649
     650        psImageBinningSetScale (binning, PS_IMAGE_BINNING_CENTER);
     651        psImageBinningSetSkipByOffset (binning, options->psfFieldXo, options->psfFieldYo);
     652        psf->params->data[i] = pmTrend2DNoImageAlloc (psfTrendMode, binning, NULL);
     653    }
     654    psFree (binning);
    540655
    541656    // other required information describing the PSF
     
    557672        int xPow = psMetadataLookupS32 (&status, row, "X_POWER");
    558673        int yPow = psMetadataLookupS32 (&status, row, "Y_POWER");
    559         // XXX sanity check here
    560 
    561         psPolynomial2D *poly = psf->params->data[iPar];
    562         if (poly == NULL) {
    563             psError(PS_ERR_UNKNOWN, true, "values for parameter %d, but missing NX", iPar);
     674
     675        pmTrend2D *trend = psf->params->data[iPar];
     676        if (trend == NULL) {
     677            psError(PS_ERR_UNKNOWN, true, "parameter %d not available", iPar);
    564678            return false;
    565679        }
    566680
    567         poly->coeff[xPow][yPow]    = psMetadataLookupF32 (&status, row, "VALUE");
    568         poly->coeffErr[xPow][yPow] = psMetadataLookupF32 (&status, row, "ERROR");
    569         poly->mask[xPow][yPow]     = psMetadataLookupU8  (&status, row, "MASK");
     681        if (trend->mode == PM_TREND_MAP) {
     682            psImageMap *map = trend->map;
     683            assert (map);
     684            assert (map->map);
     685            assert (map->error);
     686            assert (xPow >= 0);
     687            assert (yPow >= 0);
     688            assert (xPow < map->map->numCols);
     689            assert (yPow < map->map->numRows);
     690            map->map->data.F32[yPow][xPow]    = psMetadataLookupF32 (&status, row, "VALUE");
     691            map->error->data.F32[yPow][xPow]  = psMetadataLookupF32 (&status, row, "ERROR");
     692        } else {
     693            psPolynomial2D *poly = trend->poly;
     694            assert (poly);
     695            assert (xPow >= 0);
     696            assert (yPow >= 0);
     697            assert (xPow <= poly->nX);
     698            assert (yPow <= poly->nY);
     699            poly->coeff[xPow][yPow]    = psMetadataLookupF32 (&status, row, "VALUE");
     700            poly->coeffErr[xPow][yPow] = psMetadataLookupF32 (&status, row, "ERROR");
     701            poly->mask[xPow][yPow]     = psMetadataLookupU8  (&status, row, "MASK");
     702        }
    570703    }
    571704    psFree (header);
     
    618751
    619752// create a psMetadata representation (human-readable) of a psf model
    620 psMetadata *pmPSFtoMetadata (psMetadata *metadata, pmPSF *psf)
    621 {
    622 
    623     if (metadata == NULL) {
    624         metadata = psMetadataAlloc ();
    625     }
    626 
    627     char *modelName = pmModelClassGetName (psf->type);
    628     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_MODEL_NAME", PS_DATA_STRING, "PSF model name", modelName);
    629 
    630     int nPar = pmModelClassParameterCount (psf->type)    ;
    631     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_MODEL_NPAR", PS_DATA_S32, "PSF model parameter count", nPar);
    632 
    633     for (int i = 0; i < nPar; i++) {
    634         psPolynomial2D *poly = psf->params->data[i];
    635         if (poly == NULL)
    636             continue;
    637         psPolynomial2DtoMetadata (metadata, poly, "PSF_PAR%02d", i);
    638     }
    639 
    640     // XXX fix this
    641     psWarning ("APTREND is currently missing");
    642     // psPolynomial4DtoMetadata (metadata, psf->ApTrend, "APTREND");
    643 
    644     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_AP_RESID", PS_DATA_F32, "aperture residual", psf->ApResid);
    645     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_dAP_RESID", PS_DATA_F32, "aperture residual scatter", psf->dApResid);
    646     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_SKY_BIAS", PS_DATA_F32, "sky bias level", psf->skyBias);
    647 
    648     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_CHISQ", PS_DATA_F32, "chi-square for fit", psf->chisq);
    649     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_NSTARS", PS_DATA_S32, "number of stars used to measure PSF", psf->nPSFstars);
    650     psMetadataAdd (metadata, PS_LIST_TAIL, "PSF_POISSON_ERRORS", PS_DATA_BOOL, "Poisson errors for fits", psf->poissonErrors);
    651 
    652     return metadata;
    653 }
    654 
    655 // parse a psMetadata representation (human-readable) of a psf model
    656 pmPSF *pmPSFfromMetadata (psMetadata *metadata)
    657 {
    658 
    659     bool status;
    660     char keyword[80];
    661 
    662     char *modelName = psMetadataLookupPtr (&status, metadata, "PSF_MODEL_NAME");
    663     pmModelType type = pmModelClassGetType (modelName);
    664 
    665     bool poissonErrors = psMetadataLookupPtr (&status, metadata, "PSF_POISSON_ERRORS");
    666     if (!status)
    667         poissonErrors = true;
    668 
    669     // we determine the PSF parameter polynomials from the MD-defined polynomials
    670     pmPSF *psf = pmPSFAlloc (type, poissonErrors, NULL);
    671 
    672     int nPar = psMetadataLookupS32 (&status, metadata, "PSF_MODEL_NPAR");
    673     if (nPar != pmModelClassParameterCount (psf->type))
    674         psAbort("mismatch model par count");
    675 
    676     // un-fitted terms, not in the Metadata, are left NULL
    677     // XXX add a double-check of the expected number?
    678     for (int i = 0; i < nPar; i++) {
    679         sprintf (keyword, "PSF_PAR%02d", i);
    680         psMetadata *folder = psMetadataLookupPtr (&status, metadata, keyword);
    681         if (!status)
    682             continue;
    683         psPolynomial2D *poly = psPolynomial2DfromMetadata (folder);
    684         psFree (psf->params->data[i]);
    685         psf->params->data[i] = poly;
    686     }
    687 
    688     // load the APTREND data
    689     // XXX fix this to work with pmTrend2D
    690     psWarning ("APTREND is not being read");
    691     # if (0)
    692     sprintf (keyword, "APTREND");
    693     psMetadata *folder = psMetadataLookupPtr (&status, metadata, keyword);
    694     psPolynomial4D *poly = psPolynomial4DfromMetadata (folder);
    695     psFree (psf->ApTrend);
    696     psf->ApTrend = poly;
    697     # endif
    698 
    699     psf->ApResid = psMetadataLookupF32 (&status, metadata, "PSF_AP_RESID");
    700     psf->dApResid = psMetadataLookupF32 (&status, metadata, "PSF_dAP_RESID");
    701     psf->skyBias = psMetadataLookupF32 (&status, metadata, "PSF_SKY_BIAS");
    702 
    703     psf->chisq = psMetadataLookupF32 (&status, metadata, "PSF_CHISQ");
    704     psf->nPSFstars = psMetadataLookupS32 (&status, metadata, "PSF_NSTARS");
    705 
    706     psFree (metadata);
    707     return (psf);
    708 }
     753// XXX pmPSF to/from Metadata functions were defined for 1.22 and earlier, but were dropped
  • trunk/psModules/src/objects/pmPSF_IO.h

    r14652 r15000  
    66 * @author EAM, IfA
    77 *
    8  * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2007-08-24 00:11:02 $
     8 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2007-09-24 21:27:58 $
    1010 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    1111 */
     
    3333bool pmPSFmodelCheckDataStatusForChip (const pmChip *chip);
    3434
    35 psMetadata *pmPSFtoMetadata (psMetadata *metadata, pmPSF *psf);
    36 pmPSF *pmPSFfromMetadata (psMetadata *metadata);
    37 
    3835/// @}
    3936# endif
  • trunk/psModules/src/objects/pmPSFtry.c

    r14937 r15000  
    55 *  @author EAM, IfA
    66 *
    7  *  @version $Revision: 1.45 $ $Name: not supported by cvs2svn $
    8  *  @date $Date: 2007-09-21 00:06:57 $
     7 *  @version $Revision: 1.46 $ $Name: not supported by cvs2svn $
     8 *  @date $Date: 2007-09-24 21:27:58 $
    99 *
    1010 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    4444static void pmPSFtryFree (pmPSFtry *test)
    4545{
    46 
    47     if (test == NULL)
    48         return;
     46    if (test == NULL) return;
    4947
    5048    psFree (test->psf);
     
    5856
    5957// allocate a pmPSFtry based on the desired sources and the model (identified by name)
    60 pmPSFtry *pmPSFtryAlloc (psArray *sources, char *modelName, bool poissonErrors, psPolynomial2D *psfTrendMask)
     58pmPSFtry *pmPSFtryAlloc (psArray *sources, pmPSFOptions *options)
    6159{
    62 
    63     // validate the requested model name
    64     pmModelType type = pmModelClassGetType (modelName);
    65     if (type == -1) {
    66         psError (PS_ERR_UNKNOWN, true, "invalid model name %s", modelName);
    67         return NULL;
    68     }
    69 
    7060    pmPSFtry *test = (pmPSFtry *) psAlloc(sizeof(pmPSFtry));
    71 
    72     test->psf       = pmPSFAlloc (type, poissonErrors, psfTrendMask);
     61    psMemSetDeallocator(test, (psFreeFunc) pmPSFtryFree);
     62
     63    test->psf       = pmPSFAlloc (options);
    7364    test->metric    = psVectorAlloc (sources->n, PS_TYPE_F32);
    7465    test->metricErr = psVectorAlloc (sources->n, PS_TYPE_F32);
     
    7667    test->mask      = psVectorAlloc (sources->n, PS_TYPE_U8);
    7768
     69    psVectorInit (test->mask,        0);
     70    psVectorInit (test->metric,    0.0);
     71    psVectorInit (test->metricErr, 0.0);
     72    psVectorInit (test->fitMag,    0.0);
     73
    7874    test->sources   = psArrayAlloc (sources->n);
     75
    7976    for (int i = 0; i < sources->n; i++) {
    8077        test->sources->data[i] = pmSourceCopy (sources->data[i]);
    81         test->mask->data.U8[i]  = 0;
    82         test->metric->data.F32[i] = 0;
    83         test->metricErr->data.F32[i] = 0;
    84         test->fitMag->data.F32[i] = 0;
    85     }
    86 
    87     psMemSetDeallocator(test, (psFreeFunc) pmPSFtryFree);
     78    }
     79
    8880    return (test);
    8981}
     
    9991
    10092// generate a pmPSFtry with a copy of the test PSF sources
    101 pmPSFtry *pmPSFtryModel (psArray *sources, char *modelName, float RADIUS, bool poissonErrors, psPolynomial2D *psfTrendMask, bool applyWeights, psMaskType maskVal, psMaskType mark)
     93pmPSFtry *pmPSFtryModel (psArray *sources, char *modelName, pmPSFOptions *options, psMaskType maskVal, psMaskType mark)
    10294{
    10395    bool status;
     
    10597    int Npsf = 0;
    10698
    107     pmPSFtry *psfTry = pmPSFtryAlloc (sources, modelName, poissonErrors, psfTrendMask);
     99    // validate the requested model name
     100    options->type = pmModelClassGetType (modelName);
     101    if (options->type == -1) {
     102        psError (PS_ERR_UNKNOWN, true, "invalid model name %s", modelName);
     103        return NULL;
     104    }
     105
     106    pmPSFtry *psfTry = pmPSFtryAlloc (sources, options);
    108107    if (psfTry == NULL) {
    109108        psError (PS_ERR_UNKNOWN, false, "failed to allocate psf model");
     
    111110    }
    112111
    113     // stage 1:  fit an independent model (freeModel) to all sources
     112    // stage 1:  fit an EXT model to all candidates PSF sources
    114113    psTimerStart ("fit");
    115114    for (int i = 0; i < psfTry->sources->n; i++) {
     
    123122        }
    124123
    125         // set object mask to define valid pixels
    126         psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, RADIUS, "OR", mark);
     124        // set object mask to define valid pixels -- XXX not unset?
     125        psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->radius, "OR", mark);
    127126
    128127        // fit model as EXT, not PSF
     
    140139
    141140    // stage 2: construct a psf (pmPSF) from this collection of model fits
    142     if (!pmPSFFromPSFtry (psfTry, applyWeights)) {
     141    if (!pmPSFFromPSFtry (psfTry)) {
    143142        psError(PS_ERR_UNKNOWN, false, "failed to construct a psf model from collection of sources");
    144143        psFree(psfTry);
     
    162161            continue;
    163162        }
    164         source->modelPSF->radiusFit = RADIUS;
    165 
    166         // set object mask to define valid pixels
    167         psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, RADIUS, "OR", mark);
     163        source->modelPSF->radiusFit = options->radius;
     164
     165        // set object mask to define valid pixels -- XXX not unset?
     166        psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, options->radius, "OR", mark);
    168167
    169168        // fit the PSF model to the source
     
    241240
    242241    // XXX this function wants aperture radius for pmSourcePhotometry
    243     pmPSFtryMetric (psfTry, RADIUS);
     242    pmPSFtryMetric (psfTry, options->radius);
    244243    psLogMsg ("psphot.pspsf", 3, "try model %s, ap-fit: %f +/- %f : sky bias: %f\n",
    245244              modelName, psfTry->psf->ApResid, psfTry->psf->dApResid, psfTry->psf->skyBias);
     
    339338/*****************************************************************************
    340339pmPSFFromPSFtry (psfTry): build a PSF model from a collection of
    341 source->modelEXT entires.  The PSF ignores the first 4 (independent) model
     340source->modelEXT entries.  The PSF ignores the first 4 (independent) model
    342341parameters and constructs a polynomial fit to the remaining as a function of
    343342image coordinate.
     
    345344Note: some of the array entries may be NULL (failed fits); ignore them.
    346345 *****************************************************************************/
    347 bool pmPSFFromPSFtry (pmPSFtry *psfTry, bool applyWeight)
     346bool pmPSFFromPSFtry (pmPSFtry *psfTry)
    348347{
    349348    pmPSF *psf = psfTry->psf;
     
    355354
    356355    psVector *dz = NULL;
    357     if (applyWeight) {
     356    if (psf->poissonErrorsParams) {
    358357        dz = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);
    359358    }
     
    377376    // more deviant than three sigma.
    378377    // mask is currently updated for each pass. this is inconsistent?
    379 
    380     psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
    381378
    382379    // The shape parameters (SXX, SXY, SYY) are strongly coupled.  We have to handle them very
     
    389386    // threshold.
    390387
     388    // XXX this function needs to check the fit residuals and modify Nx,Ny as needed
     389
    391390    // convert the measured source shape paramters to polarization terms
    392391    psVector *e0   = psVectorAlloc (psfTry->sources->n, PS_TYPE_F32);
     
    406405    // we run 'clipIter' cycles clipping in each of x and y, with only one iteration each.
    407406    // This way, the parameters masked by one of the fits will be applied to the others
    408     for (int i = 0; i < stats->clipIter; i++) {
    409         psVectorClipFitPolynomial2D (psf->params->data[PM_PAR_E0], stats, psfTry->mask, 0xff, e0, dz, x, y);
    410         psTrace ("psModules.pmPSFtry", 4, "clipped E0 : keeping %ld of %ld\n", stats->clippedNvalues, e0->n);
    411         psVectorClipFitPolynomial2D (psf->params->data[PM_PAR_E1], stats, psfTry->mask, 0xff, e1, dz, x, y);
    412         psTrace ("psModules.pmPSFtry", 4, "clipped E1 : keeping %ld of %ld\n", stats->clippedNvalues, e1->n);
    413         psVectorClipFitPolynomial2D (psf->params->data[PM_PAR_E2], stats, psfTry->mask, 0xff, e2, dz, x, y);
    414         psTrace ("psModules.pmPSFtry", 4, "clipped E2 : keeping %ld of %ld\n", stats->clippedNvalues, e2->n);
    415     }
    416 
    417     // XXX temporary dump of the psf parameters
     407    for (int i = 0; i < psf->psfTrendStats->clipIter; i++) {
     408
     409        // XXX we are using the same stats structure on each pass: do we need to re-init it?
     410        pmTrend2DFit (psf->params->data[PM_PAR_E0], psfTry->mask, 0xff, x, y, e0, dz);
     411        psTrace ("psModules.pmPSFtry", 4, "clipped E0 : keeping %ld of %ld\n", psf->psfTrendStats->clippedNvalues, e0->n);
     412        pmTrend2DFit (psf->params->data[PM_PAR_E1], psfTry->mask, 0xff, x, y, e1, dz);
     413        psTrace ("psModules.pmPSFtry", 4, "clipped E1 : keeping %ld of %ld\n", psf->psfTrendStats->clippedNvalues, e1->n);
     414        pmTrend2DFit (psf->params->data[PM_PAR_E2], psfTry->mask, 0xff, x, y, e2, dz);
     415        psTrace ("psModules.pmPSFtry", 4, "clipped E2 : keeping %ld of %ld\n", psf->psfTrendStats->clippedNvalues, e2->n);
     416    }
     417
     418    // test dump of the psf parameters
    418419    if (psTraceGetLevel("psModules.objects") >= 4) {
    419420        FILE *f = fopen ("pol.dat", "w");
     421        fprintf (f, "# x y  :  e0obs e1obs e2obs  : e0fit e1fit e2fit : mask\n");
    420422        for (int i = 0; i < e0->n; i++) {
    421             fprintf (f, "%f %f  :  %f %f %f  : %d\n",
     423            fprintf (f, "%f %f  :  %f %f %f  : %f %f %f  : %d\n",
    422424                     x->data.F32[i], y->data.F32[i],
    423                      e0->data.F32[i], e1->data.F32[i], e2->data.F32[i], psfTry->mask->data.U8[i]);
     425                     e0->data.F32[i], e1->data.F32[i], e2->data.F32[i],
     426                     pmTrend2DEval (psf->params->data[PM_PAR_E0], x->data.F32[i], y->data.F32[i]),
     427                     pmTrend2DEval (psf->params->data[PM_PAR_E1], x->data.F32[i], y->data.F32[i]),
     428                     pmTrend2DEval (psf->params->data[PM_PAR_E2], x->data.F32[i], y->data.F32[i]),
     429                     psfTry->mask->data.U8[i]);
    424430        }
    425431        fclose (f);
     
    455461        // fit the collection of measured parameters to the PSF 2D model
    456462        // the mask is carried from previous steps and updated with this operation
    457         // the weight is either the flux error or NULL, depending on 'applyWeights'
    458         if (!psVectorClipFitPolynomial2D(psf->params->data[i], stats, psfTry->mask, 0xff, z, NULL, x, y)) {
     463        // the weight is either the flux error or NULL, depending on 'psf->poissonErrorParams'
     464        if (!pmTrend2DFit (psf->params->data[i], psfTry->mask, 0xff, x, y, e0, NULL)) {
    459465            psError(PS_ERR_UNKNOWN, false, "failed to build psf model for parameter %d", i);
    460             psFree(stats);
    461466            psFree(x);
    462467            psFree(y);
     
    485490
    486491            for (int i = 0; i < psf->params->n; i++) {
    487                 if (psf->params->data[i] == NULL)
    488                     continue;
     492                if (psf->params->data[i] == NULL) continue;
    489493                fprintf (f, "%f %f : ", model->params->data.F32[i], modelPSF->params->data.F32[i]);
    490494            }
     
    496500    }
    497501
    498     psFree (stats);
    499502    psFree (x);
    500503    psFree (y);
    501504    psFree (z);
    502505    psFree (dz);
    503     return (true);
     506    return true;
    504507}
    505508
  • trunk/psModules/src/objects/pmPSFtry.h

    r14505 r15000  
    66 * @author EAM, IfA
    77 *
    8  * @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    9  * @date $Date: 2007-08-15 20:21:18 $
     8 * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     9 * @date $Date: 2007-09-24 21:27:58 $
    1010 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    1111 */
     
    7878 *
    7979 */
    80 pmPSFtry *pmPSFtryAlloc (psArray *sources, char *modelName, bool poissonErrors, psPolynomial2D *psfTrendMask);
     80pmPSFtry *pmPSFtryAlloc (psArray *sources, pmPSFOptions *options);
    8181
    8282/** pmPSFtryModel()
     
    8787 *
    8888 */
    89 pmPSFtry *pmPSFtryModel (psArray *sources, char *modelName, float RADIUS, bool poissonErrors, psPolynomial2D *psfTrendMask, bool applyWeights, psMaskType maskVal, psMaskType mark);
     89pmPSFtry *pmPSFtryModel (psArray *sources, char *modelName, pmPSFOptions *options, psMaskType maskVal, psMaskType mark);
    9090
    9191/** pmPSFtryMetric()
     
    123123 *
    124124 */
    125 bool pmPSFFromPSFtry (pmPSFtry *psfTry, bool applyWeights);
     125bool pmPSFFromPSFtry (pmPSFtry *psfTry);
    126126
    127127/// @}
  • trunk/psModules/src/objects/pmSourcePhotometry.c

    r14962 r15000  
    33 *  @author EAM, IfA; GLG, MHPCC
    44 *
    5  *  @version $Revision: 1.31 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-09-21 02:46:46 $
     5 *  @version $Revision: 1.32 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-09-24 21:27:58 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    8181    // we must have a valid model
    8282    model = pmSourceGetModel (&isPSF, source);
    83     if (model == NULL)
    84         return false;
     83    if (model == NULL) {
     84        psTrace ("psModules.objects", 3, "fail mag : no valid model");
     85        return false;
     86    }
    8587
    8688    if (model->dparams->data.F32[PM_PAR_I0] > 0) {
     
    102104            source->psfMag = NAN;
    103105        }
    104         fprintf (stderr, ".");
    105106    } else {
    106107        status = pmSourcePhotometryModel (&source->psfMag, source->modelPSF);
     
    109110    // measure EXT model photometry
    110111    status = pmSourcePhotometryModel (&source->extMag, source->modelEXT);
     112
    111113    // for PSFs, correct both apMag and psfMag to same system, consistent with infinite flux star in aperture RADIUS
    112     if ((mode & PM_SOURCE_PHOT_APCORR) && isPSF && psf) {
    113         // convert to the equivalent 2D model?
     114    if ((mode & PM_SOURCE_PHOT_APCORR) && isPSF && psf && psf->ApTrend) {
    114115        source->psfMag += pmTrend2DEval (psf->ApTrend, x, y);
    115116    }
    116117
    117     if (!isfinite(SN) || (SN < AP_MIN_SN))
    118         return false;
     118    if (!isfinite(SN) || (SN < AP_MIN_SN)) {
     119        psTrace ("psModules.objects", 3, "fail mag : bad SN: %f (limit: %f)", SN, AP_MIN_SN);
     120        return false;
     121    }
    119122
    120123    // replace source flux
     
    209212    status = pmSourcePhotometryAper  (&source->apMag, model, flux, source->maskObj, maskVal);
    210213    if (!status) {
     214        psTrace ("psModules.objects", 3, "fail mag : bad Ap Mag");
    211215        psErrorCode last = psErrorCodeLast();
    212216        if (last == PM_ERR_PHOTOM) {
  • trunk/psModules/src/objects/pmTrend2D.c

    r14938 r15000  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-09-21 00:09:18 $
     5 *  @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-09-24 21:27:58 $
    77 *
    88 *  Copyright 2004 Institute for Astronomy, University of Hawaii
     
    1414#endif
    1515
     16# include <strings.h>
    1617# include <pslib.h>
    1718# include "pmTrend2D.h"
     
    3132{
    3233    assert (image);
    33     assert (stats);
    3434
    3535    pmTrend2D *trend = (pmTrend2D *) psAlloc(sizeof(pmTrend2D));
     
    4444      case PM_TREND_POLY_ORD:
    4545        trend->poly = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXtrend, nYtrend);
     46        // set masking somehow
     47        for (int nx = 0; nx < trend->poly->nX + 1; nx++) {
     48            for (int ny = 0; ny < trend->poly->nY + 1; ny++) {
     49                if (nx + ny >= PS_MAX (trend->poly->nX, trend->poly->nY) + 1) {
     50                    trend->poly->mask[nx][ny] = 1;
     51                } else {
     52                    trend->poly->mask[nx][ny] = 0;
     53                }
     54            }
     55        }
    4656        break;
    4757
     
    6979}
    7080
    71 pmTrend2D *pmTrend2DFieldAlloc (pmTrend2DMode mode, int nXfield, int nYfield, int nXtrend, int nYtrend, psStats *stats)
     81pmTrend2D *pmTrend2DNoImageAlloc (pmTrend2DMode mode, psImageBinning *binning, psStats *stats)
    7282{
    7383    pmTrend2D *trend = (pmTrend2D *) psAlloc(sizeof(pmTrend2D));
     
    8191    switch (mode) {
    8292      case PM_TREND_POLY_ORD:
     93        trend->poly = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, binning->nXruff, binning->nYruff);
     94        // set masking somehow
     95        for (int nx = 0; nx < trend->poly->nX + 1; nx++) {
     96            for (int ny = 0; ny < trend->poly->nY + 1; ny++) {
     97                if (nx + ny >= PS_MAX (trend->poly->nX, trend->poly->nY) + 1) {
     98                    trend->poly->mask[nx][ny] = 1;
     99                } else {
     100                    trend->poly->mask[nx][ny] = 0;
     101                }
     102            }
     103        }
     104        break;
     105
     106      case PM_TREND_POLY_CHEB:
     107        trend->poly = psPolynomial2DAlloc (PS_POLYNOMIAL_CHEB, binning->nXruff, binning->nYruff);
     108        break;
     109
     110      case PM_TREND_MAP: {
     111          // binning defines the map scale relationship
     112          trend->map = psImageMapNoImageAlloc (binning, stats);
     113          break;
     114      }
     115
     116      default:
     117        psAbort ("error");
     118    }
     119    return (trend);
     120}
     121
     122pmTrend2D *pmTrend2DFieldAlloc (pmTrend2DMode mode, int nXfield, int nYfield, int nXtrend, int nYtrend, psStats *stats)
     123{
     124    pmTrend2D *trend = (pmTrend2D *) psAlloc(sizeof(pmTrend2D));
     125    psMemSetDeallocator(trend, (psFreeFunc) pmTrend2DFree);
     126
     127    trend->map = NULL;
     128    trend->poly = NULL;
     129    trend->stats = psMemIncrRefCounter (stats);
     130    trend->mode = mode;
     131       
     132    switch (mode) {
     133      case PM_TREND_POLY_ORD:
    83134        trend->poly = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXtrend, nYtrend);
     135        // set masking somehow
     136        for (int nx = 0; nx < trend->poly->nX + 1; nx++) {
     137            for (int ny = 0; ny < trend->poly->nY + 1; ny++) {
     138                if (nx + ny >= PS_MAX (trend->poly->nX, trend->poly->nY) + 1) {
     139                    trend->poly->mask[nx][ny] = 1;
     140                } else {
     141                    trend->poly->mask[nx][ny] = 0;
     142                }
     143            }
     144        }
    84145        break;
    85146
     
    111172    bool status;
    112173
     174    assert (trend);
     175    assert (x);
     176    assert (y);
     177    assert (f);
     178
    113179    switch (trend->mode) {
    114180      case PM_TREND_POLY_ORD:
     
    136202    double result;
    137203
    138     if (!trend) return 0.0;
     204    assert (trend);
    139205
    140206    switch (trend->mode) {
     
    158224    psVector *result;
    159225
     226    assert (trend);
     227    assert (x);
     228    assert (y);
     229
    160230    switch (trend->mode) {
    161231      case PM_TREND_POLY_ORD:
     
    173243    return result;
    174244}
     245
     246psString pmTrend2DModeToString (pmTrend2DMode mode) {
     247   
     248    psString name;
     249
     250    switch (mode) {
     251      case PM_TREND_NONE:
     252        name = psStringCopy ("NONE");
     253        break;
     254      case PM_TREND_POLY_ORD:
     255        name = psStringCopy ("POLY_ORD");
     256        break;
     257      case PM_TREND_POLY_CHEB:
     258        name = psStringCopy ("POLY_CHEB");
     259        break;
     260      case PM_TREND_MAP:
     261        name = psStringCopy ("MAP");
     262        break;
     263      default:
     264        psAbort ("invalid mode %d", mode);
     265    }
     266    return name;
     267}
     268
     269pmTrend2DMode pmTrend2DModeFromString (psString name) {
     270
     271    if (!name) return PM_TREND_NONE;
     272
     273    if (!strcasecmp (name, "NONE")) {
     274        return PM_TREND_NONE;
     275    }
     276    if (!strcasecmp (name, "POLY_ORD")) {
     277        return PM_TREND_POLY_ORD;
     278    }
     279    if (!strcasecmp (name, "POLY_CHEB")) {
     280        return PM_TREND_POLY_CHEB;
     281    }
     282    if (!strcasecmp (name, "MAP")) {
     283        return PM_TREND_MAP;
     284    }
     285    psError (PS_ERR_UNKNOWN, true, "Unknown pmTrend2D mode %s\n", name);
     286    return PM_TREND_NONE;
     287}
  • trunk/psModules/src/objects/pmTrend2D.h

    r14938 r15000  
    55 * @author EAM, IfA
    66 *
    7  * @version $Revision: 1.2 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2007-09-21 00:09:18 $
     7 * @version $Revision: 1.3 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2007-09-24 21:27:58 $
    99 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    1010 */
     
    1717
    1818typedef enum {
     19    PM_TREND_NONE,
    1920    PM_TREND_POLY_ORD,
    2021    PM_TREND_POLY_CHEB,
     
    3334pmTrend2D *pmTrend2DAlloc (pmTrend2DMode mode, psImage *image, int nXtrend, int nYtrend, psStats *stats);
    3435
     36pmTrend2D *pmTrend2DNoImageAlloc (pmTrend2DMode mode, psImageBinning *binning, psStats *stats);
     37
    3538// allocate a pmTrend2D tied to an abstract field with size nXfield,nYfield
    3639pmTrend2D *pmTrend2DFieldAlloc (pmTrend2DMode mode, int nXfield, int nYfield, int nXtrend, int nYtrend, psStats *stats);
     
    4144psVector *pmTrend2DEvalVector (pmTrend2D *trend, psVector *x, psVector *y);
    4245
     46psString pmTrend2DModeToString (pmTrend2DMode mode);
     47pmTrend2DMode pmTrend2DModeFromString (psString name);
     48
    4349/// @}
    4450# endif
  • trunk/psphot/doc/psfmodel.txt

    r9772 r15000  
     1
     22007.09.21
     3
     4  there are three places where we can choose to use errors in the fits or not:
     5
     6  * non-linear fitting of the models to the pixel flux distribution (poissonErrorsPhotLMM)
     7  * linear fitting of the models to the pixel flux distribution (poissonErrorsPhotLin)
     8  * fitting of the 2D variations in the psf parameters (poissonErrorsParams)
     9  * fitting of the 2D variations in the aperture residuals
     10
     112007.09.20
     12
     13  I am upgrading the PSF model to allow the parameter variation to be
     14  modeled with pmTrend2D instead of just polynomials.  I am making a
     15  list of places to modify the code:
     16
     17pmPSFAlloc : need a method beyong psfTrendMask to carry in the psf
     18options
     19
     20pmPSF_ModelToFit : no need to change these
     21
     22update pmPSFBuildSimple to set the parameters of the pmTrend, which
     23ever is used.
     24
     25pmPSFtry.c: some significant re-work!
     26
     27
     28
     29pmPSF_IO : need new functions to save / load the trend (psImages)
    130
    2312006.10.27
  • trunk/psphot/src/models/pmModel_STRAIL.c

    r14655 r15000  
    530530 
    531531    for (int i = 4; i < 7; i++) {
    532       psPolynomial2D *poly = psf->params->data[i-4];
    533         out[i] = psPolynomial2DEval (poly, out[2], out[3]);
     532      pmTrend2D *trend = psf->params->data[i-4];
     533        out[i] = pmTrend2DEval (trend, out[2], out[3]);
    534534    }
    535535    return(true);
     
    554554    for (int i = 0; i < psf->params->n; i++) {
    555555        if (i == PM_PAR_SKY) continue;
    556         psPolynomial2D *poly = psf->params->data[i];
    557         assert (poly);
    558         PAR[i] = psPolynomial2DEval(poly, Xo, Yo);
     556        pmTrend2D *trend = psf->params->data[i];
     557        PAR[i] = pmTrend2DEval(trend, Xo, Yo);
    559558    }
    560559
  • trunk/psphot/src/models/pmModel_TEST1.c

    r14655 r15000  
    217217            out[i] = in[i];
    218218        } else {           
    219             psPolynomial2D *poly = psf->params->data[i];
    220             out[i] = psPolynomial2DEval(poly, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
     219            pmTrend2D *trend = psf->params->data[i];
     220            out[i] = pmTrend2DEval(trend, in[PM_PAR_XPOS], in[PM_PAR_YPOS]);
    221221        }
    222222    }
     
    246246    for (int i = 0; i < psf->params->n; i++) {
    247247        if (i == PM_PAR_SKY) continue;
    248         psPolynomial2D *poly = psf->params->data[i];
    249         assert (poly);
    250         PAR[i] = psPolynomial2DEval(poly, Xo, Yo);
     248        pmTrend2D *trend = psf->params->data[i];
     249        PAR[i] = pmTrend2DEval(trend, Xo, Yo);
    251250    }
    252251
  • trunk/psphot/src/psphot.h

    r14963 r15000  
    4747bool            psphotReplaceAll (psArray *sources, psMaskType maskVal);
    4848bool            psphotApResid (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psMaskType maskVal, psMaskType mark);
    49 bool            psphotMagErrorScale (float *errorScale, float *errorFloor, psVector *dMag, psVector *dap, int nGroup);
     49bool            psphotMagErrorScale (float *errorScale, float *errorFloor, psVector *dMag, psVector *dap, psVector *mask, int nGroup);
    5050bool            psphotApResidTrend (pmReadout *readout, pmPSF *psf, int Npsf, int scale, float *errorScale, float *errorFloor, psVector *mask, psVector *xPos, psVector *yPos, psVector *apResid, psVector *dMag);
    5151bool            psphotMagnitudes (psArray *sources, psMetadata *recipe, pmPSF *psf, pmReadout *background, psMaskType maskVal, psMaskType mark);
  • trunk/psphot/src/psphotApResid.c

    r14965 r15000  
    11# include "psphotInternal.h"
    22
     3# define SKIPSTAR(MSG) { psTrace ("psphot", 3, "invalid : %s", MSG); continue; }
    34// measure the aperture residual statistics and 2D variations
    45bool psphotApResid (pmReadout *readout, psArray *sources, psMetadata *recipe, pmPSF *psf, psMaskType maskVal, psMaskType mark)
     
    6364        model = source->modelPSF;
    6465
    65         if (source->type != PM_SOURCE_TYPE_STAR) continue;
    66         if (source->mode &  PM_SOURCE_MODE_SATSTAR) continue;
    67         if (source->mode &  PM_SOURCE_MODE_BLEND) continue;
    68         if (source->mode &  PM_SOURCE_MODE_FAIL) continue;
    69         if (source->mode &  PM_SOURCE_MODE_POOR) continue;
     66        if (source->type != PM_SOURCE_TYPE_STAR) SKIPSTAR ("NOT STAR");
     67        if (source->mode &  PM_SOURCE_MODE_SATSTAR) SKIPSTAR ("SATSTAR");
     68        if (source->mode &  PM_SOURCE_MODE_BLEND) SKIPSTAR ("BLEND");
     69        if (source->mode &  PM_SOURCE_MODE_FAIL) SKIPSTAR ("FAIL STAR");
     70        if (source->mode &  PM_SOURCE_MODE_POOR) SKIPSTAR ("POOR STAR");
    7071
    7172        // get growth-corrected, apTrend-uncorrected magnitudes in scaled apertures
     
    7374        if (!pmSourceMagnitudes (source, psf, photMode, maskVal, mark)) {
    7475            Nskip ++;
     76            psTrace ("psphot", 3, "skip : bad source mag");
    7577            continue;
    7678        }
    7779
    78         if (!isfinite(source->apMag) || !isfinite(source->apMag)) {
     80        if (!isfinite(source->apMag) || !isfinite(source->psfMag)) {
    7981            Nfail ++;
     82            psTrace ("psphot", 3, "fail : nan mags : %f %f", source->apMag, source->psfMag);
    8083            continue;
    8184        }
     
    8790        if ((MAX_AP_OFFSET > 0) && (fabs(dap) > MAX_AP_OFFSET)) {
    8891            Nfail ++;
     92            psTrace ("psphot", 3, "fail : bad dap %f %f", dap, MAX_AP_OFFSET);
    8993            continue;
    9094        }
     
    99103        dMag->data.F32[Npsf] = model->dparams->data.F32[PM_PAR_I0] / model->params->data.F32[PM_PAR_I0];
    100104
     105        psVectorExtend (mag,     100, 1);
    101106        psVectorExtend (mask,    100, 1);
    102107        psVectorExtend (xPos,    100, 1);
     
    146151    }
    147152
     153    // XXX catch error condition
    148154    psphotApResidTrend (readout, psf, Npsf, entryMin, &errorScale, &errorFloor, mask, xPos, yPos, apResid, dMag);
    149155
     
    152158    psVector *apResidRes = (psVector *) psBinaryOp (NULL, (void *) apResid, "-", (void *) apResidFit);
    153159    psVector *dMagSys = (psVector *) psBinaryOp (NULL, (void *) dMag, "*", (void *) psScalarAlloc(errorScale, PS_TYPE_F32));
    154 
    155     psphotSaveImage (NULL, psf->ApTrend->map->map, "apresid.map.fits");
    156160
    157161    if (psTraceGetLevel("psphot") >= 5) {
     
    170174    float xc = 0.5*readout->image->numCols + readout->image->col0 + 0.5;
    171175    float yc = 0.5*readout->image->numRows + readout->image->row0 + 0.5;
     176
    172177    psf->ApResid  = pmTrend2DEval (psf->ApTrend, xc, yc); // ap-fit at chip center
    173178    psf->dApResid = errorFloor;
     
    206211*/
    207212
    208 bool psphotMagErrorScale (float *errorScale, float *errorFloor, psVector *dMag, psVector *dap, int nGroup) {
     213bool psphotMagErrorScale (float *errorScale, float *errorFloor, psVector *dMag, psVector *dap, psVector *mask, int nGroup) {
    209214
    210215    psStats *statsS = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     
    225230    psVector *dMSubset = psVectorAllocEmpty (nGroup, PS_TYPE_F32);
    226231    psVector *dASubset = psVectorAllocEmpty (nGroup, PS_TYPE_F32);
     232    psVector *mkSubset = psVectorAllocEmpty (nGroup, PS_TYPE_U8);
    227233
    228234    int n = 0;
     
    233239            dMSubset->data.F32[j] = dMag->data.F32[N];
    234240            dASubset->data.F32[j] = dap->data.F32[N];
     241            mkSubset->data.U8[j]  = mask->data.U8[N];
    235242        }
    236243        dMSubset->n = j;
    237244        dASubset->n = j;
     245        mkSubset->n = j;
    238246
    239247        psStatsInit (statsS);
    240248        psStatsInit (statsM);
    241249
    242         psVectorStats (statsS, dASubset, NULL, NULL, 0xff);
    243         psVectorStats (statsM, dMSubset, NULL, NULL, 0xff);
     250        psVectorStats (statsS, dASubset, NULL, mkSubset, 0xff);
     251        psVectorStats (statsM, dMSubset, NULL, mkSubset, 0xff);
    244252
    245253        dSo->data.F32[i] = statsS->robustStdev;
     
    250258    psFree (dMSubset);
    251259    psFree (dASubset);
     260    psFree (mkSubset);
    252261   
    253262    psStats *stats = psStatsAlloc (PS_STAT_SAMPLE_MEDIAN);
     
    286295    }
    287296
     297    // the mask marks the values not used to calculate the ApTrend
     298    psVectorInit (mask, 0);
     299
    288300    // XXX stats structure for use by ApTrend : make parameters user setable
    289301    psStats *stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     
    305317    // XXX this is a bit arbitrary, but it forces ~3 stars from the bright bin per spatial bin
    306318    int nGroup = PS_MAX (3*Nx*Ny, 10);
    307     psphotMagErrorScale (errorScale, errorFloor, dMag, apResidRes, nGroup);
     319    psphotMagErrorScale (errorScale, errorFloor, dMag, apResidRes, mask, nGroup);
    308320
    309321    psLogMsg ("psphot.apresid", PS_LOG_INFO, "result of %d x %d grid (%d stars per bin)\n", Nx, Ny, nGroup);
  • trunk/psphot/src/psphotChoosePSF.c

    r14966 r15000  
    1111    sources = psArraySort (sources, pmSourceSortBySN);
    1212
     13    // structure to store user options defining the psf
     14    pmPSFOptions *options = pmPSFOptionsAlloc ();
     15
     16    // load user options from the recipe. no need to check existence -- they are
    1317    // array to store candidate PSF stars
    1418    int NSTARS = psMetadataLookupS32 (&status, recipe, "PSF_MAX_NSTARS");
    15     PS_ASSERT (status, NULL);
     19    assert (status);
    1620
    1721    float PSF_MIN_DS = psMetadataLookupF32 (&status, recipe, "PSF_MIN_DS");
    18     PS_ASSERT (status, NULL);
     22    assert (status);
    1923
    2024    // supply the measured sky variance for optional constant errors (non-poissonian)
    2125    float SKY_SIG = psMetadataLookupF32 (&status, recipe, "SKY_SIG");
    22     PS_ASSERT (status, NULL);
     26    assert (status);
    2327
    2428    // use poissonian errors or local-sky errors
    25     bool POISSON_ERRORS = psMetadataLookupBool (&status, recipe, "POISSON_ERRORS");
    26     PS_ASSERT (status, NULL);
     29    options->poissonErrorsPhotLMM = psMetadataLookupBool (&status, recipe, "POISSON.ERRORS.PHOT.LMM");
     30    assert (status);
    2731
    2832    // use poissonian errors or local-sky errors
    29     bool PSF_PARAM_WEIGHTS = psMetadataLookupBool (&status, recipe, "PSF_PARAM_WEIGHTS");
    30     PS_ASSERT (status, NULL);
     33    options->poissonErrorsPhotLin = psMetadataLookupBool (&status, recipe, "POISSON.ERRORS.PHOT.LIN");
     34    assert (status);
     35
     36    // use poissonian errors or local-sky errors
     37    options->poissonErrorsParams = psMetadataLookupBool (&status, recipe, "POISSON.ERRORS.PARAMS");
     38    assert (status);
    3139
    3240    // how to model the PSF variations across the field
    33     psMetadata *md = psMetadataLookupMetadata (&status, recipe, "PSF.TREND.MASK");
    34     PS_ASSERT (status, NULL);
     41    options->psfTrendMode = pmTrend2DModeFromString (psMetadataLookupStr (&status, recipe, "PSF.TREND.MODE"));
     42    assert (status);
     43   
     44    options->psfTrendNx = psMetadataLookupS32 (&status, recipe, "PSF.TREND.NX");
     45    assert (status);
     46
     47    options->psfTrendNy = psMetadataLookupS32 (&status, recipe, "PSF.TREND.NY");
     48    assert (status);
    3549
    3650    // get the fixed PSF fit radius
    3751    // XXX check that PSF_FIT_RADIUS < SKY_OUTER_RADIUS
    38     float RADIUS = psMetadataLookupF32 (&status, recipe, "PSF_FIT_RADIUS");
    39     PS_ASSERT (status, NULL);
    40 
    41     pmSourceFitModelInit (15, 0.01, PS_SQR(SKY_SIG), POISSON_ERRORS);
    42 
    43     psPolynomial2D *psfTrendMask = psPolynomial2DfromMetadata (md);
    44     if (!psfTrendMask) {
    45         psError(PSPHOT_ERR_PSF, true, "Unable to construct polynomial from PSF.TREND.MASK in the recipe");
    46         return NULL;
    47     }
     52    options->radius = psMetadataLookupF32 (&status, recipe, "PSF_FIT_RADIUS");
     53    assert (status);
     54
     55    options->stats = psStatsAlloc (PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
     56
     57    // dimensions of the field for which the PSF is defined
     58    options->psfFieldNx = readout->image->numCols;
     59    options->psfFieldNy = readout->image->numRows;
     60    options->psfFieldXo = readout->image->col0;
     61    options->psfFieldYo = readout->image->row0;
     62
     63    pmSourceFitModelInit (15, 0.01, PS_SQR(SKY_SIG), options->poissonErrorsPhotLMM);
    4864
    4965    psArray *stars = psArrayAllocEmpty (sources->n);
     
    6682        psLogMsg ("psphot.choosePSF", PS_LOG_WARN, "Failed to find any PSF candidates");
    6783        psFree (stars);
    68         psFree (psfTrendMask);
    6984        return NULL;
    7085    }
     
    91106        psMetadataItem *item = psListGetAndIncrement (iter);
    92107        char *modelName = item->data.V;
    93         models->data[i] = pmPSFtryModel (stars, modelName, RADIUS, POISSON_ERRORS, psfTrendMask, PSF_PARAM_WEIGHTS, maskVal, mark);
     108        models->data[i] = pmPSFtryModel (stars, modelName, options, maskVal, mark);
    94109    }
    95110
     
    97112    psFree (list);
    98113    psFree (stars);
    99     psFree (psfTrendMask);
    100114
    101115    // select the best of the models
     
    128142    if (psTraceGetLevel("psphot") >= 5) {
    129143        for (int i = PM_PAR_SXX; i < try->psf->params->n; i++) {
    130             psPolynomial2D *poly = try->psf->params->data[i];
    131             for (int nx = 0; nx <= poly->nX; nx++) {
    132                 for (int ny = 0; ny <= poly->nY; ny++) {
    133                     if (poly->mask[nx][ny]) continue;
    134                     fprintf (stderr, "%g x^%d y^%d\n", poly->coeff[nx][ny], nx, ny);
    135                 }
    136             }
     144            // XXX re-write the output or some other status info
    137145        }
    138146    }
     
    236244            // use pmModelSub because modelFlux has not been generated
    237245            assert (source->maskObj);
    238             psImageKeepCircle (source->maskObj, x, y, RADIUS, "OR", PM_MASK_MARK);
     246            psImageKeepCircle (source->maskObj, x, y, options->radius, "OR", PM_MASK_MARK);
    239247            pmModelSub (source->pixels, source->maskObj, source->modelPSF, PM_MODEL_OP_FULL, maskVal);
    240             psImageKeepCircle (source->maskObj, x, y, RADIUS, "AND", PS_NOT_U8(PM_MASK_MARK));
     248            psImageKeepCircle (source->maskObj, x, y, options->radius, "AND", PS_NOT_U8(PM_MASK_MARK));
    241249        }
    242250
     
    283291        pmSourcesWritePSFs (try->sources, "psfstars.dat");
    284292        pmSourcesWriteEXTs (try->sources, "extstars.dat", false);
    285         psMetadata *psfData = pmPSFtoMetadata (NULL, try->psf);
    286         psMetadataConfigWrite (psfData, "psfmodel.dat");
    287         psFree (psfData);
     293        // XXX need alternative output function
     294        // psMetadata *psfData = pmPSFtoMetadata (NULL, try->psf);
     295        // psMetadataConfigWrite (psfData, "psfmodel.dat");
    288296        psLogMsg ("psphot.choosePSF", PS_LOG_INFO, "wrote out psf-subtracted image, psf data, exiting\n");
    289297        exit (0);
     
    306314    psLogMsg ("psphot.pspsf", PS_LOG_INFO, "psf model %s, ApResid: %f +/- %f\n", modelName, psf->ApResid, psf->dApResid);
    307315
     316    psFree (options);
    308317    return (psf);
    309318}
  • trunk/psphot/src/psphotRoughClass.c

    r14760 r15000  
    11# include "psphotInternal.h"
     2# define CHECK_STATUS(S,MSG) { \
     3  if (!status) { \
     4    psError(PSPHOT_ERR_CONFIG, false, "missing PSF Clump entry: %s\n", MSG); \
     5    return false; \
     6  } }
    27
    38// 2006.02.02 : no leaks
    49bool psphotRoughClass (psArray *sources, psMetadata *recipe, const bool havePSF, psMaskType maskSat) {
    510
    6     static pmPSFClump   psfClump;
     11    bool status;
     12    static pmPSFClump psfClump;
    713
    814    psTimerStart ("psphot");
     
    1117        // determine the PSF parameters from the source moment values
    1218        psfClump = pmSourcePSFClump (sources, recipe);
     19        psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.X", 0, "psf clump center", psfClump.X);
     20        psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.Y", 0, "psf clump center", psfClump.Y);
     21        psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.DX", 0, "psf clump center", psfClump.dX);
     22        psMetadataAddF32 (recipe, PS_LIST_TAIL, "PSF.CLUMP.DY", 0, "psf clump center", psfClump.dY);
    1323    } else {
    1424        // pull FWHM_X,Y from the recipe, use to define psfClump.X,Y
    15         bool status_x, status_y, status_a;
    16         float FWHM_X = psMetadataLookupF32 (&status_x, recipe, "FWHM_X");
    17         float FWHM_Y = psMetadataLookupF32 (&status_y, recipe, "FWHM_Y");
    18         float ANGLE  = psMetadataLookupF32 (&status_a, recipe, "ANGLE");
    19         if (!status_x | !status_y | !status_a) {
    20             psError(PSPHOT_ERR_CONFIG, false, "FWHM_X, FWHM_Y, or ANGLE not defined");
    21             return false;
    22         }
    23 
    24         psEllipseAxes axes;
    25         axes.major = FWHM_X / (2.0*sqrt(2.0*log(2.0)));
    26         axes.minor = FWHM_Y / (2.0*sqrt(2.0*log(2.0)));
    27         axes.theta = ANGLE;
    28         psEllipseShape shape = psEllipseAxesToShape (axes);
    29 
    30         psfClump.X   = shape.sx;
    31         psfClump.Y   = shape.sy;
    32         psfClump.dX  = 0.1*shape.sx;
    33         psfClump.dY  = 0.1*shape.sy;
    34         // dX,dY are somewhat crudely defined, but only used to select PSF candidates.
    35         // if we already have a PSF, this is not actually used...
     25        psfClump.X  = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.X");  CHECK_STATUS (status, "PSF.CLUMP.X");
     26        psfClump.Y  = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.Y");  CHECK_STATUS (status, "PSF.CLUMP.Y");
     27        psfClump.dX = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DX");  CHECK_STATUS (status, "PSF.CLUMP.DX");
     28        psfClump.dY = psMetadataLookupF32 (&status, recipe, "PSF.CLUMP.DY");  CHECK_STATUS (status, "PSF.CLUMP.DY");
    3629    }
    3730
  • trunk/psphot/src/psphotSourcePlots.c

    r13900 r15000  
    2020    int dY = 0;                         // height of row so far
    2121    int NX = 20*DX;                     // full width of output image
    22     int NY = 0;                         // total height of output image
     22    int NY = DY;                        // total height of output image so far
    2323
    24     // first, examine the PSF and SAT stars:
    25     // - determine bounding boxes for summary image
     24    // first, examine the PSF and SAT stars to set output image size:
     25    // - add stamp widths until we exceed output image width,
     26    // - then start a new row offset by max height
    2627    for (int i = 0; i < sources->n; i++) {
    2728
     
    3132        keep |= (source->mode & PM_SOURCE_MODE_PSFSTAR);
    3233        keep |= (source->mode & PM_SOURCE_MODE_SATSTAR);
    33         if (!keep) continue;
     34        if (!keep) {
     35            psTrace ("psphot", 4, "not plotting star %d: %x", i, source->mode);
     36            continue;
     37        }
    3438
    3539        // how does this subimage get placed into the output image?
     
    5761    }
    5862
     63    if (NY == 0) {
     64        psWarning ("no PSF or SAT stars to plot? skipping.\n");
     65        return false;
     66    }
     67
    5968    // allocate output image
    6069    psImage *outpos = psImageAlloc (NX, NY, PS_TYPE_F32);
    6170    psImage *outsub = psImageAlloc (NX, NY, PS_TYPE_F32);
     71
     72    psImageInit (outpos, 0.0);
     73    psImageInit (outsub, 0.0);
    6274
    6375    int Xo = 0;                         // starting corner of next box
     
    142154    psFree (outpos);
    143155    psFree (outsub);
    144     return (sources);
     156    return true;
    145157}
    146158
Note: See TracChangeset for help on using the changeset viewer.