IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 14586


Ignore:
Timestamp:
Aug 21, 2007, 10:37:05 AM (19 years ago)
Author:
Paul Price
Message:

Moved all the work into psModules function pmSubtractionMatch, to
avoid code duplication (with ppStack, which also wants to do image
matching).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ppSub/src/ppSubReadout.c

    r14572 r14586  
    1010#include "ppSub.h"
    1111
    12 //#define TESTING
    1312#define WCS_TOLERANCE 0.001             // Tolerance for WCS
    14 
    15 #include <unistd.h>
    16 static void memCheck(const char *where)
    17 {
    18     return;
    19     psMemBlock **leaks = NULL;
    20     int numLeaks = psMemCheckLeaks(0, &leaks, NULL, true);
    21     size_t largestSize = 0;
    22     psMemId largest = 0;
    23     size_t totalSize = 0;
    24     for (int i = 0; i < numLeaks; i++) {
    25         psMemBlock *mb = leaks[i];
    26         totalSize += mb->userMemorySize;
    27         if (mb->userMemorySize > largestSize) {
    28             largestSize = mb->userMemorySize;
    29             largest = mb->id;
    30         }
    31     }
    32     psFree(leaks);
    33     fprintf(stderr, "%s:\n", where);
    34     fprintf(stderr, "    Memory in use: %zd\n", totalSize);
    35     fprintf(stderr, "    Largest block: %ld\n", largest);
    36     fprintf(stderr, "    sbrk(): %zd\n", (size_t)sbrk(0));
    37     return;
    38 }
    3913
    4014bool ppSubReadout(pmConfig *config, const pmFPAview *view)
     
    7549    psMaskType maskBlank = pmConfigMask(psMetadataLookupStr(NULL, config->arguments, "MASK.BLANK"),
    7650                                        config); // Mask for blank reg.
    77     const char *stampsFile = psMetadataLookupStr(NULL, config->arguments, "STAMPS"); // Filename for stamps
     51    const char *stampsName = psMetadataLookupStr(NULL, config->arguments, "STAMPS"); // Filename for stamps
    7852
     53    // Generate masks if they don't exist
    7954    int numCols = input->numCols, numRows = input->numRows; // Image dimensions
    8055    if (!inRO->mask) {
     
    9570    }
    9671
    97     memCheck("start");
    98 
    99     // Mask for subtraction
    100     psImage *subMask = pmSubtractionMask(refRO->mask, inRO->mask, maskBad, size, footprint);
    101 
    102     memCheck("mask");
    103 
    104 #if 0
    105     if (!inRO->weight) {
    106         // Need to ensure input image is completely above zero, so we're not weighting by negative numbers
    107         psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV);
    108         if (!psImageBackground(stats, inRO->image, inRO->mask, maskBad, NULL)) {
    109             psError(PS_ERR_UNKNOWN, false, "Unable to determine statistics of input image.");
    110             return false;
    111         }
    112         float diff = stats->robustMedian - 5.0 * stats->robustStdev;
    113         if (diff < 0.0) {
    114             psLogMsg("ppSub", PS_LOG_INFO, "Adding %f to image background to get positive pixels.");
    115             (void)psBinaryOp(in->image, inRO->image, "+", psScalarAlloc(diff, PS_TYPE_F32));
    116         }
    117     }
    118 #endif
    119 
    120     // Kernel basis functions
    121     pmSubtractionKernels *kernels = pmSubtractionKernelsGenerate(type, size, order, widths, orders,
    122                                                                  inner, binning, ringsOrder);
    123     psArray *stamps = NULL;             // Stamps for matching PSF
    124     psVector *solution = NULL;          // Solution to match PSF
    125 
    126     memCheck("kernels");
    127 
    128     int xRegions = 1, yRegions = 1;     // Number of iso-kernel regions
    129     float xRegionSize = 0, yRegionSize = 0; // Size of iso-kernel regions
    130     psRegion *region = NULL;            // Iso-kernel region
    131     if (isfinite(regionSize) || regionSize == 0.0) {
    132         xRegions = numCols / regionSize + 1;
    133         yRegions = numRows / regionSize + 1;
    134         xRegionSize = (float)numCols / (float)xRegions;
    135         yRegionSize = (float)numRows / (float)yRegions;
    136         region = psRegionAlloc(NAN, NAN, NAN, NAN);
     72    if (!pmSubtractionMatch(outRO, refRO, inRO, footprint, regionSize, spacing, threshold, stampsName,
     73                            NAN, type, size, order, widths, orders, inner, ringsOrder, binning, iter,
     74                            rej, maskBad, maskBlank)) {
     75        psError(PS_ERR_UNKNOWN, false, "Unable to match images.");
     76        psFree(outRO);
     77        return false;
    13778    }
    13879
    139     psImage *convImage = NULL, *convWeight = NULL, *convMask = NULL; // Convolved images
    140 
    141     // Iterate over iso-kernel regions
    142     for (int j = 0; j < yRegions; j++) {
    143         for (int i = 0; i < xRegions; i++) {
    144             psTrace("ppSub", 1, "Subtracting region %d of %d...\n",
    145                     j * xRegions + i + 1, xRegions * yRegions);
    146             if (region) {
    147                 *region = psRegionSet((int)(i * xRegionSize), (int)((i + 1) * xRegionSize),
    148                                       (int)(j * yRegionSize), (int)((j + 1) * yRegionSize));
    149                 psString string = psRegionToString(*region);
    150                 psTrace("ppSub", 3, "Iso-kernel region: %s out of %d,%d\n", string, numCols, numRows);
    151                 psFree(string);
    152             }
    153 
    154             int numRejected = -1;               // Number of rejected stamps in each iteration
    155             for (int k = 0; k < iter && numRejected != 0; k++) {
    156                 psTrace("ppSub", 2, "Iteration %d...\n", k);
    157 
    158                 psTrace("ppSub", 3, "Finding stamps...\n");
    159                 if (stampsFile) {
    160                     iter = 1;           // There is no iterating because we use all the stamps we have
    161                     psArray *stampData = psVectorsReadFromFile(stampsFile, "%f %f"); // Stamp positions
    162                     psVector *xStamp = stampData->data[0]; // x coordinates
    163                     psVector *yStamp = stampData->data[1]; // y coordinates
    164                     // Correct for IRAF (unit-offset) positions to C (zero-offset) positions
    165                     psBinaryOp(xStamp, xStamp, "-", psScalarAlloc(1.0, PS_TYPE_F32));
    166                     psBinaryOp(yStamp, yStamp, "-", psScalarAlloc(1.0, PS_TYPE_F32));
    167 
    168                     stamps = pmSubtractionSetStamps(xStamp, yStamp, NULL, subMask, region);
    169                 } else {
    170                     stamps = pmSubtractionFindStamps(stamps, refRO->image, subMask, region,
    171                                                      threshold, spacing);
    172                 }
    173                 if (!stamps) {
    174                     psError(PS_ERR_UNKNOWN, false, "Unable to find stamps on reference image.");
    175                     goto ERROR;
    176                 }
    177 
    178                 memCheck("  find stamps");
    179 
    180                 psTrace("ppSub", 3, "Extracting stamps...\n");
    181                 if (!pmSubtractionExtractStamps(stamps, refRO->image, inRO->image, inRO->weight,
    182                                                 footprint, kernels)) {
    183                     psError(PS_ERR_UNKNOWN, false, "Unable to extract stamps.");
    184                     goto ERROR;
    185                 }
    186 
    187                 memCheck("   extract stamps");
    188 
    189                 psTrace("ppSub", 3, "Calculating equation...\n");
    190                 if (!pmSubtractionCalculateEquation(stamps, kernels, footprint)) {
    191                     psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
    192                     goto ERROR;
    193                 }
    194 
    195                 memCheck("  calculate equation");
    196 
    197                 psTrace("ppSub", 3, "Solving equation...\n");
    198                 solution = pmSubtractionSolveEquation(solution, stamps);
    199                 if (!solution) {
    200                     psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
    201                     goto ERROR;
    202                 }
    203 
    204                 memCheck("  solve equation");
    205 
    206                 psTrace("ppSub", 3, "Rejecting stamps...\n");
    207                 numRejected = pmSubtractionRejectStamps(stamps, subMask, solution, footprint, rej, kernels);
    208                 if (numRejected < 0) {
    209                     psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps.");
    210                     goto ERROR;
    211                 }
    212                 psLogMsg("ppSub", PS_LOG_INFO, "%d stamps rejected on iteration %d.", numRejected, k);
    213 
    214                 memCheck("  reject stamps");
    215             }
    216 
    217             if (numRejected > 0) {
    218                 psTrace("ppSub", 3, "Solving equation...\n");
    219                 solution = pmSubtractionSolveEquation(solution, stamps);
    220                 if (!solution) {
    221                     psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation.");
    222                     goto ERROR;
    223                 }
    224             }
    225             psFree(stamps);
    226             stamps = NULL;
    227 
    228             memCheck("solution");
    229 
    230 #ifdef TESTING
    231             psTrace("ppSub", 2, "Generating diagnostics...\n");
    232             {
    233                 // Generate image with convolution kernels
    234                 int fullSize = 2 * size + 1 + 1;    // Full size of kernel
    235                 psImage *convKernels = psImageAlloc(5 * fullSize - 1, 5 * fullSize - 1, PS_TYPE_F32);
    236                 psImageInit(convKernels, NAN);
    237                 for (int j = -2; j <= 2; j++) {
    238                     for (int i = -2; i <= 2; i++) {
    239                         psImage *kernel = pmSubtractionKernelImage(solution, kernels, (float)i / 2.0,
    240                                                                    (float)j / 2.0); // Image of the kernel
    241                         if (!kernel) {
    242                             psError(PS_ERR_UNKNOWN, false, "Unable to generate kernel image.");
    243                             psFree(convKernels);
    244                             goto ERROR;
    245                         }
    246 
    247                         if (psImageOverlaySection(convKernels, kernel, (i + 2) * fullSize,
    248                                                   (j + 2) * fullSize, "=") == 0) {
    249                             psError(PS_ERR_UNKNOWN, false, "Unable to overlay kernel image.");
    250                             psFree(kernel);
    251                             psFree(convKernels);
    252                             goto ERROR;
    253                         }
    254                         psFree(kernel);
    255                     }
    256                 }
    257 
    258                 // XXX What do we do with this image?
    259 
    260                 psFits *kernelFile = psFitsOpen("kernel.fits", "w");
    261                 (void)psFitsWriteImage(kernelFile, NULL, convKernels, 0, NULL);
    262                 psFitsClose(kernelFile);
    263 
    264                 psFree(convKernels);
    265             }
    266 
    267             {
    268                 // Generate images of the kernel components
    269                 psMetadata *header = psMetadataAlloc(); // Header
    270                 for (int i = 0; i < solution->n; i++) {
    271                     psString name = NULL;       // Header keyword
    272                     psStringAppend(&name, "SOLN%04d", i);
    273                     psMetadataAddF64(header, PS_LIST_TAIL, name, 0, NULL, solution->data.F64[i]);
    274                     psFree(name);
    275                 }
    276                 psArray *kernelImages = pmSubtractionKernelSolutions(solution, kernels, 0.0, 0.0);
    277                 psFits *kernelFile = psFitsOpen("kernels.fits", "w");
    278                 (void)psFitsWriteImageCube(kernelFile, header, kernelImages, NULL);
    279                 psFitsClose(kernelFile);
    280                 psFree(kernelImages);
    281                 psFree(header);
    282             }
    283 #endif
    284 
    285             memCheck("diag outputs");
    286 
    287             psTrace("ppSub", 2, "Convolving...\n");
    288             if (!pmSubtractionConvolve(&convImage, &convWeight, &convMask, refRO->image, refRO->weight,
    289                                        subMask, maskBlank, region, solution, kernels)) {
    290                 psError(PS_ERR_UNKNOWN, false, "Unable to convolve reference image.");
    291                 goto ERROR;
    292             }
    293 
    294             psFree(solution);
    295             solution = NULL;
    296         }
    297     }
    298 
    299     psFree(region);
    300     region = NULL;
    301     psFree(subMask);
    302     subMask = NULL;
    303 
    304     if (!pmSubtractionBorder(convImage, convWeight, convMask, kernels, maskBlank)) {
    305         psError(PS_ERR_UNKNOWN, false, "Unable to set border region of convolved image.");
    306         goto ERROR;
    307     }
    30880
    30981    // Add kernel descrption to header
    310     psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.KERNEL", 0,
    311                      "Subtraction kernel", kernels->description);
    312     psFree(kernels);
    313 
    314     memCheck("convolution");
     82    psMetadataAddStr(outHDU->header, PS_LIST_TAIL, "PPSUB.KERNEL", 0, "Subtraction kernel",
     83                     psMetadataLookupStr(NULL, outRO->analysis, "SUBTRACTION.KERNEL.DESCRIPTION"));
    31584
    31685    // Do the subtraction
    31786    if (reverse) {
    318         outRO->image = (psImage*)psBinaryOp(NULL, convImage, "-", inRO->image);
     87        psBinaryOp(outRO->image, outRO->image, "-", inRO->image);
    31988    } else {
    320         outRO->image = (psImage*)psBinaryOp(NULL, inRO->image, "-", convImage);
     89        psBinaryOp(outRO->image, inRO->image, "-", outRO->image);
    32190    }
    322     outRO->mask = (psImage*)psBinaryOp(NULL, convMask, "|", inRO->mask);
    323     if (convWeight) {
    324         outRO->weight = (psImage*)psBinaryOp(NULL, convWeight, "+", inRO->weight);
     91    psBinaryOp(outRO->mask, outRO->mask, "|", inRO->mask);
     92    if (outRO->weight) {
     93        psBinaryOp(outRO->weight, outRO->weight, "+", inRO->weight);
    32594    }
    326 
    327     memCheck("subtraction");
    328 
    329     psFree(convImage);
    330     psFree(convMask);
    331     psFree(convWeight);
    332 
    333     memCheck("subtraction freed");
    334 
    335     outRO->data_exists = true;
    336     outCell->data_exists = true;
    337     outCell->parent->data_exists = true;
    33895
    33996#ifdef TESTING
     
    349106    if (!pmFPACopyConcepts(outCell->parent->parent, inRO->parent->parent->parent)) {
    350107        psError(PS_ERR_UNKNOWN, false, "Unable to copy concepts from input to output.");
     108        psFree(outRO);
    351109        return false;
    352110    }
     
    387145                     "Subtraction input", inFile->filename);
    388146
    389     memCheck("header");
    390 
    391147    psFree(outRO);
    392148
    393149    return true;
    394 
    395 ERROR:
    396     psFree(region);
    397     psFree(subMask);
    398     psFree(kernels);
    399     psFree(stamps);
    400     psFree(solution);
    401     psFree(outRO);
    402     return false;
    403150}
Note: See TracChangeset for help on using the changeset viewer.