IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 27657


Ignore:
Timestamp:
Apr 11, 2010, 5:08:29 PM (16 years ago)
Author:
eugene
Message:

updates to support psphotStack

Location:
trunk
Files:
1 deleted
48 edited

Legend:

Unmodified
Added
Removed
  • trunk/ippconfig

  • trunk/ippconfig/recipes/filerules-simple.mdc

    r27652 r27657  
    167167PSPHOT.PSF.RAW.SAVE     OUTPUT {OUTPUT}.psf          PSF       NONE       FPA        TRUE      NONE
    168168PSPHOT.PSF.SKY.SAVE     OUTPUT {OUTPUT}.psf          PSF       NONE       FPA        TRUE      NONE
    169                                                      
     169
    170170# outputs for psphotStack:
    171171PSPHOT.CHISQ.IMAGE      OUTPUT {OUTPUT}.chisq.im.fits IMAGE    NONE       FPA        TRUE      SIMPLE
  • trunk/ppSim

  • trunk/ppSim/src/ppSimInsertGalaxies.c

    r18011 r27657  
    7474    int dY = PM_CELL_TO_CHIP (0.0, y0Cell, yParityCell, binning);
    7575
    76     // psMetadataLookupPtr (readout->analysis, "PSPHOT.SOURCES", 0);
    77 
    78     psArray *sources = psArrayAllocEmpty (galaxies->n);
    79 
     76    pmDetections *detections = psMetadataLookupPtr (&mdok, readout->analysis, "PSPHOT.DETECTIONS");
     77    if (!detections) {
     78        detections = pmDetectionsAlloc();
     79        detections->allSources = psArrayAllocEmpty (galaxies->n);
     80        psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_DATA_ARRAY | PS_META_REPLACE, "psphot detections", detections);
     81    } else {
     82        psMemIncrRefCounter (detections);
     83    }
     84    psArray *sources = sources = detections->allSources;
    8085
    8186    // add sources to the readout image & weight
     
    181186    }
    182187
    183     // NOTE: readout must be part of the pmFPAfile named "PPSIM.OUTPUT"
    184     // psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY | PS_META_REPLACE, "psphot sources", sources);
     188    // XXX many leaks in here, i think
     189    psFree (detections);
    185190
    186     // XXX many leaks in here, i think
    187191    return true;
    188192}
  • trunk/ppSim/src/ppSimInsertStars.c

    r27533 r27657  
    145145    fclose (outfile);
    146146
    147     // NOTE: the pmFPAfile "PPSIM.OUTPUT" points at these sources
    148     psMetadataAdd (readout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_DATA_ARRAY, "fake sources", sources);
    149     psFree(sources);
     147    pmDetections *detections = pmDetectionsAlloc();
     148    detections->allSources = sources;
     149
     150    // save detections on the readout->analysis
     151    if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "fake sources", detections)) {
     152        psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
     153        return false;
     154    }
     155    psFree(detections);
    150156
    151157    // XXX many leaks in here, i think
  • trunk/ppSim/src/ppSimPhotomReadout.c

    r26900 r27657  
    66    PS_ASSERT_PTR_NON_NULL (readout, NULL);
    77
    8     psArray *sources = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.SOURCES");
     8    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     9    psAssert (detections, "missing detections?");
     10
     11    psArray *sources = detections->allSources;
    912    return sources;
    1013}
     
    151154
    152155    // create the exported-metadata and free local data
    153     // XXX this places the sources on readout->analysis as PSPHOT.SOURCES.  modify?
    154     // (or don't supply the sources, and do this with a different function)
    155156    psphotReadoutCleanup(config, readout, recipe, NULL, psf, NULL);
    156157
     
    167168    psAssert (forceReadout, "no forceReadout?");
    168169    pmChipSetDataStatus (forceChip, true);
    169     psMetadataAddArray (forceReadout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_META_REPLACE, "forced photometry ", forceSources);
    170     psFree (forceSources);
     170
     171    pmDetections *detectionsForce = pmDetectionsAlloc();
     172    detectionForce->allSources = forceSources;
     173
     174    // save detections on the readout->analysis
     175    if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "force sources", detectionsForce)) {
     176        psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
     177        return false;
     178    }
     179    psFree(detectionsForce);
    171180
    172181    pmCell    *fakeCell    = pmFPAfileThisCell (config->files, view, "PPSIM.FAKE.SOURCES"); psAssert (fakeCell, "no cell?");
     
    179188    psAssert (fakeReadout, "no fakeReadout?");
    180189    pmChipSetDataStatus (fakeChip, true);
    181     psMetadataAddArray (fakeReadout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_META_REPLACE, "fake photometry ", fakeSources);
     190
     191    pmDetections *detectionsFake = pmDetectionsAlloc();
     192    detectionFake->allSources = fakeSources;
     193
     194    // save detections on the readout->analysis
     195    if (!psMetadataAddPtr (readout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE | PS_DATA_UNKNOWN, "fake sources", detectionsFake)) {
     196        psError (PSPHOT_ERR_CONFIG, false, "problem saving detections on readout");
     197        return false;
     198    }
     199    psFree(detectionsFake);
    182200
    183201    return true;
  • trunk/ppSim/src/ppSimPhotomReadoutFake.c

    r26900 r27657  
    111111    psAssert (fakeReadout, "no fakeReadout?");
    112112    pmChipSetDataStatus (fakeChip, true);
    113     psMetadataAddArray (fakeReadout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_META_REPLACE, "fake photometry ", fakeSources);
     113
     114    pmDetections *detections = pmDetectionsAlloc();
     115    detection->allSources = fakeSources;
     116
     117    psMetadataAddArray (fakeReadout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE, "fake photometry ", detections);
     118    psFree(detections);
    114119
    115120    return true;
  • trunk/ppSim/src/ppSimPhotomReadoutForce.c

    r26900 r27657  
    9898
    9999    // create the exported-metadata and free local data
    100     // XXX this places the sources on readout->analysis as PSPHOT.SOURCES.  modify?
    101     // (or don't supply the sources, and do this with a different function)
    102100    psphotReadoutCleanup(config, readout, recipe, NULL, psf, NULL);
    103101
     
    111109    psAssert (forceReadout, "no forceReadout?");
    112110    pmChipSetDataStatus (forceChip, true);
    113     psMetadataAddArray (forceReadout->analysis, PS_LIST_TAIL, "PSPHOT.SOURCES", PS_META_REPLACE, "force photometry ", forceSources);
     111
     112    pmDetections *detections = pmDetectionsAlloc();
     113    detection->allSources = forceSources;
     114    psMetadataAddArray (forceReadout->analysis, PS_LIST_TAIL, "PSPHOT.DETECTIONS", PS_META_REPLACE, "force photometry ", detections);
     115    psFree(detections);
    114116
    115117    return true;
  • trunk/ppSim/src/ppSimUtils.c

    r24807 r27657  
    270270psArray *ppSimSelectSources (pmConfig *config, const pmFPAview *view, const char *filename) {
    271271
     272    bool status;
     273
    272274    pmReadout *readout = pmFPAfileThisReadout (config->files, view, filename);
    273275    PS_ASSERT_PTR_NON_NULL (readout, NULL);
    274276
    275     psArray *sources = psMetadataLookupPtr (NULL, readout->analysis, "PSPHOT.SOURCES");
     277    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     278    psAssert (detections, "missing detections?");
     279
     280    psArray *sources = detections->allSources;
    276281    return sources;
    277282}
  • trunk/psModules

  • trunk/psModules/src/camera/pmFPAfile.c

    r27134 r27657  
    111111    file->save = false;
    112112
    113     file->index = fileNum++;
     113    file->fileIndex = fileNum++;
     114    file->fileID = 0;
    114115
    115116    file->imageId = 0;
     
    372373        // Number of the file in list
    373374        psString num = NULL;            // Number to use
    374         psStringAppend(&num, "%d", file->index);
     375        psStringAppend(&num, "%d", file->fileIndex);
    375376        psStringSubstitute(&newRule, num, "{FILE.INDEX}");
     377        psFree(num);
     378    }
     379
     380    if (strstr(newRule, "{FILE.ID}")) {
     381        // Number of the file in list
     382        psString num = NULL;            // Number to use
     383        psStringAppend(&num, "%03d", file->fileID);
     384        psStringSubstitute(&newRule, num, "{FILE.ID}");
    376385        psFree(num);
    377386    }
     
    638647    psFree(iter);
    639648
    640     psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to find instance %d of file %s", num, name);
     649    psLogMsg("psModules.camera", PS_LOG_MINUTIA, "Unable to find instance %d of file %s", num, name);
    641650    return NULL;
    642651}
  • trunk/psModules/src/camera/pmFPAfile.h

    r27134 r27657  
    111111    psString formatName;                // name of the camera format
    112112
    113     int index;                          // Index of file
     113    int fileIndex;                      // Index of file
     114    int fileID;                         // internal sequence number
    114115
    115116    psS64 imageId, sourceId;            // Image and source identifiers
  • trunk/psModules/src/camera/pmFPAfileDefine.c

    r27417 r27657  
    12711271    file->name = psStringCopy (name);
    12721272
     1273    // free a previously existing readout
     1274    psFree(file->readout);
    12731275    file->readout = readout;
    1274     psMetadataAddPtr(files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN, "", file);
     1276
     1277    // allow for multiple entries
     1278    // XXX handle replace vs multiple?
     1279    psMetadataAddPtr(files, PS_LIST_TAIL, name, PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "", file);
    12751280    psFree(file);
    12761281    // we free this copy of file, but 'files' still has a copy
     
    13131318                                const char *name, // name of internal/external file
    13141319                                const pmFPA *fpa, // use this fpa to generate
    1315                                 const psImageBinning *binning) {
     1320                                const psImageBinning *binning,
     1321                                int index) {
    13161322  pmReadout *readout = NULL;
    13171323
    1318   bool status = true;
    1319   pmFPAfile *file = psMetadataLookupPtr(&status, config->files, name);
     1324  pmFPAfile *file = pmFPAfileSelectSingle(config->files, name, index);
    13201325
    13211326  // if the file does not exist, it is not being used as an I/O file: define an internal version
    13221327  if (file == NULL) {
    1323     readout = pmFPAfileDefineInternal (config->files, name, binning->nXruff, binning->nYruff, PS_TYPE_F32);
    1324     return readout;
     1328      // XXX currently, we do not guarantee that the defined file lands on entry 'index'
     1329      psAssert (binning, "internal files must be supplied a psImageBinning for the output images size");
     1330      readout = pmFPAfileDefineInternal (config->files, name, binning->nXruff, binning->nYruff, PS_TYPE_F32);
     1331      return readout;
    13251332  }
    13261333
  • trunk/psModules/src/camera/pmFPAfileDefine.h

    r23354 r27657  
    172172                                const char *name, // name of internal/external file
    173173                                const pmFPA *fpa, // use this fpa to generate
    174                                 const psImageBinning *binning);
     174                                const psImageBinning *binning,
     175                                int index
     176    );
    175177
    176178/// @}
  • trunk/psModules/src/objects/Makefile.am

    r27531 r27657  
    2020        pmModelUtils.c \
    2121        pmSource.c \
     22        pmPhotObj.c \
    2223        pmSourceMasks.c \
    2324        pmSourceMoments.c \
     
    8081        pmModelUtils.h \
    8182        pmSource.h \
     83        pmPhotObj.h \
    8284        pmSourceMasks.h \
    8385        pmSourceDiffStats.h \
  • trunk/psModules/src/objects/pmPeaks.h

    r20945 r27657  
    6363    bool assigned;                      ///< is peak assigned to a source?
    6464    pmPeakType type;                    ///< Description of peak.
    65     pmFootprint *footprint;     ///< reference to containing footprint
     65    pmFootprint *footprint;             ///< reference to containing footprint
    6666}
    6767pmPeak;
  • trunk/psModules/src/objects/pmPhotObj.c

    r26893 r27657  
    1717#include <pslib.h>
    1818#include "pmPhotObj.h"
     19#include "pmSource.h"
    1920
    2021static void pmPhotObjFree (pmPhotObj *tmp)
     
    3839}
    3940
     41bool pmPhotObjAddSource(pmPhotObj *object, pmSource *source) {
     42
     43    psAssert (source, "programming error: NULL source");
     44    if (!source->peak) {
     45        psError(PS_ERR_UNKNOWN, true, "source missing peak");
     46        return false;
     47    }
     48    if (!finite(source->peak->xf)) {
     49        psError(PS_ERR_UNKNOWN, true, "NAN peak coordinate");
     50        return false;
     51    }
     52    if (!finite(source->peak->yf)) {
     53        psError(PS_ERR_UNKNOWN, true, "NAN peak coordinate");
     54        return false;
     55    }
     56
     57    // XXX we should probably use the fitted position if it exists
     58    if (!object->sources) {
     59        object->sources = psArrayAllocEmpty(1);
     60        object->x = source->peak->xf;
     61        object->y = source->peak->yf;
     62    }
     63    psArrayAdd (object->sources, 1, source);
     64    return true;
     65}
  • trunk/psModules/src/objects/pmPhotObj.h

    r26893 r27657  
    3434 */
    3535typedef struct {
    36   int seq;                            ///< ID for output (generated on write OR set on read)
    37   psArray *sources;
     36    int id;                            ///< ID for output (generated on write OR set on read)
     37    psArray *sources;
     38    int flags;
     39    float x;
     40    float y;
    3841} pmPhotObj;
     42
     43bool pmPhotObjAddSource(pmPhotObj *object, pmSource *source);
     44pmPhotObj *pmPhotObjAlloc(void);
    3945
    4046/// @}
    4147# endif /* PM_PHOT_OBJ_H */
     48
  • trunk/psModules/src/objects/pmSource.c

    r27531 r27657  
    180180    source->type = in->type;
    181181    source->mode = in->mode;
     182    source->imageID = in->imageID;
    182183
    183184    return(source);
     
    10581059    psF32 fA = (A->peak == NULL) ? 0 : A->peak->y;
    10591060    psF32 fB = (B->peak == NULL) ? 0 : B->peak->y;
     1061
     1062    psF32 diff = fA - fB;
     1063    if (diff > FLT_EPSILON) return (+1);
     1064    if (diff < FLT_EPSILON) return (-1);
     1065    return (0);
     1066}
     1067
     1068// sort by X (ascending)
     1069int pmSourceSortByX (const void **a, const void **b)
     1070{
     1071    pmSource *A = *(pmSource **)a;
     1072    pmSource *B = *(pmSource **)b;
     1073
     1074    psF32 fA = (A->peak == NULL) ? 0 : A->peak->x;
     1075    psF32 fB = (B->peak == NULL) ? 0 : B->peak->x;
    10601076
    10611077    psF32 diff = fA - fB;
  • trunk/psModules/src/objects/pmSource.h

    r27531 r27657  
    4343    PM_SOURCE_TMPF_SIZE_MEASURED     = 0x0004,
    4444    PM_SOURCE_TMPF_SIZE_CR_CANDIDATE = 0x0008,
     45    PM_SOURCE_TMPF_MOMENTS_MEASURED  = 0x0010,
    4546} pmSourceTmpF;
    4647
     
    9091    pmSourceExtendedPars *extpars;      ///< extended source parameters
    9192    pmSourceDiffStats *diffStats;       ///< extra parameters for difference detections
     93    int imageID;
    9294};
    9395
     
    245247int  pmSourceSortBySN (const void **a, const void **b);
    246248int  pmSourceSortByY (const void **a, const void **b);
     249int  pmSourceSortByX (const void **a, const void **b);
    247250int  pmSourceSortBySeq (const void **a, const void **b);
    248251
  • trunk/psModules/src/psmodules.h

    r27531 r27657  
    124124#include <pmSourceMasks.h>
    125125#include <pmSource.h>
     126#include <pmPhotObj.h>
    126127#include <pmSourceUtils.h>
    127128#include <pmSourceIO.h>
  • trunk/psphot

  • trunk/psphot/src

    • Property svn:ignore
      •  

        old new  
        2121psphotForced
        2222psphotMakePSF
         23psphotStack
  • trunk/psphot/src/Makefile.am

    r26894 r27657  
    1717# Force recompilation of psphotVersion.c, since it gets the version information
    1818psphotVersion.c: psphotVersionDefinitions.h
    19 psphotVersionDefinitions.h: psphotVersionDefinitions.h.in FORCE
    20         -$(RM) psphotVersionDefinitions.h
    21         $(SED) -e "s|@PSPHOT_VERSION@|\"$(PSPHOT_VERSION)\"|" -e "s|@PSPHOT_BRANCH@|\"$(PSPHOT_BRANCH)\"|" -e "s|@PSPHOT_SOURCE@|\"$(PSPHOT_SOURCE)\"|" psphotVersionDefinitions.h.in > psphotVersionDefinitions.h
    22 FORCE: ;
     19# psphotVersionDefinitions.h: psphotVersionDefinitions.h.in FORCE
     20#       -$(RM) psphotVersionDefinitions.h
     21#       $(SED) -e "s|@PSPHOT_VERSION@|\"$(PSPHOT_VERSION)\"|" -e "s|@PSPHOT_BRANCH@|\"$(PSPHOT_BRANCH)\"|" -e "s|@PSPHOT_SOURCE@|\"$(PSPHOT_SOURCE)\"|" psphotVersionDefinitions.h.in > psphotVersionDefinitions.h
     22# FORCE: ;
    2323
    2424libpsphot_la_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
    2525libpsphot_la_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    2626
    27 bin_PROGRAMS = psphot psphotForced psphotMakePSF
     27bin_PROGRAMS = psphot psphotForced psphotMakePSF psphotStack
    2828# bin_PROGRAMS = psphotPetrosianStudy psphotTest psphotMomentsStudy
    2929
     
    3939psphotMakePSF_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
    4040psphotMakePSF_LDADD = libpsphot.la
     41
     42psphotStack_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     43psphotStack_LDFLAGS = $(PSPHOT_LIBS) $(PSMODULE_LIBS) $(PSLIB_LIBS)
     44psphotStack_LDADD = libpsphot.la
    4145
    4246# psphotMomentsStudy_CFLAGS = $(PSPHOT_CFLAGS) $(PSMODULE_CFLAGS) $(PSLIB_CFLAGS)
     
    8084        psphotMosaicChip.c         \
    8185        psphotCleanup.c
     86
     87# a psphot-variant for stack photometry
     88psphotStack_SOURCES = \
     89        psphotStack.c                 \
     90        psphotStackArguments.c        \
     91        psphotStackParseCamera.c      \
     92        psphotStackImageLoop.c        \
     93        psphotStackReadout.c          \
     94        psphotStackChisqImage.c       \
     95        psphotFitSourcesLinearStack.c \
     96        psphotSourceMatch.c           \
     97        psphotCleanup.c
     98
     99
    82100
    83101# # psphot analysis of the detectability of specified positions
  • trunk/psphot/src/psphot.h

    r27532 r27657  
    341341bool psphotMakePSFReadout(pmConfig *config, const pmFPAview *view);
    342342
     343/**** psphotStack prototypes ****/
     344
     345pmConfig *psphotStackArguments(int argc, char **argv);
     346bool psphotStackParseCamera (pmConfig *config);
     347bool psphotStackImageLoop (pmConfig *config);
     348bool psphotStackReadout (pmConfig *config, const pmFPAview *view);
     349bool psphotStackChisqImage (pmConfig *config, const pmFPAview *view);
     350bool psphotStackChisqImageAddReadout(const pmConfig *config, // Configuration
     351                                     const pmFPAview *view,
     352                                     pmReadout **chiReadout,
     353                                     char *filename,
     354                                     int index);
     355
     356bool psphotStackRemoveChisqFromInputs (pmConfig *config);
     357bool pmFPAfileRemoveSingle(psMetadata *files, const char *name, int num);
     358
     359psArray *psphotMatchSources (pmConfig *config, const pmFPAview *view);
     360bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, char *filename, int index);
     361bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS);
     362
     363bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final);
     364int pmPhotObjSortBySN (const void **a, const void **b);
     365int pmPhotObjSortByX (const void **a, const void **b);
     366
    343367#endif
  • trunk/psphot/src/psphotApResid.c

    r26894 r27657  
    1616    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    1717
     18    // skip the chisq image (optionally?)
     19    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     20    if (!status) chisqNum = -1;
     21
    1822    // loop over the available readouts
    1923    for (int i = 0; i < num; i++) {
     24        if (i == chisqNum) continue; // skip chisq image
    2025        if (!psphotApResidReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
    2126            psError (PSPHOT_ERR_CONFIG, false, "failed to measure aperture residual for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotChoosePSF.c

    r27568 r27657  
    1313    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    1414
     15    // skip the chisq image (optionally?)
     16    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     17    if (!status) chisqNum = -1;
     18
    1519    // loop over the available readouts
    1620    for (int i = 0; i < num; i++) {
     21        if (i == chisqNum) continue; // skip chisq image
    1722        if (!psphotChoosePSFReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
    1823            psError (PSPHOT_ERR_CONFIG, false, "failed to choose a psf model for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotEfficiency.c

    r27532 r27657  
    160160    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    161161
     162    // skip the chisq image (optionally?)
     163    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     164    if (!status) chisqNum = -1;
     165
    162166    // loop over the available readouts
    163167    for (int i = 0; i < num; i++) {
     168        if (i == chisqNum) continue; // skip chisq image
    164169        if (!psphotEfficiencyReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
    165170            psError (PSPHOT_ERR_CONFIG, false, "failed to measure detection efficiency for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotFitSourcesLinearStack.c

    r27547 r27657  
    11# include "psphotInternal.h"
     2// XXX need array of covar factors for each image
     3// XXX define the 'good' / 'bad' flags?
    24
    3 // for now, let's store the detections on the readout->analysis for each readout
    4 bool psphotFitSourcesLinearStack (pmConfig *config, const pmFPAview *view, bool final)
    5 {
    6     bool status = true;
     5# define COVAR_FACTOR 1.0
    76
    8     int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
    9     psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    10 
    11     // loop over the available readouts
    12     for (int i = 0; i < num; i++) {
    13         if (!psphotFitSourcesLinearReadoutStack (config, view, "PSPHOT.INPUT", i, final)) {
    14             psError (PSPHOT_ERR_CONFIG, false, "failed to fit sources (linear) for PSPHOT.INPUT entry %d", i);
    15             return false;
    16         }
    17     }
    18     return true;
    19 }
    20 
    21 bool psphotFitSourcesLinearReadout (pmConfig *config, const pmFPAview *view, const char *filename, int index, bool final) {
     7bool psphotFitSourcesLinearStack (pmConfig *config, psArray *objects, bool final) {
    228
    239    bool status;
    24     float x;
    25     float y;
    2610    float f;
    27     // float r;
    2811
    2912    // select the appropriate recipe information
    3013    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
    3114    assert (recipe);
    32 
    33     // find the currently selected readout
    34     pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
    35     psAssert (file, "missing file?");
    36 
    37     pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
    38     psAssert (readout, "missing readout?");
    39 
    40     pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    41     psAssert (detections, "missing detections?");
    42 
    43     psArray *sources = detections->allSources;
    44     psAssert (sources, "missing sources?");
    45 
    46     if (!sources->n) {
    47         psLogMsg ("psphot", PS_LOG_INFO, "no sources, skipping linear fit");
    48         return true;
    49     }
    50 
    51     pmPSF *psf = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
    52     psAssert (sources, "missing psf?");
    5315
    5416    psTimerStart ("psphot.linear");
     
    6527    maskVal |= markVal;
    6628
    67     // source analysis is done in spatial order
    68     sources = psArraySort (sources, pmSourceSortByY);
     29    // analysis is done in spatial order (to speed up overlap search)
     30    // sort by first element in each source list
     31    objects = psArraySort (objects, pmPhotObjSortByX);
    6932
    7033    // storage array for fitSources
    71     psArray *fitSources = psArrayAllocEmpty (sources->n);
     34    psArray *fitSources = psArrayAllocEmpty (objects->n);
    7235
    73     // option to limit analysis to a specific region
    74     char *region = psMetadataLookupStr (&status, recipe, "ANALYSIS_REGION");
    75     psRegion AnalysisRegion = psRegionFromString (region);
    76     AnalysisRegion = psRegionForImage (readout->image, AnalysisRegion);
    77     if (psRegionIsNaN (AnalysisRegion)) psAbort("analysis region mis-defined");
     36    bool CONSTANT_PHOTOMETRIC_WEIGHTS = psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS");
     37    psAssert (status, "You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS");
    7838
    79     bool CONSTANT_PHOTOMETRIC_WEIGHTS =
    80         psMetadataLookupBool(&status, recipe, "CONSTANT_PHOTOMETRIC_WEIGHTS");
    81     if (!status) {
    82         psAbort("You must provide a value for the BOOL recipe CONSTANT_PHOTOMETRIC_WEIGHTS");
    83     }
    84     int SKY_FIT_ORDER = psMetadataLookupS32(&status, recipe, "SKY_FIT_ORDER");
    85     if (!status) {
    86         SKY_FIT_ORDER = 0;
    87     }
    88     bool SKY_FIT_LINEAR = psMetadataLookupBool(&status, recipe, "SKY_FIT_LINEAR");
    89     if (!status) {
    90         SKY_FIT_LINEAR = false;
    91     }
    92 
    93     // XXX test: choose a larger-than expected radius:
    94     float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
    95     psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor);
    96 
    97     // XXX do not apply covarFactor for the moment...
    98     // covarFactor = 1.0;
     39    // XXX store a local static array of covar factors for each of the images (by image ID)
     40    // float covarFactor = psImageCovarianceFactorForAperture(readout->covariance, 10.0); // Covariance matrix
     41    // psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "covariance factor: %f\n", covarFactor);
    9942
    10043    // select the sources which will be used for the fitting analysis
     
    10447        if (!object->sources) continue;
    10548
    106         // check an element of the group to see if we should use it
    107         if (!object->flags & PM_PHOT_OBJ_BAD) continue;
     49        // XXX check an element of the group to see if we should use it
     50        // if (!object->flags & PM_PHOT_OBJ_BAD) continue;
    10851
    10952        for (int j = 0; j < object->sources->n; j++) {
     
    12366        }
    12467    }
    125     psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), sources->n);
     68    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "built fitSources: %f sec (%ld objects)\n", psTimerMark ("psphot.linear"), objects->n);
    12669
    12770    if (fitSources->n == 0) {
     
    14386
    14487        // diagonal elements of the sparse matrix (auto-cross-product)
    145         f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);
     88        f = pmSourceModelDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR);
    14689        psSparseMatrixElement (sparse, i, i, f);
    14790
    14891        // the formal error depends on the weighting scheme
    14992        if (CONSTANT_PHOTOMETRIC_WEIGHTS) {
    150             float var = pmSourceModelDotModel (SRCi, SRCi, false, covarFactor);
     93            float var = pmSourceModelDotModel (SRCi, SRCi, false, COVAR_FACTOR);
    15194            errors->data.F32[i] = 1.0 / sqrt(var);
    15295        } else {
     
    15598
    15699        // find the image x model value
    157         f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);
     100        f = pmSourceDataDotModel (SRCi, SRCi, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR);
    158101        psSparseVectorElement (sparse, i, f);
    159102
     
    162105            pmSource *SRCj = fitSources->data[j];
    163106
    164             // XXX I need to know if this source is on the same image as SRCi --
    165             if (!sameImge) { continue; }
     107            // we only need to generate dot terms for source on the same image
     108            if (SRCj->imageID != SRCi->imageID) { continue; }
    166109
    167110            // skip over disjoint source images, break after last possible overlap
    168             if (SRCi->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) break;
    169             if (SRCj->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue;
    170             if (SRCi->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) continue;
    171             if (SRCj->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue;
     111            if (SRCj->pixels->row0 + SRCj->pixels->numRows < SRCi->pixels->row0) continue;  // source(i) is above source(j)
     112            if (SRCi->pixels->row0 + SRCi->pixels->numRows < SRCj->pixels->row0) continue;  // source(i) is below source(j)
     113            if (SRCj->pixels->col0 + SRCj->pixels->numCols < SRCi->pixels->col0) continue;  // source(i) is right of source(j)
     114            if (SRCi->pixels->col0 + SRCi->pixels->numCols < SRCj->pixels->col0) break;     // source(i) is left of source(j) [no other source(j) can overlap source(i)]
    172115
    173116            // got an overlap; calculate cross-product and add to output array
    174             f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, covarFactor);
     117            f = pmSourceModelDotModel (SRCi, SRCj, CONSTANT_PHOTOMETRIC_WEIGHTS, COVAR_FACTOR);
    175118            psSparseMatrixElement (sparse, j, i, f);
    176119        }
     
    190133    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "solve matrix: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
    191134
    192     // XXXX **** philosophical question:
    193     // we measure bright objects in three passes: 1) linear fit; 2) non-linear fit; 3) linear fit:
    194     // should retain the chisq and errors from the intermediate non-linear fit?
    195     // the non-linear fit provides better values for the position errors, and for
    196     // extended sources, the shape errors
    197 
    198135    // adjust I0 for fitSources and subtract
    199136    for (int i = 0; i < fitSources->n; i++) {
     
    208145        model->params->data.F32[PM_PAR_I0] = norm->data.F32[i];
    209146        model->dparams->data.F32[PM_PAR_I0] = errors->data.F32[i];
    210         // XXX is the value of 'errors' modified by the sky fit?
    211147
    212148        // subtract object
     
    221157        if (source->mode & PM_SOURCE_MODE_NONLINEAR_FIT) continue;
    222158        pmModel *model = pmSourceGetModel (NULL, source);
    223         pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, covarFactor);
     159        pmSourceChisq (model, source->pixels, source->maskObj, source->variance, maskVal, COVAR_FACTOR);
    224160    }
    225161    psLogMsg ("psphot.ensemble", PS_LOG_MINUTIA, "get chisqs: %f sec (%d elements)\n", psTimerMark ("psphot.linear"), sparse->Nelem);
     
    229165    psFree (fitSources);
    230166    psFree (norm);
    231     psFree (skyfit);
    232167    psFree (errors);
    233     psFree (border);
    234168
    235169    psLogMsg ("psphot.ensemble", PS_LOG_INFO, "measure ensemble of PSFs: %f sec\n", psTimerMark ("psphot.linear"));
    236 
    237     psphotVisualShowResidualImage (readout);
    238     psphotVisualPlotChisq (sources);
    239     // psphotVisualShowFlags (sources);
    240 
    241     // We have to place this visualization here because the models are not realized until
    242     // psphotGuessModels or fitted until psphotFitSourcesLinear.
    243     psphotVisualShowPSFStars (recipe, psf, sources);
    244170
    245171    return true;
    246172}
    247173
    248 // XXX do we need this?
    249 // XXX disallow the simultaneous sky fit and remove this code...
     174// sort by X (ascending)
     175int pmPhotObjSortByX (const void **a, const void **b)
     176{
     177    pmPhotObj *objA = *(pmPhotObj **)a;
     178    pmPhotObj *objB = *(pmPhotObj **)b;
    250179
    251 // Calculate the weight terms for the sky fit component of the matrix.  This function operates
    252 // on the pixels which correspond to all of the sources of interest.  These elements fill in
    253 // the border matrix components in the sparse matrix equation.
    254 static bool SetBorderMatrixElements (psSparseBorder *border, pmReadout *readout, psArray *sources, bool constant_weights, int SKY_FIT_ORDER, psImageMaskType markVal) {
     180    psF32 fA = objA->x;
     181    psF32 fB = objB->x;
    255182
    256     // generate the image-wide weight terms
    257     // turn on MARK for all image pixels
    258     psRegion fullArray = psRegionSet (0, 0, 0, 0);
    259     fullArray = psRegionForImage (readout->mask, fullArray);
    260     psImageMaskRegion (readout->mask, fullArray, "OR", markVal);
    261 
    262     // turn off MARK for all object pixels
    263     for (int i = 0; i < sources->n; i++) {
    264         pmSource *source = sources->data[i];
    265         pmModel *model = pmSourceGetModel (NULL, source);
    266         if (model == NULL) continue;
    267         float x = model->params->data.F32[PM_PAR_XPOS];
    268         float y = model->params->data.F32[PM_PAR_YPOS];
    269         psImageMaskCircle (source->maskView, x, y, model->fitRadius, "AND", PS_NOT_IMAGE_MASK(markVal));
    270     }
    271 
    272     // accumulate the image statistics from the masked regions
    273     psF32 **image  = readout->image->data.F32;
    274     psF32 **variance = readout->variance->data.F32;
    275     psImageMaskType  **mask   = readout->mask->data.PS_TYPE_IMAGE_MASK_DATA;
    276 
    277     double w, x, y, x2, xy, y2, xc, yc, wt, f, fo, fx, fy;
    278     w = x = y = x2 = xy = y2 = fo = fx = fy = 0;
    279 
    280     int col0 = readout->image->col0;
    281     int row0 = readout->image->row0;
    282 
    283     for (int j = 0; j < readout->image->numRows; j++) {
    284         for (int i = 0; i < readout->image->numCols; i++) {
    285             if (mask[j][i]) continue;
    286             if (constant_weights) {
    287                 wt = 1.0;
    288             } else {
    289                 wt = variance[j][i];
    290             }
    291             f = image[j][i];
    292             w   += 1/wt;
    293             fo  += f/wt;
    294             if (SKY_FIT_ORDER == 0) continue;
    295 
    296             xc  = i + col0;
    297             yc  = j + row0;
    298             x  +=    xc/wt;
    299             y  +=    yc/wt;
    300             x2 += xc*xc/wt;
    301             xy += xc*yc/wt;
    302             y2 += yc*yc/wt;
    303             fx +=  f*xc/wt;
    304             fy +=  f*yc/wt;
    305         }
    306     }
    307 
    308     // turn off MARK for all image pixels
    309     psImageMaskRegion (readout->mask, fullArray, "AND", PS_NOT_IMAGE_MASK(markVal));
    310 
    311     // set the Border T elements
    312     psSparseBorderElementG (border, 0, fo);
    313     psSparseBorderElementT (border, 0, 0, w);
    314     if (SKY_FIT_ORDER > 0) {
    315         psSparseBorderElementG (border, 0, fx);
    316         psSparseBorderElementG (border, 0, fy);
    317         psSparseBorderElementT (border, 1, 0, x);
    318         psSparseBorderElementT (border, 2, 0, y);
    319         psSparseBorderElementT (border, 0, 1, x);
    320         psSparseBorderElementT (border, 1, 1, x2);
    321         psSparseBorderElementT (border, 2, 1, xy);
    322         psSparseBorderElementT (border, 0, 2, y);
    323         psSparseBorderElementT (border, 1, 2, xy);
    324         psSparseBorderElementT (border, 2, 2, y2);
    325     }
    326 
    327     return true;
     183    psF32 diff = fA - fB;
     184    if (diff > FLT_EPSILON) return (+1);
     185    if (diff < FLT_EPSILON) return (-1);
     186    return (0);
    328187}
  • trunk/psphot/src/psphotGuessModels.c

    r26894 r27657  
    1515    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    1616
     17    // skip the chisq image (optionally?)
     18    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     19    if (!status) chisqNum = -1;
     20
    1721    // loop over the available readouts
    1822    for (int i = 0; i < num; i++) {
     23        if (i == chisqNum) continue; // skip chisq image
    1924        if (!psphotGuessModelsReadout (config, view, "PSPHOT.INPUT", i)) {
    2025            psError (PSPHOT_ERR_CONFIG, false, "failed on to guess models for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotImageLoop.c

    r25755 r27657  
    9191            }
    9292
    93             status = true;
    94             status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL");
    95             status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV");
    96             status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND");
    97             if (!status) {
    98                 psError(PSPHOT_ERR_PROG, false, "trouble dropping internal files");
    99                 psFree (view);
    100                 return false;
    101             }
     93            // drop all versions of the internal files
     94            status = true;
     95            status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL");
     96            status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV");
     97            status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND");
     98            if (!status) {
     99                psError(PSPHOT_ERR_PROG, false, "trouble dropping internal files");
     100                psFree (view);
     101                return false;
     102            }
    102103        }
    103 
    104104        // save output which is saved at the chip level
    105105        if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE ("failed output for Chip in psphot.");
  • trunk/psphot/src/psphotImageQuality.c

    r26894 r27657  
    1616    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    1717
     18    // skip the chisq image (optionally?)
     19    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     20    if (!status) chisqNum = -1;
     21
    1822    // loop over the available readouts
    1923    for (int i = 0; i < num; i++) {
     24        if (i == chisqNum) continue; // skip chisq image
    2025        if (!psphotImageQualityReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
    2126            psError (PSPHOT_ERR_CONFIG, false, "failed on to measure image quality for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotMagnitudes.c

    r27532 r27657  
    1212    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    1313
     14    // skip the chisq image (optionally?)
     15    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     16    if (!status) chisqNum = -1;
     17
    1418    // loop over the available readouts
    1519    for (int i = 0; i < num; i++) {
     20        if (i == chisqNum) continue; // skip chisq image
    1621
    1722        // find the currently selected readout
  • trunk/psphot/src/psphotMergeSources.c

    r27314 r27657  
    7676    pmDetections *extCMF = NULL;
    7777    psArray *extSourcesTXT = NULL;
    78 
    79     // find the currently selected readout
    80     pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", 0); // File of interest
     78    int index = 0;
     79
     80    // find the currently selected readout
     81    pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", index); // File of interest
    8182    psAssert (file, "missing file?");
    8283
     
    118119                psFree (source->modelPSF);
    119120                source->modelPSF = NULL;
     121                source->imageID = index;
    120122
    121123                psArrayAdd (detections->newSources, 100, source);
     
    140142                psFree (source->modelPSF);
    141143                source->modelPSF = NULL;
     144                source->imageID = index;
    142145
    143146                psArrayAdd (detections->newSources, 100, source);
  • trunk/psphot/src/psphotModelBackground.c

    r26894 r27657  
    371371
    372372    psImageBinning *binning = psphotBackgroundBinning(readout->image, config); // Image binning parameters
    373     pmReadout *model = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL", inFPA, binning);
    374     pmReadout *modelStdev = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL.STDEV", inFPA, binning);
     373    pmReadout *model = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL", inFPA, binning, index);
     374    pmReadout *modelStdev = pmFPAGenerateReadout(config, view, "PSPHOT.BACKMDL.STDEV", inFPA, binning, index);
    375375
    376376    if (!psphotModelBackgroundReadout(model->image, modelStdev->image, model->analysis, readout, binning, config)) {
  • trunk/psphot/src/psphotReadout.c

    r27532 r27657  
    3434
    3535    // Generate the mask and weight images, including the user-defined analysis region of interest
    36     psphotSetMaskAndVariance (config, view);
     36    if (!psphotSetMaskAndVariance (config, view)) {
     37        return psphotReadoutCleanup(config, view);
     38    }
    3739    if (!strcasecmp (breakPt, "NOTHING")) {
    3840        return psphotReadoutCleanup(config, view);
  • trunk/psphot/src/psphotReadoutCleanup.c

    r26894 r27657  
    5353    pmPSF        *psf        = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.PSF");
    5454    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    55     psArray      *sources    = detections->allSources;
     55    psArray      *sources    = detections ? detections->allSources : NULL;
    5656    // XXX where do we free these, in here (psMetadataRemove?)
    5757
     
    7373    // Check to see if the image quality was measured
    7474    // XXX not sure we want / need this test
    75     if (!psf) {
     75    if (0 && !psf) {
    7676        bool mdok;                      // Status of MD lookup
    7777        int nIQ = psMetadataLookupS32(&mdok, recipe, "IQ_NSTAR"); // Number of stars for IQ measurement
  • trunk/psphot/src/psphotRoughClass.c

    r26894 r27657  
    1919    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    2020
     21    // skip the chisq image (optionally?)
     22    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     23    if (!status) chisqNum = -1;
     24
    2125    // loop over the available readouts
    2226    for (int i = 0; i < num; i++) {
     27        if (i == chisqNum) continue; // skip chisq image
    2328        if (!psphotRoughClassReadout (config, view, "PSPHOT.INPUT", i, recipe)) {
    2429            psError (PSPHOT_ERR_CONFIG, false, "failed on rough classification for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotSkyReplace.c

    r26894 r27657  
    88    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    99
     10    // skip the chisq image (optionally?)
     11    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     12    if (!status) chisqNum = -1;
     13
    1014    // loop over the available readouts
    1115    for (int i = 0; i < num; i++) {
     16        if (i == chisqNum) continue; // skip chisq image
    1217        if (!psphotSkyReplaceReadout (config, view, "PSPHOT.INPUT", i)) {
    1318            psError (PSPHOT_ERR_CONFIG, false, "failed to replace sky for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotSourceMatch.c

    r27547 r27657  
    1 # include "psphotInternal.h"
    2                                                                                                                                                                                
    3 // we need a couple of functions to distinguish coincident sources:                                                                                                             
    4 // XXX these are similar (identical?) to the goals of pmSourceMatch.c                                                                                                           
    5                                                                                                                                                                                  
    6 # define NEXT1 { i++; continue; }                                                                                                                                               
    7 # define NEXT2 { j++; continue; }                                                                                                                                               
    8                                                                                                                                                                                  
    9 psphotSourceMerge () {                                                                                                                                                           
    10                                                                                                                                                                                  
    11     float dx, dy;                                                                                                                                                               
    12                                                                                                                                                                                  
    13     // sort the source list by X                                                                                                                                                 
    14     pmSourceSortByX (sources1);                                                                                                                                                 
    15     pmSourceSortByX (sources2);                                                                                                                                                 
    16                                                                                                                                                                                  
    17     int i, j;                                                                                                                                                                   
    18     for (i = j = 0; (i < sources1->n) && (j < sources2->n); ) {                                                                                                                 
    19                                                                                                                                                                                  
    20         pmSource *src1 = sources1->data[i];                                                                                                                                     
    21         pmSource *src2 = sources2->data[j];                                                                                                                                     
    22                                                                                                                                                                                  
    23         if (!src1) NEXT1;                                                                                                                                                       
    24         if (!src1->peak) NEXT1;                                                                                                                                                 
    25         if (!finite(src1->peak->xf)) NEXT1;                                                                                                                                     
    26         if (!finite(src1->peak->yf)) NEXT1;                                                                                                                                     
    27                                                                                                                                                                                  
    28         if (!src2) NEXT2;                                                                                                                                                       
    29         if (!src2->peak) NEXT2;                                                                                                                                                 
    30         if (!finite(src2->peak->xf)) NEXT2;                                                                                                                                     
    31         if (!finite(src2->peak->yf)) NEXT2;                                                                                                                                     
    32                                                                                                                                                                                  
    33         dx = src1->peak->xf - src2->peak->xf;                                                                                                                                   
    34         if (dx < -1.02*RADIUS) NEXT1;                                                                                                                                           
    35         if (dx > +1.02*RADIUS) NEXT2;                                                                                                                                           
    36                                                                                                                                                                                  
    37         // we are within match range, look for matches:                                                                                                                         
    38         for (int J = j; (dx > -1.02*radius) && (J < sources2->n); J++) {                                                                                                         
    39                                                                                                                                                                                  
    40             dx = src1->peak->xf - src2->peak->xf;                                                                                                                               
    41             dy = src1->peak->yf - src2->peak->yf;                                                                                                                               
    42                                                                                                                                                                                  
    43             dr = dx*dx + dy*dy;                                                                                                                                                 
    44             if (dr > RADIUS2) continue;                                                                                                                                         
    45                                                                                                                                                                                  
    46             // add to group?                                                                                                                                                     
    47         }                                                                                                                                                                       
    48         i++;                                                                                                                                                                     
    49     }                                                                                                                                                                           
    50 }     
     1# include "psphotInternal.h"
     2
     3bool psphotMatchSourcesGenerate (pmConfig *config, const pmFPAview *view, psArray *objects);
     4 
     5psArray *psphotMatchSources (pmConfig *config, const pmFPAview *view)
     6{
     7    bool status = true;
     8
     9    psArray *objects = psArrayAllocEmpty(100);
     10
     11    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
     12    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
     13
     14    // loop over the available readouts
     15    for (int i = 0; i < num; i++) {
     16        if (!psphotMatchSourcesReadout (objects, config, view, "PSPHOT.INPUT", i)) {
     17            psError (PSPHOT_ERR_CONFIG, false, "failed to merge sources for PSPHOT.INPUT entry %d", i);
     18            psFree (objects);
     19            return NULL;
     20        }
     21    }
     22
     23    psphotMatchSourcesGenerate (config, view, objects);
     24
     25    return objects;
     26}
     27
     28bool psphotMatchSourcesReadout (psArray *objects, pmConfig *config, const pmFPAview *view, char *filename, int index) {
     29 
     30    bool status = false;
     31
     32    // select the appropriate recipe information
     33    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     34    psAssert (recipe, "missing recipe?");
     35
     36    int RADIUS = psMetadataLookupF32 (&status, recipe, "PSPHOT.STACK.MATCH.RADIUS");
     37    psAssert (status, "programming error: must define PSPHOT.STACK.MATCH.RADIUS");
     38
     39    // find the currently selected readout
     40    pmFPAfile *file = pmFPAfileSelectSingle(config->files, filename, index); // File of interest
     41    psAssert (file, "missing file?");
     42
     43    pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     44    psAssert (readout, "missing readout?");
     45
     46    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     47    psAssert (detections, "missing detections?");
     48    psAssert (detections->newSources, "new sources not defined?");
     49    psAssert (!detections->allSources, "all sources already defined?");
     50
     51    // XXX TEST:
     52    if (detections->newSources) {
     53        psphotMatchSourcesToObjects(objects, detections->newSources, RADIUS);
     54    }
     55
     56    return true;
     57}
     58
     59# define NEXT1 { i++; continue; }
     60# define NEXT2 { j++; continue; }
     61bool psphotMatchSourcesToObjects (psArray *objects, psArray *sources, float RADIUS) {
     62 
     63    float dx, dy;
     64 
     65    float RADIUS2 = RADIUS*RADIUS;
     66
     67    // sort the source list by X
     68    sources = psArraySort (sources, pmSourceSortByX);
     69    objects = psArraySort (objects, pmPhotObjSortByX);
     70 
     71    psVector *found = psVectorAlloc(sources->n, PS_TYPE_U8);
     72    psVectorInit (found, 0);
     73
     74    // match sources to existing objects
     75
     76    psLogMsg ("psphot", PS_LOG_DETAIL, "attempt to match sources (%ld vs %ld)", sources->n, objects->n);
     77
     78    int i, j;
     79    for (i = j = 0; (i < sources->n) && (j < objects->n); ) {
     80 
     81        pmSource  *src = sources->data[i];
     82        pmPhotObj *obj = objects->data[j];
     83 
     84        if (!src) NEXT1;
     85        if (!src->peak) NEXT1;
     86        if (!finite(src->peak->xf)) NEXT1;
     87        if (!finite(src->peak->yf)) NEXT1;
     88 
     89        if (!obj) NEXT2;
     90        if (!finite(obj->x)) NEXT2;
     91        if (!finite(obj->y)) NEXT2;
     92 
     93        dx = src->peak->xf - obj->x;
     94        if (dx < -1.02*RADIUS) NEXT1;
     95        if (dx > +1.02*RADIUS) NEXT2;
     96 
     97        // we are within match range, look for matches:
     98        int Jmin = -1;
     99        float Rmin = RADIUS2;
     100        for (int J = j; (dx > -1.02*RADIUS) && (J < objects->n); J++) {
     101 
     102            obj = objects->data[J];
     103           
     104            dx = src->peak->xf - obj->x;
     105            dy = src->peak->yf - obj->y;
     106 
     107            float dr = dx*dx + dy*dy;
     108            if (dr > RADIUS2) continue;
     109            if (dr < Rmin) {
     110                Rmin = dr;
     111                Jmin  = J;
     112            }
     113        }
     114
     115        // no match, try next source
     116        if (Jmin == -1) {
     117            i++;
     118            continue;
     119        }
     120        obj = objects->data[Jmin];
     121
     122        // add to object
     123        pmPhotObjAddSource (obj, src);
     124        found->data.U8[i] = 1;
     125        i++;
     126    }
     127
     128    // add missed sources to new objects
     129
     130    for (i = 0; i < sources->n; i++) {
     131
     132        if (found->data.U8[i]) continue;
     133
     134        pmSource *src = sources->data[i];
     135
     136        pmPhotObj *obj = pmPhotObjAlloc();
     137        pmPhotObjAddSource(obj, src);
     138        psArrayAdd (objects, 100, obj);
     139        psFree (obj);
     140    }
     141    psLogMsg ("psphot", PS_LOG_DETAIL, "matched sources (%ld vs %ld)", sources->n, objects->n);
     142
     143    psFree (found);
     144    return true;
     145}
     146
     147bool psphotMatchSourcesGenerate (pmConfig *config, const pmFPAview *view, psArray *objects) {
     148
     149    bool status = false;
     150
     151    // select the appropriate recipe information
     152    psMetadata *recipe  = psMetadataLookupPtr (&status, config->recipes, PSPHOT_RECIPE);
     153    psAssert (recipe, "missing recipe?");
     154
     155    // determine properties (sky, moments) of initial sources
     156    float OUTER = psMetadataLookupF32 (&status, recipe, "SKY_OUTER_RADIUS");
     157    psAssert (status, "missing SKY_OUTER_RADIUS in recipe?");
     158
     159    int nImages = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
     160    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
     161
     162    // generate look-up arrays for detections and readouts
     163    psArray *detArrays = psArrayAlloc(nImages);
     164    psArray *readouts = psArrayAlloc(nImages);
     165
     166    for (int i = 0; i < nImages; i++) {
     167
     168        // find the currently selected readout
     169        pmFPAfile *file = pmFPAfileSelectSingle(config->files, "PSPHOT.INPUT", i); // File of interest
     170        psAssert (file, "missing file?");
     171
     172        pmReadout *readout = pmFPAviewThisReadout(view, file->fpa);
     173        psAssert (readout, "missing readout?");
     174
     175        pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
     176        psAssert (detections, "missing detections?");
     177
     178        detArrays->data[i] = psMemIncrRefCounter(detections);
     179        readouts->data[i] = psMemIncrRefCounter(readout);
     180    }
     181
     182    // vector to track if source for an image is found
     183    psVector *found = psVectorAlloc(nImages, PS_TYPE_U8);
     184
     185    for (int i = 0; i < objects->n; i++) {
     186        pmPhotObj *obj = objects->data[i];
     187
     188        // mark the images for which sources have been found
     189        psVectorInit (found, 0);
     190        for (int j = 0; j < obj->sources->n; j++) {
     191
     192            pmSource *src = obj->sources->data[j];
     193            int index = src->imageID;
     194            psAssert (index >= 0, "invalid index");
     195            psAssert (index < found->n, "invalid index");
     196
     197            found->data.U8[index] = 1;
     198        }
     199
     200        // generate new sources for the image that are missing
     201        for (int index = 0; index < found->n; index++) {
     202            if (found->data.U8[index]) continue;
     203
     204            pmDetections *detections = detArrays->data[index];
     205            pmReadout *readout = readouts->data[index];
     206            int row0 = readout->image->row0;
     207            int col0 = readout->image->col0;
     208
     209            // XXX the peak type is not really used in psphot
     210            // PM_PEAK_LONE is certainly not true, but irrelevant
     211            float peakFlux = readout->image->data.F32[(int)(obj->y-row0-0.5)][(int)(obj->x-col0-0.5)];
     212            pmPeak *peak = pmPeakAlloc(obj->x, obj->y, peakFlux, PM_PEAK_LONE);
     213            peak->flux = peakFlux;
     214            peak->SN = 1.0;
     215            peak->xf = obj->x;
     216            peak->yf = obj->y;
     217            peak->dx = NAN;
     218            peak->dy = NAN;
     219           
     220            // XXX assign to a footprint?
     221
     222            // create a new source
     223            pmSource *source = pmSourceAlloc();
     224            source->imageID = index;
     225
     226            // add the peak
     227            source->peak = psMemIncrRefCounter(peak);
     228
     229            // allocate space for moments
     230            source->moments = pmMomentsAlloc();
     231
     232            // allocate image, weight, mask arrays for each peak (square of radius OUTER)
     233            pmSourceDefinePixels (source, readout, source->peak->x, source->peak->y, OUTER);
     234
     235            peak->assigned = true;
     236            pmPhotObjAddSource(obj, source);
     237            psArrayAdd (detections->newSources, 100, source);
     238            psFree (source);
     239            psFree (peak);
     240        }
     241    }
     242
     243    // how many sources do we have now?
     244    int nSources = 0;
     245    for (int i = 0; i < objects->n; i++) {
     246        pmPhotObj *obj = objects->data[i];
     247        nSources += obj->sources->n;
     248    }
     249    psLogMsg ("psphot", PS_LOG_DETAIL, "total of %d sources for %d images", nSources, nImages);
     250
     251
     252    psFree (found);
     253    psFree (detArrays);
     254    psFree (readouts);
     255    return true;
     256}
  • trunk/psphot/src/psphotSourceSize.c

    r27532 r27657  
    4444    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
    4545
     46    // skip the chisq image (optionally?)
     47    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     48    if (!status) chisqNum = -1;
     49
    4650    // loop over the available readouts
    4751    for (int i = 0; i < num; i++) {
     52        if (i == chisqNum) continue; // skip chisq image
    4853        if (!psphotSourceSizeReadout (config, view, "PSPHOT.INPUT", i, recipe, getPSFsize)) {
    4954            psError (PSPHOT_ERR_CONFIG, false, "failed on source size analysis for PSPHOT.INPUT entry %d", i);
  • trunk/psphot/src/psphotSourceStats.c

    r27571 r27657  
    22
    33// convert detections to sources and measure their basic properties (moments, local sky, sky
    4 // variance) Note: this function only generates sources for the new peaks (peak->assigned)
     4// variance) Note: this function only generates sources for the new peaks (peak->assigned).
     5// The new sources are added to any existing sources on detections->newSources.  The sources
     6// on detections->allSources are ignored.
    57bool psphotSourceStats (pmConfig *config, const pmFPAview *view, bool setWindow)
    68{
     
    4042    pmDetections *detections = psMetadataLookupPtr (&status, readout->analysis, "PSPHOT.DETECTIONS");
    4143    psAssert (detections, "missing detections?");
    42     psAssert (!detections->newSources, "new sources already defined?");
    4344
    4445    // XXX TEST:
     
    8485
    8586    // generate the array of sources, define the associated pixel
    86     sources = psArrayAllocEmpty (peaks->n);
     87    if (!detections->newSources) {
     88        detections->newSources = psArrayAllocEmpty (peaks->n);
     89    }
     90    sources = detections->newSources;
    8791
    8892    // if there are no peaks, we save the empty source array and return
    8993    if (!peaks->n) {
    90         // save the new sources on the detection structure:
    91         detections->newSources = sources;
    9294        return true;
    9395    }
     
    100102        // create a new source
    101103        pmSource *source = pmSourceAlloc();
     104        source->imageID = index;
    102105
    103106        // add the peak
     
    119122        psLogMsg ("psphot", PS_LOG_INFO, "break point PEAKS, skipping MOMENTS\n");
    120123        psphotVisualShowMoments (sources);
    121         detections->newSources = sources;
    122124        return true;
    123125    }
     
    126128        if (!psphotSetMomentsWindow(recipe, readout->analysis, sources)) {
    127129            psError(PS_ERR_UNEXPECTED_NULL, false, "Failed to determine Moments Window!");
    128             psFree(sources);
     130            psFree(detections->newSources);
    129131            return false;
    130132        }
     
    178180                psError(PS_ERR_UNKNOWN, false, "Unable to launch thread job PSPHOT_SOURCE_STATS");
    179181                psFree (job);
    180                 psFree(sources);
     182                psFree(detections->newSources);
    181183                return false;
    182184            }
     
    187189        if (!psThreadPoolWait (false)) {
    188190            psError(PS_ERR_UNKNOWN, false, "Failure in thread job PSPHOT_SOURCE_STATS");
    189             psFree(sources);
     191            psFree(detections->newSources);
    190192            return false;
    191193        }
     
    215217    psphotVisualShowMoments (sources);
    216218
    217     // save the new sources on the detection structure:
    218     detections->newSources = sources;
    219 
    220 
    221219    if (detections->allSources) {
    222220        psphotMaskCosmicRayFootprintCheck(detections->allSources);
     
    377375        pmSource *source = sources->data[i];
    378376
     377        if (source->tmpFlags & PM_SOURCE_TMPF_MOMENTS_MEASURED) continue;
     378        source->tmpFlags |= PM_SOURCE_TMPF_MOMENTS_MEASURED;
     379
    379380        // skip faint sources for moments measurement
    380381        if (source->peak->SN < MIN_SN) {
  • trunk/psphot/src/psphotStackArguments.c

    r26894 r27657  
    22
    33static void usage(pmConfig *config, int exitCode);
    4 static void writeHelpInfo(pmConfig* config, FILE* ofile);
     4static void writeHelpInfo(FILE* ofile);
    55
    66pmConfig *psphotStackArguments(int argc, char **argv) {
    77
    88    int N;
    9     bool status;
    109
    1110    // print help info
    12     if (psArgumentGet(argc, argv, "-help")) writeHelpInfo(argv[0], config, stdout);
    13     if (psArgumentGet(argc, argv, "-h")) writeHelpInfo(argv[0], config, stdout);
     11    if (psArgumentGet(argc, argv, "-help")) writeHelpInfo(stdout);
     12    if (psArgumentGet(argc, argv, "-h")) writeHelpInfo(stdout);
    1413
    1514    // load config data from default locations
     
    2928    // Number of threads is handled
    3029    PSARGUMENTS_INSTANTIATE_THREADSARG( psphot, config, argc, argv )
    31 
    32     // photcode : used in output to supplement header data (argument or recipe?)
    33     if ((N = psArgumentGet (argc, argv, "-photcode"))) {
    34         if (argc <= N+1) {
    35           psErrorStackPrint(stderr, "Expected to see 1 more argument; saw %d", argc - 1);
    36           exit(PS_EXIT_CONFIG_ERROR);
    37         }
    38         psArgumentRemove (N, &argc, argv);
    39         psMetadataAddStr (options, PS_LIST_TAIL, "PHOTCODE", PS_META_REPLACE, "", argv[N]);
    40         psArgumentRemove (N, &argc, argv);
    41     }
    4230
    4331    // visual : interactive display mode
     
    9078}
    9179
    92 static void writeHelpInfo(pmConfig* config, FILE* ofile)
     80static void writeHelpInfo(FILE* ofile)
    9381{
    9482  fprintf(ofile,
    95           "Usage: psphotStack -input (input.mdc) outroot\n"
     83          "Usage: psphotStack -input (INPUTS.mdc) (OUTROOT)\n"
    9684          "\n"
    97           "where:\n"
    98           "  FileNameList is a text file containing filenames, one per line\n"
    99           "  MaskFileNameList is a text file of mask filenames, one per line\n"
    100           "  VarFileNameList is a text file of variance filenames, one per line\n"
    101           "  OutFileBaseName is the 'root name' for output files\n"
     85          "where INPUTS.mdc contains various METADATAs, each with:\n"
     86          "\tIMAGE(STR):     Image filename\n"
     87          "\tMASK(STR):      Mask filename\n"
     88          "\tVARIANCE(STR):  Variance map filename\n"
     89          "OUTROOT is the 'root name' for output files\n"
    10290          "\n"
    10391          "additional options:\n"
     
    136124          "  -trace-levels\n"
    137125          "     print current trace levels\n");
    138     psFree(config);
    139     pmConfigDone();
    140126    psLibFinalize();
    141127    exit(PS_EXIT_SUCCESS);
  • trunk/psphot/src/psphotStackChisqImage.c

    r27547 r27657  
    1212    psTimerStart ("psphot.chisq.image");
    1313
    14     // create a holder for the image
    15     pmReadout *chiImage = pmReadoutAlloc();
     14    pmFPAfile *chisqFile = pmFPAfileSelectSingle(config->files, "PSPHOT.CHISQ.IMAGE", 0);
     15    psAssert (chisqFile, "missing chisq image FPA?");
     16
     17    pmReadout *chiReadout = NULL;
    1618
    1719    int num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
     
    2022    // loop over the available readouts
    2123    for (int i = 0; i < num; i++) {
    22         if (!psphotStackChisqImageAddReadout(config, view, chiImage, "PSPHOT.INPUT", i)) {
     24        if (!psphotStackChisqImageAddReadout(config, view, &chiReadout, "PSPHOT.INPUT", i)) {
    2325            psError (PSPHOT_ERR_CONFIG, false, "failed to model background for PSPHOT.INPUT entry %d", i);
    2426            return false;
     
    2628    }
    2729
     30    num = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
     31    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
     32
     33    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "PSPHOT.CHISQ.NUM", PS_META_REPLACE, "", num);
     34    num++;
     35    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "", num);
     36
    2837    // need to save the resulting image somewhere (PSPHOT.INPUT?)
     38    if (!psMetadataAddPtr(config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "", chisqFile)) {
     39        psError(PM_ERR_CONFIG, false, "could not add chisqFPA to config files");
     40        return false;
     41    }
    2942
    3043    psLogMsg ("psphot", PS_LOG_INFO, "built chisq image: %f sec\n", psTimerMark ("psphot.chisq.image"));
     
    3447
    3548bool psphotStackChisqImageAddReadout(const pmConfig *config, // Configuration
    36                                      pmFPAview *view,
    37                                      pmReadout *chiReadout,
     49                                     const pmFPAview *view,
     50                                     pmReadout **chiReadout,
    3851                                     char *filename,
    3952                                     int index)
     
    4962
    5063    psImage *inImage     = inReadout->image;
     64    psAssert (inImage, "missing image?");
     65
    5166    psImage *inVariance  = inReadout->variance;
     67    psAssert (inVariance, "missing variance?");
     68
    5269    psImage *inMask      = inReadout->mask;
     70    psAssert (inMask, "missing mask?");
    5371
    54     psImage *chiImage    = chiReadout->image;
    55     psImage *chiVariance = chiReadout->variance;
    56     psImage *chiMask     = chiReadout->mask;
     72    if (*chiReadout == NULL) {
     73        *chiReadout = pmFPAGenerateReadout(config, view, "PSPHOT.CHISQ.IMAGE", input->fpa, NULL, 0);
     74    }
     75
     76    psImage *chiImage = (*chiReadout)->image;
     77    psAssert (chiImage, "missing chi image");
     78
     79    psImage *chiVariance = (*chiReadout)->variance;
     80    psAssert (chiVariance, "missing chi variance");
     81
     82    psImage *chiMask = (*chiReadout)->mask;
     83    psAssert (chiMask, "missing chi mask");
    5784
    5885    // select the appropriate recipe information
     
    83110    return true;
    84111}
     112
     113bool psphotStackRemoveChisqFromInputs (pmConfig *config) {
     114
     115    bool status = false;
     116
     117    int chisqNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.CHISQ.NUM");
     118    psAssert (status, "programming error: must define PSPHOT.CHISQ.NUM");
     119
     120    int inputNum = psMetadataLookupS32 (&status, config->arguments, "PSPHOT.INPUT.NUM");
     121    psAssert (status, "programming error: must define PSPHOT.INPUT.NUM");
     122
     123    pmFPAfileRemoveSingle (config->files, "PSPHOT.INPUT", chisqNum);
     124
     125    inputNum --;
     126    psMetadataAddS32(config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "", inputNum);
     127
     128    return true;
     129}
     130
     131bool pmFPAfileRemoveSingle(psMetadata *files, const char *name, int num)
     132{
     133    PS_ASSERT_PTR_NON_NULL(files, NULL);
     134    PS_ASSERT_INT_NONNEGATIVE(num, NULL);
     135
     136    psList* mdList = files->list;
     137    psHash* mdHash = files->hash;
     138
     139    // Generate a REGEX to select only items that match 'name'
     140    psString regex = NULL;              // Regular expression
     141    if (name) {
     142        if (!psMetadataLookup(files, name)) {
     143            // No files match the requested name
     144            return false;
     145        }
     146        psStringAppend(&regex, "^%s$", name);
     147    }
     148
     149    psMetadataIterator *iter = psMetadataIteratorAlloc(files, PS_LIST_HEAD, regex); // Iterator
     150    psFree(regex);
     151    psMetadataItem *item;               // Item from iteration
     152
     153    bool found = false;
     154    int i = 0;                          // Counter
     155    for (i = 0; !found && (item = psMetadataGetAndIncrement(iter)); i++) {
     156        if (i == num) found = true;
     157    }
     158    psFree(iter);
     159    if (!found) {
     160        return false;
     161    }
     162
     163    char *key = item->name;
     164
     165    // look up the name via hash to see if we have a multi or not
     166    psMetadataItem* hashItem = psHashLookup(mdHash, name);
     167    if (hashItem == NULL) {
     168        psError(PS_ERR_UNKNOWN, false, _("Failed to remove metadata item, %s, from metadata table."), key);
     169        return false;
     170    }
     171
     172    if (hashItem->type == PS_DATA_METADATA_MULTI) {
     173        // multiple entries with same key, remove just the specified one
     174        psListRemoveData(hashItem->data.list, item);
     175    } else {
     176        psHashRemove(mdHash, key);
     177    }
     178    psListRemoveData(mdList, item);
     179
     180    return true;
     181}
  • trunk/psphot/src/psphotStackImageLoop.c

    r27547 r27657  
    77}
    88
    9 bool psphotImageLoop (pmConfig *config) {
     9bool psphotStackImageLoop (pmConfig *config) {
    1010
    1111    bool status;
     
    1414    pmReadout *readout;
    1515
     16    pmFPAfile *input = psMetadataLookupPtr (&status, config->files, "PSPHOT.INPUT");
     17    if (!status) {
     18        psError(PSPHOT_ERR_PROG, false, "Can't find input data!");
     19        return false;
     20    }
     21
    1622    pmFPAview *view = pmFPAviewAlloc (0);
    1723
     
    1925    if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE ("failed input for fpa in psphot.");
    2026
    21     // XXX for now, we assume there is only a single chip in the PHU:
    22     psphotStackReadout (config, view);
     27    // for psphot, we force data to be read at the chip level
     28    while ((chip = pmFPAviewNextChip (view, input->fpa, 1)) != NULL) {
     29        psLogMsg ("psphot", 4, "Chip %d: %x %x\n", view->chip, chip->file_exists, chip->process);
     30        if (! chip->process || ! chip->file_exists) { continue; }
     31        if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE ("failed input for Chip in psphotStack.");
     32
     33        // there is now only a single chip (multiple readouts?). loop over it and process
     34        while ((cell = pmFPAviewNextCell (view, input->fpa, 1)) != NULL) {
     35            psLogMsg ("psphot", 5, "Cell %d: %x %x\n", view->cell, cell->file_exists, cell->process);
     36            if (!pmFPAfileIOChecks (config, view, PM_FPA_BEFORE)) ESCAPE ("failed input for Cell in psphotStack.");
     37
     38            // process each of the readouts
     39            while ((readout = pmFPAviewNextReadout (view, input->fpa, 1)) != NULL) {
     40                psLogMsg ("psphot", 6, "Readout %d: %x %x\n", view->readout, cell->file_exists, cell->process);
     41                if (! readout->data_exists) { continue; }
     42
     43                // XXX for now, we assume there is only a single chip in the PHU:
     44                if (!psphotStackReadout (config, view)) {
     45                    psError(psErrorCodeLast(), false, "failure in psphotReadout for chip %d, cell %d, readout %d\n", view->chip, view->cell, view->readout);
     46                    psFree (view);
     47                    return false;
     48                }
     49
     50            }
     51            // drop all versions of the internal files
     52            status = true;
     53            status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL");
     54            status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV");
     55            status &= pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND");
     56            if (!status) {
     57                psError(PSPHOT_ERR_PROG, false, "trouble dropping internal files");
     58                psFree (view);
     59                return false;
     60            }
     61        }
     62        // save output which is saved at the chip level
     63        if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE ("failed output for Chip in psphot.");
     64    }
     65    // save output which is saved at the fpa level
     66    if (!pmFPAfileIOChecks (config, view, PM_FPA_AFTER)) ESCAPE ("failed ouput for FPA in psphot.");
    2367
    2468    // fail if we failed to handle an error
     
    3276   the easiest way to implement this is to assume we can pre-load the full set of images up front.
    3377   with 5 filters and 6000^2 (image, mask, var = 10 byte per pixel), we need 1.8GB, which is not too bad.
    34  */
     78*/
    3579
  • trunk/psphot/src/psphotStackParseCamera.c

    r26894 r27657  
    1515    }
    1616
    17     psMetadata *item == NULL;
    18     int nInputs = 0;
    19     while ((item = psMetadataGetIndex(inputs, nInputs)) != NULL) {
     17    int nInputs = inputs->list->n;
     18    for (int i = 0; i < nInputs; i++) {
     19        psMetadataItem *item = psMetadataGet(inputs, i);
    2020        if (item->type != PS_DATA_METADATA) {
    2121            psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Component %s of the input metadata is not of type METADATA", item->name);
     
    4040        psString mask = psMetadataLookupStr(&status, input, "MASK"); // Name of mask
    4141        if (mask && strlen(mask) > 0) {
    42             if (!defineFile(config, imageFile, "PSPHOT.INPUT.MASK", mask, PM_FPA_FILE_MASK)) {
     42            if (!defineFile(config, imageFile, "PSPHOT.MASK", mask, PM_FPA_FILE_MASK)) {
    4343                psError(PS_ERR_UNKNOWN, false, "Unable to define file from mask %d (%s)", i, mask);
    4444                return false;
     
    4646        }
    4747
    48         psString variance = psMetadataLookupStr(&mdok, input, "VARIANCE"); // Name of variance map
     48        psString variance = psMetadataLookupStr(&status, input, "VARIANCE"); // Name of variance map
    4949        if (variance && strlen(variance) > 0) {
    50             if (!defineFile(config, imageFile, "PSPHOT.INPUT.VARIANCE", variance, PM_FPA_FILE_VARIANCE)) {
     50            if (!defineFile(config, imageFile, "PSPHOT.VARIANCE", variance, PM_FPA_FILE_VARIANCE)) {
    5151                psError(PS_ERR_UNKNOWN, false, "Unable to define file from variance %d (%s)", i, variance);
    5252                return false;
    5353            }
    5454        }
    55         nInputs ++;
     55        // the output sources are carried on the input->fpa structures
     56        pmFPAfile *outsources = pmFPAfileDefineOutputFromFile (config, imageFile, "PSPHOT.STACK.OUTPUT");
     57        if (!outsources) {
     58            psError(PSPHOT_ERR_CONFIG, false, "Cannot find a rule for PSPHOT.STACK.OUTPUT");
     59            return false;
     60        }
     61        outsources->save = true;
     62        outsources->fileID = i;         // this is used to generate output names
    5663    }
    5764    psMetadataRemoveKey(config->arguments, "FILENAMES");
    5865    psMetadataAddS32 (config->arguments, PS_LIST_TAIL, "PSPHOT.INPUT.NUM", PS_META_REPLACE, "number of inputs", nInputs);
    5966
     67    if (!psphotSetMaskBits (config)) {
     68        psError (PS_ERR_UNKNOWN, false, "failed to set mask bit values");
     69        return NULL;
     70    }
     71
     72    // generate an pmFPAimage for the chisqImage
     73    pmFPAfile *chisqImage = pmFPAfileDefineOutput(config, NULL, "PSPHOT.CHISQ.IMAGE");
     74    if (!chisqImage) {
     75        psError(PSPHOT_ERR_CONFIG, false, "Trouble defining PSPHOT.CHISQ.IMAGE");
     76        return false;
     77    }
     78    chisqImage->save = true;
     79
     80    pmFPAfile *chisqMask = pmFPAfileDefineOutput(config, chisqImage->fpa, "PSPHOT.CHISQ.MASK");
     81    if (!chisqMask) {
     82        psError(PS_ERR_IO, false, _("Unable to generate output file from PSPHOT.CHISQ.MASK"));
     83        return NULL;
     84    }
     85    if (chisqMask->type != PM_FPA_FILE_MASK) {
     86        psError(PS_ERR_IO, true, "PSPHOT.CHISQ.MASK is not of type MASK");
     87        return NULL;
     88    }
     89    chisqMask->save = true;
     90
     91    pmFPAfile *chisqVariance = pmFPAfileDefineOutput(config, chisqImage->fpa, "PSPHOT.CHISQ.VARIANCE");
     92    if (!chisqVariance) {
     93        psError(PS_ERR_IO, false, _("Unable to generate output file from PSPHOT.CHISQ.VARIANCE"));
     94        return NULL;
     95    }
     96    if (chisqVariance->type != PM_FPA_FILE_VARIANCE) {
     97        psError(PS_ERR_IO, true, "PSPHOT.CHISQ.VARIANCE is not of type VARIANCE");
     98        return NULL;
     99    }
     100    chisqVariance->save = true;
     101
     102# if (0)   
    60103    // define the additional input/output files associated with psphot
    61104    // XXX figure out which files are needed by psphotStack
     
    64107        return false;
    65108    }
     109# endif
    66110
    67111    psTrace("psphot", 1, "Done with psphotStackParseCamera...\n");
  • trunk/psphot/src/psphotStackReadout.c

    r26894 r27657  
    1313        return false;
    1414    }
     15    // optional break-point for processing
     16    char *breakPt = psMetadataLookupStr (NULL, recipe, "BREAK_POINT");
     17    PS_ASSERT_PTR_NON_NULL (breakPt, false);
    1518
    16     // set the photcode for this image (XXX currently goes into recipe, should it go into analysis?)
     19    // set the photcode for each image
    1720    if (!psphotAddPhotcode (config, view)) {
    1821        psError (PSPHOT_ERR_CONFIG, false, "trouble defining the photcode");
     
    2023    }
    2124
    22     // generate a background model (median, smoothed image)
    23     if (!psphotSetMaskAndVariance (config, view, recipe)) {
    24         return psphotReadoutCleanup (config, NULL, recipe, NULL, NULL, NULL);
     25    // Generate the mask and weight images
     26    if (!psphotSetMaskAndVariance (config, view)) {
     27        return psphotReadoutCleanup (config, view);
    2528    }
    2629    if (!strcasecmp (breakPt, "NOTHING")) {
    27         return psphotReadoutCleanup(config, NULL, recipe, NULL, NULL, NULL);
     30        return psphotReadoutCleanup (config, view);
    2831    }
    2932
    30     // optional break-point for processing
    31     char *breakPt = psMetadataLookupStr (NULL, recipe, "BREAK_POINT");
    32     PS_ASSERT_PTR_NON_NULL (breakPt, false);
    33 
    3433    // generate a background model (median, smoothed image)
     34    // XXX I think this is not defined correctly for an array of images.
    3535    if (!psphotModelBackground (config, view)) {
    36         return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);
     36        return psphotReadoutCleanup (config, view);
    3737    }
    3838    if (!psphotSubtractBackground (config, view)) {
    39         return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);
     39        return psphotReadoutCleanup (config, view);
    4040    }
    4141    if (!strcasecmp (breakPt, "BACKMDL")) {
    42         return psphotReadoutCleanup (config, readout, recipe, NULL, NULL, NULL);
     42        return psphotReadoutCleanup (config, view);
     43    }
     44
     45    // load the psf model, if suppled.  FWHM_X,FWHM_Y,etc are determined and saved on
     46    // readout->analysis XXX this function currently only works with a single PSPHOT.INPUT
     47    if (!psphotLoadPSF (config, view)) {
     48        psError (PSPHOT_ERR_UNKNOWN, false, "error loading psf model");
     49        return psphotReadoutCleanup (config, view);
     50    }
     51
     52    if (!psphotStackChisqImage(config, view)) {
     53        psError (PSPHOT_ERR_UNKNOWN, false, "failure to generate chisq image");
     54        return psphotReadoutCleanup (config, view);
     55    }
     56    if (!strcasecmp (breakPt, "CHISQ")) {
     57        return psphotReadoutCleanup (config, view);
    4358    }
    4459
    4560    // find the detections (by peak and/or footprint) in the image.
    46     pmDetections *detections = psphotFindDetections (NULL, readout, recipe);
    47     if (!detections) {
    48         psLogMsg ("psphot", 3, "unable to find detections in this image");
    49         return psphotReadoutCleanup (config, readout, recipe, detections, psf, NULL);
     61    // This finds the detections on Chisq image as well as the individuals
     62    if (!psphotFindDetections (config, view, true)) { // pass 1
     63        // this only happens if we had an error in psphotFindDetections
     64        psError (PSPHOT_ERR_UNKNOWN, false, "failure in peak analysis");
     65        return psphotReadoutCleanup (config, view);
    5066    }
    5167
    52     // construct sources and measure basic stats
    53     psArray *sources = psphotSourceStats (config, readout, detections, true);
    54     if (!sources) return false;
    55     if (!strcasecmp (breakPt, "PEAKS")) {
    56         return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
     68    // construct sources and measure basic stats (saved on detections->newSources)
     69    // only run this on detections from the input images, not chisq image
     70    if (!psphotSourceStats (config, view, true)) { // pass 1
     71        psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources");
     72        return psphotReadoutCleanup (config, view);
    5773    }
    5874
    59     // find blended neighbors of very saturated stars
    60     // XXX merge this with Basic Deblend?
    61     psphotDeblendSatstars (readout, sources, recipe);
     75    // *** generate the objects (which unify the sources from the different images)
     76    psArray *objects = psphotMatchSources (config, view);
    6277
    63     // mark blended peaks PS_SOURCE_BLEND
    64     if (!psphotBasicDeblend (sources, recipe)) {
    65         psLogMsg ("psphot", 3, "failed on deblend analysis");
    66         return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
     78    // construct sources for the newly-generated sources (from other images)
     79    if (!psphotSourceStats (config, view, false)) { // pass 1
     80        psError(PSPHOT_ERR_UNKNOWN, false, "failure to generate sources");
     81        return psphotReadoutCleanup (config, view);
    6782    }
    6883
     84    // find blended neighbors of very saturated stars (detections->newSources)
     85    // if (!psphotDeblendSatstars (config, view)) {
     86    //     psError (PSPHOT_ERR_UNKNOWN, false, "failed on satstar deblend analysis");
     87    //     return psphotReadoutCleanup (config, view);
     88    // }
     89
     90    // mark blended peaks PS_SOURCE_BLEND (detections->newSources)
     91    // if (!psphotBasicDeblend (config, view)) {
     92    //     psError (PSPHOT_ERR_UNKNOWN, false, "failed on deblend analysis");
     93    //     return psphotReadoutCleanup (config, view);
     94    // }
     95
    6996    // classify sources based on moments, brightness
    70     if (!psphotRoughClass (readout, sources, recipe, havePSF)) {
    71         psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
    72         return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
     97    // only run this on detections from the input images, not chisq image
     98    if (!psphotRoughClass (config, view)) {
     99        psError (PSPHOT_ERR_UNKNOWN, false, "failed to determine rough classifications");
     100        return psphotReadoutCleanup (config, view);
     101    }
     102    // if we were not supplied a PSF model, determine the IQ stats here (detections->newSources)
     103    // only run this on detections from the input images, not chisq image
     104    if (!psphotImageQuality (config, view)) { // pass 1
     105        psError (PSPHOT_ERR_UNKNOWN, false, "failed to measure image quality");
     106        return psphotReadoutCleanup(config, view);
    73107    }
    74108    if (!strcasecmp (breakPt, "MOMENTS")) {
    75         return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
     109        return psphotReadoutCleanup (config, view);
    76110    }
    77111
    78     if (!havePSF && !psphotImageQuality (recipe, sources)) {
    79         psLogMsg("psphot", 3, "failed to measure image quality");
    80         return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
     112    // use bright stellar objects to measure PSF if we were supplied a PSF for any input file,
     113    // this step is skipped
     114    if (!psphotChoosePSF (config, view)) { // pass 1
     115        psLogMsg ("psphot", 3, "failure to construct a psf model");
     116        return psphotReadoutCleanup (config, view);
     117    }
     118    if (!strcasecmp (breakPt, "PSFMODEL")) {
     119        return psphotReadoutCleanup (config, view);
    81120    }
    82121
    83     // if we were not supplied a PSF, choose one here
    84     if (psf == NULL) {
    85         // use bright stellar objects to measure PSF
    86         // XXX if we do not have enough stars to generate the PSF, build one
    87         // from the SEEING guess and model class
    88         psf = psphotChoosePSF (readout, sources, recipe);
    89         if (psf == NULL) {
    90             psLogMsg ("psphot", 3, "failure to construct a psf model");
    91             return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
    92         }
    93         havePSF = true;
    94     }
    95     if (!strcasecmp (breakPt, "PSFMODEL")) {
    96         return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
    97     }
    98     psphotVisualShowPSFModel (readout, psf);
    99 
    100122    // include externally-supplied sources
    101     psphotLoadExtSources (config, view, sources);
     123    // XXX fix this in the new multi-input context
     124    // psphotLoadExtSources (config, view); // pass 1
    102125
    103126    // construct an initial model for each object, set the radius to fitRadius, set circular fit mask
    104     psphotGuessModels (config, readout, sources, psf);
     127    psphotGuessModels (config, view);
     128
     129    // merge the newly selected sources into the existing list
     130    // NOTE: merge OLD and NEW
     131    psphotMergeSources (config, view);
    105132
    106133    // linear PSF fit to source peaks, subtract the models from the image (in PSF mask)
    107     psphotFitSourcesLinear (readout, sources, recipe, psf, FALSE);
    108 
    109     // We have to place these visualizations here because the models are not realized until
    110     // psphotGuessModels or fitted until psphotFitSourcesLinear.
    111     psphotVisualShowPSFStars (recipe, psf, sources);
     134    psphotFitSourcesLinearStack (config, objects, FALSE);
     135    psFree (objects);
    112136
    113137    // identify CRs and extended sources
    114     psphotSourceSize (config, readout, sources, recipe, psf, 0);
    115     if (!strcasecmp (breakPt, "ENSEMBLE")) {
    116         goto finish;
    117     }
    118     psphotVisualShowSatStars (recipe, psf, sources);
    119 
    120     // non-linear PSF and EXT fit to brighter sources
    121     // replace model flux, adjust mask as needed, fit, subtract the models (full stamp)
    122     psphotBlendFit (config, readout, sources, psf);
    123 
    124     // replace all sources
    125     psphotReplaceAllSources (sources, recipe);
    126 
    127     // linear fit to include all sources (subtract again)
    128     psphotFitSourcesLinear (readout, sources, recipe, psf, TRUE);
    129 
    130     // if we only do one pass, skip to extended source analysis
    131     if (!strcasecmp (breakPt, "PASS1")) {
    132         goto pass1finish;
    133     }
    134     // NOTE: possibly re-measure background model here with objects subtracted
    135 
    136     // add noise for subtracted objects
    137     psphotAddNoise (readout, sources, recipe);
    138 
    139     // find fainter sources (pass 2)
    140     detections = psphotFindDetections (detections, readout, recipe);
    141 
    142     // remove noise for subtracted objects (ie, return to normal noise level)
    143     psphotSubNoise (readout, sources, recipe);
    144 
    145     // define new sources based on only the new peaks
    146     psArray *newSources = psphotSourceStats (config, readout, detections, false);
    147 
    148     // set source type
    149     if (!psphotRoughClass (readout, newSources, recipe, havePSF)) {
    150         psLogMsg ("psphot", 3, "failed to find a valid PSF clump for image");
    151         return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
    152     }
    153 
    154     // create full input models, set the radius to fitRadius, set circular fit mask
    155     psphotGuessModels (config, readout, newSources, psf);
    156 
    157     // replace all sources so fit below applies to all at once
    158     psphotReplaceAllSources (sources, recipe);
    159 
    160     // merge the newly selected sources into the existing list
    161     psphotMergeSources (sources, newSources);
    162     psFree (newSources);
    163 
    164     // linear fit to all sources
    165     psphotFitSourcesLinear (readout, sources, recipe, psf, TRUE);
    166 
    167 pass1finish:
    168 
    169     // measure source size for the remaining sources
    170     psphotSourceSize (config, readout, sources, recipe, psf, 0);
    171 
    172     psphotExtendedSourceAnalysis (readout, sources, recipe);
    173 
    174     psphotExtendedSourceFits (readout, sources, recipe);
    175 
    176 finish:
    177 
    178     // plot positive sources
    179     // psphotSourcePlots (readout, sources, recipe);
     138    psphotSourceSize (config, view, TRUE);
    180139
    181140    // measure aperture photometry corrections
    182     if (!psphotApResid (config, readout, sources, psf)) {
     141    if (!psphotApResid (config, view)) {
    183142        psLogMsg ("psphot", 3, "failed on psphotApResid");
    184         return psphotReadoutCleanup (config, readout, recipe, detections, psf, sources);
     143        return psphotReadoutCleanup (config, view);
    185144    }
    186145
    187146    // calculate source magnitudes
    188     psphotMagnitudes(config, readout, view, sources, psf);
     147    psphotMagnitudes(config, view);
    189148
    190     if (!psphotEfficiency(config, readout, view, psf, recipe, sources)) {
     149    if (!psphotEfficiency(config, view)) {
    191150        psErrorStackPrint(stderr, "Unable to determine detection efficiencies from fake sources");
    192151        psErrorClear();
     
    200159
    201160    // drop the references to the image pixels held by each source
    202     psphotSourceFreePixels (sources);
     161    psphotSourceFreePixels (config, view);
     162
     163    // remove chisq image from config->file:PSPHOT.INPUT (why?)
     164    psphotStackRemoveChisqFromInputs(config);
    203165
    204166    // create the exported-metadata and free local data
    205     return psphotReadoutCleanup(config, readout, recipe, detections, psf, sources);
     167    return psphotReadoutCleanup (config, view);
    206168}
    207169
  • trunk/psphot/src/psphotSubtractBackground.c

    r26894 r27657  
    2323    pmFPAfile *modelFile = pmFPAfileSelectSingle(config->files, "PSPHOT.BACKMDL", index); // File of interest
    2424    assert (modelFile);
    25     pmReadout *model = pmFPAviewThisReadout (view, modelFile->fpa);
     25
     26    pmReadout *model = NULL;
     27    if (modelFile->mode == PM_FPA_MODE_INTERNAL) {
     28        model = modelFile->readout;
     29    } else {
     30        model = pmFPAviewThisReadout (view, modelFile->fpa);
     31    }
    2632    assert (model);
    2733
Note: See TracChangeset for help on using the changeset viewer.