IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 13034


Ignore:
Timestamp:
Apr 25, 2007, 3:20:29 PM (19 years ago)
Author:
magnier
Message:

incorporating updates from eam_02_branch (cached models, pmPSF FITS IO)

Location:
trunk/psModules
Files:
25 edited

Legend:

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

    r12838 r13034  
    211211        if (mdok && trimsec && !psRegionIsNaN(*trimsec)) {
    212212            *trimsec = psImageBinningSetRuffRegion(binning, *trimsec);
     213            // force integer pixels : truncate x0, roundup x1:
     214            trimsec->x0 = (int)trimsec->x0;
     215            if (trimsec->x1 > (int)trimsec->x1) {
     216                trimsec->x1 = (int)trimsec->x1 + 1;
     217            } else {
     218                trimsec->x1 = (int)trimsec->x1;
     219            }           
     220            trimsec->y0 = (int)trimsec->y0;
     221            if (trimsec->y1 > (int)trimsec->y1) {
     222                trimsec->y1 = (int)trimsec->y1 + 1;
     223            } else {
     224                trimsec->y1 = (int)trimsec->y1;
     225            }           
    213226        }
    214227        psList *biassecs = psMetadataLookupPtr(&mdok, target->concepts, "CELL.BIASSEC"); // The bias sections
     
    219232                if (!psRegionIsNaN(*biassec)) {
    220233                    *biassec = psImageBinningSetRuffRegion(binning, *biassec);
     234                    // force integer pixels : truncate x0, roundup x1:
     235                    biassec->x0 = (int)biassec->x0;
     236                    if (biassec->x1 > (int)biassec->x1) {
     237                        biassec->x1 = (int)biassec->x1 + 1;
     238                    } else {
     239                        biassec->x1 = (int)biassec->x1;
     240                    }           
     241                    biassec->y0 = (int)biassec->y0;
     242                    if (biassec->y1 > (int)biassec->y1) {
     243                        biassec->y1 = (int)biassec->y1 + 1;
     244                    } else {
     245                        biassec->y1 = (int)biassec->y1;
     246                    }           
    221247                }
    222248            }
  • trunk/psModules/src/camera/pmFPAfile.c

    r12890 r13034  
    1717#include "pmFPAfile.h"
    1818#include "pmFPACopy.h"
     19#include "pmConcepts.h"
    1920
    2021static void pmFPAfileFree(pmFPAfile *file)
     
    326327    PS_ASSERT_PTR_NON_NULL(view, false);
    327328
     329    // XXX this should be smarter (ie, only copy concepts from the current chips)
     330    // but such a call is needed, so re-copy stuff rather than no copy
     331    pmFPACopyConcepts (out, in);
     332
    328333    // pmFPAWrite takes care of all PHUs as needed
    329     if ((view->chip == -1) || in->hdu) {
     334    if (view->chip == -1) {
    330335        status = pmFPACopyStructure (out, in, xBin, yBin);
    331336        return status;
     
    338343    pmChip *outChip = out->chips->data[view->chip];
    339344
    340     if ((view->cell == -1) || inChip->hdu) {
     345    if (view->cell == -1) {
    341346        status = pmChipCopyStructure (outChip, inChip, xBin, yBin);
    342347        return status;
    343     }
     348    } 
    344349    if (view->cell >= inChip->cells->n) {
    345350        psError(PS_ERR_IO, true, "Requested cell == %d>= inChip->cells->n == %ld",
     
    350355    pmCell *outCell = outChip->cells->data[view->cell];
    351356
    352     if ((view->readout == -1) || inCell->hdu) {
    353         status = pmCellCopyStructure (outCell, inCell, xBin, yBin);
    354         return status;
    355     }
    356     psError(PS_ERR_UNKNOWN, true, "Returning false");
    357     return false;
     357    status = pmCellCopyStructure (outCell, inCell, xBin, yBin);
     358    return status;
    358359}
    359360
  • trunk/psModules/src/camera/pmFPAfileIO.c

    r12949 r13034  
    434434      case PM_FPA_FILE_FRINGE:
    435435      case PM_FPA_FILE_CMF:
     436      case PM_FPA_FILE_PSF:
    436437        psTrace ("psModules.camera", 5, "closing %s (%s) (%d:%d:%d)\n", file->filename, file->name, view->chip, view->cell, view->readout);
    437438        status = psFitsClose (file->fits);
     
    447448      case PM_FPA_FILE_OBJ:
    448449      case PM_FPA_FILE_CMP:
    449       case PM_FPA_FILE_PSF:
    450450      case PM_FPA_FILE_JPEG:
    451451      case PM_FPA_FILE_KAPA:
     
    500500      case PM_FPA_FILE_CMP:
    501501      case PM_FPA_FILE_CMF:
     502      case PM_FPA_FILE_PSF:
    502503        psTrace ("psModules.camera", 5, "NOT freeing %s (%s) : save for further analysis\n", file->filename, file->name);
    503504        return true;
    504       case PM_FPA_FILE_PSF:
    505505      case PM_FPA_FILE_JPEG:
    506506      case PM_FPA_FILE_KAPA:
     
    638638      case PM_FPA_FILE_FRINGE:
    639639      case PM_FPA_FILE_CMF:
     640      case PM_FPA_FILE_PSF:
    640641        psTrace ("psModules.camera", 5, "opening %s (%s) (%d:%d:%d)\n", file->filename, file->name, view->chip, view->cell, view->readout);
    641642        file->fits = psFitsOpen (file->filename, mode);
     
    672673      case PM_FPA_FILE_CMP:
    673674      case PM_FPA_FILE_RAW:
    674       case PM_FPA_FILE_PSF:
    675675      case PM_FPA_FILE_JPEG:
    676676      case PM_FPA_FILE_KAPA:
     
    751751
    752752// XXX this function is only called from pmFPAfileWrite
     753// XXX for each data type, there should be a function which writes the PHU, if needed
    753754bool pmFPAfileWritePHU(pmFPAfile *file, const pmFPAview *view, const pmConfig *config)
    754755{
  • trunk/psModules/src/concepts/pmConcepts.c

    r12696 r13034  
    888888
    889889
     890// XXX EAM : Paul, please handle the biassec independently so the
     891// psList is copied without a verbose warning.  when this is fixed, you can
     892// convert the trace back to a log (psMetadata.c:429)
     893
    890894bool pmFPACopyConcepts(pmFPA *target, const pmFPA *source)
    891895{
  • trunk/psModules/src/concepts/pmConceptsUpdate.c

    r12696 r13034  
    4444            psRegion *trimsec = psMetadataLookupPtr(NULL, cell->concepts, "CELL.TRIMSEC"); // Trim section
    4545            *trimsec = psImageBinningSetRuffRegion (binning, *trimsec);
     46            // force integer pixels : truncate x0, roundup x1:
     47            trimsec->x0 = (int)trimsec->x0;
     48            if (trimsec->x1 > (int)trimsec->x1) {
     49                trimsec->x1 = (int)trimsec->x1 + 1;
     50            } else {
     51                trimsec->x1 = (int)trimsec->x1;
     52            }           
     53            trimsec->y0 = (int)trimsec->y0;
     54            if (trimsec->y1 > (int)trimsec->y1) {
     55                trimsec->y1 = (int)trimsec->y1 + 1;
     56            } else {
     57                trimsec->y1 = (int)trimsec->y1;
     58            }           
    4659            psMetadataRemoveKey(cell->concepts, "CELL.TRIMSEC.UPDATE");
    4760        }
     
    5467            while ((biassec = psListGetAndIncrement(biassecsIter))) {
    5568                *biassec = psImageBinningSetRuffRegion (binning, *biassec);
     69                // force integer pixels : truncate x0, roundup x1:
     70                biassec->x0 = (int)biassec->x0;
     71                if (biassec->x1 > (int)biassec->x1) {
     72                    biassec->x1 = (int)biassec->x1 + 1;
     73                } else {
     74                    biassec->x1 = (int)biassec->x1;
     75                }               
     76                biassec->y0 = (int)biassec->y0;
     77                if (biassec->y1 > (int)biassec->y1) {
     78                    biassec->y1 = (int)biassec->y1 + 1;
     79                } else {
     80                    biassec->y1 = (int)biassec->y1;
     81                }               
    5682            }
    5783            psFree(biassecsIter);
  • trunk/psModules/src/objects/pmModel.h

    r12949 r13034  
    55 * @author EAM, IfA
    66 *
    7  * @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
    8  * @date $Date: 2007-04-21 19:47:14 $
     7 * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
     8 * @date $Date: 2007-04-26 01:20:29 $
     9 *
    910 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    1011 */
     
    2627    PM_MODEL_BADARGS   ///< model fit called with invalid args
    2728} pmModelStatus;
     29
     30typedef enum {
     31    PM_MODEL_OP_NONE    = 0x00,
     32    PM_MODEL_OP_FUNC    = 0x01,
     33    PM_MODEL_OP_RES0    = 0x02,
     34    PM_MODEL_OP_RES1    = 0x04,
     35    PM_MODEL_OP_FULL   = 0x07,
     36    PM_MODEL_OP_SKY     = 0x08,
     37    PM_MODEL_OP_CENTER = 0x10,
     38    PM_MODEL_OP_NORM    = 0x20,
     39} pmModelOpMode;
    2840
    2941/** pmModel data structure
     
    91103 */
    92104bool pmModelAdd(
    93     psImage *image,   ///< The output image (float)
    94     psImage *mask,   ///< The image pixel mask (valid == 0)
    95     pmModel *model,   ///< The input pmModel
    96     bool center,   ///< A boolean flag that determines whether pixels are centered
    97     bool sky    ///< A boolean flag that determines if the sky is subtracted
     105    psImage *image,                     ///< The output image (float)
     106    psImage *mask,                      ///< The image pixel mask (valid == 0)
     107    pmModel *model,                     ///< The input pmModel
     108    pmModelOpMode mode               ///< mode to control how the model is added into the image
    98109);
    99 
    100110
    101111/** pmModelSub()
     
    110120 */
    111121bool pmModelSub(
    112     psImage *image,   ///< The output image (float)
    113     psImage *mask,   ///< The image pixel mask (valid == 0)
    114     pmModel *model,   ///< The input pmModel
    115     bool center,   ///< A boolean flag that determines whether pixels are centered
    116     bool sky    ///< A boolean flag that determines if the sky is subtracted
     122    psImage *image,                     ///< The output image (float)
     123    psImage *mask,                      ///< The image pixel mask (valid == 0)
     124    pmModel *model,                     ///< The input pmModel
     125    pmModelOpMode mode               ///< mode to control how the model is added into the image
    117126);
    118127
  • trunk/psModules/src/objects/pmPSF.c

    r12949 r13034  
    66 *  @author EAM, IfA
    77 *
    8  *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-04-21 19:47:14 $
     8 *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-04-26 01:20:29 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    424424    // place the reference object in the image center
    425425    // no need to mask the source here
    426     pmModelAdd (image, NULL, model, false, false);
     426    // XXX should we measure this for the analytical model only or the full model?
     427    pmModelAdd (image, NULL, model, PM_MODEL_OP_FULL);
    427428
    428429    // loop over a range of source fluxes
     
    436437        psImageKeepCircle (mask, xc, yc, radius, "OR", PM_MASK_MARK);
    437438        pmSourcePhotometryAper (&apMag, model, image, mask);
     439
     440        // XXX since we re-mask on each pass, this could be dropped.
    438441        psImageKeepCircle (mask, xc, yc, radius, "AND", PS_NOT_U8(PM_MASK_MARK));
    439442
  • trunk/psModules/src/objects/pmPSF_IO.c

    r12949 r13034  
    66 *  @author EAM, IfA
    77 *
    8  *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-04-21 19:47:14 $
     8 *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-04-26 01:20:29 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    4444#include "pmSourceIO.h"
    4545
     46bool pmFPAviewWritePSFmodel (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     47{
     48
     49    pmFPA *fpa = file->fpa;
     50
     51    if (view->chip == -1) {
     52        if (!pmFPAWritePSFmodel (fpa, view, file, config)) {
     53            psError(PS_ERR_IO, false, "Failed to write PSF for fpa");
     54            return false;
     55        }
     56        return true;
     57    }
     58
     59    if (view->chip >= fpa->chips->n) {
     60        return false;
     61    }
     62    pmChip *chip = fpa->chips->data[view->chip];
     63
     64    if (view->cell == -1) {
     65        if (!pmChipWritePSFmodel (chip, view, file, config)) {
     66            psError(PS_ERR_IO, false, "Failed to write PSF for chip");
     67            return false;
     68        }
     69        return true;
     70    }
     71
     72    if (view->cell >= chip->cells->n) {
     73        return false;
     74    }
     75    pmCell *cell = chip->cells->data[view->cell];
     76
     77    if (view->readout == -1) {
     78        if (!pmCellWritePSFmodel (cell, view, file, config)) {
     79            psError(PS_ERR_IO, false, "Failed to write PSF for cell");
     80            return false;
     81        }
     82        return true;
     83    }
     84
     85    if (view->readout >= cell->readouts->n) {
     86        return false;
     87    }
     88    pmReadout *readout = cell->readouts->data[view->readout];
     89
     90    if (!pmReadoutWritePSFmodel (readout, view, file, config)) {
     91        psError(PS_ERR_IO, false, "Failed to write PSF for readout");
     92        return false;
     93    }
     94    return true;
     95}
     96
     97// read in all chip-level PSFmodel files for this FPA
     98bool pmFPAWritePSFmodel (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     99{
     100
     101    for (int i = 0; i < fpa->chips->n; i++) {
     102
     103        pmChip *chip = fpa->chips->data[i];
     104        if (!pmChipWritePSFmodel (chip, view, file, config)) {
     105            psError(PS_ERR_IO, false, "Failed to write PSF for %dth chip", i);
     106            return false;
     107        }
     108    }
     109    return true;
     110}
     111
     112// read in all cell-level PSFmodel files for this chip
     113bool pmChipWritePSFmodel (pmChip *chip, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     114{
     115
     116    for (int i = 0; i < chip->cells->n; i++) {
     117
     118        pmCell *cell = chip->cells->data[i];
     119        if (!pmCellWritePSFmodel (cell, view, file, config)) {
     120            psError(PS_ERR_IO, false, "Failed to write PSF for %dth cell", i);
     121            return false;
     122        }
     123    }
     124    return true;
     125}
     126
     127// read in all readout-level PSFmodel files for this cell
     128bool pmCellWritePSFmodel (pmCell *cell, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     129{
     130
     131    for (int i = 0; i < cell->readouts->n; i++) {
     132
     133        pmReadout *readout = cell->readouts->data[i];
     134        if (!pmReadoutWritePSFmodel (readout, view, file, config)) {
     135            psError(PS_ERR_IO, false, "Failed to write PSF for %dth readout", i);
     136            return false;
     137        }
     138    }
     139    return true;
     140}
     141
     142// for each Readout (ie, analysed image), we write out: header + table with PSF model parameters,
     143// and header + image for the PSF residual images
     144bool pmReadoutWritePSFmodel (pmReadout *readout, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     145{
     146    bool status;
     147
     148    // select the psf of interest
     149    pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
     150    if (!psf) {
     151        psError(PS_ERR_UNKNOWN, true, "missing PSF for this readout");
     152        return false;
     153    }
     154
     155    // lookup the EXTNAME values used for table data and residual image segments
     156    char *rule = NULL;
     157
     158    // Menu of EXTNAME rules
     159    psMetadata *menu = psMetadataLookupMetadata(&status, file->camera, "EXTNAME.RULES");
     160    if (!menu) {
     161        psError(PS_ERR_UNKNOWN, true, "missing EXTNAME.RULES in camera.config");
     162        return false;
     163    }
     164    // EXTNAME for table data
     165    rule = psMetadataLookupStr(&status, menu, "PSF.TABLE");
     166    if (!rule) {
     167        psError(PS_ERR_UNKNOWN, true, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");
     168        return false;
     169    }
     170    char *tableName = pmFPAfileNameFromRule (rule, file, view);
     171
     172    // write the PSF model parameters in a FITS table
     173
     174    // we need to write a header for the table,
     175    psMetadata *header = psMetadataAlloc();
     176
     177    char *modelName = pmModelGetType (psf->type);
     178    psMetadataAddStr (header, PS_LIST_TAIL, "PSF_NAME", 0, "PSF model name", modelName);
     179
     180    psMetadataAddBool (header, PS_LIST_TAIL, "POISSON",  0, "Use Poisson errors in fits?", psf->poissonErrors);
     181
     182    int nPar = pmModelParameterCount (psf->type)    ;
     183    psMetadataAdd (header, PS_LIST_TAIL, "PSF_NPAR", PS_DATA_S32, "PSF model parameter count", nPar);
     184
     185    // save the dimensions of each parameter
     186    for (int i = 0; i < nPar; i++) {
     187        char name[9];
     188        psPolynomial2D *poly = psf->params_NEW->data[i];
     189        if (poly == NULL) continue;
     190        snprintf (name, 9, "PAR%02d_NX", i);
     191        psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", poly->nX);
     192        snprintf (name, 9, "PAR%02d_NY", i);
     193        psMetadataAddS32 (header, PS_LIST_TAIL, name, 0, "", poly->nY);
     194    }
     195
     196    // other required information describing the PSF
     197    psMetadataAddF32  (header, PS_LIST_TAIL, "AP_RESID", 0, "aperture residual", psf->ApResid);
     198    psMetadataAddF32  (header, PS_LIST_TAIL, "AP_ERROR", 0, "aperture residual scatter", psf->dApResid);
     199    psMetadataAddF32  (header, PS_LIST_TAIL, "CHISQ",    0, "chi-square for fit", psf->chisq);
     200    psMetadataAddS32  (header, PS_LIST_TAIL, "NSTARS",   0, "number of stars used to measure PSF", psf->nPSFstars);
     201
     202    // XXX can we drop this now?
     203    psMetadataAddF32 (header, PS_LIST_TAIL, "SKY_BIAS", PS_DATA_F32, "sky bias level", psf->skyBias);
     204
     205    // build a FITS table of the PSF parameters
     206    psArray *psfTable = psArrayAllocEmpty (100);
     207    for (int i = 0; i < nPar; i++) {
     208        psPolynomial2D *poly = psf->params_NEW->data[i];
     209        if (poly == NULL) continue; // skip unset parameters (eg, XPOS)
     210        for (int ix = 0; ix < poly->nX; ix++) {
     211            for (int iy = 0; iy < poly->nY; iy++) {
     212
     213                psMetadata *row = psMetadataAlloc ();
     214                psMetadataAddS32 (row, PS_LIST_TAIL, "MODEL_TERM", 0, "", i);
     215                psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
     216                psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
     217                psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", poly->coeff[ix][iy]);
     218                psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", poly->coeffErr[ix][iy]);
     219                psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", poly->mask[ix][iy]);
     220
     221                psArrayAdd (psfTable, 100, row);
     222                psFree (row);
     223            }
     224        }
     225    }
     226   
     227    // write an empty FITS segment if we have no PSF information
     228    if (psfTable->n == 0) {
     229        // XXX this is probably an error (if we have a PSF, how do we have no data?)
     230        psFitsWriteBlank (file->fits, header, tableName);
     231    } else {
     232        psTrace ("pmFPAfile", 5, "writing psf data %s\n", tableName);
     233        if (!psFitsWriteTable (file->fits, header, psfTable, tableName)) {
     234            psError(PS_ERR_IO, false, "writing psf table data %s\n", tableName);
     235            psFree (tableName);
     236            psFree (psfTable);
     237            psFree (header);
     238            return false;
     239        }
     240    }
     241    psFree (tableName);
     242    psFree (psfTable);
     243    psFree (header);
     244
     245    // EXTNAME for residual images
     246    rule = psMetadataLookupStr(&status, menu, "PSF.RESID");
     247    if (!rule) {
     248        psError(PS_ERR_UNKNOWN, true, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config");
     249        return false;
     250    }
     251    char *imageName = pmFPAfileNameFromRule (rule, file, view);
     252
     253    // write the residual images (3D)
     254    header = psMetadataAlloc ();
     255    if (psf->residuals == NULL) {
     256        // set some header keywords to make it clear there are no residuals?
     257        psFitsWriteBlank (file->fits, header, imageName);
     258        psFree (imageName);
     259        psFree (header);
     260        return true;
     261    }
     262
     263    psMetadataAddS32 (header, PS_LIST_TAIL, "XBIN",    0, "", psf->residuals->xBin);
     264    psMetadataAddS32 (header, PS_LIST_TAIL, "YBIN",    0, "", psf->residuals->yBin);
     265    psMetadataAddS32 (header, PS_LIST_TAIL, "XCENTER", 0, "", psf->residuals->xCenter);
     266    psMetadataAddS32 (header, PS_LIST_TAIL, "YCENTER", 0, "", psf->residuals->yCenter);
     267
     268    // write the residuals as three planes of the image
     269    // this call creates an extension with NAXIS3 = 3
     270    if (psf->residuals->Rx) {
     271        // this call creates an extension with NAXIS3 = 3
     272        psArray *images = psArrayAllocEmpty (3);
     273        psArrayAdd (images, 1, psf->residuals->Ro);
     274        psArrayAdd (images, 1, psf->residuals->Rx);
     275        psArrayAdd (images, 1, psf->residuals->Ry);
     276
     277        psFitsWriteImageCube (file->fits, header, images, imageName);
     278
     279        // psFitsWriteImage(file->fits, header, psf->residuals->Ro, 3, imageName);
     280        // psFitsUpdateImage(file->fits, psf->residuals->Rx, 0, 0, 1);
     281        // psFitsUpdateImage(file->fits, psf->residuals->Ry, 0, 0, 2);
     282    } else {
     283        // this call creates an extension with NAXIS3 = 1
     284        psFitsWriteImage(file->fits, header, psf->residuals->Ro, 0, imageName);
     285    }
     286 
     287    psFree (imageName);
     288    psFree (header);
     289    return true;
     290
     291    // XXX save the growth curve
     292    // XXX save the ApResid fit
     293
     294# if (0)
     295    // build a FITS table of the fit to the Aperture Residuals
     296    psArray *apresTable = psArrayAllocEmpty (100);
     297    psPolynomial4D *poly = psf->ApTrend;
     298    for (int ix = 0; ix < poly->nX; ix++) {
     299        for (int iy = 0; iy < poly->nY; iy++) {
     300
     301            row = psMetadataAlloc ();
     302            psMetadataAddS32 (row, PS_LIST_TAIL, "X_POWER",    0, "", ix);
     303            psMetadataAddS32 (row, PS_LIST_TAIL, "Y_POWER",    0, "", iy);
     304            psMetadataAddF32 (row, PS_LIST_TAIL, "VALUE",      0, "", poly->coeff[ix][iy]);
     305            psMetadataAddF32 (row, PS_LIST_TAIL, "ERROR",      0, "", poly->coeffErr[ix][iy]);
     306            psMetadataAddU8  (row, PS_LIST_TAIL, "MASK",       0, "", poly->mask[ix][iy]);
     307
     308            psArrayAdd (psfTable, 100, row);
     309            psFree (row);
     310        }
     311    }
     312# endif
     313}
     314
     315// XXX add in error handling
     316bool pmFPAviewReadPSFmodel (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     317{
     318
     319    pmFPA *fpa = file->fpa;
     320
     321    if (view->chip == -1) {
     322        pmFPAReadPSFmodel (fpa, view, file, config);
     323        return true;
     324    }
     325
     326    if (view->chip >= fpa->chips->n) {
     327        return false;
     328    }
     329    pmChip *chip = fpa->chips->data[view->chip];
     330
     331    if (view->cell == -1) {
     332        pmChipReadPSFmodel (chip, view, file, config);
     333        return true;
     334    }
     335
     336    if (view->cell >= chip->cells->n) {
     337        return false;
     338    }
     339    pmCell *cell = chip->cells->data[view->cell];
     340
     341    if (view->readout == -1) {
     342        pmCellReadPSFmodel (cell, view, file, config);
     343        return true;
     344    }
     345
     346    if (view->readout >= cell->readouts->n) {
     347        return false;
     348    }
     349    pmReadout *readout = cell->readouts->data[view->readout];
     350
     351    pmReadoutReadPSFmodel (readout, view, file, config);
     352    return true;
     353}
     354
     355// read in all chip-level PSFmodel files for this FPA
     356bool pmFPAReadPSFmodel (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     357{
     358
     359    for (int i = 0; i < fpa->chips->n; i++) {
     360
     361        pmChip *chip = fpa->chips->data[i];
     362        pmChipReadPSFmodel (chip, view, file, config);
     363    }
     364    return true;
     365}
     366
     367// read in all cell-level PSFmodel files for this chip
     368bool pmChipReadPSFmodel (pmChip *chip, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     369{
     370
     371    for (int i = 0; i < chip->cells->n; i++) {
     372
     373        pmCell *cell = chip->cells->data[i];
     374        pmCellReadPSFmodel (cell, view, file, config);
     375    }
     376    return true;
     377}
     378
     379// read in all readout-level PSFmodel files for this cell
     380bool pmCellReadPSFmodel (pmCell *cell, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     381{
     382
     383    for (int i = 0; i < cell->readouts->n; i++) {
     384
     385        pmReadout *readout = cell->readouts->data[i];
     386        pmReadoutReadPSFmodel (readout, view, file, config);
     387    }
     388    return true;
     389}
     390
     391// for each Readout (ie, analysed image), we write out: header + table with PSF model parameters,
     392// and header + image for the PSF residual images
     393bool pmReadoutReadPSFmodel (pmReadout *readout, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     394{
     395    bool status;
     396    char *rule = NULL;
     397    psMetadata *header = NULL;
     398
     399    // Menu of EXTNAME rules
     400    psMetadata *menu = psMetadataLookupMetadata(&status, file->camera, "EXTNAME.RULES");
     401    if (!menu) {
     402        psError(PS_ERR_UNKNOWN, true, "missing EXTNAME.RULES in camera.config");
     403        return false;
     404    }
     405    // EXTNAME for table data
     406    rule = psMetadataLookupStr(&status, menu, "PSF.TABLE");
     407    if (!rule) {
     408        psError(PS_ERR_UNKNOWN, true, "missing entry for PSF.TABLE in EXTNAME.RULES in camera.config");
     409        return false;
     410    }
     411    char *tableName = pmFPAfileNameFromRule (rule, file, view);
     412    // EXTNAME for residual images
     413    rule = psMetadataLookupStr(&status, menu, "PSF.RESID");
     414    if (!rule) {
     415        psError(PS_ERR_UNKNOWN, true, "missing entry for PSF.RESID in EXTNAME.RULES in camera.config");
     416        return false;
     417    }
     418    char *imageName = pmFPAfileNameFromRule (rule, file, view);
     419
     420    // move fits pointer to table and read header
     421    // advance to the table data extension
     422    // since we have read the IMAGE header, the TABLE header should exist
     423    if (!psFitsMoveExtName (file->fits, tableName)) {
     424        psAbort("cannot find data extension %s in %s", tableName, file->filename);
     425    }
     426
     427    // load the PSF model table header
     428    header = psFitsReadHeader (NULL, file->fits);
     429    if (!header) psAbort("cannot read table header");
     430
     431    // load the PSF model parameters from the FITS table
     432    char *modelName = psMetadataLookupStr (&status, header, "PSF_NAME");
     433    pmModelType type = pmModelSetType (modelName);
     434
     435    bool poissonErrors = psMetadataLookupBool (&status, header, "POISSON");
     436
     437    // we determine the PSF parameter polynomials from the MD-defined polynomials
     438    pmPSF *psf = pmPSFAlloc (type, poissonErrors, NULL);
     439
     440    // check the number of expected parameters
     441    int nPar = psMetadataLookupS32 (&status, header, "PSF_NPAR");
     442    if (nPar != pmModelParameterCount (psf->type))
     443        psAbort("mismatch model par count");
     444
     445    // load the dimensions of each parameter
     446    for (int i = 0; i < nPar; i++) {
     447        char name[9];
     448        snprintf (name, 9, "PAR%02d_NX", i);
     449        int nXorder = psMetadataLookupS32 (&status, header, name);
     450        snprintf (name, 9, "PAR%02d_NY", i);
     451        int nYorder = psMetadataLookupS32 (&status, header, name);
     452        psf->params_NEW->data[i] = psPolynomial2DAlloc (PS_POLYNOMIAL_ORD, nXorder, nYorder);
     453    }
     454
     455    // other required information describing the PSF
     456    psf->ApResid   = psMetadataLookupF32 (&status, header, "AP_RESID");
     457    psf->dApResid  = psMetadataLookupF32 (&status, header, "AP_ERROR");
     458    psf->chisq     = psMetadataLookupF32 (&status, header, "CHISQ");
     459    psf->nPSFstars = psMetadataLookupS32 (&status, header, "NSTARS");
     460
     461    // XXX can we drop this now?
     462    psf->skyBias   = psMetadataLookupF32 (&status, header, "SKY_BIAS");
     463
     464    // read the raw table data
     465    psArray *table = psFitsReadTable (file->fits);
     466
     467    // fill in the matching psf->params entries
     468    for (int i = 0; i > table->n; i++) {
     469        psMetadata *row = table->data[i];
     470        int iPar = psMetadataLookupS32 (&status, row, "MODEL_TERM");
     471        int xPow = psMetadataLookupS32 (&status, row, "X_POWER");
     472        int yPow = psMetadataLookupS32 (&status, row, "Y_POWER");
     473        // XXX sanity check here
     474
     475        psPolynomial2D *poly = psf->params_NEW->data[iPar];
     476
     477        poly->coeff[xPow][yPow]    = psMetadataLookupF32 (&status, row, "VALUE");
     478        poly->coeffErr[xPow][yPow] = psMetadataLookupF32 (&status, row, "ERROR");
     479        poly->mask[xPow][yPow]     = psMetadataLookupU8  (&status, row, "MASK");
     480    }
     481    psFree (header);
     482    psFree (table);
     483
     484    // move fits pointer to residual image and read header
     485    // advance to the table data extension
     486    // since we have read the IMAGE header, the TABLE header should exist
     487    if (!psFitsMoveExtName (file->fits, imageName)) {
     488        psAbort("cannot find data extension %s in %s", imageName, file->filename);
     489    }
     490
     491    header = psFitsReadHeader (NULL, file->fits);
     492    int Naxis = psMetadataLookupS32 (&status, header, "NAXIS");
     493    if (Naxis != 0) {
     494
     495        int Nx = psMetadataLookupS32 (&status, header, "NAXIS1");
     496        int Ny = psMetadataLookupS32 (&status, header, "NAXIS2");
     497        int Nz = psMetadataLookupS32 (&status, header, "NAXIS3");
     498
     499        int xBin  = psMetadataLookupS32 (&status, header, "XBIN");
     500        int yBin  = psMetadataLookupS32 (&status, header, "YBIN");
     501
     502        int xSize = Nx / xBin;
     503        int ySize = Ny / yBin;
     504
     505        psf->residuals = pmResidualsAlloc (xSize, ySize, xBin, yBin);
     506
     507        psf->residuals->xCenter = psMetadataLookupS32 (&status, header, "XCENTER");
     508        psf->residuals->yCenter = psMetadataLookupS32 (&status, header, "YCENTER");
     509
     510        psRegion fullImage = {0, 0, 0, 0};
     511        psFitsReadImageBuffer(psf->residuals->Ro, file->fits, fullImage, 0); // Desired pixels
     512        if (Nz > 1) {
     513            assert (Nz == 3);
     514            psFitsReadImageBuffer(psf->residuals->Rx, file->fits, fullImage, 1); // Desired pixels
     515            psFitsReadImageBuffer(psf->residuals->Ry, file->fits, fullImage, 2); // Desired pixels
     516        }
     517    }
     518
     519    psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.PSF",     PS_DATA_UNKNOWN,  "psphot psf", psf);
     520    psFree (psf);
     521
     522    psFree (tableName);
     523    psFree (imageName);
     524
     525    return true;
     526}
     527
     528/************ old support functions, deprecate? **************/
     529
    46530psMetadata *pmPSFtoMetadata (psMetadata *metadata, pmPSF *psf)
    47531{
     
    124608}
    125609
    126 bool pmFPAviewWritePSFmodel (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    127 {
    128 
    129     pmFPA *fpa = file->fpa;
    130 
    131     if (view->chip == -1) {
    132         pmFPAWritePSFmodel (fpa, view, file, config);
    133         return true;
    134     }
    135 
    136     if (view->chip >= fpa->chips->n) {
    137         return false;
    138     }
    139     pmChip *chip = fpa->chips->data[view->chip];
    140 
    141     if (view->cell == -1) {
    142         pmChipWritePSFmodel (chip, view, file, config);
    143         return true;
    144     }
    145 
    146     if (view->cell >= chip->cells->n) {
    147         return false;
    148     }
    149     pmCell *cell = chip->cells->data[view->cell];
    150 
    151     if (view->readout == -1) {
    152         pmCellWritePSFmodel (cell, view, file, config);
    153         return true;
    154     }
    155 
    156     if (view->readout >= cell->readouts->n) {
    157         return false;
    158     }
    159     pmReadout *readout = cell->readouts->data[view->readout];
    160 
    161     pmReadoutWritePSFmodel (readout, view, file, config);
    162     return true;
    163 }
    164 
    165 // read in all chip-level PSFmodel files for this FPA
    166 bool pmFPAWritePSFmodel (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    167 {
    168 
    169     for (int i = 0; i < fpa->chips->n; i++) {
    170 
    171         pmChip *chip = fpa->chips->data[i];
    172         pmChipWritePSFmodel (chip, view, file, config);
    173     }
    174     return true;
    175 }
    176 
    177 // read in all cell-level PSFmodel files for this chip
    178 bool pmChipWritePSFmodel (pmChip *chip, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    179 {
    180 
    181     for (int i = 0; i < chip->cells->n; i++) {
    182 
    183         pmCell *cell = chip->cells->data[i];
    184         pmCellWritePSFmodel (cell, view, file, config);
    185     }
    186     return true;
    187 }
    188 
    189 // read in all readout-level PSFmodel files for this cell
    190 bool pmCellWritePSFmodel (pmCell *cell, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    191 {
    192 
    193     for (int i = 0; i < cell->readouts->n; i++) {
    194 
    195         pmReadout *readout = cell->readouts->data[i];
    196         pmReadoutWritePSFmodel (readout, view, file, config);
    197     }
    198     return true;
    199 }
    200 
    201610// read in all readout-level Objects files for this cell
    202 bool pmReadoutWritePSFmodel (pmReadout *readout, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     611bool pmReadoutWritePSFmodel_Config (pmReadout *readout, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    203612{
    204613    bool status;
     
    228637}
    229638
    230 
    231 
    232 bool pmFPAviewReadPSFmodel (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    233 {
    234 
    235     pmFPA *fpa = file->fpa;
    236 
    237     if (view->chip == -1) {
    238         pmFPAReadPSFmodel (fpa, view, file, config);
    239         return true;
    240     }
    241 
    242     if (view->chip >= fpa->chips->n) {
    243         return false;
    244     }
    245     pmChip *chip = fpa->chips->data[view->chip];
    246 
    247     if (view->cell == -1) {
    248         pmChipReadPSFmodel (chip, view, file, config);
    249         return true;
    250     }
    251 
    252     if (view->cell >= chip->cells->n) {
    253         return false;
    254     }
    255     pmCell *cell = chip->cells->data[view->cell];
    256 
    257     if (view->readout == -1) {
    258         pmCellReadPSFmodel (cell, view, file, config);
    259         return true;
    260     }
    261 
    262     if (view->readout >= cell->readouts->n) {
    263         return false;
    264     }
    265     pmReadout *readout = cell->readouts->data[view->readout];
    266 
    267     pmReadoutReadPSFmodel (readout, view, file, config);
    268     return true;
    269 }
    270 
    271 // read in all chip-level PSFmodel files for this FPA
    272 bool pmFPAReadPSFmodel (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    273 {
    274 
    275     for (int i = 0; i < fpa->chips->n; i++) {
    276 
    277         pmChip *chip = fpa->chips->data[i];
    278         pmChipReadPSFmodel (chip, view, file, config);
    279     }
    280     return true;
    281 }
    282 
    283 // read in all cell-level PSFmodel files for this chip
    284 bool pmChipReadPSFmodel (pmChip *chip, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    285 {
    286 
    287     for (int i = 0; i < chip->cells->n; i++) {
    288 
    289         pmCell *cell = chip->cells->data[i];
    290         pmCellReadPSFmodel (cell, view, file, config);
    291     }
    292     return true;
    293 }
    294 
    295 // read in all readout-level PSFmodel files for this cell
    296 bool pmCellReadPSFmodel (pmCell *cell, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    297 {
    298 
    299     for (int i = 0; i < cell->readouts->n; i++) {
    300 
    301         pmReadout *readout = cell->readouts->data[i];
    302         pmReadoutReadPSFmodel (readout, view, file, config);
    303     }
    304     return true;
    305 }
    306 
    307639// read in all readout-level Objects files for this cell
    308 bool pmReadoutReadPSFmodel (pmReadout *readout, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
     640bool pmReadoutReadPSFmodel_Config (pmReadout *readout, const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    309641{
    310642
  • trunk/psModules/src/objects/pmPSFtry.c

    r12949 r13034  
    55 *  @author EAM, IfA
    66 *
    7  *  @version $Revision: 1.35 $ $Name: not supported by cvs2svn $
    8  *  @date $Date: 2007-04-21 19:47:14 $
     7 *  @version $Revision: 1.36 $ $Name: not supported by cvs2svn $
     8 *  @date $Date: 2007-04-26 01:20:29 $
    99 *
    1010 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    9999{
    100100    bool status;
    101     float x;
    102     float y;
    103101    int Next = 0;
    104102    int Npsf = 0;
     
    120118            return NULL;
    121119        }
    122         x = source->peak->x;
    123         y = source->peak->y;
    124 
    125         // set temporary object mask and fit object
     120
     121        // set object mask to define valid pixels
     122        psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, RADIUS, "OR", PM_MASK_MARK);
     123
    126124        // fit model as EXT, not PSF
    127 
    128         psImageKeepCircle (source->mask, x, y, RADIUS, "OR", PM_MASK_MARK);
    129125        status = pmSourceFitModel (source, source->modelEXT, PM_SOURCE_FIT_EXT);
    130         psImageKeepCircle (source->mask, x, y, RADIUS, "AND", PS_NOT_U8(PM_MASK_MARK));
    131126
    132127        // exclude the poor fits
     
    158153        source->modelPSF = pmModelFromPSF (source->modelEXT, psfTry->psf);
    159154        source->modelPSF->radiusFit = RADIUS;
    160         x = source->peak->x;
    161         y = source->peak->y;
    162 
    163         // set the mask and fit the PSF model
    164         psImageKeepCircle (source->mask, x, y, RADIUS, "OR", PM_MASK_MARK);
     155
     156        // set object mask to define valid pixels
     157        psImageKeepCircle (source->maskObj, source->peak->x, source->peak->y, RADIUS, "OR", PM_MASK_MARK);
     158
     159        // fit the PSF model to the source
    165160        status = pmSourceFitModel (source, source->modelPSF, PM_SOURCE_FIT_PSF);
    166         psImageKeepCircle (source->mask, x, y, RADIUS, "AND", PS_NOT_U8(PM_MASK_MARK));
    167161
    168162        // skip poor fits
  • trunk/psModules/src/objects/pmPeaks.c

    r12816 r13034  
    66 *  @author EAM, IfA: significant modifications.
    77 *
    8  *  @version $Revision: 1.14 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-04-12 18:56:52 $
     8 *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-04-26 01:20:29 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    134134    tmp->flux = 0;
    135135    tmp->SN = 0;
     136    tmp->xf = x;
     137    tmp->yf = y;
    136138
    137139    tmp->type = type;
  • trunk/psModules/src/objects/pmSource.c

    r12949 r13034  
    66 *  @author EAM, IfA: significant modifications.
    77 *
    8  *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-04-21 19:47:14 $
     8 *  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-04-26 01:20:29 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    3939    psFree(tmp->pixels);
    4040    psFree(tmp->weight);
    41     psFree(tmp->mask);
     41    psFree(tmp->maskObj);
     42    psFree(tmp->maskView);
     43    psFree(tmp->modelFlux);
    4244    psFree(tmp->moments);
    4345    psFree(tmp->modelPSF);
     
    4749}
    4850
     51// free only the pixel data associated with this source
    4952void pmSourceFreePixels(pmSource *source)
    5053{
     
    5558    psFree (source->pixels);
    5659    psFree (source->weight);
    57     psFree (source->mask);
     60    psFree (source->maskObj);
     61    psFree (source->maskView);
     62    psFree (source->modelFlux);
    5863
    5964    source->pixels = NULL;
    6065    source->weight = NULL;
    61     source->mask = NULL;
     66    source->maskObj = NULL;
     67    source->maskView = NULL;
     68    source->modelFlux = NULL;
    6269    return;
    6370}
     
    7683    source->pixels = NULL;
    7784    source->weight = NULL;
    78     source->mask = NULL;
     85    source->maskObj = NULL;
     86    source->maskView = NULL;
     87    source->modelFlux = NULL;
    7988    source->moments = NULL;
    8089    source->blends = NULL;
     
    114123    // the original values.
    115124    pmSource *source = pmSourceAlloc ();
    116     source->peak = psMemIncrRefCounter (in->peak);
    117     source->pixels = psMemIncrRefCounter (in->pixels);
    118     source->weight = psMemIncrRefCounter (in->weight);
    119     source->mask = psMemIncrRefCounter (in->mask);
    120     source->moments = psMemIncrRefCounter (in->moments);
    121     source->blends = NULL;
    122     source->modelPSF = NULL;
    123     source->modelEXT = NULL;
     125
     126    // this is actually the same peak as the original, is this the correct way to handle this?
     127    source->peak = pmPeakAlloc (in->peak->x, in->peak->y, in->peak->value, in->peak->type);
     128    source->peak->xf = in->peak->xf;
     129    source->peak->yf = in->peak->yf;
     130    source->peak->flux = in->peak->flux;
     131    source->peak->SN = in->peak->SN;
     132
     133    // copy the values in the moments structure
     134    source->moments  =  pmMomentsAlloc();
     135    *source->moments = *in->moments;
     136
     137    // These images are all views to the parent. 
     138    // We want a new view, but pointing at the same pixels.
     139    source->pixels   = psImageCopyView (NULL, in->pixels);
     140    source->weight   = psImageCopyView (NULL, in->weight);
     141    source->maskView = psImageCopyView (NULL, in->maskView);
     142
     143    // the maskObj is a unique mask array; create a new mask image
     144    if (in->maskObj) {
     145        source->maskObj = psImageCopy (NULL, in->maskObj, PS_TYPE_MASK);
     146    }
     147
    124148    source->type = in->type;
    125149    source->mode = in->mode;
    126     psMemSetDeallocator(source, (psFreeFunc) sourceFree);
    127 
    128     // default values are NAN
    129     source->psfMag = NAN;
    130     source->extMag = NAN;
    131     source->errMag = NAN;
    132     source->apMag  = NAN;
    133     source->sky    = NAN;
    134     source->skyErr = NAN;
    135     source->pixWeight = NAN;
    136150
    137151    return(source);
     
    151165    srcRegion = psRegionForImage (readout->image, srcRegion);
    152166
    153     mySource->pixels = psMemIncrRefCounter(psImageSubset(readout->image, srcRegion));
    154     mySource->weight = psMemIncrRefCounter(psImageSubset(readout->weight, srcRegion));
    155     mySource->mask   = psMemIncrRefCounter(psImageSubset(readout->mask,  srcRegion));
    156     mySource->region = srcRegion;
     167    // these images are subset images of the equivalent parents
     168    mySource->pixels   = psMemIncrRefCounter(psImageSubset(readout->image, srcRegion));
     169    mySource->weight   = psMemIncrRefCounter(psImageSubset(readout->weight, srcRegion));
     170    mySource->maskView = psMemIncrRefCounter(psImageSubset(readout->mask,  srcRegion));
     171    mySource->region   = srcRegion;
     172
     173    // the object mask is a copy, and used to define the source pixels
     174    mySource->maskObj = psImageCopy (NULL, mySource->maskView, PS_TYPE_MASK);
    157175
    158176    return true;
     
    183201    extend |= (mySource->pixels == NULL);
    184202    extend |= (mySource->weight == NULL);
    185     extend |= (mySource->mask == NULL);
     203    extend |= (mySource->maskObj == NULL);
     204    extend |= (mySource->maskView == NULL);
    186205
    187206    // extend = true;
     
    190209        psFree (mySource->pixels);
    191210        psFree (mySource->weight);
    192         psFree (mySource->mask);
    193 
    194         mySource->pixels = psMemIncrRefCounter(psImageSubset(readout->image,  newRegion));
    195         mySource->weight = psMemIncrRefCounter(psImageSubset(readout->weight, newRegion));
    196         mySource->mask   = psMemIncrRefCounter(psImageSubset(readout->mask,   newRegion));
    197         mySource->region = newRegion;
    198     }
    199 
     211        psFree (mySource->maskView);
     212
     213        mySource->pixels   = psMemIncrRefCounter(psImageSubset(readout->image,  newRegion));
     214        mySource->weight   = psMemIncrRefCounter(psImageSubset(readout->weight, newRegion));
     215        mySource->maskView = psMemIncrRefCounter(psImageSubset(readout->mask,   newRegion));
     216        mySource->region   = newRegion;
     217
     218        // re-copy the main mask pixels.  NOTE: the user will need to reset the object mask
     219        // pixels (eg, with psImageKeepCircle)
     220        mySource->maskObj = psImageCopy (mySource->maskObj, mySource->maskView, PS_TYPE_MASK);
     221       
     222        // drop the old modelFlux pixels and force the user to re-create
     223        psFree (mySource->modelFlux);
     224        mySource->modelFlux = NULL;
     225    }
    200226    return extend;
    201227}
     
    207233
    208234// XXX EAM include a S/N cutoff in selecting the sources?
     235// XXX this function should probably accept the values, not a recipe. wrap with a
     236// psphot-specific function which applies the recipe values
    209237pmPSFClump pmSourcePSFClump(psArray *sources, psMetadata *recipe)
    210238{
     
    458486        // XXX EAM : can we use the value of SATURATE if mask is NULL?
    459487        inner = psRegionForSquare (source->peak->x, source->peak->y, 2);
    460         inner = psRegionForImage (source->mask, inner);
    461         int Nsatpix = psImageCountPixelMask (source->mask, inner, PM_MASK_SAT);
     488        inner = psRegionForImage (source->maskView, inner);
     489        int Nsatpix = psImageCountPixelMask (source->maskView, inner, PM_MASK_SAT);
    462490
    463491        // saturated star (size consistent with PSF or larger)
     
    572600    PS_ASSERT_PTR_NON_NULL(source->peak, false);
    573601    PS_ASSERT_PTR_NON_NULL(source->pixels, false);
    574     PS_ASSERT_PTR_NON_NULL(source->mask, false);
     602    PS_ASSERT_PTR_NON_NULL(source->maskObj, false);
    575603    PS_ASSERT_FLOAT_LARGER_THAN(radius, 0.0, false);
    576604
     
    622650        psF32 *vPix = source->pixels->data.F32[row];
    623651        psF32 *vWgt = source->weight->data.F32[row];
    624         psU8  *vMsk = (source->mask == NULL) ? NULL : source->mask->data.U8[row];
     652        psU8  *vMsk = (source->maskObj == NULL) ? NULL : source->maskObj->data.U8[row];
    625653
    626654        for (psS32 col = 0; col < source->pixels->numCols ; col++, vPix++, vWgt++) {
     
    719747}
    720748
    721 pmModel *pmSourceSelectModel (pmSource *source)
    722 {
     749// construct a realization of the source model
     750bool pmSourceCacheModel (pmSource *source) {
     751
     752    // select appropriate model
     753    pmModel *model = pmSourceGetModel (NULL, source);
     754    if (model == NULL) return false;  // model must be defined
     755       
     756    // if we already have a cached image, re-use that memory
     757    source->modelFlux = psImageCopy (source->modelFlux, source->pixels, PS_TYPE_F32);
     758    psImageInit (source->modelFlux, 0.0);
     759
     760    // in some places (psphotEnsemble), we need a normalized version
     761    // in others, we just want the model.  which is more commonly used?
     762    // modelFlux always has unity normalization (I0 = 1.0)
     763    pmModelAdd (source->modelFlux, source->maskObj, model, PM_MODEL_OP_FULL | PM_MODEL_OP_NORM);
     764    return true;
     765}
     766
     767// should we call pmSourceCacheModel if it does not exist?
     768bool pmSourceOp (pmSource *source, pmModelOpMode mode, bool add) {
     769
     770    bool status;
     771
     772    if (add) {
     773        psTrace ("psphot", 3, "replacing object at %f,%f\n", source->peak->xf, source->peak->yf);
     774    } else {
     775        psTrace ("psphot", 3, "removing object at %f,%f\n", source->peak->xf, source->peak->yf);
     776    }
     777
     778    pmModel *model = pmSourceGetModel (NULL, source);
     779    if (model == NULL) return false;  // model must be defined
     780
     781    if (source->modelFlux) {
     782        // add in the pixels from the modelFlux image
     783        int dX = source->modelFlux->col0 - source->pixels->col0;
     784        int dY = source->modelFlux->row0 - source->pixels->row0;
     785        assert (dX >= 0);
     786        assert (dY >= 0);
     787        assert (dX + source->modelFlux->numCols <= source->pixels->numCols);
     788        assert (dY + source->modelFlux->numRows <= source->pixels->numRows);
     789       
     790        // modelFlux has unity normalization
     791        float Io = model->params->data.F32[PM_PAR_I0];
     792        if (mode & PM_MODEL_OP_NORM) {
     793            Io = 1.0;
     794        }
     795
     796        psU8 **mask = NULL;
     797        if (source->maskObj) {
     798            mask = source->maskObj->data.U8;
     799        }
     800
     801        // XXX need to respect the source and model masks?
     802        for (int iy = 0; iy < source->modelFlux->numRows; iy++) {
     803            int oy = iy + dY;
     804            for (int ix = 0; ix < source->modelFlux->numCols; ix++) {
     805                int ox = ix + dX;
     806                if (mask && mask[iy][ix]) continue;
     807                float value = Io*source->modelFlux->data.F32[iy][ix];
     808                if (add) {
     809                    source->pixels->data.F32[oy][ox] += value;
     810                } else {
     811                    source->pixels->data.F32[oy][ox] -= value;
     812                }
     813            }
     814        }
     815        return true;
     816    }
     817
     818    if (add) {
     819        status = pmModelAdd (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL);
     820    } else {
     821        status = pmModelSub (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL);
     822    }
     823
     824    return true;
     825}
     826
     827bool pmSourceAdd (pmSource *source, pmModelOpMode mode) {
     828    bool status = pmSourceOp (source, mode, true);
     829    return status;
     830}
     831
     832bool pmSourceSub (pmSource *source, pmModelOpMode mode) {
     833    bool status = pmSourceOp (source, mode, false);
     834    return status;
     835}
     836
     837// given a source, which model is currently appropriate?
     838// choose PSF or EXT based on source->type, but fall back on PSF
     839// if the EXT model is NULL
     840pmModel *pmSourceGetModel (bool *isPSF, const pmSource *source)
     841{
     842
     843    pmModel *model;
     844
     845    if (isPSF) {
     846      *isPSF = false;
     847    }
     848
    723849    switch (source->type) {
    724850    case PM_SOURCE_TYPE_STAR:
    725         return source->modelPSF;
     851        model = source->modelPSF;
     852        if (model == NULL)
     853            return NULL;
     854        if (isPSF) {
     855            *isPSF = true;
     856        }
     857        return model;
    726858
    727859    case PM_SOURCE_TYPE_EXTENDED:
    728         return source->modelEXT;
     860        model = source->modelEXT;
     861        if (!model && source->modelPSF) {
     862            if (isPSF) {
     863                *isPSF = true;
     864            }
     865            return source->modelPSF;
     866        }
     867        return (model);
     868        break;
    729869
    730870    default:
  • trunk/psModules/src/objects/pmSource.h

    r11253 r13034  
    33 * @author EAM, IfA; GLG, MHPCC
    44 *
    5  * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
    6  * @date $Date: 2007-01-24 02:54:15 $
     5 * @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
     6 * @date $Date: 2007-04-26 01:20:29 $
    77 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    88 */
     
    1313/// @addtogroup Objects Object Detection / Analysis Functions
    1414/// @{
    15 
    16 /**
    17  * In the object analysis process, we will use specific mask values to mark the
    18  * image pixels. The following structure defines the relevant mask values.
    19  *
    20  * XXX: This is probably a bad solution: we will want to set mask values
    21  * outside of the PSPHOT code.  Perhaps we can set up a registered set of mask
    22  * values with specific meanings that other functions can add to or define?
    23  
    24  * XXX We will only use the PM_MASK_xxx mask values
    25 typedef enum {
    26     PM_SOURCE_MASK_CLEAR     = 0x00,
    27     PM_SOURCE_MASK_INVALID   = 0x01,
    28     PM_SOURCE_MASK_SATURATED = 0x02,
    29     PM_SOURCE_MASK_MARKED    = 0x08,
    30 } psphotMaskValues;
    31 */
    3215
    3316/** pmSourceType enumeration
     
    7558typedef struct
    7659{
    77     const int id;   ///< Unique ID for object
    78     pmPeak *peak;   ///< Description of peak pixel.
    79     psImage *pixels;   ///< Rectangular region including object pixels.
    80     psImage *weight;   ///< Image variance.
    81     psImage *mask;   ///< Mask which marks pixels associated with objects.
    82     pmMoments *moments;   ///< Basic moments measure for the object.
    83     pmModel *modelPSF;   ///< PSF Model fit (parameters and type)
    84     pmModel *modelEXT;   ///< EXT (floating) Model fit (parameters and type).
    85     pmSourceType type;   ///< Best identification of object.
    86     pmSourceMode mode;   ///< Best identification of object.
     60    const int id;                       ///< Unique ID for object
     61    pmPeak *peak;                       ///< Description of peak pixel.
     62    psImage *pixels;                    ///< Rectangular region including object pixels.
     63    psImage *weight;                    ///< Image variance.
     64    psImage *modelFlux;                 ///< cached copy of the model for this source
     65    psImage *maskObj;                   ///< unique mask for this object which marks included pixels associated with objects.
     66    psImage *maskView;                  ///< view into global image mask for this object region
     67    pmMoments *moments;                 ///< Basic moments measure for the object.
     68    pmModel *modelPSF;                  ///< PSF Model fit (parameters and type)
     69    pmModel *modelEXT;                  ///< EXT (floating) Model fit (parameters and type).
     70    pmSourceType type;                  ///< Best identification of object.
     71    pmSourceMode mode;                  ///< Best identification of object.
    8772    psArray *blends;
    88     float psfMag;   ///< calculated from flux in modelPsf
    89     float extMag;   ///< calculated from flux in modelEXT
    90     float errMag;   ///< error in psfMag OR extMag (depending on type)
    91     float apMag;   ///< apMag corresponding to psfMag or extMag (depending on type)
    92     float pixWeight;   // model-weighted coverage of valid pixels
    93     psRegion region;   // area on image covered by selected pixels
    94     float sky, skyErr;   //?< The sky and its error at the center of the object
     73    float psfMag;                       ///< calculated from flux in modelPsf
     74    float extMag;                       ///< calculated from flux in modelEXT
     75    float errMag;                       ///< error in psfMag OR extMag (depending on type)
     76    float apMag;               ///< apMag corresponding to psfMag or extMag (depending on type)
     77    float pixWeight;                    // model-weighted coverage of valid pixels
     78    psRegion region;                    // area on image covered by selected pixels
     79    float sky, skyErr;                  //?< The sky and its error at the center of the object
    9580}
    9681pmSource;
     
    225210);
    226211
    227 
    228 // select the model used for this source
    229 pmModel *pmSourceSelectModel (pmSource *source);
     212pmModel *pmSourceGetModel (bool *isPSF, const pmSource *source);
     213
     214bool pmSourceAdd (pmSource *source, pmModelOpMode mode);
     215bool pmSourceSub (pmSource *source, pmModelOpMode mode);
     216
     217bool pmSourceOp (pmSource *source, pmModelOpMode mode, bool add);
     218bool pmSourceCacheModel (pmSource *source);
    230219
    231220/// @}
  • trunk/psModules/src/objects/pmSourceFitModel.c

    r12949 r13034  
    66 *  @author GLG, MHPCC
    77 *
    8  *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-04-21 19:47:14 $
     8 *  @version $Revision: 1.21 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-04-26 01:20:29 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    5757    PS_ASSERT_PTR_NON_NULL(source, false);
    5858    PS_ASSERT_PTR_NON_NULL(source->pixels, false);
    59     PS_ASSERT_PTR_NON_NULL(source->mask, false);
     59    PS_ASSERT_PTR_NON_NULL(source->maskObj, false);
    6060    PS_ASSERT_PTR_NON_NULL(source->weight, false);
    6161
     
    7777        for (psS32 j = 0; j < source->pixels->numCols; j++) {
    7878            // skip masked points
    79             if (source->mask->data.U8[i][j]) {
     79            if (source->maskObj->data.U8[i][j]) {
    8080                continue;
    8181            }
     
    334334    PS_ASSERT_PTR_NON_NULL(source, false);
    335335    PS_ASSERT_PTR_NON_NULL(source->pixels, false);
    336     PS_ASSERT_PTR_NON_NULL(source->mask, false);
     336    PS_ASSERT_PTR_NON_NULL(source->maskObj, false);
    337337    PS_ASSERT_PTR_NON_NULL(source->weight, false);
    338338
     
    354354        for (psS32 j = 0; j < source->pixels->numCols; j++) {
    355355            // skip masked points
    356             if (source->mask->data.U8[i][j]) {
     356            if (source->maskObj->data.U8[i][j]) {
    357357                continue;
    358358            }
  • trunk/psModules/src/objects/pmSourceIO.c

    r12949 r13034  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.36 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.37 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    402402
    403403// Given a FITS file pointer, read the table of object data
     404// XXX add in error handling
    404405bool pmFPAviewReadObjects (const pmFPAview *view, pmFPAfile *file, const pmConfig *config)
    405406{
  • trunk/psModules/src/objects/pmSourceIO_CMF.c

    r12949 r13034  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.19 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.20 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    5656    for (i = 0; i < sources->n; i++) {
    5757        pmSource *source = (pmSource *) sources->data[i];
    58         pmModel *model = pmSourceSelectModel (source);
     58
     59        // no difference between PSF and non-PSF model
     60        pmModel *model = pmSourceGetModel (NULL, source);
    5961        if (model == NULL)
    6062            continue;
  • trunk/psModules/src/objects/pmSourceIO_CMP.c

    r12949 r13034  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.26 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.27 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    107107    for (i = 0; i < sources->n; i++) {
    108108        pmSource *source = (pmSource *) sources->data[i];
    109         pmModel *model = pmSourceSelectModel (source);
     109
     110        // no difference between PSF and non-PSF model
     111        pmModel *model = pmSourceGetModel (NULL, source);
    110112        if (model == NULL)
    111113            continue;
  • trunk/psModules/src/objects/pmSourceIO_OBJ.c

    r12949 r13034  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    6161    for (int i = 0; i < sources->n; i++) {
    6262        pmSource *source = (pmSource *) sources->data[i];
    63         pmModel *model = pmSourceSelectModel (source);
     63
     64        // no difference between PSF and non-PSF model
     65        pmModel *model = pmSourceGetModel (NULL, source);
    6466        if (model == NULL)
    6567            continue;
  • trunk/psModules/src/objects/pmSourceIO_PS1_DEV_0.c

    r12949 r13034  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    6363    for (i = 0; i < sources->n; i++) {
    6464        pmSource *source = (pmSource *) sources->data[i];
    65         pmModel *model = pmSourceSelectModel (source);
     65
     66        // no difference between PSF and non-PSF model
     67        pmModel *model = pmSourceGetModel (NULL, source);
    6668
    6769        if (model != NULL) {
  • trunk/psModules/src/objects/pmSourceIO_SMPDATA.c

    r12949 r13034  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    6262    for (i = 0; i < sources->n; i++) {
    6363        pmSource *source = (pmSource *) sources->data[i];
    64         pmModel *model = pmSourceSelectModel (source);
     64
     65        // no difference between PSF and non-PSF model
     66        pmModel *model = pmSourceGetModel (NULL, source);
    6567        if (model != NULL) {
    6668            PAR = model->params->data.F32;
  • trunk/psModules/src/objects/pmSourceIO_SX.c

    r12949 r13034  
    33 *  @author EAM, IfA
    44 *
    5  *  @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.10 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    5757    for (int i = 0; i < sources->n; i++) {
    5858        pmSource *source = (pmSource *) sources->data[i];
    59         pmModel *model = pmSourceSelectModel (source);
     59
     60        // no difference between PSF and non-PSF model
     61        pmModel *model = pmSourceGetModel (NULL, source);
    6062        if (model == NULL)
    6163            continue;
  • trunk/psModules/src/objects/pmSourcePhotometry.c

    r12949 r13034  
    33 *  @author EAM, IfA; GLG, MHPCC
    44 *
    5  *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
    6  *  @date $Date: 2007-04-21 19:47:14 $
     5 *  @version $Revision: 1.24 $ $Name: not supported by cvs2svn $
     6 *  @date $Date: 2007-04-26 01:20:29 $
    77 *
    88 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    106106    // replace source flux
    107107    // XXX need to be certain which model and size of mask for prior subtraction
     108    // XXX full model or just analytical?
     109    // XXX use pmSourceAdd instead?
    108110    if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
    109         pmModelAdd (source->pixels, source->mask, model, false, false);
     111        pmModelAdd (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL);
    110112    }
    111113
     
    180182    // set aperture mask circle to model radius
    181183    // XXX use a different radius for apertures and fits...
    182     psImageKeepCircle (source->mask, x, y, model->radiusFit, "OR", PM_MASK_MARK);
     184    // XXX can I remove this?  the source should have the mask defined when it is constructed or
     185    // when the fit / aperture radius is changed...
     186    psImageKeepCircle (source->maskObj, x, y, model->radiusFit, "OR", PM_MASK_MARK);
    183187
    184188    // measure the weight of included pixels
    185189    // XXX is this supposed to use the weight or the flux?
    186190    if (mode & PM_SOURCE_PHOT_WEIGHT) {
    187         pmSourcePixelWeight (&source->pixWeight, model, source->pixels, source->mask);
     191        pmSourcePixelWeight (&source->pixWeight, model, source->pixels, source->maskObj);
    188192    }
    189193
    190194    // measure object aperture photometry
    191     status = pmSourcePhotometryAper  (&source->apMag, model, flux, source->mask);
     195    status = pmSourcePhotometryAper  (&source->apMag, model, flux, source->maskObj);
    192196
    193197    // for PSFs, correct both apMag and psfMag to same system, consistent with infinite flux star in aperture RADIUS
     
    206210
    207211    // unmask aperture
    208     psImageKeepCircle (source->mask, x, y, model->radiusFit, "AND", PS_NOT_U8(PM_MASK_MARK));
     212    // XXX can I remove this?  this will probably break things downstream...
     213    psImageKeepCircle (source->maskObj, x, y, model->radiusFit, "AND", PS_NOT_U8(PM_MASK_MARK));
    209214
    210215    // if source was originally subtracted, re-subtract object, leave local sky
     216    // XXX replace with pmSourceSub...
    211217    if (source->mode & PM_SOURCE_MODE_SUBTRACTED) {
    212         pmModelSub (source->pixels, source->mask, model, false, false);
     218        pmModelSub (source->pixels, source->maskObj, model, PM_MODEL_OP_FULL);
    213219    }
    214220
     
    363369}
    364370
     371# if (0)
    365372double pmSourceCrossProduct (const pmSource *Mi,
    366373                             const pmSource *Mj,
     
    379386    const psImage *Wi = Mi->weight;
    380387
    381     const psImage *Ti = Mi->mask;
    382     const psImage *Tj = Mj->mask;
     388    const psImage *Ti = Mi->maskObj;
     389    const psImage *Tj = Mj->maskObj;
    383390
    384391    Xs = PS_MAX (Pi->col0, Pj->col0);
     
    435442    const psImage *Wi = Mi->weight;
    436443
    437     const psImage *Ti = Mi->mask;
    438     const psImage *Tj = Mj->mask;
     444    const psImage *Ti = Mi->maskObj;
     445    const psImage *Tj = Mj->maskObj;
    439446
    440447    Xs = PS_MAX (Pi->col0, Pj->col0);
     
    483490    const psImage *Pi = Mi->pixels;
    484491    const psImage *Wi = Mi->weight;
    485     const psImage *Ti = Mi->mask;
     492    const psImage *Ti = Mi->maskObj;
    486493
    487494    // note that this is addressing the same image pixels,
     
    521528    return flux;
    522529}
     530# endif
    523531
    524532bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight)
     
    543551}
    544552
    545 // given a source, which model is currently appropriate?
    546 // choose PSF or EXT based on source->type, but fall back on PSF
    547 // if the EXT model is NULL
    548 pmModel *pmSourceGetModel (bool *isPSF, const pmSource *source)
    549 {
    550 
    551     pmModel *model;
    552 
    553     switch (source->type) {
    554     case PM_SOURCE_TYPE_STAR:
    555         model = source->modelPSF;
    556         if (model == NULL)
    557             return NULL;
    558         if (isPSF)
    559             *isPSF = true;
    560         return model;
    561 
    562     case PM_SOURCE_TYPE_EXTENDED:
    563         model = source->modelEXT;
    564         if (isPSF)
    565             *isPSF = false;
    566         if (model == NULL) {
    567             model = source->modelPSF;
    568             if (isPSF)
    569                 *isPSF = true;
    570         }
    571         if (model == NULL) {
    572             if (isPSF)
    573                 *isPSF = FALSE;
    574             return NULL;
    575         }
    576         return (model);
    577         break;
    578 
    579     default:
    580         if (isPSF)
    581             *isPSF = false;
    582         return NULL;
    583     }
    584     return NULL;
    585 }
     553
     554double pmSourceModelWeight(const pmSource *Mi,
     555                      int term,
     556                      const bool unweighted_sum) // should the cross product be weighted?
     557{
     558    double flux = 0, wt = 0, factor = 0;
     559
     560    const psImage *Pi = Mi->modelFlux;
     561    const psImage *Wi = Mi->weight;
     562    const psImage *Ti = Mi->maskObj;
     563
     564    for (int yi = 0; yi < Pi->numRows; yi++) {
     565        for (int xi = 0; xi < Pi->numCols; xi++) {
     566            if (Ti->data.U8[yi][xi])
     567                continue;
     568            if (!unweighted_sum) {
     569                wt = Wi->data.F32[yi][xi];
     570                if (wt == 0)
     571                    continue;
     572            }
     573
     574            switch (term) {
     575            case 0:
     576                factor = 1;
     577                break;
     578            case 1:
     579                factor = xi + Pi->col0;
     580                break;
     581            case 2:
     582                factor = yi + Pi->row0;
     583                break;
     584            default:
     585                psAbort("invalid term for pmSourceWeight");
     586            }
     587
     588            if (unweighted_sum) {
     589                flux += (factor * Pi->data.F32[yi][xi]);
     590            } else {
     591                flux += (factor * Pi->data.F32[yi][xi]) / wt;
     592            }
     593        }
     594    }
     595    return flux;
     596}
     597
     598double pmSourceModelDotModel (const pmSource *Mi,
     599                              const pmSource *Mj,
     600                              const bool unweighted_sum) // should the cross product be weighted?
     601{
     602    int Xs, Xe, Ys, Ye;
     603    int xi, xj, yi, yj;
     604    int xIs, xJs, yIs, yJs;
     605    int xIe, yIe;
     606    double flux, wt;
     607
     608    const psImage *Pi = Mi->modelFlux;
     609    const psImage *Pj = Mj->modelFlux;
     610
     611    const psImage *Wi = Mi->weight;
     612
     613    const psImage *Ti = Mi->maskObj;
     614    const psImage *Tj = Mj->maskObj;
     615
     616    Xs = PS_MAX (Pi->col0, Pj->col0);
     617    Xe = PS_MIN (Pi->col0 + Pi->numCols, Pj->col0 + Pj->numCols);
     618
     619    Ys = PS_MAX (Pi->row0, Pj->row0);
     620    Ye = PS_MIN (Pi->row0 + Pi->numRows, Pj->row0 + Pj->numRows);
     621
     622    xIs = Xs - Pi->col0;
     623    xJs = Xs - Pj->col0;
     624    yIs = Ys - Pi->row0;
     625    yJs = Ys - Pj->row0;
     626
     627    xIe = Xe - Pi->col0;
     628    yIe = Ye - Pi->row0;
     629
     630    // note that weight is addressing the same image pixels
     631    flux = 0;
     632    for (yi = yIs, yj = yJs; yi < yIe; yi++, yj++) {
     633        for (xi = xIs, xj = xJs; xi < xIe; xi++, xj++) {
     634            if (Ti->data.U8[yi][xi])
     635                continue;
     636            if (Tj->data.U8[yj][xj])
     637                continue;
     638
     639            // XXX skip the nonsense weight pixels?
     640            if (unweighted_sum) {
     641                flux += (Pi->data.F32[yi][xi] * Pj->data.F32[yj][xj]);
     642            } else {
     643                wt = Wi->data.F32[yi][xi];
     644                if (wt > 0) {
     645                    flux += (Pi->data.F32[yi][xi] * Pj->data.F32[yj][xj]) / wt;
     646                }
     647            }
     648        }
     649    }
     650    return flux;
     651}
     652
     653double pmSourceDataDotModel (const pmSource *Mi,
     654                             const pmSource *Mj,
     655                             const bool unweighted_sum) // should the cross product be weighted?
     656{
     657
     658    int Xs, Xe, Ys, Ye;
     659    int xi, xj, yi, yj;
     660    int xIs, xJs, yIs, yJs;
     661    int xIe, yIe;
     662    double flux, wt;
     663
     664    const psImage *Pi = Mi->pixels;
     665    const psImage *Pj = Mj->modelFlux;
     666
     667    const psImage *Wi = Mi->weight;
     668
     669    const psImage *Ti = Mi->maskObj;
     670    const psImage *Tj = Mj->maskObj;
     671
     672    Xs = PS_MAX (Pi->col0, Pj->col0);
     673    Xe = PS_MIN (Pi->col0 + Pi->numCols, Pj->col0 + Pj->numCols);
     674
     675    Ys = PS_MAX (Pi->row0, Pj->row0);
     676    Ye = PS_MIN (Pi->row0 + Pi->numRows, Pj->row0 + Pj->numRows);
     677
     678    xIs = Xs - Pi->col0;
     679    xJs = Xs - Pj->col0;
     680    yIs = Ys - Pi->row0;
     681    yJs = Ys - Pj->row0;
     682
     683    xIe = Xe - Pi->col0;
     684    yIe = Ye - Pi->row0;
     685
     686    // note that weight is addressing the same image pixels,
     687    flux = 0;
     688    for (yi = yIs, yj = yJs; yi < yIe; yi++, yj++) {
     689        for (xi = xIs, xj = xJs; xi < xIe; xi++, xj++) {
     690            if (Ti->data.U8[yi][xi])
     691                continue;
     692            if (Tj->data.U8[yj][xj])
     693                continue;
     694
     695            // XXX skip the nonsense weight pixels?
     696            if (unweighted_sum) {
     697                flux += (Pi->data.F32[yi][xi] * Pj->data.F32[yj][xj]);
     698            } else {
     699                wt = Wi->data.F32[yi][xi];
     700                if (wt > 0) {
     701                    flux += (Pi->data.F32[yi][xi] * Pj->data.F32[yj][xj]) / wt;
     702                }
     703            }
     704        }
     705    }
     706    return flux;
     707}
     708
  • trunk/psModules/src/objects/pmSourcePhotometry.h

    r11253 r13034  
    44 * @author EAM, IfA; GLG, MHPCC
    55 *
    6  * @version $Revision: 1.8 $ $Name: not supported by cvs2svn $
    7  * @date $Date: 2007-01-24 02:54:15 $
     6 * @version $Revision: 1.9 $ $Name: not supported by cvs2svn $
     7 * @date $Date: 2007-04-26 01:20:29 $
    88 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii
    99 */
     
    5050bool pmSourceMagnitudesInit (psMetadata *config);
    5151bool pmSourceMagnitudes (pmSource *source, pmPSF *psf, pmSourcePhotometryMode mode);
    52 double pmSourceCrossProduct(const pmSource *Mi, const pmSource *Mj, const bool unweighted_sum);
    53 double pmSourceCrossWeight(const pmSource *Mi, const pmSource *Mj, const bool unweighted_sum);
    5452bool pmSourcePixelWeight (float *pixWeight, pmModel *model, psImage *image, psImage *mask);
    5553bool pmSourceChisq (pmModel *model, psImage *image, psImage *mask, psImage *weight);
    56 pmModel *pmSourceGetModel (bool *isPSF, const pmSource *source);
    5754
    58 double pmSourceWeight(const pmSource *Mi, int term, const bool unweighted_sum);
     55
     56double pmSourceDataDotModel (const pmSource *Mi, const pmSource *Mj, const bool unweighted_sum);
     57double pmSourceModelDotModel (const pmSource *Mi, const pmSource *Mj, const bool unweighted_sum);
     58double pmSourceModelWeight(const pmSource *Mi, int term, const bool unweighted_sum);
     59
     60// retire these:
     61// double pmSourceCrossProduct(const pmSource *Mi, const pmSource *Mj, const bool unweighted_sum);
     62// double pmSourceCrossWeight(const pmSource *Mi, const pmSource *Mj, const bool unweighted_sum);
     63// double pmSourceWeight(const pmSource *Mi, int term, const bool unweighted_sum);
    5964
    6065/// @}
  • trunk/psModules/src/objects/pmSourceSky.c

    r12949 r13034  
    66 *  @author EAM, IfA: significant modifications.
    77 *
    8  *  @version $Revision: 1.11 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2007-04-21 19:47:14 $
     8 *  @version $Revision: 1.12 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2007-04-26 01:20:29 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    4949    PS_ASSERT_PTR_NON_NULL(source, false);
    5050    PS_ASSERT_IMAGE_NON_NULL(source->pixels, false);
    51     PS_ASSERT_IMAGE_NON_NULL(source->mask, false);
     51    PS_ASSERT_IMAGE_NON_NULL(source->maskObj, false);
    5252    PS_ASSERT_PTR_NON_NULL(source->peak, false);
    5353    PS_ASSERT_INT_POSITIVE(Radius, false);
     
    6161
    6262    psImage *image = source->pixels;
    63     psImage *mask  = source->mask;
     63    psImage *mask  = source->maskObj;
    6464    pmPeak *peak  = source->peak;
    6565    psRegion srcRegion;
     
    100100    PS_ASSERT_PTR_NON_NULL(source, false);
    101101    PS_ASSERT_IMAGE_NON_NULL(source->weight, false);
    102     PS_ASSERT_IMAGE_NON_NULL(source->mask, false);
     102    PS_ASSERT_IMAGE_NON_NULL(source->maskObj, false);
    103103    PS_ASSERT_PTR_NON_NULL(source->peak, false);
    104104    PS_ASSERT_INT_POSITIVE(Radius, false);
     
    112112
    113113    psImage *image = source->weight;
    114     psImage *mask  = source->mask;
     114    psImage *mask  = source->maskObj;
    115115    pmPeak *peak  = source->peak;
    116116    psRegion srcRegion;
  • trunk/psModules/test/objects/tap_pmSourceFitModel.c

    r10263 r13034  
    136136
    137137    // create an image with the model, and add noise: gain is 1, subtracted sky is 100, readnoise is 5
    138     pmModelAdd (source->pixels, source->mask, source->modelEXT, false, false);
     138    pmModelAdd (source->pixels, source->mask, source->modelEXT, PM_MODEL_OP_FULL);
    139139    int npix = 0;
    140140    for (int j = 0; j < source->pixels->numRows; j++) {
  • trunk/psModules/test/objects/tap_pmSourceFitModel_Delta.c

    r10194 r13034  
    5454
    5555    // create an image with the model, and add noise: gain is 1, subtracted sky is 100, readnoise is 5
    56     pmModelAdd (source->pixels, source->mask, source->modelEXT, false, false);
     56    pmModelAdd (source->pixels, source->mask, source->modelEXT, PM_MODEL_OP_FULL);
    5757    int npix = 0;
    5858    for (int j = 0; j < source->pixels->numRows; j++) {
Note: See TracChangeset for help on using the changeset viewer.