IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 15844


Ignore:
Timestamp:
Dec 14, 2007, 3:32:16 PM (18 years ago)
Author:
Paul Price
Message:

Using pmPSFEnvelope to generate a target PSF.

Location:
trunk/ppStack/src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppStack/src/ppStack.h

    r14811 r15844  
    3838                  const pmReadout *input, ///< Readout to be convolved
    3939                  const pmReadout *sourcesRO, ///< Readout with sources
     40                  const pmPSF *psf,     ///< Target PSF
    4041                  const pmConfig *config ///< Configuration
    4142    );
  • trunk/ppStack/src/ppStackArguments.c

    r14842 r15844  
    2525            "\tMASK(STR):      Mask filename\n"
    2626            "\tWEIGHT(STR)     Weight map filename\n"
     27            "\tPSF(STR)        PSF filename\n"
    2728            "\tWEIGHTING(F32): Relative weighting to be applied\n"
    2829            "\tSCALE(F32):     Relative scaling to be applied\n",
     
    117118    psMetadataAddF32(arguments, PS_LIST_TAIL, "-threshold-mask", 0, "Threshold for mask deconvolution", NAN);
    118119    psMetadataAddBool(arguments, PS_LIST_TAIL, "-photometry", 0, "Do photometry on stacked image?", false);
     120    psMetadataAddS32(arguments, PS_LIST_TAIL, "-psf-instances", 0, "Number of instances for PSF generation", 5);
     121    psMetadataAddF32(arguments, PS_LIST_TAIL, "-psf-radius", 0, "Radius for PSF generation", 20.0);
     122    psMetadataAddStr(arguments, PS_LIST_TAIL, "-psf-model", 0, "Model name for PSF generation", "PS_MODEL_RGAUSS");
     123    psMetadataAddS32(arguments, PS_LIST_TAIL, "-psf-order", 0, "Spatial order for PSF generation", 3);
    119124
    120125    if (argc == 1 || !psArgumentParse(arguments, &argc, argv) || argc != 3) {
     
    165170    VALUE_ARG_RECIPE_FLOAT("-threshold-mask", "THRESHOLD.MASK", F32);
    166171
     172    VALUE_ARG_RECIPE_INT("-psf-instances", "PSF.INSTANCES", S32, 0);
     173    VALUE_ARG_RECIPE_FLOAT("-psf-radius",  "PSF.RADIUS",    F32);
     174    VALUE_ARG_RECIPE_INT("-psf-order",     "PSF.ORDER",     S32, 0);
     175    valueArgStr(config, arguments, "-psf-model", "PSF.MODEL", config->arguments);
     176
    167177    if (psMetadataLookupBool(NULL, arguments, "-photometry") ||
    168178        psMetadataLookupBool(NULL, recipe, "PHOTOMETRY")) {
  • trunk/ppStack/src/ppStackCamera.c

    r14834 r15844  
    1414{
    1515    bool haveWeights = false;           // Do we have weight maps?
     16    bool havePSFs = false;              // Do we have PSFs?
    1617
    1718    psMetadata *inputs = psMetadataLookupMetadata(NULL, config->arguments, "INPUTS"); // The inputs info
     
    3940        psString mask = psMetadataLookupStr(&mdok, input, "MASK"); // Name of mask
    4041        psString weight = psMetadataLookupStr(&mdok, input, "WEIGHT"); // Name of weight map
     42        psString psf = psMetadataLookupStr(&mdok, input, "PSF"); // Name of PSF
    4143
    4244        float weighting = psMetadataLookupF32(&mdok, input, "WEIGHTING"); // Relative weighting
     
    115117        }
    116118
     119        // Optionally add the psf file
     120        if (psf && strlen(psf) > 0) {
     121            havePSFs = true;
     122            psArray *psfFiles = psArrayAlloc(1); // Array of filenames for this FPA
     123            psfFiles->data[0] = psMemIncrRefCounter(psf);
     124            psMetadataAddArray(config->arguments, PS_LIST_TAIL, "PSF.FILENAMES", PS_META_REPLACE,
     125                               "Filenames of PSF files", psfFiles);
     126            psFree(psfFiles);
     127
     128            bool status;
     129            pmFPAfile *psfFile = pmFPAfileBindFromArgs(&status, imageFile, config, "PSPHOT.PSF.LOAD",
     130                                                       "PSF.FILENAMES");
     131            if (!status) {
     132                psError(PS_ERR_UNKNOWN, false, "Unable to define file from psf %d (%s)", i, psf);
     133                return false;
     134            }
     135            if (psfFile->type != PM_FPA_FILE_PSF) {
     136                psError(PS_ERR_IO, true, "PSPHOT.PSF.LOAD is not of type PSF");
     137                return false;
     138            }
     139        }
     140
    117141        psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0,
    118142                         "Relative weighting for image", weighting);
     
    129153    if (psMetadataLookup(config->arguments, "WEIGHT.FILENAMES")) {
    130154        psMetadataRemoveKey(config->arguments, "WEIGHT.FILENAMES");
     155    }
     156    if (psMetadataLookup(config->arguments, "PSF.FILENAMES")) {
     157        psMetadataRemoveKey(config->arguments, "PSF.FILENAMES");
    131158    }
    132159
     
    214241    }
    215242
     243    // Output PSF
     244    if (havePSFs) {
     245        pmFPAfile *outPSF = pmFPAfileDefineOutput(config, output->fpa, "PSPHOT.PSF.SAVE");
     246        if (!outPSF) {
     247            psError(PS_ERR_IO, false, _("Unable to generate output file from PSPHOT.PSF.SAVE"));
     248            return false;
     249        }
     250        if (outPSF->type != PM_FPA_FILE_PSF) {
     251            psError(PS_ERR_IO, true, "PSPHOT.PSF.SAVE is not of type PSF");
     252            return false;
     253        }
     254        outPSF->save = true;
     255    }
     256
    216257    // Sources for use as stamps
    217258    bool status = false;                // Found the file?
  • trunk/ppStack/src/ppStackMatch.c

    r15816 r15844  
    1212
    1313bool ppStackMatch(pmReadout *output, const pmReadout *input, const pmReadout *sourcesRO,
    14                   const pmConfig *config)
     14                  const pmPSF *psf, const pmConfig *config)
    1515{
    1616    // Look up appropriate values from the ppSub recipe
     
    4646    // These values are specified specifically for stacking
    4747    const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS"); // Filename for stamps
    48     float target = psMetadataLookupF32(NULL, config->arguments, "TARGET"); // Target PSF width
    4948
    5049    psVector *optWidths = NULL;         // Vector with FWHMs for optimum search
     
    6665        }
    6766    }
    68     pmReadout *fake = pmReadoutFakeFromSources(input->image->numCols, input->image->numRows,
    69                                                sources, target, powf(10.0, -0.4 * maxMag));
     67
     68    pmReadout *fake = pmReadoutAlloc(NULL); // Fake readout with target PSF
     69
     70    if (!pmReadoutFakeFromSources(fake, input->image->numCols, input->image->numRows, sources, NULL, NULL,
     71                                  psf, powf(10.0, -0.4 * maxMag), 0, false)) {
     72        psError(PS_ERR_UNKNOWN, false, "Unable to generate fake image with target PSF.");
     73        psFree(fake);
     74        psFree(optWidths);
     75        return false;
     76    }
    7077
    7178#ifdef TESTING
  • trunk/ppStack/src/ppStackReadout.c

    r15457 r15844  
    2828    float threshold = psMetadataLookupF32(NULL, config->arguments, "THRESHOLD.MASK"); // Threshold for mask deconvolution
    2929    bool photometry = psMetadataLookupBool(&mdok, config->arguments, "PHOTOMETRY"); // Perform photometry?
     30    int psfInstances = psMetadataLookupS32(&mdok, config->arguments, "PSF.INSTANCES"); // Number of instances for PSF
     31    float psfRadius = psMetadataLookupF32(NULL, config->arguments, "PSF.RADIUS"); // Radius for PSF
     32    const char *psfModel = psMetadataLookupStr(NULL, config->arguments, "PSF.MODE"); // Model for PSF
     33    int psfOrder = psMetadataLookupS32(&mdok, config->arguments, "PSF.ORDER"); // Spatial order for PSF
    3034
    3135    // Get the output target
     
    4347                                                           "^PPSTACK.INPUT$"); // Iterator over input files
    4448    psMetadataItem *fileItem;           // Item from iteration
     49    int fileNum = 0;                    // Number of file
     50    psList *psfList = psListAlloc(NULL); // List of PSFs for PSF envelope
     51    pmPSF *outPSF = NULL;               // Ouptut PSF
     52    int numCols = 0, numRows = 0;       // Size of image
     53    while ((fileItem = psMetadataGetAndIncrement(fileIter))) {
     54        assert(fileItem->type == PS_DATA_UNKNOWN);
     55        pmFPAfile *inputFile = fileItem->data.V; // An input file
     56        pmReadout *ro = pmFPAviewThisReadout(view, inputFile->fpa); // Corresponding readout
     57        pmCell *cell = ro->parent;      // The cell
     58        pmChip *chip = cell->parent;    // The chip: holds the PSF
     59
     60        bool mdok;                      // Status of MD lookup
     61        pmPSF *psf = psMetadataLookupPtr(&mdok, chip->analysis, "PSPHOT.PSF");
     62        if (mdok && psf) {
     63            psListAdd(psfList, PS_LIST_TAIL, psf);
     64            if (numCols == 0 && numRows == 0) {
     65                numCols = ro->image->numCols;
     66                numRows = ro->image->numRows;
     67            }
     68        }
     69    }
     70
     71    bool convolve = false;              // Convolve the input images?
     72    if (psfList->n > 0) {
     73        psArray *psfArray = psListToArray(psfList); // Array of PSFs
     74        outPSF = pmPSFEnvelope(numCols, numRows, psfArray, psfInstances, psfRadius, psfModel,
     75                               psfOrder, psfOrder);
     76        psFree(psfArray);
     77        if (!outPSF) {
     78            psError(PS_ERR_UNKNOWN, false, "Unable to determine output PSF.");
     79            // XXX Free stuff
     80            return false;
     81        }
     82        convolve = true;
     83        PS_ASSERT_PTR_NON_NULL(sources, false);
     84    }
     85
     86    // Iterate through again to get the convolved images (or not)
     87
    4588    psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics
    4689    psRandom *rng = psRandomAlloc(0, PS_RANDOM_TAUS); // Random number generator
    47     int fileNum = 0;                    // Number of file
    4890    float totExposure = 0.0;            // Total exposure time
    4991    psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging
    5092    psList *cellList = psListAlloc(NULL); // List of input cells, for concept averaging
     93
     94    psMetadataIteratorSet(fileIter, PS_LIST_HEAD);
     95    fileNum = 0;
    5196    while ((fileItem = psMetadataGetAndIncrement(fileIter))) {
    5297        assert(fileItem->type == PS_DATA_UNKNOWN);
     
    85130
    86131        // Generate convolved version of input
    87         pmReadout *convolved = pmReadoutAlloc(NULL); // Convolved version of input readout
    88 #ifndef NO_CONVOLUTION
    89         if (!ppStackMatch(convolved, ro, sources, config)) {
    90             psWarning("Unable to match image %d --- ignoring.", fileNum);
    91             psErrorClear();
    92             psFree(convolved);
    93             // XXX Free the bad image so it's not taking up good memory!
    94             continue;
    95         }
     132        pmReadout *convolved;
     133        if (convolve) {
     134            convolved = pmReadoutAlloc(NULL); // Convolved version of input readout
     135            // Background subtraction, scaling and normalisation is performed automatically by the image
     136            // matching
     137            if (!ppStackMatch(convolved, ro, sources, outPSF, config)) {
     138                psWarning("Unable to match image %d --- ignoring.", fileNum);
     139                psErrorClear();
     140                psFree(convolved);
     141                // XXX Free the bad image so it's not taking up good memory!
     142                continue;
     143            }
    96144
    97145#ifdef CONVOLUTION_FILES
    98         if (convolved->image) {
    99             psString name = NULL;           // Name of image
    100             psStringAppend(&name, "convolved%03d_image.fits", fileNum);
    101             psFits *fits = psFitsOpen(name, "w");
    102             psFree(name);
    103             psFitsWriteImage(fits, NULL, convolved->image, 0, NULL);
    104             psFitsClose(fits);
    105         }
    106         if (convolved->mask) {
    107             psString name = NULL;           // Name of image
    108             psStringAppend(&name, "convolved%03d_mask.fits", fileNum);
    109             psFits *fits = psFitsOpen(name, "w");
    110             psFree(name);
    111             psFitsWriteImage(fits, NULL, convolved->mask, 0, NULL);
    112             psFitsClose(fits);
    113         }
    114         if (convolved->weight) {
    115             psString name = NULL;           // Name of image
    116             psStringAppend(&name, "convolved%03d_weight.fits", fileNum);
    117             psFits *fits = psFitsOpen(name, "w");
    118             psFree(name);
    119             psFitsWriteImage(fits, NULL, convolved->weight, 0, NULL);
    120             psFitsClose(fits);
    121         }
     146            if (convolved->image) {
     147                psString name = NULL;           // Name of image
     148                psStringAppend(&name, "convolved%03d_image.fits", fileNum);
     149                psFits *fits = psFitsOpen(name, "w");
     150                psFree(name);
     151                psFitsWriteImage(fits, NULL, convolved->image, 0, NULL);
     152                psFitsClose(fits);
     153            }
     154            if (convolved->mask) {
     155                psString name = NULL;           // Name of image
     156                psStringAppend(&name, "convolved%03d_mask.fits", fileNum);
     157                psFits *fits = psFitsOpen(name, "w");
     158                psFree(name);
     159                psFitsWriteImage(fits, NULL, convolved->mask, 0, NULL);
     160                psFitsClose(fits);
     161            }
     162            if (convolved->weight) {
     163                psString name = NULL;           // Name of image
     164                psStringAppend(&name, "convolved%03d_weight.fits", fileNum);
     165                psFits *fits = psFitsOpen(name, "w");
     166                psFree(name);
     167                psFitsWriteImage(fits, NULL, convolved->weight, 0, NULL);
     168                psFitsClose(fits);
     169            }
    122170#endif // CONVOLUTION_FILES
    123171
    124 #else
    125         convolved = psMemIncrRefCounter(ro);
    126         sources = NULL;
    127 #endif // NO_CONVOLVUTION
    128 
    129 
    130 #if 0
    131         // Background subtraction, scaling and normalisation is performed automatically by the image matching
    132 
    133         // Brain-dead background subtraction
    134         if (!psImageBackground(stats, ro->image, ro->mask, maskBad, rng)) {
    135             psError(PS_ERR_UNKNOWN, false, "Unable to get image background on image %ld", stack->n);
    136             psFree(stats);
    137             psFree(rng);
    138             psFree(fileIter);
    139             psFree(fpaList);
    140             psFree(cellList);
    141             psFree(stack);
    142             psFree(outRO);
    143             psFree(convolved);
    144             return false;
    145         }
    146         psTrace("ppStack", 3, "Background for image %d is %f\n", fileNum, stats->robustMedian);
    147         (void)psBinaryOp(ro->image, ro->image, "-", psScalarAlloc(stats->robustMedian, PS_TYPE_F32));
    148 
    149         // Apply scaling
    150         (void)psBinaryOp(ro->image, ro->image, "*", psScalarAlloc(1.0 / scale, PS_TYPE_F32));
    151 
    152         // Normalise each input by the exposure time
    153         float exposure = psMetadataLookupF32(NULL, ro->parent->concepts, "CELL.EXPOSURE"); // Exposure time
    154         if (!isfinite(exposure)) {
    155             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    156                     "CELL.EXPOSURE is not set for input file %ld", stack->n);
    157             psFree(stats);
    158             psFree(rng);
    159             psFree(fileIter);
    160             psFree(fpaList);
    161             psFree(cellList);
    162             psFree(outRO);
    163             psFree(convolved);
    164             psFree(stack);
    165             return false;
    166         }
    167 
    168         (void)psBinaryOp(ro->image, ro->image, "/", psScalarAlloc(exposure, PS_TYPE_F32));
    169         if (ro->weight) {
    170             (void)psBinaryOp(ro->weight, ro->weight, "/", psScalarAlloc(exposure, PS_TYPE_F32));
    171         }
    172 #endif
     172        } else {
     173            // No convolution --- just use the unconvolved images as the "convolved" images, with some tweaks
     174            convolved = psMemIncrRefCounter(ro);
     175            sources = NULL;
     176
     177            // Brain-dead background subtraction
     178            if (!psImageBackground(stats, NULL, ro->image, ro->mask, maskBad, rng)) {
     179                psError(PS_ERR_UNKNOWN, false, "Unable to get image background on image %ld", stack->n);
     180                psFree(stats);
     181                psFree(rng);
     182                psFree(fileIter);
     183                psFree(fpaList);
     184                psFree(cellList);
     185                psFree(stack);
     186                psFree(outRO);
     187                psFree(convolved);
     188                return false;
     189            }
     190            psTrace("ppStack", 3, "Background for image %d is %f\n", fileNum, stats->robustMedian);
     191            (void)psBinaryOp(ro->image, ro->image, "-", psScalarAlloc(stats->robustMedian, PS_TYPE_F32));
     192
     193            // Apply scaling
     194            (void)psBinaryOp(ro->image, ro->image, "*", psScalarAlloc(1.0 / scale, PS_TYPE_F32));
     195
     196            // Normalise each input by the exposure time
     197            float exposure = psMetadataLookupF32(NULL, ro->parent->concepts, "CELL.EXPOSURE");// Exposure time
     198            if (!isfinite(exposure)) {
     199                psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     200                        "CELL.EXPOSURE is not set for input file %ld", stack->n);
     201                psFree(stats);
     202                psFree(rng);
     203                psFree(fileIter);
     204                psFree(fpaList);
     205                psFree(cellList);
     206                psFree(outRO);
     207                psFree(convolved);
     208                psFree(stack);
     209                return false;
     210            }
     211
     212            (void)psBinaryOp(ro->image, ro->image, "/", psScalarAlloc(exposure, PS_TYPE_F32));
     213            if (ro->weight) {
     214                (void)psBinaryOp(ro->weight, ro->weight, "/", psScalarAlloc(exposure, PS_TYPE_F32));
     215            }
     216        }
    173217
    174218        if (fileNum == 0) {
     
    330374    }
    331375
    332 #if 0
    333     // Restore image to counts using the total exposure time
    334     (void)psBinaryOp(outRO->image, outRO->image, "*", psScalarAlloc(totExposure, PS_TYPE_F32));
    335     if (outRO->weight) {
    336         (void)psBinaryOp(outRO->weight, outRO->weight, "*", psScalarAlloc(totExposure, PS_TYPE_F32));
    337     }
    338 #endif
     376    if (!convolve) {
     377        // Restore image to counts using the total exposure time
     378        (void)psBinaryOp(outRO->image, outRO->image, "*", psScalarAlloc(totExposure, PS_TYPE_F32));
     379        if (outRO->weight) {
     380            (void)psBinaryOp(outRO->weight, outRO->weight, "*", psScalarAlloc(totExposure, PS_TYPE_F32));
     381        }
     382    }
     383
    339384    psMetadataAddF32(outCell->concepts, PS_LIST_TAIL, "CELL.EXPOSURE", PS_META_REPLACE,
    340385                     "Summed exposure time (sec)", totExposure);
Note: See TracChangeset for help on using the changeset viewer.