IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 14626


Ignore:
Timestamp:
Aug 22, 2007, 4:47:19 PM (19 years ago)
Author:
Paul Price
Message:

Changes to stacking to allow it to work on convolved images.

Location:
trunk/ppStack/src
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppStack/src/Makefile.am

    r14404 r14626  
    1010        ppStackLoop.c           \
    1111        ppStackReadout.c        \
    12         ppStackVersion.c
     12        ppStackVersion.c        \
     13        ppStackMatch.c
    1314
    1415noinst_HEADERS =                \
  • trunk/ppStack/src/ppStack.h

    r13464 r14626  
    3434    );
    3535
     36/// Convolve image to match specified seeing
     37bool ppStackMatch(pmReadout *output,    ///< Convolved readout
     38                  const pmReadout *input, ///< Readout to be convolved
     39                  const pmConfig *config ///< Configuration
     40    );
     41
    3642#endif
  • trunk/ppStack/src/ppStackArguments.c

    r14404 r14626  
    1919{
    2020    fprintf(stderr, "\nPan-STARRS Image combination\n\n");
    21     fprintf(stderr, "Usage: %s INPUTS.mdc OUTPUT_ROOT\n"
     21    fprintf(stderr, "Usage: %s INPUTS.mdc OUTPUT_ROOT -target FWHM -stamps FILENAME\n"
    2222            "where INPUTS.mdc contains various METADATAs, each with:\n"
    2323            "\tIMAGE(STR):     Image filename\n"
    2424            "\tMASK(STR):      Mask filename\n"
    2525            "\tWEIGHT(STR)     Weight map filename\n"
    26             "\tSEEING(F32):    Seeing FWHM (pixels)\n"
    2726            "\tWEIGHTING(F32): Relative weighting to be applied\n"
    2827            "\tSCALE(F32):     Relative scaling to be applied\n",
     
    103102
    104103    psMetadata *arguments = psMetadataAlloc(); // Command-line arguments
     104    psMetadataAddStr(arguments, PS_LIST_TAIL, "-stamps", 0, "Stamps file with x,y,flux per line", NULL);
     105    psMetadataAddF32(arguments, PS_LIST_TAIL, "-target", 0, "Target PSF FWHM", NAN);
    105106    psMetadataAddStr(arguments, PS_LIST_TAIL, "-stats", 0, "Statistics file", NULL);
    106107    psMetadataAddS32(arguments, PS_LIST_TAIL, "-iter", 0, "Number of rejection iterations", 0);
     
    110111    psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-bad", 0, "Mask value for bad pixels", 0);
    111112    psMetadataAddU8(arguments,  PS_LIST_TAIL, "-mask-blank", 0, "Mask value for blank region", 0);
     113    psMetadataAddF32(arguments, PS_LIST_TAIL, "-threshold-mask", 0, "Threshold for mask deconvolution", NAN);
    112114
    113115    // XXX I want to get this from the recipe as well.  (same for everything else...)
     
    117119        usage(argv[0], arguments, config);
    118120    }
     121
     122    const char *stampsName = psMetadataLookupStr(NULL, arguments, "-stamps"); // Name of stamps file
     123    if (!stampsName || strlen(stampsName) == 0) {
     124        psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Stamps file not specified with -stamps.");
     125        goto ERROR;
     126    }
     127    psMetadataAddStr(config->arguments, PS_LIST_TAIL, "STAMPS", 0, "Stamps file", stampsName);
     128
     129    float target = psMetadataLookupF32(NULL, arguments, "-target"); // Target PSF width
     130    if (!isfinite(target)) {
     131        psError(PS_ERR_BAD_PARAMETER_VALUE, false, "Target PSF width not specified with -target.");
     132        goto ERROR;
     133    }
     134    psMetadataAddF32(config->arguments, PS_LIST_TAIL, "TARGET", 0, "Target PSF width", target);
     135
    119136
    120137    unsigned int numBad = 0;                     // Number of bad lines
     
    138155    }
    139156
    140     VALUE_ARG_RECIPE_INT("-iter",           "ITER",         S32, 0);
    141     VALUE_ARG_RECIPE_FLOAT("-combine-rej",  "COMBINE.REJ",  F32);
    142     VALUE_ARG_RECIPE_FLOAT("-convolve-rej", "CONVOLVE.REJ", F32);
    143     VALUE_ARG_RECIPE_FLOAT("-extent",       "EXTENT",       F32);
    144     VALUE_ARG_RECIPE_MASK("-mask-bad",      "MASK.BAD");
    145     VALUE_ARG_RECIPE_MASK("-mask-blank",    "MASK.BLANK");
     157    VALUE_ARG_RECIPE_INT("-iter",             "ITER",           S32, 0);
     158    VALUE_ARG_RECIPE_FLOAT("-combine-rej",    "COMBINE.REJ",    F32);
     159    VALUE_ARG_RECIPE_FLOAT("-convolve-rej",   "CONVOLVE.REJ",   F32);
     160    VALUE_ARG_RECIPE_FLOAT("-extent",         "EXTENT",         F32);
     161    VALUE_ARG_RECIPE_MASK("-mask-bad",        "MASK.BAD");
     162    VALUE_ARG_RECIPE_MASK("-mask-blank",      "MASK.BLANK");
     163    VALUE_ARG_RECIPE_FLOAT("-threshold-mask", "THRESHOLD.MASK", F32);
    146164
    147165    psTrace("ppStack", 1, "Done reading command-line arguments\n");
  • trunk/ppStack/src/ppStackCamera.c

    r14520 r14626  
    4040        psString weight = psMetadataLookupStr(&mdok, input, "WEIGHT"); // Name of weight map
    4141
    42         float seeing = psMetadataLookupF32(&mdok, input, "SEEING"); // Seeing FWHM
    43         if (!mdok || isnan(seeing) || seeing == 0.0) {
    44             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Component %s lacks SEEING of type F32", item->name);
    45             psFree(iter);
    46             return false;
    47         }
    48 
    4942        float weighting = psMetadataLookupF32(&mdok, input, "WEIGHTING"); // Relative weighting
    5043        if (!mdok || isnan(weighting) || weighting == 0.0) {
     
    122115        }
    123116
    124         psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.SEEING", 0,
    125                          "Seeing for image", seeing);
    126117        psMetadataAddF32(imageFile->fpa->analysis, PS_LIST_TAIL, "PPSTACK.WEIGHTING", 0,
    127118                         "Relative weighting for image", weighting);
  • trunk/ppStack/src/ppStackReadout.c

    r14520 r14626  
    1515{
    1616    // Get the recipe values
    17     bool mdok;                          // Status of MD lookup
    1817    int iter = psMetadataLookupS32(NULL, config->arguments, "ITER"); // Rejection iterations
    1918    float combineRej = psMetadataLookupF32(NULL, config->arguments, "COMBINE.REJ"); // Combination threshold
    20     float convolveRej = psMetadataLookupF32(NULL, config->arguments, "CONVOLVE.REJ"); // Convolution threshold
    21     float extent = psMetadataLookupF32(NULL, config->arguments, "EXTENT"); // Extent of convolution
    2219    psMaskType maskBad = psMetadataLookupU8(NULL, config->arguments, "MASK.BAD"); // Value to mask
    2320    psMaskType maskBlank = psMetadataLookupU8(NULL, config->arguments, "MASK.BLANK"); // Mask for blank reg.
    24     psVector *seeing = psMetadataLookupPtr(&mdok, config->arguments, "SEEING"); // Seeing in each image
     21    float threshold = psMetadataLookupF32(NULL, config->arguments, "THRESHOLD.MASK"); // Threshold for mask deconvolution
    2522
    2623    // Get the output target
     
    4138    int fileNum = 0;                    // Number of file
    4239    float totExposure = 0.0;            // Total exposure time
    43     pmReadout *templateRO = NULL;       // Template readout, for copy WCS
    4440    psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging
    4541    psList *cellList = psListAlloc(NULL); // List of input cells, for concept averaging
     
    5349
    5450        bool mdok;                      // Status of MD lookup
    55         float seeing = psMetadataLookupF32(&mdok, inputFile->fpa->analysis, "PPSTACK.SEEING"); // Seeing FWHM
    56         if (!mdok || !isfinite(seeing)) {
    57             psWarning("No SEEING supplied for image %d --- set to unity.", fileNum);
    58             seeing = 1.0;
    59         }
    6051        float weighting = psMetadataLookupF32(&mdok, inputFile->fpa->analysis,
    6152                                              "PPSTACK.WEIGHTING"); // Relative weighting
     
    6960            scale = 1.0;
    7061        }
     62
     63        float exposure = psMetadataLookupF32(NULL, ro->parent->concepts, "CELL.EXPOSURE"); // Exposure time
     64#if 0
     65        if (!isfinite(exposure)) {
     66            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     67                    "CELL.EXPOSURE is not set for input file %ld", stack->n);
     68            psFree(stats);
     69            psFree(rng);
     70            psFree(fileIter);
     71            psFree(fpaList);
     72            psFree(cellList);
     73            psFree(outRO);
     74            psFree(stack);
     75            return false;
     76        }
     77#endif
     78        totExposure += exposure;        // Total exposure time
     79        // Generate convolved version of input
     80        pmReadout *convolved = pmReadoutAlloc(NULL); // Convolved version of input readout
     81        if (!ppStackMatch(convolved, ro, config)) {
     82            psError(PS_ERR_UNKNOWN, false, "Unable to match image %d.", fileNum);
     83            psFree(stats);
     84            psFree(rng);
     85            psFree(fileIter);
     86            psFree(fpaList);
     87            psFree(cellList);
     88            psFree(stack);
     89            psFree(outRO);
     90            psFree(convolved);
     91            return false;
     92        }
     93
     94#ifdef REJECTION_FILES
     95        {
     96            psString name = NULL;           // Name of image
     97            psStringAppend(&name, "convolved%03d.fits", fileNum);
     98            psFits *fits = psFitsOpen(name, "w");
     99            psFree(name);
     100            psFitsWriteImage(fits, NULL, convolved->image, 0, NULL);
     101            psFitsClose(fits);
     102        }
     103#endif
     104
     105
     106#if 0
     107        // Background subtraction, scaling and normalisation is performed automatically by the image matching
    71108
    72109        // Brain-dead background subtraction
     
    80117            psFree(stack);
    81118            psFree(outRO);
     119            psFree(convolved);
    82120            return false;
    83121        }
     
    99137            psFree(cellList);
    100138            psFree(outRO);
     139            psFree(convolved);
    101140            psFree(stack);
    102141            return false;
    103142        }
    104         totExposure += exposure;        // Total exposure time
     143
    105144        (void)psBinaryOp(ro->image, ro->image, "/", psScalarAlloc(exposure, PS_TYPE_F32));
    106145        if (ro->weight) {
    107146            (void)psBinaryOp(ro->weight, ro->weight, "/", psScalarAlloc(exposure, PS_TYPE_F32));
    108147        }
    109         pmStackData *data = pmStackDataAlloc(ro, seeing, weighting); // Data to stack
     148#endif
     149
     150        if (fileNum == 0) {
     151            // Copy astrometry over
     152            pmFPA *fpa = ro->parent->parent->parent; // Template FPA
     153            pmHDU *hdu = fpa->hdu; // Template HDU
     154            pmHDU *outHDU = outFPA->hdu; // Output HDU
     155            if (!outHDU || !hdu) {
     156                psWarning("Unable to find HDU at FPA level to copy astrometry.");
     157            } else {
     158                if (!pmAstromReadWCS(outFPA, outCell->parent, hdu->header, 1.0)) {
     159                    psError(PS_ERR_UNKNOWN, false, "Unable to read WCS astrometry from input FPA.");
     160                    psFree(stack);
     161                    psFree(outRO);
     162                    return false;
     163                }
     164                if (!outHDU->header) {
     165                    outHDU->header = psMetadataAlloc();
     166                }
     167                if (!pmAstromWriteWCS(outHDU->header, outFPA, outCell->parent, WCS_TOLERANCE)) {
     168                    psError(PS_ERR_UNKNOWN, false, "Unable to write WCS astrometry to output FPA.");
     169                    psFree(stack);
     170                    psFree(outRO);
     171                    return false;
     172                }
     173            }
     174        }
     175
     176        // Don't need the original any more!
     177        psFree(ro);
     178
     179        // Ensure there is a mask, or pmStackCombine will complain
     180        if (!convolved->mask) {
     181            convolved->mask = psImageAlloc(convolved->image->numCols, convolved->image->numRows,
     182                                           PS_TYPE_MASK);
     183            psImageInit(convolved->mask, 0);
     184        }
     185
     186        pmStackData *data = pmStackDataAlloc(convolved, weighting); // Data to stack
     187        psFree(convolved);
    110188        psArrayAdd(stack, ARRAY_BUFFER, data);
    111189        psFree(data);                   // Drop reference
    112 
    113         // Ensure there is a mask, or pmStackCombine will complain
    114         if (!ro->mask) {
    115             ro->mask = psImageAlloc(ro->image->numCols, ro->image->numRows, PS_TYPE_MASK);
    116             psImageInit(ro->mask, 0);
    117         }
    118 
    119         if (fileNum == 0) {
    120             templateRO = ro;
    121         }
    122190
    123191        fileNum++;
     
    159227#endif
    160228
    161     // Only perform the additional rejection if we have seeing information
    162     if (seeing && !pmStackReject(stack, maskBad, extent, convolveRej)) {
    163         psError(PS_ERR_UNKNOWN, false, "Unable to reject input pixels.");
    164         psFree(fpaList);
    165         psFree(cellList);
    166         psFree(stack);
    167         psFree(outRO);
    168         return false;
     229    for (int i = 0; i < num; i++) {
     230        pmStackData *data = stack->data[i]; // Data for this image
     231        pmReadout *readout = data->readout; // Readout for this image
     232
     233        // Extract the regions and solutions used in the image matching
     234        psArray *regions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of regions
     235        {
     236            psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD,
     237                                                               "^SUBTRACTION.REGION$"); // Iterator
     238            psMetadataItem *item = NULL;// Item from iteration
     239            while ((item = psMetadataGetAndIncrement(iter))) {
     240                assert(item->type == PS_DATA_REGION);
     241                regions = psArrayAdd(regions, ARRAY_BUFFER, item->data.V);
     242            }
     243            psFree(iter);
     244        }
     245        psArray *solutions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of solutions
     246        {
     247            psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD,
     248                                                               "^SUBTRACTION.SOLUTION$"); // Iterator
     249            psMetadataItem *item = NULL;// Item from iteration
     250            while ((item = psMetadataGetAndIncrement(iter))) {
     251                assert(item->type == PS_DATA_VECTOR);
     252                solutions = psArrayAdd(solutions, ARRAY_BUFFER, item->data.V);
     253            }
     254            psFree(iter);
     255        }
     256        assert(regions->n == solutions->n);
     257
     258        pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, readout->analysis,
     259                                                            "SUBTRACTION.KERNEL"); // Kernels
     260
     261        psPixels *reject = pmSubtractionDeconvolveMask(data->pixels, threshold, regions,
     262                                                       solutions, kernels); // List of pixels to reject
     263        psFree(data->pixels);
     264        data->pixels = reject;
    169265    }
    170266
     
    195291    }
    196292
     293#if 0
    197294    // Restore image to counts using the total exposure time
    198295    (void)psBinaryOp(outRO->image, outRO->image, "*", psScalarAlloc(totExposure, PS_TYPE_F32));
     
    200297        (void)psBinaryOp(outRO->weight, outRO->weight, "*", psScalarAlloc(totExposure, PS_TYPE_F32));
    201298    }
     299#endif
    202300    psMetadataAddF32(outCell->concepts, PS_LIST_TAIL, "CELL.EXPOSURE", PS_META_REPLACE,
    203301                     "Summed exposure time (sec)", totExposure);
     
    215313    psFree(cellList);
    216314
    217     // Copy astrometry over
    218     pmFPA *templateFPA = templateRO->parent->parent->parent; // Template FPA
    219     pmHDU *templateHDU = templateFPA->hdu; // Template HDU
    220     pmHDU *outHDU = outFPA->hdu; // Output HDU
    221     if (!outHDU || !templateHDU) {
    222         psWarning("Unable to find HDU at FPA level to copy astrometry.");
    223     } else {
    224         if (!pmAstromReadWCS(outFPA, outCell->parent, templateHDU->header, 1.0)) {
    225             psError(PS_ERR_UNKNOWN, false, "Unable to read WCS astrometry from input FPA.");
    226             psFree(stack);
    227             psFree(outRO);
    228             return false;
    229         }
    230         if (!outHDU->header) {
    231             outHDU->header = psMetadataAlloc();
    232         }
    233         if (!pmAstromWriteWCS(outHDU->header, outFPA, outCell->parent, WCS_TOLERANCE)) {
    234             psError(PS_ERR_UNKNOWN, false, "Unable to write WCS astrometry to output FPA.");
    235             psFree(stack);
    236             psFree(outRO);
    237             return false;
    238         }
    239     }
    240 
    241315    psFree(stack);
    242316    psFree(outRO);                      // Drop reference
Note: See TracChangeset for help on using the changeset viewer.