IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Feb 22, 2008, 9:28:00 AM (18 years ago)
Author:
Paul Price
Message:

Merging in branch development. ppStack now works with incremental reads. Needs some cleanup, but it works.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppStack/src/ppStackReadout.c

    r15849 r16605  
    1010#include "ppStack.h"
    1111
    12 #define ARRAY_BUFFER 16                 // Number to add to array at a time
    1312#define WCS_TOLERANCE 0.001             // Tolerance for WCS
    1413
    15 //#define NO_CONVOLUTION                  // Don't perform convolutions?
    16 //#define CONVOLUTION_FILES               // Write convolutions?
    1714//#define REJECTION_FILES                 // Write rejection mask?
    1815//#define INSPECTION_FILES                // Write inspection mask?
    1916
    20 bool ppStackReadout(pmConfig *config, const pmFPAview *view)
     17static int sectionNum = 0;              // Section number; for debugging outputs
     18
     19
     20bool ppStackReadout(const pmConfig *config, pmReadout *outRO, const psArray *readouts,
     21                    const psArray *regions, const psArray *kernels)
    2122{
     23    assert(config);
     24    assert(outRO);
     25    assert(readouts);
     26    assert(regions);
     27    assert(kernels);
     28    assert(readouts->n == regions->n);
     29    assert(regions->n == kernels->n);
     30
     31
    2232    // Get the recipe values
    23     bool mdok;                          // Status of MD lookup
    2433    int iter = psMetadataLookupS32(NULL, config->arguments, "ITER"); // Rejection iterations
    2534    float combineRej = psMetadataLookupF32(NULL, config->arguments, "COMBINE.REJ"); // Combination threshold
     
    2736    psMaskType maskBlank = psMetadataLookupU8(NULL, config->arguments, "MASK.BLANK"); // Mask for blank reg.
    2837    float threshold = psMetadataLookupF32(NULL, config->arguments, "THRESHOLD.MASK"); // Threshold for mask deconvolution
    29     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.MODEL"); // Model for PSF
    33     int psfOrder = psMetadataLookupS32(&mdok, config->arguments, "PSF.ORDER"); // Spatial order for PSF
    34 
    35     // Get the output target
    36     pmCell *outCell = pmFPAfileThisCell(config->files, view, "PPSTACK.OUTPUT"); // Output cell
    37     pmReadout *outRO = pmReadoutAlloc(outCell); // Output readout
    38     pmFPA *outFPA = outCell->parent->parent; // Output FPA
    39 
    40     int num = psMetadataLookupS32(NULL, config->arguments, "INPUTS.NUM"); // Number of inputs
    41     assert(num > 0);
    42 
    43     // Get the input sources
    44     psArray *stack = psArrayAllocEmpty(ARRAY_BUFFER); // The stack of inputs
    45     pmReadout *sources = pmFPAfileThisReadout(config->files, view, "PPSTACK.SOURCES"); // Sources for stamps
    46     psMetadataIterator *fileIter = psMetadataIteratorAlloc(config->files, PS_LIST_HEAD,
    47                                                            "^PPSTACK.INPUT$"); // Iterator over input files
    48     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 
    88     psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics
    89     psRandom *rng = psRandomAlloc(0, PS_RANDOM_TAUS); // Random number generator
     38
     39    int num = readouts->n;              // Number of inputs
     40    psArray *stack = psArrayAlloc(num); // Array for stacking
     41
     42    pmCell *outCell = outRO->parent;    // Output cell
     43    pmChip *outChip = outCell->parent;  // Output chip
     44    pmFPA *outFPA = outChip->parent;    // Output FPA
     45
    9046    float totExposure = 0.0;            // Total exposure time
    9147    psList *fpaList = psListAlloc(NULL); // List of input FPAs, for concept averaging
    9248    psList *cellList = psListAlloc(NULL); // List of input cells, for concept averaging
    93 
    94     psMetadataIteratorSet(fileIter, PS_LIST_HEAD);
    95     fileNum = 0;
    96     while ((fileItem = psMetadataGetAndIncrement(fileIter))) {
    97         assert(fileItem->type == PS_DATA_UNKNOWN);
    98         pmFPAfile *inputFile = fileItem->data.V; // An input file
    99         pmReadout *ro = pmFPAviewThisReadout(view, inputFile->fpa); // Corresponding readout
     49    for (int i = 0; i < num; i++) {
     50        pmReadout *ro = readouts->data[i];
     51        assert(ro);
     52        pmFPA *fpa = ro->parent->parent->parent; // Parent FPA
    10053
    10154        bool mdok;                      // Status of MD lookup
    102         float weighting = psMetadataLookupF32(&mdok, inputFile->fpa->analysis,
    103                                               "PPSTACK.WEIGHTING"); // Relative weighting
     55        float weighting = psMetadataLookupF32(&mdok, fpa->analysis, "PPSTACK.WEIGHTING"); // Relative weight
    10456        if (!mdok || !isfinite(weighting)) {
    105             psWarning("No WEIGHTING supplied for image %d --- set to unity.", fileNum);
     57            psWarning("No WEIGHTING supplied for image %d --- set to unity.", i);
    10658            weighting = 1.0;
    10759        }
    108         float scale = psMetadataLookupF32(&mdok, inputFile->fpa->analysis, "PPSTACK.SCALE"); // Rel. scale
    109         if (!mdok || !isfinite(scale)) {
    110             psWarning("No SCALE supplied for image %d --- set to unity.", fileNum);
    111             scale = 1.0;
    112         }
    11360
    11461        float exposure = psMetadataLookupF32(NULL, ro->parent->concepts, "CELL.EXPOSURE"); // Exposure time
    115 #if 0
    11662        if (!isfinite(exposure)) {
    11763            psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    11864                    "CELL.EXPOSURE is not set for input file %ld", stack->n);
    119             psFree(stats);
    120             psFree(rng);
    121             psFree(fileIter);
    12265            psFree(fpaList);
    12366            psFree(cellList);
    124             psFree(outRO);
    12567            psFree(stack);
    12668            return false;
    12769        }
    128 #endif
    12970        totExposure += exposure;        // Total exposure time
    13071
    131         // Generate convolved version of input
    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             }
    144 
    145 #ifdef CONVOLUTION_FILES
    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             }
    170 #endif // CONVOLUTION_FILES
    171 
    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         }
    217 
    218         if (fileNum == 0) {
     72#if 0
     73        if (i == 0) {
    21974            // Copy astrometry over
    220             pmFPA *fpa = ro->parent->parent->parent; // Template FPA
    22175            pmHDU *hdu = fpa->hdu; // Template HDU
    22276            pmHDU *outHDU = outFPA->hdu; // Output HDU
     
    22478                psWarning("Unable to find HDU at FPA level to copy astrometry.");
    22579            } else {
    226                 if (!pmAstromReadWCS(outFPA, outCell->parent, hdu->header, 1.0)) {
     80                if (!pmAstromReadWCS(outFPA, outChip, hdu->header, 1.0)) {
    22781                    psErrorClear();
    22882                    psWarning("Unable to read WCS astrometry from input FPA.");
     
    23185                        outHDU->header = psMetadataAlloc();
    23286                    }
    233                     if (!pmAstromWriteWCS(outHDU->header, outFPA, outCell->parent, WCS_TOLERANCE)) {
     87                    if (!pmAstromWriteWCS(outHDU->header, outFPA, outChip, WCS_TOLERANCE)) {
    23488                        psErrorClear();
    23589                        psWarning("Unable to write WCS astrometry to output FPA.");
     
    23892            }
    23993        }
    240 
    241         // Don't need the original any more!
    242         psFree(ro);
     94#endif
    24395
    24496        // Ensure there is a mask, or pmStackCombine will complain
    245         if (!convolved->mask) {
    246             convolved->mask = psImageAlloc(convolved->image->numCols, convolved->image->numRows,
    247                                            PS_TYPE_MASK);
    248             psImageInit(convolved->mask, 0);
    249         }
    250 
    251         psListAdd(fpaList, PS_LIST_TAIL, inputFile->fpa);
     97        if (!ro->mask) {
     98            ro->mask = psImageAlloc(ro->image->numCols, ro->image->numRows, PS_TYPE_MASK);
     99            psImageInit(ro->mask, 0);
     100        }
     101
     102        psListAdd(fpaList, PS_LIST_TAIL, fpa);
    252103        psListAdd(cellList, PS_LIST_TAIL, ro->parent);
    253104
    254         pmStackData *data = pmStackDataAlloc(convolved, weighting); // Data to stack
    255         psFree(convolved);
    256         psArrayAdd(stack, ARRAY_BUFFER, data);
    257         psFree(data);                   // Drop reference
    258 
    259         fileNum++;
    260     }
    261     psFree(fileIter);
    262     psFree(stats);
    263     psFree(rng);
    264 
    265     if (fileNum == 0) {
    266         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Not enough good files to combine.");
    267         psFree(fpaList);
    268         psFree(cellList);
    269         psFree(stack);
    270         psFree(outRO);
    271         return false;
     105        stack->data[i] = pmStackDataAlloc(ro, weighting);
    272106    }
    273107
     
    277111        psFree(cellList);
    278112        psFree(stack);
    279         psFree(outRO);
    280113        return false;
    281114    }
     
    283116#ifdef INSPECTION_FILES
    284117    {
    285         psFits *fits = psFitsOpen("combined.fits", "w");
     118        psString name = NULL;           // Name of image
     119        psStringAppend(&name, "combined_%03d.fits", sectionNum);
     120        psFits *fits = psFitsOpen(name, "w");
     121        psFree(name);
    286122        psFitsWriteImage(fits, NULL, outRO->image, 0, NULL);
    287123        psFitsClose(fits);
     
    291127        pmStackData *data = stack->data[i]; // Data for this image
    292128        psImage *inspected = psPixelsToMask(NULL, data->pixels,
    293                                             psRegionSet(0, data->readout->image->numCols,
    294                                                         0, data->readout->image->numRows),
     129                                            psRegionSet(0, data->readout->image->numCols - 1,
     130                                                        0, data->readout->image->numRows - 1),
    295131                                            maskBlank);
    296132        psString name = NULL;           // Name of image
    297         psStringAppend(&name, "inspect%03d.fits", i);
     133        psStringAppend(&name, "inspect_%03d_%03d.fits", sectionNum, i);
    298134        psFits *fits = psFitsOpen(name, "w");
    299135        psFree(name);
     
    304140#endif
    305141
    306     for (int i = 0; i < stack->n; i++) {
     142    // Reject pixels
     143    for (int i = 0; i < num; i++) {
    307144        pmStackData *data = stack->data[i]; // Data for this image
    308         pmReadout *readout = data->readout; // Readout for this image
    309 
    310         // Extract the regions and solutions used in the image matching
    311         psArray *regions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of regions
    312         {
    313             psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD,
    314                                                                "^SUBTRACTION.REGION$"); // Iterator
    315             psMetadataItem *item = NULL;// Item from iteration
    316             while ((item = psMetadataGetAndIncrement(iter))) {
    317                 assert(item->type == PS_DATA_REGION);
    318                 regions = psArrayAdd(regions, ARRAY_BUFFER, item->data.V);
    319             }
    320             psFree(iter);
    321         }
    322         psArray *solutions = psArrayAllocEmpty(ARRAY_BUFFER); // Array of solutions
    323         {
    324             psMetadataIterator *iter = psMetadataIteratorAlloc(readout->analysis, PS_LIST_HEAD,
    325                                                                "^SUBTRACTION.SOLUTION$"); // Iterator
    326             psMetadataItem *item = NULL;// Item from iteration
    327             while ((item = psMetadataGetAndIncrement(iter))) {
    328                 assert(item->type == PS_DATA_VECTOR);
    329                 solutions = psArrayAdd(solutions, ARRAY_BUFFER, item->data.V);
    330             }
    331             psFree(iter);
    332         }
    333         assert(regions->n == solutions->n);
    334 
    335         pmSubtractionKernels *kernels = psMetadataLookupPtr(NULL, readout->analysis,
    336                                                             "SUBTRACTION.KERNEL"); // Kernels
    337 
    338         psPixels *reject = pmStackReject(data->pixels, threshold, regions,
    339                                          solutions, kernels); // List of pixels to reject
     145        pmReadout *readout = data->readout; // Readout of interest
     146        int col0 = readout->col0, row0 = readout->row0; // Offset for readout
     147        int numCols = readout->image->numCols, numRows = readout->image->numRows; // Size of image
     148
     149        psRegion *valid = psRegionAlloc(col0, col0 + numCols, row0, row0 + numRows); // Valid region for rej
     150        psPixels *reject = pmStackReject(data->pixels, valid, threshold, regions->data[i],
     151                                         kernels->data[i]); // Pixels to reject
     152        psFree(valid);
    340153        psFree(data->pixels);
    341154        data->pixels = reject;
    342 
    343         psFree(solutions);
    344         psFree(regions);
    345155    }
    346156
     
    352162        }
    353163        psImage *rejected = psPixelsToMask(NULL, data->pixels,
    354                                            psRegionSet(0, data->readout->image->numCols,
    355                                                        0, data->readout->image->numRows),
     164                                           psRegionSet(0, data->readout->image->numCols - 1,
     165                                                       0, data->readout->image->numRows - 1),
    356166                                           maskBlank);
    357167        psString name = NULL;           // Name of image
    358         psStringAppend(&name, "reject%03d.fits", i);
     168        psStringAppend(&name, "reject_%03d_%03d.fits", sectionNum, i);
    359169        psFits *fits = psFitsOpen(name, "w");
    360170        psFree(name);
     
    370180        psFree(cellList);
    371181        psFree(stack);
    372         psFree(outRO);
    373182        return false;
    374     }
    375 
    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         }
    382183    }
    383184
     
    397198    psFree(cellList);
    398199
    399     if (photometry) {
    400         pmFPAfile *photFile = psMetadataLookupPtr(NULL, config->files, "PSPHOT.INPUT");
    401         pmFPACopy(photFile->fpa, outRO->parent->parent->parent);
    402 
    403         if (!psphotReadout(config, view)) {
    404             psWarning("Unable to perform photometry on stacked image.");
    405             psErrorStackPrint(stderr, "Error stack from photometry:");
    406             psErrorClear();
    407         }
    408 
    409         pmFPAfileActivate(config->files, false, "PSPHOT.INPUT");
    410     }
    411 
    412200    psFree(stack);
    413     psFree(outRO);                      // Drop reference
     201
     202    sectionNum++;
    414203
    415204    return true;
Note: See TracChangeset for help on using the changeset viewer.