IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 26, 2009, 1:59:32 PM (17 years ago)
Author:
beaumont
Message:

merged with trunk

Location:
branches/cnb_branches/cnb_branch_20090301
Files:
3 deleted
19 edited
9 copied

Legend:

Unmodified
Added
Removed
  • branches/cnb_branches/cnb_branch_20090301

  • branches/cnb_branches/cnb_branch_20090301/ppSub

  • branches/cnb_branches/cnb_branch_20090301/ppSub/src

    • Property svn:ignore
      •  

        old new  
        1010stamp-h1
        1111ppSubKernel
         12ppSubErrorCodes.h
         13ppSubErrorCodes.c
         14ppSubVersionDefinitions.h
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/Makefile.am

    r23352 r24244  
    11bin_PROGRAMS = ppSub ppSubKernel
    22
    3 # PPSUB_VERSION=`if [ -e ../../VERSION ]; then cat ../../VERSION; else svnversion; fi`
    4 # PPSUB_BRANCH=`if [ -e ../../BRANCH ]; then cat ../../BRANCH; else svn info | sed -n -e '/URL:/ h' -e '/Repository Root:/ { x; H; x; s|Repository Root: \(.*\)\nURL: \1\(.*\)|\2| ; s|^/|| ; s|/[a-zA-Z]*/src.*|| ; p }'; fi`
    5 # PPSUB_SOURCE=`if [ -e ../../SOURCE ]; then cat ../../SOURCE; else svn info | sed -n -e 's/Repository UUID: // p'; fi`
    6 #
    7 # # Force recompilation of ppSubVersion.c, since it gets the version information
    8 # ppSubVersion.c: FORCE
    9 #       touch ppSubVersion.c
    10 # FORCE: ;
     3if HAVE_SVNVERSION
     4PPSUB_VERSION=`$(SVNVERSION) ..`
     5else
     6PPSUB_VERSION="UNKNOWN"
     7endif
    118
    12 ppSub_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(PPSTATS_CFLAGS) $(PSPHOT_CFLAGS) $(PPSUB_CFLAGS) -DPPSUB_VERSION=$(SVN_VERSION) -DPPSUB_BRANCH=$(SVN_BRANCH) -DPPSUB_SOURCE=$(SVN_SOURCE)
     9if HAVE_SVN
     10PPSUB_BRANCH=`$(SVN) info .. | $(SED) -n -e '/URL:/ h' -e '/Repository Root:/ { x; H; x; s|Repository Root: \(.*\)\nURL: \1\(.*\)|\2| ; s|^/|| ; s|/[a-zA-Z]*/src.*|| ; p }'`
     11PPSUB_SOURCE=`$(SVN) info | $(SED) -n -e 's/Repository UUID: // p'`
     12else
     13PPSUB_BRANCH="UNKNOWN"
     14PPSUB_SOURCE="UNKNOWN"
     15endif
     16
     17# Force recompilation of ppSubVersion.c, since it gets the version information
     18ppSubVersion.c: ppSubVersionDefinitions.h
     19ppSubVersionDefinitions.h: ppSubVersionDefinitions.h.in FORCE
     20        -$(RM) ppSubVersionDefinitions.h
     21        $(SED) -e "s|@PPSUB_VERSION@|\"$(PPSUB_VERSION)\"|" -e "s|@PPSUB_BRANCH@|\"$(PPSUB_BRANCH)\"|" -e "s|@PPSUB_SOURCE@|\"$(PPSUB_SOURCE)\"|" ppSubVersionDefinitions.h.in > ppSubVersionDefinitions.h
     22FORCE: ;
     23
     24ppSub_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(PPSTATS_CFLAGS) $(PSPHOT_CFLAGS) $(PPSUB_CFLAGS)
    1325ppSub_LDFLAGS  = $(PSLIB_LIBS)   $(PSMODULE_LIBS)   $(PPSTATS_LIBS)   $(PSPHOT_LIBS)   $(PPSUB_LIBS)
    1426
    15 ppSub_SOURCES =                  \
    16         ppSub.c                  \
    17         ppSubArguments.c         \
    18         ppSubVersion.c           \
    19         ppSubBackground.c        \
    20         ppSubCamera.c            \
    21         ppSubLoop.c              \
    22         ppSubReadout.c           \
    23         ppSubDefineOutput.c      \
    24         ppSubExtras.c            \
    25         ppSubMakePSF.c           \
    26         ppSubMatchPSFs.c         \
    27         ppSubReadoutPhotometry.c \
    28         ppSubReadoutSubtract.c   \
    29         ppSubReadoutUpdate.c     \
    30         ppSubSetMasks.c          \
    31         ppSubReadoutRenorm.c     \
    32         ppSubVarianceFactors.c
     27ppSub_SOURCES =                         \
     28        ppSub.c                         \
     29        ppSubArguments.c                \
     30        ppSubVersion.c                  \
     31        ppSubBackground.c               \
     32        ppSubCamera.c                   \
     33        ppSubData.c                     \
     34        ppSubErrorCodes.c               \
     35        ppSubFiles.c                    \
     36        ppSubLoop.c                     \
     37        ppSubDefineOutput.c             \
     38        ppSubExtras.c                   \
     39        ppSubMakePSF.c                  \
     40        ppSubMatchPSFs.c                \
     41        ppSubReadoutInverse.c           \
     42        ppSubReadoutJpeg.c              \
     43        ppSubReadoutPhotometry.c        \
     44        ppSubReadoutStats.c             \
     45        ppSubReadoutSubtract.c          \
     46        ppSubSetMasks.c
    3347
    3448ppSubKernel_CPPFLAGS = $(PSLIB_CFLAGS) $(PSMODULE_CFLAGS) $(PPSUB_CFLAGS)
     
    4155        ppSub.h
    4256
     57
     58### Error codes.
     59BUILT_SOURCES = ppSubErrorCodes.h ppSubErrorCodes.c
     60CLEANFILES = ppSubErrorCodes.h ppSubErrorCodes.c
     61
     62ppSubErrorCodes.h : ppSubErrorCodes.dat ppSubErrorCodes.h.in
     63        $(ERRORCODES) --data=ppSubErrorCodes.dat --outdir=. ppSubErrorCodes.h
     64
     65ppSubErrorCodes.c : ppSubErrorCodes.dat ppSubErrorCodes.c.in ppSubErrorCodes.h
     66        $(ERRORCODES) --data=ppSubErrorCodes.dat --outdir=. ppSubErrorCodes.c
     67
     68
    4369clean-local:
    4470        -rm -f TAGS
     
    4773tags:
    4874        etags `find . -name \*.[ch] -print`
    49 
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSub.c

    r23352 r24244  
    2828    psLibInit(NULL);
    2929
     30    ppSubData *data = NULL;             // Processing data
    3031    pmConfig *config = pmConfigRead(&argc, argv, PPSUB_RECIPE); // Configuration
    3132    if (!config) {
     
    4041        psErrorStackPrint(stderr, "Error initialising model classes.\n");
    4142        exitValue = PS_EXIT_PROG_ERROR;
     43        psFree(config);
    4244        goto die;
    4345    }
     
    4648        psErrorStackPrint(stderr, "Error initialising psphot.\n");
    4749        exitValue = PS_EXIT_PROG_ERROR;
     50        psFree(config);
    4851        goto die;
    4952    }
    5053
    51     if (!ppSubArgumentsSetup(argc, argv, config)) {
     54    data = ppSubDataAlloc(config);
     55
     56    if (!ppSubArguments(argc, argv, data)) {
    5257        psErrorStackPrint(stderr, "Error reading arguments.\n");
    5358        exitValue = PS_EXIT_CONFIG_ERROR;
     
    5560    }
    5661
    57     if (!ppSubCamera(config)) {
     62    if (!ppSubCamera(data)) {
    5863        psErrorStackPrint(stderr, "Error setting up camera.\n");
    5964        exitValue = PS_EXIT_CONFIG_ERROR;
     
    6166    }
    6267
    63     if (!ppSubArgumentsParse(config)) {
    64         psErrorStackPrint(stderr, "Error reading arguments.\n");
    65         exitValue = PS_EXIT_CONFIG_ERROR;
    66         goto die;
    67     }
    68 
    69     if (!ppSubLoop(config)) {
     68    if (!ppSubLoop(data)) {
    7069        psErrorStackPrint(stderr, "Error performing subtraction.\n");
    7170        exitValue = PS_EXIT_SYS_ERROR;
     
    7776    psTimerStop();
    7877
     78    psFree(data);
     79
    7980    pmVisualClose(); //close plot windows, if -visual is set
    80     psFree(config);
    8181    pmModelClassCleanup();
    8282    pmConfigDone();
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSub.h

    r23352 r24244  
    1414#define PP_SUB_H
    1515
     16#include <stdio.h>
    1617#include <pslib.h>
    1718#include <psmodules.h>
     19
     20#include "ppSubErrorCodes.h"
    1821
    1922/// @addtogroup ppSub
     
    2124
    2225#define PPSUB_RECIPE "PPSUB"            /// Name of the recipe to use
     26#define WCS_TOLERANCE 0.001             // Tolerance for WCS
     27
     28// Output files, for activation/deactivation
     29typedef enum {
     30    PPSUB_FILES_INPUT    = 0x01,        // Input files
     31    PPSUB_FILES_CONV     = 0x02,        // Convolved files (output)
     32    PPSUB_FILES_SUB      = 0x04,        // Subtracted files (output)
     33    PPSUB_FILES_INV      = 0x08,        // Inverse subtracted files (output)
     34    PPSUB_FILES_PSF      = 0x10,        // PSF files (output)
     35    PPSUB_FILES_PHOT_SUB = 0x20,        // Subtraction photometry files (output)
     36    PPSUB_FILES_PHOT_INV = 0x40,        // Inverse subtraction photometry files (output)
     37    PPSUB_FILES_PHOT     = 0x80,        // General photometry files (internal)
     38    PPSUB_FILES_ALL      = 0xFF,        // All files
     39} ppSubFiles;
     40
     41/// Data for processing
     42typedef struct {
     43    pmConfig *config;                   // Configuration
     44    psErrorCode quality;                // Quality code; 0 for no problem
     45    bool photometry;                    // Perform photometry?
     46    bool inverse;                       // Output inverse subtraction as well?
     47    psString stamps;                    // Stamps file
     48    pmPSF *psf;                         // Point Spread Function
     49    psString statsName;                 // Name of statistics file
     50    FILE *statsFile;                    // Statistics file
     51    psMetadata *stats;                  // Statistics
     52} ppSubData;
     53
     54/// Constructor
     55ppSubData *ppSubDataAlloc(pmConfig *config ///< Configuration
     56    );
    2357
    2458/// Setup the arguments parsing
    25 bool ppSubArgumentsSetup(int argc, char *argv[], ///< Command-line arguments
    26                          pmConfig *config    ///< Configuration
    27     );
    28 
    29 /// Parse the arguments
    30 bool ppSubArgumentsParse(pmConfig *config ///< Configuration
     59bool ppSubArguments(int argc, char *argv[], ///< Command-line arguments
     60                    ppSubData *data ///< Processing data
    3161    );
    3262
    3363/// Parse the camera input
    34 bool ppSubCamera(pmConfig *config       ///< Configuration
     64bool ppSubCamera(ppSubData *data        ///< Processing data
    3565    );
    3666
    3767/// Loop over the FPA hierarchy
    38 bool ppSubLoop(pmConfig *config         ///< Configuration
    39     );
    40 
    41 /// Perform PSF-matched image subtraction on the readout
    42 bool ppSubReadout(pmConfig *config,     ///< Configuration
    43                   psMetadata *stats,    ///< Statistics, for output
    44                   const pmFPAview *view ///< View of readout to subtract
     68bool ppSubLoop(ppSubData *data          ///< Processing data
    4569    );
    4670
    4771/// Generate (if needed) and set or update the masks for input and reference images
    48 bool ppSubSetMasks(pmConfig *config,     ///< Configuration
    49                    const pmFPAview *view ///< View of active readout
     72bool ppSubSetMasks(pmConfig *config     ///< Configuration
    5073    );
    5174
    5275/// Generate the PSF-matching kernel and convolve the images as needed.  Most of this function involves
    5376/// looking up the parameters in the recipe and supplying them to the function pmSubtractionMatch()
    54 bool ppSubMatchPSFs(pmConfig *config,    ///< Configuration
    55                     const pmFPAview *view ///< View of active readout
     77bool ppSubMatchPSFs(ppSubData *data     ///< Processing data
    5678    );
    5779
    5880/// Generate the output readout and pass the kernel info to the header
    59 bool ppSubDefineOutput(pmConfig *config, ///< Configuration
    60                        const pmFPAview *view ///< View of active readout
     81bool ppSubDefineOutput(const char *name,///< Name of output to define
     82                       pmConfig *config ///< Configuration
    6183    );
    6284
    6385/// Photometry stage 1: measure the PSF from the minuend image
    64 bool ppSubMakePSF(pmConfig *config,       ///< Configuration
    65                   const pmFPAview *view ///< View of active readout
     86bool ppSubMakePSF(ppSubData *data       ///< Processing data
    6687    );
    6788
    6889/// Perform the actual image subtraction, update output concepts
    69 bool ppSubReadoutSubtract(pmConfig *config,       ///< Configuration
    70                           const pmFPAview *view ///< View of active readout
     90bool ppSubReadoutSubtract(pmConfig *config ///< Configuration
    7191    );
    7292
    7393
    7494/// Photometry stage 2: find and measure sources on the subtracted image
    75 bool ppSubReadoutPhotometry(pmConfig *config,     ///< Configuration
    76                             psMetadata *stats,    ///< Statistics, for output
    77                             const pmFPAview *view ///< View of active readout
    78     );
    79 
    80 /// Renormalize, update headers and generate JPEGs
    81 bool ppSubReadoutUpdate(pmConfig *config, ///< Configuration
    82                         psMetadata *stats, ///< Statistics for output, or NULL
    83                         const pmFPAview *view ///< View of active readout
     95bool ppSubReadoutPhotometry(const char *name, ///< Name of file to photometer
     96                            ppSubData *data ///< Processing data
    8497    );
    8598
    8699/// Higher-order background subtraction
    87 bool ppSubBackground(pmConfig *config,  ///< Configuration
    88                      const pmFPAview *view ///< View to readout
     100bool ppSubBackground(pmConfig *config   ///< Configuration
    89101    );
    90102
     
    96108void ppSubVersionPrint(void);
    97109
     110/// Mark the data quality as bad and prepare to suspend processing
     111void ppSubDataQuality(ppSubData *data,  ///< Processing data
     112                      psErrorCode error,///< Error code
     113                      ppSubFiles files  ///< Files to deactivate
     114    );
     115
     116
     117/// Activate or deactivate files
     118void ppSubFilesActivate(pmConfig *config, // Configuration
     119                        ppSubFiles files, // File to activate/deactivate
     120                        bool state      // Activation state
     121    );
     122
     123/// Generate a view suitable for a readout
     124///
     125/// Assumes we're working with skycells
     126pmFPAview *ppSubViewReadout(void);
     127
     128/// Iterate down the FPA hierarchy, opening files
     129bool ppSubFilesIterateDown(pmConfig *config, // Configuration
     130                           ppSubFiles files // Files to open
     131    );
     132
     133/// Iterate up the FPA hierarchy, closing files
     134bool ppSubFilesIterateUp(pmConfig *config, // Configuration
     135                         ppSubFiles files // Files to open
     136    );
     137
     138/// Collect statistics
     139bool ppSubReadoutStats(ppSubData *data  // Processing data
     140    );
     141
     142/// Generate JPEG images
     143bool ppSubReadoutJpeg(pmConfig *config  // Configuration
     144    );
     145
     146/// Generate inverse subtraction
     147bool ppSubReadoutInverse(pmConfig *config // Configuration
     148    );
     149
    98150
    99151// Copy every instance of a single keyword from one metadata to another
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubArguments.c

    r23594 r24244  
    4141}
    4242
    43 // Get a float-point value from the command-line or recipe, and add it to the arguments
    44 #define VALUE_ARG_RECIPE_FLOAT(ARGNAME, RECIPENAME, TYPE) { \
    45     ps##TYPE value = psMetadataLookup##TYPE(NULL, config->arguments, ARGNAME); \
    46     if (isnan(value)) { \
    47         bool mdok; \
    48         value = psMetadataLookup##TYPE(&mdok, recipe, RECIPENAME); \
    49         if (!mdok) { \
    50             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to find %s in recipe %s", \
    51                 RECIPENAME, PPSUB_RECIPE); \
    52             goto ERROR; \
    53         } \
    54     } \
    55     psMetadataAdd##TYPE(recipe, PS_LIST_TAIL, RECIPENAME, PS_META_REPLACE, NULL, value); \
    56 }
    57 
    58 // Get an integer value from the command-line or recipe, and add it to the arguments
    59 #define VALUE_ARG_RECIPE_INT(ARGNAME, RECIPENAME, TYPE, UNSET) { \
    60     ps##TYPE value = psMetadataLookup##TYPE(NULL, config->arguments, ARGNAME); \
    61     if (value == UNSET) { \
    62         bool mdok; \
    63         value = psMetadataLookup##TYPE(&mdok, recipe, RECIPENAME); \
    64         if (!mdok) { \
    65             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to find %s in recipe %s", \
    66                 RECIPENAME, PPSUB_RECIPE); \
    67             goto ERROR; \
    68         } \
    69     } \
    70     psMetadataAdd##TYPE(recipe, PS_LIST_TAIL, RECIPENAME, PS_META_REPLACE, NULL, value); \
    71 }
    72 
    73 /**
    74  * Get a string value from the command-line and add it to the target
    75  */
    76 static bool valueArgStr(psMetadata *arguments, // Command-line arguments
    77                         const char *argName, // Argument name in the command-line arguments
    78                         const char *mdName, // Name for value in the metadata
    79                         psMetadata *target // Target metadata to which to add value
    80                         )
    81 {
    82     psString value = psMetadataLookupStr(NULL, arguments, argName); // Value of interest
    83     if (value && strlen(value) > 0) {
    84         return psMetadataAddStr(target, PS_LIST_TAIL, mdName, PS_META_REPLACE, NULL, value);
    85     }
    86     return false;
    87 }
    88 
    89 /**
    90  * Get a string value from the command-line or recipe and add it to the target
    91  */
    92 static bool valueArgRecipeStr(psMetadata *arguments, // Command-line arguments
    93                               psMetadata *recipe, // Recipe
    94                               const char *argName, // Argument name in the command-line arguments
    95                               const char *mdName, // Name for value in the metadata and recipe
    96                               psMetadata *target // Target metadata to which to add value
    97                               )
    98 {
    99     bool mdok;                          // Status of MD lookup
    100     psString value = psMetadataLookupStr(&mdok, arguments, argName); // Value of interest
    101     if (!value) {
    102         value = psMetadataLookupStr(&mdok, recipe, mdName);
    103         if (!value) {
    104             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to find %s in recipe %s",
    105                     mdName, PPSUB_RECIPE);
    106             return false;
    107         }
    108     }
    109     return psMetadataAddStr(target, PS_LIST_TAIL, mdName, PS_META_REPLACE, NULL, value);
    110 }
    111 
    112 /**
    113  * Get a vector from the command-line or recipe, and add it to the target
    114  */
    115 static bool vectorArgRecipe(psMetadata *arguments, // Command-line arguments
    116                             const char *argName, // Argument name in the command-line arguments
    117                             const psMetadata *recipe, // Recipe
    118                             const char *recipeName, // Name for value in the recipe
    119                             psMetadata *target, // Target to which to add value
    120                             psElemType type // Type for vector
    121     )
    122 {
    123     psVector *vector;                   // Vector
    124     psString string = psMetadataLookupStr(NULL, arguments, argName); // String from arguments
    125     if (string) {
    126         psArray *array = psStringSplitArray(string, ", ", false); // Array of strings
    127         vector = psVectorAlloc(array->n, type);
    128         for (int i = 0; i < array->n; i++) {
    129             const char *subString = array->data[i]; // String with a value
    130             char *end;                  // Ptr to end of string parsed
    131 
    132             switch (type) {
    133               case PS_TYPE_F32:
    134                 vector->data.F32[i] = strtof(subString, &end);
    135                 break;
    136               case PS_TYPE_S32: {
    137                   long value = strtol(subString, &end, 10);
    138                   if (value > PS_MAX_S32 || value < PS_MIN_S32) {
    139                       psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    140                               "%s list includes value beyond S32 representation: %s",
    141                               argName, string);
    142                       psFree(vector);
    143                       return false;
    144                   }
    145                   vector->data.S32[i] = value;
    146                   break;
    147               }
    148               default:
    149                 psAbort("Unsupported type: %x\n", type);
    150             }
    151             if (end == subString) {
    152                 psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to decipher %s list: %s",
    153                         argName, string);
    154                 psFree(vector);
    155                 return false;
    156             }
    157         }
    158         psFree(array);
    159     } else {
    160         vector = psMetadataLookupPtr(NULL, recipe, recipeName);
    161         if (!psMemCheckVector(vector) || vector->type.type != type) {
    162             psError(PS_ERR_BAD_PARAMETER_TYPE, false, "%s in recipe %s is not a vector of type F32.",
    163                     recipeName, PPSUB_RECIPE);
    164             return false;
    165         }
    166         psMemIncrRefCounter(vector);
    167     }
    168 
    169     psMetadataAddVector(target, PS_LIST_TAIL, recipeName, PS_META_REPLACE, NULL, vector);
    170     psFree(vector);                     // Drop reference
    171 
    172     return true;
    173 }
    174 
    17543/**
    17644 * Add a single filename to the arguments as an array, so that it can be used with pmFPAfileBindFromArgs, etc
     
    18957}
    19058
    191 bool ppSubArgumentsSetup(int argc, char *argv[], pmConfig *config)
     59bool ppSubArguments(int argc, char *argv[], ppSubData *data)
    19260{
    193     //    int argnum;                         // Argument Number
     61    assert(data);
     62    pmConfig *config = data->config;
    19463    assert(config);
    19564
    196     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
    197     if (!recipe) {
    198         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSUB_RECIPE);
    199         return false;
     65    int argNum = psArgumentGet(argc, argv, "-debug"); // Debugging argument number
     66    if (argNum) {
     67        psArgumentRemove(argNum, &argc, argv);
     68        pmSubtractionRegions(true);
    20069    }
    20170
     
    21281    psMetadataAddStr(arguments, PS_LIST_TAIL, "-kernel", 0, "Precalculated kernel to apply", NULL);
    21382    psMetadataAddStr(arguments, PS_LIST_TAIL, "-stats", 0, "Statistics file", NULL);
    214     psMetadataAddF32(arguments, PS_LIST_TAIL, "-region", 0, "Size of iso-kernel region", NAN);
    215     psMetadataAddS32(arguments, PS_LIST_TAIL, "-size", 0, "Kernel half-size (pixels)", 0);
    216     psMetadataAddS32(arguments, PS_LIST_TAIL, "-order", 0, "Spatial polynomial order", -1);
    217     psMetadataAddStr(arguments, PS_LIST_TAIL, "-type", 0,
    218                      "Kernel type (ISIS|POIS|SPAM|FRIES|GUNK|RINGS)", NULL);
    219     psMetadataAddF32(arguments, PS_LIST_TAIL, "-penalty", 0, "Penalty for wideness", NAN);
    220     psMetadataAddStr(arguments, PS_LIST_TAIL, "-isis-widths", 0,
    221                      "ISIS Gaussian FWHMs (comma-separated)", NULL);
    222     psMetadataAddStr(arguments, PS_LIST_TAIL, "-isis-orders", 0,
    223                      "ISIS polynomial orders (comma-separated)", NULL);
    224     psMetadataAddS32(arguments, PS_LIST_TAIL, "-rings-order", 0, "RINGS polynomial order", -1);
    225     psMetadataAddS32(arguments, PS_LIST_TAIL, "-inner", 0, "SPAM and FRIES inner radius", -1);
    226     psMetadataAddS32(arguments, PS_LIST_TAIL, "-spam-binning", 0, "SPAM kernel binning", 0);
    227     psMetadataAddF32(arguments, PS_LIST_TAIL, "-spacing", 0, "Typical stamp spacing (pixels)", NAN);
    228     psMetadataAddS32(arguments, PS_LIST_TAIL, "-footprint", 0, "Stamp footprint half-size (pixels)", -1);
    229     psMetadataAddF32(arguments, PS_LIST_TAIL, "-source-radius", 0, "Source matching radius (pixels)", NAN);
    230     psMetadataAddS32(arguments, PS_LIST_TAIL, "-stride", 0, "Size of convolution patches (pixels)", -1);
    231     psMetadataAddF32(arguments, PS_LIST_TAIL, "-threshold", 0, "Minimum threshold for stamps (ADU)", NAN);
    232     psMetadataAddS32(arguments, PS_LIST_TAIL, "-iter", 0, "Number of rejection iterations", -1);
    233     psMetadataAddF32(arguments, PS_LIST_TAIL, "-rej", 0, "Rejection thresold (sigma)", NAN);
    234     psMetadataAddF32(arguments, PS_LIST_TAIL, "-sys", 0, "Relative systematic error in kernel", NAN);
    235     psMetadataAddImageMask(arguments,  PS_LIST_TAIL, "-mask-bad", 0, "Mask value for bad pixels", 0);
    236     psMetadataAddImageMask(arguments,  PS_LIST_TAIL, "-mask-poor", 0, "Mask value for poor pixels", 0);
    237     psMetadataAddF32(arguments,  PS_LIST_TAIL, "-poor-frac", 0, "Fraction of variance for poor pixels", NAN);
    238     psMetadataAddF32(arguments, PS_LIST_TAIL, "-badfrac", 0, "Maximum fraction of bad pixels to accept", 1.0);
    239     psMetadataAddBool(arguments,  PS_LIST_TAIL, "-reverse", 0, "Reverse sense of subtraction?", false);
    240     psMetadataAddBool(arguments,  PS_LIST_TAIL, "-generate-mask", 0, "Generate mask if not supplied?", false);
    241     psMetadataAddStr(arguments,  PS_LIST_TAIL, "-stamps", 0,
    242                      "Stamps filename; file has x,y on each line", NULL);
    243     psMetadataAddBool(arguments, PS_LIST_TAIL, "-opt", 0,
    244                       "Derive optimum parameters for ISIS kernels?", false);
    245     psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-min", 0, "Minimum value for optimum kernel search", NAN);
    246     psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-max", 0, "Minimum value for optimum kernel search", NAN);
    247     psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-step", 0, "Step value for optimum kernel search", NAN);
    248     psMetadataAddF32(arguments, PS_LIST_TAIL, "-opt-tol", 0, "Tolerance for optimum kernel search", NAN);
    249     psMetadataAddS32(arguments, PS_LIST_TAIL, "-opt-order", 0, "Maximum order for optimum kernel search", -1);
    250     psMetadataAddBool(arguments, PS_LIST_TAIL, "-dual", 0, "Dual convolution", false);
    251     psMetadataAddBool(arguments, PS_LIST_TAIL, "-photometry", 0, "Perform photometry?", false);
     83    psMetadataAddStr(arguments,  PS_LIST_TAIL, "-stamps", 0, "Stamps filename; x,y on each line", NULL);
    25284    psMetadataAddS32(arguments, PS_LIST_TAIL, "-threads", 0, "Number of threads", 0);
    253     psMetadataAddS32(arguments, PS_LIST_TAIL, "-bin1", 0, "Binning factor for first level", 0);
    254     psMetadataAddS32(arguments, PS_LIST_TAIL, "-bin2", 0, "Binning factor for second level", 0);
    25585    psMetadataAddStr(arguments, PS_LIST_TAIL, "-dumpconfig", 0, "file to dump configuration to", NULL);
     86    psMetadataAddBool(arguments, PS_LIST_TAIL, "-photometry", 0, "Perform photometry?", NULL);
     87    psMetadataAddBool(arguments, PS_LIST_TAIL, "-inverse", 0, "Generate inverse subtractions?", NULL);
    25688    psMetadataAddBool(arguments, PS_LIST_TAIL, "-visual", 0, "Show diagnostic plots", NULL);
    25789
     
    302134    }
    303135
    304     if (psMetadataLookupBool(NULL, arguments, "-photometry")) {
    305         psMetadataAddBool(recipe, PS_LIST_TAIL, "PHOTOMETRY", PS_META_REPLACE, "Perform photometry?", true);
    306     }
     136    data->stamps = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-stamps"));
    307137
    308     return true;
    309 }
    310 
    311 bool ppSubArgumentsParse(pmConfig *config)
    312 {
    313     assert(config);
    314 
    315     psMetadata *arguments = config->arguments; // Command-line arguments
    316 
    317     valueArgStr(arguments, "-stats",  "STATS",  arguments);
    318     valueArgStr(arguments, "-stamps", "STAMPS", arguments);
    319 
    320     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
    321     if (!recipe) {
    322         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSUB_RECIPE);
    323         goto ERROR;
    324     }
    325 
    326     VALUE_ARG_RECIPE_FLOAT("-region",        "REGION.SIZE",     F32);
    327     VALUE_ARG_RECIPE_INT("-size",            "KERNEL.SIZE",     S32, 0);
    328     VALUE_ARG_RECIPE_INT("-order",           "SPATIAL.ORDER",   S32, -1);
    329     VALUE_ARG_RECIPE_FLOAT("-spacing",       "STAMP.SPACING",   F32);
    330     VALUE_ARG_RECIPE_INT("-rings-order",     "RINGS.ORDER",     S32, -1);
    331     VALUE_ARG_RECIPE_INT("-inner",           "INNER",           S32, -1);
    332     VALUE_ARG_RECIPE_INT("-spam-binning",    "SPAM.BINNING",    S32, 0);
    333     VALUE_ARG_RECIPE_INT("-footprint",       "STAMP.FOOTPRINT", S32, -1);
    334     VALUE_ARG_RECIPE_FLOAT("-source-radius", "SOURCE.RADIUS",   F32);
    335     VALUE_ARG_RECIPE_INT("-stride",          "STRIDE",          S32, -1);
    336     VALUE_ARG_RECIPE_FLOAT("-threshold",     "STAMP.THRESHOLD", F32);
    337     VALUE_ARG_RECIPE_INT("-iter",            "ITER",            S32, -1);
    338     VALUE_ARG_RECIPE_FLOAT("-rej",           "REJ",             F32);
    339     VALUE_ARG_RECIPE_FLOAT("-sys",           "SYS",             F32);
    340     VALUE_ARG_RECIPE_FLOAT("-badfrac",       "BADFRAC",         F32);
    341     VALUE_ARG_RECIPE_FLOAT("-penalty",       "PENALTY",         F32);
    342     VALUE_ARG_RECIPE_FLOAT("-poor-frac",     "POOR.FRACTION",   F32);
    343     VALUE_ARG_RECIPE_INT("-bin1",            "BIN1",            S32, 0);
    344     VALUE_ARG_RECIPE_INT("-bin2",            "BIN2",            S32, 0);
    345 
    346     valueArgRecipeStr(arguments, recipe, "-mask-in",   "MASK.IN",  recipe);
    347     valueArgRecipeStr(arguments, recipe, "-mask-bad",  "MASK.BAD",  recipe);
    348     valueArgRecipeStr(arguments, recipe, "-mask-poor", "MASK.POOR", recipe);
    349 
    350     vectorArgRecipe(arguments, "-isis-widths", recipe, "ISIS.WIDTHS", recipe, PS_TYPE_F32);
    351     vectorArgRecipe(arguments, "-isis-orders", recipe, "ISIS.ORDERS", recipe, PS_TYPE_S32);
    352 
    353     psVector *widths = psMetadataLookupPtr(NULL, recipe, "ISIS.WIDTHS"); // ISIS Gaussian widths
    354     psVector *orders = psMetadataLookupPtr(NULL, recipe, "ISIS.ORDERS"); // ISIS Polynomial orders
    355     if (widths->n != orders->n) {
    356         psError(PS_ERR_BAD_PARAMETER_SIZE, true, "Size of vectors for ISIS widths and orders do not match.");
    357         goto ERROR;
    358     }
    359 
    360     if (psMetadataLookupBool(NULL, arguments, "-opt") || psMetadataLookupBool(NULL, recipe, "OPTIMUM")) {
    361         psMetadataAddBool(recipe, PS_LIST_TAIL, "OPTIMUM", PS_META_REPLACE,
    362                           "Derive optimum parameters for ISIS kernels?", true);
    363         VALUE_ARG_RECIPE_FLOAT("-opt-min", "OPTIMUM.MIN",   F32);
    364         VALUE_ARG_RECIPE_FLOAT("-opt-max", "OPTIMUM.MAX",   F32);
    365         VALUE_ARG_RECIPE_FLOAT("-opt-step","OPTIMUM.STEP",  F32);
    366         VALUE_ARG_RECIPE_FLOAT("-opt-tol", "OPTIMUM.TOL",   F32);
    367         VALUE_ARG_RECIPE_INT("-opt-order", "OPTIMUM.ORDER", S32, -1);
    368     }
    369 
    370     psMetadataAddBool(arguments, PS_LIST_TAIL, "REVERSE", 0, "Reverse sense of subtraction",
    371                       psMetadataLookupBool(NULL, arguments, "-reverse"));
    372     psMetadataAddBool(recipe, PS_LIST_TAIL, "MASK.GENERATE", PS_META_REPLACE, "Generate mask if not supplied",
    373                       psMetadataLookupBool(NULL, arguments, "-generate-mask"));
    374     psMetadataAddBool(recipe, PS_LIST_TAIL, "DUAL", PS_META_REPLACE, "Dual convolution?",
    375                       psMetadataLookupBool(NULL, arguments, "-dual"));
    376 
    377     // Need to update this because it could have been overwritten by the camera's own recipe
    378     if (psMetadataLookupBool(NULL, arguments, "-photometry")) {
    379         psMetadataAddBool(recipe, PS_LIST_TAIL, "PHOTOMETRY", PS_META_REPLACE, "Perform photometry?", true);
     138    data->statsName = psMemIncrRefCounter(psMetadataLookupStr(NULL, arguments, "-stats"));
     139    if (data->statsName && strlen(data->statsName) > 0) {
     140        psString resolved = pmConfigConvertFilename(data->statsName, config, true, true); // Resolved filename
     141        data->statsFile = fopen(resolved, "w");
     142        if (!data->statsFile) {
     143            psError(PS_ERR_IO, true, "Unable to open statistics file %s for writing.\n", resolved);
     144            psFree(resolved);
     145            return false;
     146        }
     147        psFree(resolved);
    380148    }
    381149
     
    384152    }
    385153
    386     // Translate the kernel type
    387     psString type = psMetadataLookupStr(NULL, arguments, "-type"); // Name of kernel type
    388     if (!type || strlen(type) == 0) {
    389         type = psMetadataLookupStr(NULL, recipe, "KERNEL.TYPE");
    390         if (!type || strlen(type) == 0) {
    391             psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Unable to find KERNEL.TYPE specified.");
    392             goto ERROR;
    393         }
    394     }
    395     psMetadataAddStr(recipe, PS_LIST_TAIL, "KERNEL.TYPE", PS_META_REPLACE, "Type of kernel", type);
    396 
    397     psTrace("ppSub", 1, "Done reading command-line arguments\n");
    398 
    399     // XXX move this to ppSubArguments
    400     int threads = psMetadataLookupS32(NULL, config->arguments, "-threads"); // Number of threads
     154    int threads = psMetadataLookupS32(NULL, arguments, "-threads"); // Number of threads
    401155    if (threads > 0) {
    402156        if (!psThreadPoolInit(threads)) {
     
    406160    }
    407161
     162    psTrace("ppSub", 1, "Done reading command-line arguments\n");
     163
    408164    return true;
    409 
    410 ERROR:
    411     return false;
    412165}
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubBackground.c

    r23352 r24244  
    2222#include "ppSub.h"
    2323
    24 bool ppSubBackground(pmConfig *config, const pmFPAview *view)
     24bool ppSubBackground(pmConfig *config)
    2525{
    2626    psAssert(config, "Require configuration");
    27     psAssert(view, "Require view");
    2827
    2928    bool mdok; // Status of metadata lookups
     
    3635    psImageMaskType maskBad = pmConfigMaskGet("BLANK", config); // Bits to mask
    3736
     37    pmFPAview *view = ppSubViewReadout(); // View to readout
    3838    pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT"); // Output image
    3939    pmReadout *modelRO = pmFPAfileThisReadout(config->files, view, "PSPHOT.BACKMDL"); // Background model
     
    4444        if (!psphotModelBackground(config, view, "PPSUB.OUTPUT")) {
    4545            psError(PS_ERR_UNKNOWN, false, "Unable to model background");
     46            psFree(view);
    4647            return false;
    4748        }
     
    5051        if (!modelRO) {
    5152            psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find background model");
     53            psFree(view);
    5254            return false;
    5355        }
    5456    }
     57    psFree(view);
     58
    5559    psImageBinning *binning = psMetadataLookupPtr(&mdok, modelRO->analysis,
    5660                                                  "PSPHOT.BACKGROUND.BINNING"); // Binning for model
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubCamera.c

    r23594 r24244  
    134134
    135135
    136 bool ppSubCamera(pmConfig *config)
     136bool ppSubCamera(ppSubData *data)
    137137{
     138    psAssert(data, "Require processing data");
     139    pmConfig *config = data->config;
    138140    psAssert(config, "Require configuration");
    139141
     
    147149    pmFPAfile *inVar = defineInputFile(config, input, "PPSUB.INPUT.VARIANCE", "INPUT.VARIANCE",
    148150                                       PM_FPA_FILE_VARIANCE);
    149     defineInputFile(config, input, "PPSUB.INPUT.SOURCES", "INPUT.SOURCES", PM_FPA_FILE_CMF);
     151    defineInputFile(config, NULL, "PPSUB.INPUT.SOURCES", "INPUT.SOURCES", PM_FPA_FILE_CMF);
    150152
    151153    // Reference image
     
    158160    pmFPAfile *refVar = defineInputFile(config, ref, "PPSUB.REF.VARIANCE", "REF.VARIANCE",
    159161                                        PM_FPA_FILE_VARIANCE);
    160     defineInputFile(config, ref, "PPSUB.REF.SOURCES", "REF.SOURCES", PM_FPA_FILE_CMF);
    161 
    162 
    163     // Output image
    164     pmFPAfile *output = defineOutputFile(config, input, true, "PPSUB.OUTPUT", PM_FPA_FILE_IMAGE);
    165     pmFPAfile *outMask = defineOutputFile(config, output, false, "PPSUB.OUTPUT.MASK", PM_FPA_FILE_MASK);
    166     if (!output || !outMask) {
    167         psError(PS_ERR_UNKNOWN, false, "Unable to define output files");
    168         return false;
    169     }
    170     output->save = true;
    171     outMask->save = true;
    172     pmFPAfile *outVar = NULL;
    173     if (inVar && refVar) {
    174         outVar = defineOutputFile(config, output, false, "PPSUB.OUTPUT.VARIANCE", PM_FPA_FILE_VARIANCE);
    175         if (!outVar) {
    176             psError(PS_ERR_UNKNOWN, false, "Unable to define output files");
    177             return false;
    178         }
    179         outVar->save = true;
    180     }
     162    defineInputFile(config, NULL, "PPSUB.REF.SOURCES", "REF.SOURCES", PM_FPA_FILE_CMF);
    181163
    182164
     
    216198
    217199
     200    // Now that the camera has been determined, we can read the recipe
     201    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
     202    if (!recipe) {
     203        psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSUB_RECIPE);
     204        return false;
     205    }
     206    if (psMetadataLookupBool(NULL, config->arguments, "-photometry")) {
     207        psMetadataAddBool(recipe, PS_LIST_TAIL, "PHOTOMETRY", PS_META_REPLACE,
     208                          "Perform photometry?", true);
     209    }
     210    if (psMetadataLookupBool(NULL, config->arguments, "-inverse")) {
     211        psMetadataAddBool(recipe, PS_LIST_TAIL, "INVERSE", PS_META_REPLACE,
     212                          "Generate inverse subtractions?", true);
     213    }
     214
     215    data->inverse = psMetadataLookupBool(NULL, recipe, "INVERSE");
     216    data->photometry = psMetadataLookupBool(NULL, recipe, "PHOTOMETRY");
     217
     218
     219    // Output image
     220    pmFPAfile *output = defineOutputFile(config, inConvImage, true, "PPSUB.OUTPUT", PM_FPA_FILE_IMAGE);
     221    pmFPAfile *outMask = defineOutputFile(config, output, false, "PPSUB.OUTPUT.MASK", PM_FPA_FILE_MASK);
     222    if (!output || !outMask) {
     223        psError(PS_ERR_UNKNOWN, false, "Unable to define output files");
     224        return false;
     225    }
     226    output->save = true;
     227    outMask->save = true;
     228    if (inVar && refVar) {
     229        pmFPAfile *outVar = defineOutputFile(config, output, false, "PPSUB.OUTPUT.VARIANCE",
     230                                             PM_FPA_FILE_VARIANCE);
     231        if (!outVar) {
     232            psError(PS_ERR_UNKNOWN, false, "Unable to define output files");
     233            return false;
     234        }
     235        outVar->save = true;
     236    }
     237
     238    pmFPAfile *inverse = NULL;          // Inverse output image
     239    if (data->inverse) {
     240        // Inverse output image
     241        inverse = defineOutputFile(config, output, true, "PPSUB.INVERSE", PM_FPA_FILE_IMAGE);
     242        pmFPAfile *invMask = defineOutputFile(config, inverse, false, "PPSUB.INVERSE.MASK",
     243                                              PM_FPA_FILE_MASK);
     244        if (!inverse || !invMask) {
     245            psError(PS_ERR_UNKNOWN, false, "Unable to define output files");
     246            return false;
     247        }
     248        inverse->save = true;
     249        invMask->save = true;
     250        if (inVar && refVar) {
     251            pmFPAfile *invVar = defineOutputFile(config, inverse, false, "PPSUB.INVERSE.VARIANCE",
     252                                                 PM_FPA_FILE_VARIANCE);
     253            if (!invVar) {
     254                psError(PS_ERR_UNKNOWN, false, "Unable to define output files");
     255                return false;
     256            }
     257            invVar->save = true;
     258        }
     259    }
     260
     261
    218262    // Output JPEGs
    219263    pmFPAfile *jpeg1 = pmFPAfileDefineOutput(config, NULL, "PPSUB.OUTPUT.JPEG1");
     
    245289    }
    246290
    247     psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
    248     if (!recipe) {
    249         psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to find recipe %s", PPSUB_RECIPE);
    250         return false;
    251     }
    252 
    253291    // psPhot input
    254     if (psMetadataLookupBool(NULL, recipe, "PHOTOMETRY")) {
     292    if (data->photometry) {
    255293        psphotModelClassInit();        // load implementation-specific models
    256 
    257         // Internal-ish file for getting the PSF from the minuend
    258         pmFPAfile *psf = pmFPAfileDefineOutputFromFile(config, output, "PSPHOT.PSF.LOAD");
    259         if (!psf) {
    260             psError(PS_ERR_IO, false, "Failed to build FPA from PSPHOT.PSF.LOAD");
    261             return false;
    262         }
    263         if (psf->type != PM_FPA_FILE_PSF) {
    264             psError(PS_ERR_IO, true, "PSPHOT.PSF.LOAD is not of type PSF");
    265             return false;
    266         }
    267         pmFPAfileActivate(config->files, false, "PSPHOT.PSF.LOAD");
    268294
    269295        pmFPAfile *psphot = pmFPAfileDefineFromFPA(config, output->fpa, 1, 1, "PSPHOT.INPUT");
     
    276302            return false;
    277303        }
     304        pmFPAfileActivate(config->files, false, "PSPHOT.INPUT");
     305
     306        // Internal-ish file for getting the PSF from the minuend
     307        pmFPAfile *psf = pmFPAfileDefineOutputFromFile(config, psphot, "PSPHOT.PSF.LOAD");
     308        if (!psf) {
     309            psError(PS_ERR_IO, false, "Failed to build FPA from PSPHOT.PSF.LOAD");
     310            return false;
     311        }
     312        if (psf->type != PM_FPA_FILE_PSF) {
     313            psError(PS_ERR_IO, true, "PSPHOT.PSF.LOAD is not of type PSF");
     314            return false;
     315        }
     316        pmFPAfileActivate(config->files, false, "PSPHOT.PSF.LOAD");
    278317
    279318        if (!psphotDefineFiles(config, psphot)) {
     
    281320            return false;
    282321        }
     322
     323        // Deactivate psphot output sources --- we want to define output source files of our own
     324        pmFPAfile *psphotOutput = pmFPAfileSelectSingle(config->files, "PSPHOT.OUTPUT", 0);
     325        psphotOutput->save = false;
     326
     327        pmFPAfile *outSources = defineOutputFile(config, output, false, "PPSUB.OUTPUT.SOURCES",
     328                                                 PM_FPA_FILE_CMF);
     329        if (!outSources) {
     330            psError(PS_ERR_UNKNOWN, false, "Unable to set up output source file.");
     331            return false;
     332        }
     333        outSources->save = true;
     334
     335        if (data->inverse) {
     336            pmFPAfile *invSources = defineOutputFile(config, inverse, false, "PPSUB.INVERSE.SOURCES",
     337                                                     PM_FPA_FILE_CMF);
     338            if (!invSources) {
     339                psError(PS_ERR_UNKNOWN, false, "Unable to set up inverse source file.");
     340                return false;
     341            }
     342            invSources->save = true;
     343        }
    283344    }
    284345
    285346    return true;
    286347}
     348
     349
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubDefineOutput.c

    r23594 r24244  
    2121#include "ppSub.h"
    2222
    23 bool ppSubDefineOutput(pmConfig *config, const pmFPAview *view)
     23bool ppSubDefineOutput(const char *name, pmConfig *config)
    2424{
     25    psAssert(name, "Require name");
    2526    psAssert(config, "Require configuration");
    26     psAssert(view, "Require view");
    2727
    28     pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSUB.OUTPUT"); // Output cell
     28    pmFPAview *view = ppSubViewReadout(); // View to readout
     29    pmCell *outCell = pmFPAfileThisCell(config->files, view, name); // Output cell
    2930    pmFPA *outFPA = outCell->parent->parent; // Output FPA
    30     pmHDU *outHDU = outFPA->hdu; // Output HDU
     31    pmHDU *outHDU = outFPA->hdu;        // Output HDU
    3132    if (!outHDU->header) {
    3233        outHDU->header = psMetadataAlloc();
    3334    }
    3435
    35     // generate an output readout (first check if it's already there by virtue of kernels)
    36     pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT.KERNELS"); // RO with kernel
    37     if (!outRO) {
    38         outRO = pmReadoutAlloc(outCell); // Output readout: subtraction
     36    // The output readout may already be present if we read in the convolution kernel
     37    pmReadout *outRO = NULL;            // Output readout
     38    if (outCell->readouts && outCell->readouts->n > 0 && outCell->readouts->data[0]) {
     39        outRO = psMemIncrRefCounter(outCell->readouts->data[0]);
     40    } else {
     41        outRO = pmReadoutAlloc(outCell);
    3942    }
    4043
    41     // convolved input images
     44    // Convolved input images
    4245    pmReadout *inConv = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.CONV"); // Input readout
    4346    pmReadout *refConv = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV"); // Reference readout
     47    psFree(view);
    4448
    4549    // Add kernel descrption to header.
     
    5559    if (!kernels) {
    5660        psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find SUBTRACTION.KERNEL");
    57         psFree(inConv);
    58         psFree(refConv);
    5961        psFree(outRO);
    6062        return false;
     
    6365                     kernels->description);
    6466
     67    // Add additional data to the header
     68    pmFPAfile *refFile = psMetadataLookupPtr(NULL, config->files, "PPSUB.REF"); // Reference file
     69    pmFPAfile *inFile = psMetadataLookupPtr(NULL, config->files, "PPSUB.INPUT"); // Input file
     70    psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.REFERENCE", 0,
     71                     "Subtraction reference", refFile->filename);
     72    psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.INPUT", 0,
     73                     "Subtraction input", inFile->filename);
     74    ppSubVersionHeader(outHDU->header);
     75
     76
    6577    outRO->analysis = psMetadataCopy(outRO->analysis, analysis);
    6678
    67 #ifdef TESTING
    68     {
    69         psImage *kernelImage = psMetadataLookupPtr(&mdok, analysis,
    70                                                    "SUBTRACTION.KERNEL.IMAGE"); // Image of kernel
    71         psFits *fits = psFitsOpen("kernel.fits", "w");
    72         psFitsWriteImage(fits, NULL, kernelImage, 0, NULL);
    73         psFitsClose(fits);
    74     }
    75 #endif
     79    psFree(outRO);
    7680
    7781    return true;
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubKernel.c

    r21360 r24244  
    2929    }
    3030
    31     psTraceSetLevel("psModules.imcombine", 7);
     31    (void) psTraceSetLevel("psModules.imcombine", 7);
    3232
    3333    const char *inName = argv[1];       // Input file name
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubLoop.c

    r23352 r24244  
    1717#include <pslib.h>
    1818#include <psmodules.h>
    19 #include <ppStats.h>
    2019
    2120#include "ppSub.h"
    2221
    23 bool ppSubLoop(pmConfig *config)
     22bool ppSubLoop(ppSubData *data)
    2423{
     24    psAssert(data, "Require processing data");
     25    pmConfig *config = data->config;    // Configuration
    2526    psAssert(config, "Require configuration.");
    2627
     
    2829    pmConfigRecipesCull(config, "PPSUB,PPSTATS,PSPHOT,MASKS,JPEG");
    2930
    30     bool mdok;                          // Status of MD lookup
    31     const char *statsName = psMetadataLookupStr(&mdok, config->arguments, "STATS"); // Filename for statistics
    32     psMetadata *stats = NULL;           // Container for statistics
    33     FILE *statsFile = NULL;             // File stream for statistics
    34     if (statsName && strlen(statsName) > 0) {
    35         psString resolved = pmConfigConvertFilename(statsName, config, true, true); // Resolved filename
    36         statsFile = fopen(resolved, "w");
    37         if (!statsFile) {
    38             psError(PS_ERR_IO, true, "Unable to open statistics file %s for writing.\n", resolved);
    39             psFree(resolved);
    40             return false;
    41         } else {
    42             stats = psMetadataAlloc();
    43         }
    44         psFree(resolved);
    45     }
    4631
    4732    pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PPSUB.INPUT");
    48     if (!input) {
    49         psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find input data!\n");
     33    pmFPAfile *reference = psMetadataLookupPtr(NULL, config->files, "PPSUB.REF");
     34    pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PPSUB.OUTPUT");
     35    psAssert(input && reference && output, "Require files");
     36
     37    if (!ppSubFilesIterateDown(config, PPSUB_FILES_INPUT | PPSUB_FILES_CONV)) {
     38        psError(PPSUB_ERR_IO, false, "Unable to load files.");
    5039        return false;
    5140    }
    5241
    53     pmFPAfile *reference = psMetadataLookupPtr(NULL, config->files, "PPSUB.REF");
    54     if (!reference) {
    55         psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find reference data!\n");
     42    psTimerStart("PPSUB_MATCH");
     43
     44    if (!ppSubSetMasks(config)) {
     45        psError(PS_ERR_UNKNOWN, false, "Unable to set masks.");
    5646        return false;
    5747    }
    5848
    59     pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PPSUB.OUTPUT");
    60     if (!output) {
    61         psError(PS_ERR_UNEXPECTED_NULL, false, "Can't find output data!\n");
     49    if (!ppSubMatchPSFs(data)) {
     50        psError(PS_ERR_UNKNOWN, false, "Unable to match PSFs.");
     51        return false;
     52    }
     53    if (data->quality) {
     54        // Can't do anything at all
     55        return true;
     56    }
     57
     58    psMetadataAddF32(data->stats, PS_LIST_TAIL, "TIME_MATCH", 0, "Time to match PSFs",
     59                     psTimerClear("PPSUB_MATCH"));
     60
     61    // Close input files
     62    if (!ppSubFilesIterateUp(config, PPSUB_FILES_INPUT)) {
     63        psError(PPSUB_ERR_IO, false, "Unable to close input files.");
    6264        return false;
    6365    }
    6466
    65     pmFPAview *view = pmFPAviewAlloc(0); // Pointer into FPA hierarchy
    66 
    67     // Iterate over the FPA hierarchy
    68     if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     67    // Set up subtraction files
     68    if (!ppSubFilesIterateDown(config, PPSUB_FILES_SUB)) {
     69        psError(PPSUB_ERR_IO, false, "Unable to set up subtraction files.");
    6970        return false;
    7071    }
    7172
    72     pmChip *inChip;                    // Input chip of interest
    73     while ((inChip = pmFPAviewNextChip(view, input->fpa, 1)) != NULL) {
    74         pmChip *refChip = pmFPAviewThisChip(view, reference->fpa); // Reference chip of interest
    75         if ((!inChip->file_exists && refChip->file_exists) ||
    76             (inChip->file_exists && !refChip->file_exists)) {
    77             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "FPA format discrepency between input and reference");
    78             psFree(view);
     73    if (!ppSubDefineOutput("PPSUB.OUTPUT", config)) {
     74        psError(PS_ERR_UNKNOWN, false, "Unable to define output.");
     75        return false;
     76    }
     77
     78    if (!data->quality && !ppSubMakePSF(data)) {
     79        psError(PS_ERR_UNKNOWN, false, "Unable to generate PSF.");
     80        return false;
     81    }
     82
     83    if (!ppSubReadoutSubtract(config)) {
     84        psError(PS_ERR_UNKNOWN, false, "Unable to subtract images.");
     85        return false;
     86    }
     87
     88    // Close convolved files
     89    if (!ppSubFilesIterateUp(config, PPSUB_FILES_PSF | PPSUB_FILES_CONV)) {
     90        psError(PPSUB_ERR_IO, false, "Unable to close input files.");
     91        return false;
     92    }
     93
     94    // Higher order background subtraction using psphot
     95    if (!ppSubBackground(config)) {
     96        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
     97        return false;
     98    }
     99
     100    if (!ppSubFilesIterateDown(config, PPSUB_FILES_PHOT_SUB)) {
     101        psError(PPSUB_ERR_IO, false, "Unable to set up photometry files.");
     102        return false;
     103    }
     104
     105    if (!data->quality && !ppSubReadoutPhotometry("PPSUB.OUTPUT", data)) {
     106        psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry.");
     107        return false;
     108    }
     109
     110    if (!ppSubFilesIterateUp(config, PPSUB_FILES_PHOT_SUB)) {
     111        psError(PPSUB_ERR_IO, false, "Unable to set up photometry files.");
     112        return false;
     113    }
     114
     115    // Perform statistics on the cell
     116    if (!ppSubReadoutStats(data)) {
     117        psError(PS_ERR_UNKNOWN, false, "Unable to collect statistics");
     118        return false;
     119    }
     120
     121    if (!ppSubReadoutJpeg(config)) {
     122        psError(PS_ERR_UNKNOWN, false, "Unable to update.");
     123        return false;
     124    }
     125
     126    if (data->inverse) {
     127        // Set up inverse subtraction files
     128        if (!ppSubFilesIterateDown(config, PPSUB_FILES_INV)) {
     129            psError(PPSUB_ERR_IO, false, "Unable to set up inverse files.");
    79130            return false;
    80131        }
    81132
    82         if (!inChip->file_exists) {
    83             continue;
    84         }
    85 
    86         if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
     133        if (data->inverse && !ppSubDefineOutput("PPSUB.INVERSE", config)) {
     134            psError(PS_ERR_UNKNOWN, false, "Unable to define inverse.");
    87135            return false;
    88136        }
    89137
    90         pmCell *inCell;                // Cell of interest
    91         while ((inCell = pmFPAviewNextCell(view, input->fpa, 1)) != NULL) {
    92             pmCell *refCell = pmFPAviewThisCell(view, reference->fpa); // Reference cell of interest
    93             if ((!inCell->file_exists && refCell->file_exists) ||
    94                 (inCell->file_exists && !refCell->file_exists)) {
    95                 psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    96                         "FPA format discrepency between input and reference");
    97                 psFree(view);
    98                 return false;
    99             }
    100             if (!inCell->file_exists) {
    101                 continue;
    102             }
    103             if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    104                 return false;
    105             }
    106 
    107             pmReadout *inRO;           // Readin of interest
    108             while ((inRO = pmFPAviewNextReadout(view, input->fpa, 1))) {
    109                 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    110                     return false;
    111                 }
    112                 pmReadout *refRO = pmFPAviewThisReadout(view, reference->fpa);// Reference readout of interest
    113                 if (!refRO || (!inRO->data_exists && refRO->data_exists) ||
    114                     (inRO->data_exists && !refRO->data_exists)) {
    115                     psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    116                             "FPA format discrepency between input and reference");
    117                     psFree(view);
    118                     return false;
    119                 }
    120                 if (!inRO->data_exists) {
    121                     continue;
    122                 }
    123 
    124                 // Perform the analysis
    125                 if (!ppSubReadout(config, stats, view)) {
    126                     psError(PS_ERR_UNKNOWN, false, "Unable to subtract images.\n");
    127                     return false;
    128                 }
    129 
    130                 if (!pmFPAfileIOChecks(config, view, PM_FPA_BEFORE)) {
    131                     return false;
    132                 }
    133             }
    134 
    135             // Perform statistics on the cell
    136             if (stats) {
    137                 pmFPAfile *output = psMetadataLookupPtr(NULL, config->files, "PPSUB.OUTPUT"); // Output file
    138                 if (!output) {
    139                     psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find file PPSUB.OUTPUT.\n");
    140                     return false;
    141                 }
    142                 psImageMaskType maskValue = pmConfigMaskGet("MASK.VALUE", config);
    143                 ppStatsFPA(stats, output->fpa, view, maskValue, config);
    144             }
    145 
    146             if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
    147                 return false;
    148             }
     138        if (!ppSubReadoutInverse(config)) {
     139            psError(PS_ERR_UNKNOWN, false, "Unable to invert images.");
     140            return false;
    149141        }
    150142
    151         if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
     143        // Close subtraction files and open inverse photometry files
     144        if (!ppSubFilesIterateUp(config, PPSUB_FILES_SUB)) {
     145            psError(PPSUB_ERR_IO, false, "Unable to close subtraction files.");
     146            return false;
     147        }
     148
     149        if (!ppSubFilesIterateDown(config, PPSUB_FILES_PHOT_INV)) {
     150            psError(PPSUB_ERR_IO, false, "Unable to set up inverse files.");
     151            return false;
     152        }
     153
     154        if (!data->quality && !ppSubReadoutPhotometry("PPSUB.INVERSE", data)) {
     155            psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry.");
     156            return false;
     157        }
     158
     159        // Close inverse subtraction files
     160        if (!ppSubFilesIterateUp(config, PPSUB_FILES_INV | PPSUB_FILES_PHOT_INV)) {
     161            psError(PPSUB_ERR_IO, false, "Unable to close subtraction files.");
     162            return false;
     163        }
     164    } else {
     165        // Close subtraction files
     166        if (!ppSubFilesIterateUp(config, PPSUB_FILES_SUB)) {
     167            psError(PPSUB_ERR_IO, false, "Unable to close subtraction files.");
    152168            return false;
    153169        }
    154170    }
    155171
    156     if (!pmFPAfileIOChecks(config, view, PM_FPA_AFTER)) {
    157         return false;
    158     }
    159 
    160     psFree(view);
    161 
    162     // Write out summary statistics
    163     if (stats) {
    164         psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_SUB", 0, "Time for subtraction completion",
    165                          psTimerMark("ppSub"));
    166 
    167         const char *statsMDC = psMetadataConfigFormat(stats);
    168         if (!statsMDC || strlen(statsMDC) == 0) {
    169             psWarning("Unable to generate statistics MDC file.\n");
    170         } else {
    171             fprintf(statsFile, "%s", statsMDC);
    172         }
    173         psFree((void *)statsMDC);
    174         fclose(statsFile);
    175 
    176         psFree(stats);
    177     }
    178 
    179     psString dump_file = psMetadataLookupStr(&mdok, config->arguments, "-dumpconfig");
    180     if (dump_file) {
    181 
    182         pmFPAfile *input = psMetadataLookupPtr(NULL, config->files, "PPSUB.INPUT"); // Input file
    183         pmConfigDump(config, input->fpa, dump_file);
    184     }
    185 
    186172    return true;
    187173}
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubMakePSF.c

    r23352 r24244  
    2222#include "ppSub.h"
    2323
    24 bool ppSubMakePSF(pmConfig *config, const pmFPAview *view)
     24bool ppSubMakePSF(ppSubData *data)
    2525{
     26    psAssert(data, "Require processing data");
     27    pmConfig *config = data->config;    // Configuration
    2628    psAssert(config, "Require configuration");
    27     psAssert(view, "Require view");
     29
     30    if (!data->photometry) {
     31        return true;
     32    }
    2833
    2934    psTimerStart("PPSUB_PHOT");
     
    3641    }
    3742
    38     psMetadata *psphotRecipe = psMetadataLookupMetadata(NULL, config->recipes, PSPHOT_RECIPE);// psphot recipe
    39     psAssert(recipe, "We checked this earlier, so it should be here.");
    40 
    4143    bool reverse = psMetadataLookupBool(NULL, config->arguments, "REVERSE"); // Reverse sense of subtraction?
    4244
     
    4446    pmReadout *minuend = NULL;          // Image that will be positive following subtraction
    4547    pmFPAfile *minuendFile = NULL;      // File for minuend image
     48    pmFPAview *view = ppSubViewReadout(); // View to readout
    4649    if (reverse) {
    4750        minuend = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.CONV");
     
    5255    }
    5356
    54 #if 1
    55     pmReadout *template = minuend;
    5657    pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.INPUT"); // Photometry file
     58    if (!pmFPACopy(photFile->fpa, minuendFile->fpa)) {
     59        psError(PS_ERR_UNKNOWN, false, "Unable to copy FPA for photometry");
     60        psFree(view);
     61        return false;
     62    }
    5763    pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer
    58     if (!photRO) {
    59         pmCell *cell = pmFPAviewThisCell(view, photFile->fpa); // Cell to photometer
    60         photRO = pmReadoutAlloc(cell); // Output readout: subtraction
     64    if (psMetadataLookup(photRO->analysis, "PSPHOT.SOURCES")) {
     65        psMetadataRemoveKey(photRO->analysis, "PSPHOT.SOURCES");
    6166    }
    62     photRO->image = psImageCopy(photRO->image, template->image, PS_TYPE_F32);
    63     if (template->variance) {
    64         photRO->variance = psImageCopy(photRO->variance, template->variance, PS_TYPE_F32);
    65     } else {
    66         psFree(photRO->variance);
    67         photRO->variance = NULL;
    68     }
    69     if (template->mask) {
    70         photRO->mask = psImageCopy(photRO->mask, template->mask, PS_TYPE_IMAGE_MASK);
    71     } else {
    72         psFree(photRO->mask);
    73         photRO->mask = NULL;
    74     }
    75 #else
    76     // Supply the minuend pmFPAfile to psphot as PSPHOT.INPUT:
    77     psMetadataAddPtr(config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_REPLACE,
    78                      "psphot input: view on another pmFPAfile", minuendFile);
    79 #endif
    8067
    8168    // Extract the loaded sources from the associated readout, and generate PSF
     
    8370    psArray *sources = psMetadataLookupPtr(&mdok, minuend->analysis, "PSPHOT.SOURCES");
    8471    if (!psphotReadoutFindPSF(config, view, sources)) {
    85         psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry on subtracted image.");
    86         return false;
     72        // This is likely a data quality issue
     73        // XXX Split into multiple cases using error codes?
     74        psErrorStackPrint(stderr, "Unable to determine PSF");
     75        psWarning("Unable to determine PSF --- suspect bad data quality.");
     76        ppSubDataQuality(data, PSPHOT_ERR_PSF, PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV);
     77        psFree(view);
     78        return true;
    8779    }
    88 
    89     // Record the FWHM in the output header
    90     pmReadout *outRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT"); // Output readout
    91     pmHDU *hdu = pmHDUFromCell(outRO->parent); // HDU with header
    92     psMetadataItemSupplement(hdu->header, psphotRecipe, "FWHM_MAJ");
    93     psMetadataItemSupplement(hdu->header, psphotRecipe, "FWHM_MIN");
    9480
    9581    // Get rid of the generated header; it will be regenerated by the real photometry run
    9682    psMetadataRemoveKey(photRO->analysis, "PSPHOT.HEADER");
    9783
     84    if (!data->quality) {
     85        data->psf = psMemIncrRefCounter(psMetadataLookupPtr(NULL, photRO->parent->parent->analysis,
     86                                                            "PSPHOT.PSF"));
     87    }
     88
     89    psFree(view);
     90
    9891    return true;
    9992}
    100 
    101 // XXX we used to need this, is it still needed?
    102 
    103 // pmCell *photCell = pmFPAfileThisCell(config->files, view, "PSPHOT.INPUT");
    104 // pmCellFreeReadouts(photCell);
    105 
    106 // if (!pmFPAfileDropInternal(config->files, "PSPHOT.BACKMDL") ||
    107 //     !pmFPAfileDropInternal (config->files, "PSPHOT.BACKMDL.STDEV") ||
    108 //     !pmFPAfileDropInternal (config->files, "PSPHOT.BACKGND")) {
    109 //     psError(PS_ERR_UNKNOWN, false, "Unable to drop PSPHOT internal files.");
    110 //     return false;
    111 // }
    112 
    113 // Blow away the sources psphot found --- they're irrelevant for the subtraction
    114 // XXX is this still needed?  These are now probably not being set
    115 // pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout with sources
    116 // psMetadataRemoveKey(photRO->analysis, "PSPHOT.SOURCES");
    117 // psMetadataRemoveKey(photRO->analysis, "PSPHOT.HEADER");
    118 
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubMatchPSFs.c

    r23594 r24244  
    2222#include "ppSub.h"
    2323
    24 bool ppSubMatchPSFs(pmConfig *config, const pmFPAview *view)
     24bool ppSubMatchPSFs(ppSubData *data)
    2525{
     26    psAssert(data, "Require processing data");
     27    pmConfig *config = data->config;    // Configuration
    2628    psAssert(config, "Require configuration");
    27     psAssert(view, "Require view");
    2829
    2930    // Look up recipe values
    3031    psMetadata *recipe = psMetadataLookupMetadata(NULL, config->recipes, PPSUB_RECIPE); // Recipe for ppSim
    3132    psAssert(recipe, "We checked this earlier, so it should be here.");
     33
     34    pmFPAview *view = ppSubViewReadout(); // View to readout
    3235
    3336    // Input images
     
    5255    pmReadout *kernelRO = pmFPAfileThisReadout(config->files, view, "PPSUB.OUTPUT.KERNELS"); // RO with kernel
    5356
     57    psFree(view);
     58
    5459    // Sources in image, used for stamps: these must be loaded from previous analysis stages
    55     psArray *inSources = psMetadataLookupPtr(&mdok, inRO->analysis, "PSPHOT.SOURCES"); // Input source list
    56     psArray *refSources = psMetadataLookupPtr(&mdok, refRO->analysis, "PSPHOT.SOURCES"); // Ref source list
     60    pmReadout *inSourceRO = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT.SOURCES");
     61    pmReadout *refSourceRO = pmFPAfileThisReadout(config->files, view, "PPSUB.REF.SOURCES");
     62    psArray *inSources = inSourceRO ? psMetadataLookupPtr(&mdok, inSourceRO->analysis, "PSPHOT.SOURCES") :
     63        NULL; // Source list from input image
     64    psArray *refSources = refSourceRO ? psMetadataLookupPtr(&mdok, refSourceRO->analysis, "PSPHOT.SOURCES") :
     65        NULL ; // Source list from reference image
    5766
    5867    psArray *sources = NULL;            // Merged list of sources
     
    8594    float spacing = psMetadataLookupF32(NULL, recipe, "STAMP.SPACING"); // Typical stamp spacing
    8695    float threshold = psMetadataLookupF32(NULL, recipe, "STAMP.THRESHOLD"); // Threshold for stmps
    87     const char *stampsName = psMetadataLookupStr(&mdok, config->arguments, "STAMPS"); // Filename for stamps
    8896
    8997    const char *typeStr = psMetadataLookupStr(NULL, recipe, "KERNEL.TYPE"); // Kernel type
     
    136144
    137145    // Match the PSFs
     146    bool success = false;               // Operation was successful?
    138147    if (kernelRO) {
    139         if (!pmSubtractionMatchPrecalc(inConv, refConv, inRO, refRO, kernelRO->analysis,
    140                                        stride, sys, maskVal, maskBad, maskPoor, poorFrac, badFrac)) {
    141             psError(PS_ERR_UNKNOWN, false, "Unable to convolve images.");
    142             return false;
    143         }
     148        success = pmSubtractionMatchPrecalc(inConv, refConv, inRO, refRO, kernelRO->analysis,
     149                                            stride, sys, maskVal, maskBad, maskPoor, poorFrac, badFrac);
    144150    } else {
    145         if (!pmSubtractionMatch(inConv, refConv, inRO, refRO, footprint, stride, regionSize, spacing,
    146                                 threshold, sources, stampsName, type, size, order, widths, orders, inner,
    147                                 ringsOrder, binning, penalty, optimum, optWidths, optOrder, optThresh, iter,
    148                                 rej, sys, maskVal, maskBad, maskPoor, poorFrac, badFrac, subMode)) {
     151        success = pmSubtractionMatch(inConv, refConv, inRO, refRO, footprint, stride, regionSize,
     152                                     spacing, threshold, sources, data->stamps, type, size, order,
     153                                     widths, orders, inner, ringsOrder, binning, penalty, optimum,
     154                                     optWidths, optOrder, optThresh, iter, rej, sys, maskVal,
     155                                     maskBad, maskPoor, poorFrac, badFrac, subMode);
     156    }
     157
     158    psFree(optWidths);
     159    pmSubtractionThreadsFinalize(inRO, refRO);
     160
     161    if (!success) {
     162        psErrorCode error = psErrorCodeLast(); // Error code
     163        if (error == PM_ERR_STAMPS) {
     164            psErrorStackPrint(stderr, "Unable to find stamps");
     165            psWarning("Unable to find stamps --- suspect bad data quality.");
     166            ppSubDataQuality(data, error, PPSUB_FILES_ALL);
     167            return true;
     168        } else {
    149169            psError(PS_ERR_UNKNOWN, false, "Unable to match images.");
    150170            return false;
     
    152172    }
    153173
    154     psFree(optWidths);
    155 
    156     pmSubtractionThreadsFinalize(inRO, refRO);
     174    pmConceptsCopyFPA(inConv->parent->parent->parent, inRO->parent->parent->parent, true, true);
     175    pmConceptsCopyFPA(refConv->parent->parent->parent, refRO->parent->parent->parent, true, true);
    157176
    158177    psImageCovarianceTransfer(inConv->variance, inConv->covariance);
    159178    psImageCovarianceTransfer(refConv->variance, refConv->covariance);
    160179
    161     // XXX drop the pixels associated with inRO and refRO (now that we have inConv and refConf)
    162 #ifdef TESTING
    163     psphotSaveImage (NULL, inRO->image, "inRO.fits");
    164     psphotSaveImage (NULL, refRO->image, "refRO.fits");
    165     psphotSaveImage (NULL, inConv->image, "inConv.fits");
    166     psphotSaveImage (NULL, refConv->image, "refConv.fits");
    167 #endif
    168 
    169180    return true;
    170181}
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubReadout.c

    r21524 r24244  
    2121#include "ppSub.h"
    2222
    23 bool ppSubReadout(pmConfig *config, psMetadata *stats, const pmFPAview *view)
     23bool ppSubReadout(const char *name, bool reverse, ppSubData *data, const pmFPAview *view)
    2424{
    25     psTimerStart("PPSUB_MATCH");
     25    psAssert(data, "Require processing data");
     26    pmConfig *config = data->config;    // Configuration
     27    psAssert(config, "Require configuration");
    2628
    27     if (!ppSubSetMasks(config, view)) {
    28         psError(PS_ERR_UNKNOWN, false, "Unable to set masks.");
    29         return false;
    30     }
     29    psAssert(name, "Require name");
     30    psAssert(view, "Require view");
    3131
    32     if (!ppSubMatchPSFs(config, view)) {
    33         psError(PS_ERR_UNKNOWN, false, "Unable to match PSFs.");
    34         return false;
    35     }
    36 
    37     if (!ppSubDefineOutput(config, view)) {
     32    if (!ppSubDefineOutput(name, config, data, view)) {
    3833        psError(PS_ERR_UNKNOWN, false, "Unable to define output.");
    3934        return false;
    4035    }
    4136
    42     if (!ppSubMakePSF(config, view)) {
     37    if (!data->quality && !ppSubMakePSF(name, config, data, view)) {
    4338        psError(PS_ERR_UNKNOWN, false, "Unable to generate PSF.");
    4439        return false;
    4540    }
    4641
    47     if (!ppSubReadoutSubtract(config, view)) {
     42    if (!ppSubReadoutSubtract(name, reverse, config, view)) {
    4843        psError(PS_ERR_UNKNOWN, false, "Unable to subtract images.");
    4944        return false;
     
    5146
    5247    // Higher order background subtraction using psphot
    53     if (!ppSubBackground(config, view)) {
     48    if (!ppSubBackground(name, config, view)) {
    5449        psError(PS_ERR_UNKNOWN, false, "Unable to subtract background.");
    5550        return false;
    5651    }
    5752
    58     if (!ppSubReadoutPhotometry(config, stats, view)) {
     53    if (!data->quality && data->!ppSubReadoutPhotometry(name, config, data, view)) {
    5954        psError(PS_ERR_UNKNOWN, false, "Unable to perform photometry.");
    6055        return false;
    6156    }
    6257
    63     if (!ppSubReadoutUpdate(config, stats, view)) {
     58    if (!ppSubReadoutUpdate(name, config, data, view)) {
    6459        psError(PS_ERR_UNKNOWN, false, "Unable to update.");
    6560        return false;
    6661    }
    6762
     63
     64
     65
    6866    return true;
    6967}
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubReadoutPhotometry.c

    r21524 r24244  
    2222#include "ppSub.h"
    2323
    24 bool ppSubReadoutPhotometry (pmConfig *config, psMetadata *stats, const pmFPAview *view)
     24bool ppSubReadoutPhotometry(const char *name, ppSubData *data)
    2525{
     26    psAssert(data, "Require processing data");
     27    pmConfig *config = data->config;    // Configuration
    2628    psAssert(config, "Require configuration");
    27     psAssert(view, "Require view");
     29
     30    if (!data->photometry) {
     31        return true;
     32    }
    2833
    2934    // Look up recipe values
     
    3944    // The PSF (measured in ppSubMakePSF) is stored on the chip->analysis of PSPHOT.INPUT
    4045    // In order to use an incoming PSF, it must be stored on the chip->analysis of PSPHOT.PSF.LOAD
     46    pmFPAview *view = ppSubViewReadout(); // View to readout
    4147    pmChip *psfInputChip = pmFPAfileThisChip(config->files, view, "PSPHOT.INPUT"); // Chip with PSF
    4248    psAssert (psfInputChip, "should have been generated for ppSubMakePSF");
     
    4551    pmPSF *psf = psMetadataLookupPtr(NULL, psfInputChip->analysis, "PSPHOT.PSF"); // PSF for photometry
    4652    if (!psf) {
    47         psError(PS_ERR_UNEXPECTED_NULL, true, "Unable to find PSF from psphot");
    48         return false;
     53        psErrorStackPrint(stderr, "No PSF available");
     54        psWarning("No PSF available --- suspect bad data quality.");
     55        ppSubDataQuality(data, psErrorCodeLast(), PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV);
     56        return true;
    4957    }
    5058    psMetadataAddPtr(psfLoadChip->analysis, PS_LIST_TAIL, "PSPHOT.PSF", PS_DATA_UNKNOWN | PS_META_REPLACE,
     
    5664    // around the pointers so PSPHOT.INPUT corresponds to the output image; previously, it was
    5765    // equivalent to the minuend image.
    58     pmFPAfile *outputFile = psMetadataLookupPtr(&mdok, config->files, "PPSUB.OUTPUT"); // Output file
    59     pmReadout *outRO = pmFPAviewThisReadout(view, outputFile->fpa); // Readout with the sources
     66    pmReadout *inRO = pmFPAfileThisReadout(config->files, view, name); // Readout with image and sources
    6067
    61     // XXX possibly rename this to PPSUB.RESID?
    6268    pmFPAfile *photFile = psMetadataLookupPtr(&mdok, config->files, "PSPHOT.INPUT"); // Photometry file
     69    pmFPAfile *inFile = psMetadataLookupPtr(&mdok, config->files, name); // Input file
     70    if (!pmFPACopy(photFile->fpa, inFile->fpa)) {
     71        psError(PS_ERR_UNKNOWN, false, "Unable to copy FPA for photometry");
     72        psFree(view);
     73        return false;
     74    }
    6375    pmReadout *photRO = pmFPAviewThisReadout(view, photFile->fpa); // Readout to photometer
    64     if (!photRO) {
    65         pmCell *cell = pmFPAviewThisCell(view, photFile->fpa); // Cell to photometer
    66         photRO = pmReadoutAlloc(cell); // Output readout: subtraction
    67     }
    68     photRO->image = psImageCopy(photRO->image, outRO->image, PS_TYPE_F32);
    69     if (outRO->variance) {
    70         photRO->variance = psImageCopy(photRO->variance, outRO->variance, PS_TYPE_F32);
    71     } else {
    72         psFree(photRO->variance);
    73         photRO->variance = NULL;
    74     }
    75     if (outRO->mask) {
    76         photRO->mask = psImageCopy(photRO->mask, outRO->mask, PS_TYPE_IMAGE_MASK);
    77     } else {
    78         psFree(photRO->mask);
    79         photRO->mask = NULL;
     76    if (psMetadataLookup(photRO->analysis, "PSPHOT.SOURCES")) {
     77        psMetadataRemoveKey(photRO->analysis, "PSPHOT.SOURCES");
    8078    }
    8179
    82 #if 0
    83     psMetadataAddPtr(config->files, PS_LIST_TAIL, "PSPHOT.INPUT", PS_DATA_UNKNOWN | PS_META_REPLACE,
    84                      "psphot input: view on another pmFPAfile", photFile);
    85 #endif
     80    psMetadataAddPtr(photRO->parent->parent->analysis, PS_LIST_TAIL, "PSPHOT.PSF",
     81                     PS_META_REPLACE | PS_DATA_UNKNOWN, "Point-spread function", data->psf);
     82
     83    psFree(photRO->analysis);
     84    photRO->analysis = psMetadataAlloc();
    8685
    8786    if (!psphotReadoutMinimal(config, view)) {
    88         psWarning("Unable to perform photometry on subtracted image.");
    89         psErrorStackPrint(stderr, "Error stack from photometry:");
    90         psErrorClear();
     87        // This is likely a data quality issue
     88        // XXX Split into multiple cases using error codes?
     89        psErrorStackPrint(stderr, "Unable to perform photometry on image");
     90        psWarning("Unable to perform photometry on image --- suspect bad data quality.");
     91        ppSubDataQuality(data, psErrorCodeLast(), PPSUB_FILES_PHOT_SUB | PPSUB_FILES_PHOT_INV);
    9192    }
    92 #if 1
    93     photRO->data_exists = true;
    94     photRO->parent->data_exists = true;
    95     photRO->parent->parent->data_exists = true;
    96 #endif
    9793
    98     if (stats) {
     94    if (data->stats) {
    9995        psArray *sources = psMetadataLookupPtr(NULL, photRO->analysis, "PSPHOT.SOURCES"); // Sources
    100         psMetadataAddS32(stats, PS_LIST_TAIL, "NUM_SOURCES", 0, "Number of sources detected",
    101                          sources ? sources->n : 0);
    102         psMetadataAddF32(stats, PS_LIST_TAIL, "TIME_PHOT", 0, "Time to do photometry",
    103                          psTimerClear("PPSUB_PHOT"));
     96        bool mdok;
     97        int numSources = psMetadataLookupS32(&mdok, data->stats, "NUM_SOURCES"); // Number of sources
     98        numSources += sources ? sources->n : 0;
     99        psMetadataAddS32(data->stats, PS_LIST_TAIL, "NUM_SOURCES", PS_META_REPLACE,
     100                         "Total number of sources detected", numSources);
     101        float newTime = psTimerClear("PPSUB_PHOT"); // Time for photometry
     102        float oldTime = psMetadataLookupF32(&mdok, data->stats, "TIME_PHOT"); // Previous time for photometry
     103        psMetadataAddF32(data->stats, PS_LIST_TAIL, "TIME_PHOT", PS_META_REPLACE, "Time to do photometry",
     104                         isfinite(oldTime) ? oldTime + newTime : newTime);
     105    }
     106
     107    if (!data->quality) {
     108        if (!psMetadataCopySingle(inRO->analysis, photRO->analysis, "PSPHOT.SOURCES")) {
     109            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to copy PSPHOT.SOURCES");
     110            return false;
     111        }
     112        if (!psMetadataCopySingle(inRO->analysis, photRO->analysis, "PSPHOT.HEADER")) {
     113            psError(PS_ERR_UNEXPECTED_NULL, false, "Unable to copy PSPHOT.HEADER");
     114            return false;
     115        }
    104116    }
    105117
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubReadoutSubtract.c

    r22699 r24244  
    2121#include "ppSub.h"
    2222
    23 #define WCS_TOLERANCE 0.001             // Tolerance for WCS
    24 
    25 bool ppSubReadoutSubtract(pmConfig *config, const pmFPAview *view)
     23bool ppSubReadoutSubtract(pmConfig *config)
    2624{
    2725    psAssert(config, "Require configuration");
    28     psAssert(view, "Require view");
    29 
    3026
    3127    // Look up recipe values
     
    3531
    3632    bool reverse = psMetadataLookupBool(&mdok, config->arguments, "REVERSE"); // Reverse sense of subtraction?
     33
     34    pmFPAview *view = ppSubViewReadout(); // View to readout
    3735
    3836    // Subtraction is: minuend - subtrahend
     
    7472    covars->data[0] = psMemIncrRefCounter(minuend->covariance);
    7573    covars->data[1] = psMemIncrRefCounter(subtrahend->covariance);
    76     outRO->covariance = psImageCovarianceSum(covars);
     74    outRO->covariance = psImageCovarianceAverage(covars);
    7775    psFree(covars);
    7876
     
    9189        psError(PS_ERR_UNKNOWN, false, "Unable to copy concepts from input to output.");
    9290        psFree(outRO);
     91        psFree(view);
    9392        return false;
    9493    }
     
    9998    pmHDU *outHDU = outFPA->hdu;        // Output HDU
    10099    pmChip *outChip = pmFPAfileThisChip(config->files, view, "PPSUB.OUTPUT"); // Output chip
     100    psFree(view);
    101101    if (!outHDU || !inHDU) {
    102102        psError(PS_ERR_UNKNOWN, false, "Unable to find HDU at FPA level to copy astrometry.");
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubSetMasks.c

    r23594 r24244  
    2222#include "ppSub.h"
    2323
    24 bool ppSubSetMasks(pmConfig *config, const pmFPAview *view)
     24bool ppSubSetMasks(pmConfig *config)
    2525{
    2626    psAssert(config, "Require configuration");
    27     psAssert(view, "Require view");
    2827
    2928    psImageMaskType maskValue, markValue; // Mask values
     
    5049    psAssert(lowValue, "LOW or BAD must be non-zero");
    5150
    52     // input images
     51    // Input images
     52    pmFPAview *view = ppSubViewReadout(); // View to readout
    5353    pmReadout *inRO = pmFPAfileThisReadout(config->files, view, "PPSUB.INPUT"); // Input readout
    5454    pmReadout *refRO = pmFPAfileThisReadout(config->files, view, "PPSUB.REF"); // Reference readout
  • branches/cnb_branches/cnb_branch_20090301/ppSub/src/ppSubVersion.c

    r23352 r24244  
    2222
    2323#include "ppSub.h"
     24#include "ppSubVersionDefinitions.h"
    2425
    2526#ifndef PPSUB_VERSION
     
    3334#endif
    3435
    35 #define xstr(s) str(s)
    36 #define str(s) #s
    37 
    3836psString ppSubVersion(void)
    3937{
    4038    char *value = NULL;
    41     psStringAppend(&value, "%s@%s", xstr(PPSUB_BRANCH), xstr(PPSUB_VERSION));
     39    psStringAppend(&value, "%s@%s", PPSUB_BRANCH, PPSUB_VERSION);
    4240    return value;
    4341}
     
    4543psString ppSubSource(void)
    4644{
    47     return psStringCopy(xstr(PPSUB_SOURCE));
     45    return psStringCopy(PPSUB_SOURCE);
    4846}
    4947
Note: See TracChangeset for help on using the changeset viewer.