Changeset 19164
- Timestamp:
- Aug 22, 2008, 12:45:36 PM (18 years ago)
- Location:
- trunk/psModules/src/imcombine
- Files:
-
- 7 edited
-
pmStackReject.c (modified) (1 diff)
-
pmSubtraction.c (modified) (14 diffs)
-
pmSubtraction.h (modified) (3 diffs)
-
pmSubtractionMask.c (modified) (2 diffs)
-
pmSubtractionMatch.c (modified) (23 diffs)
-
pmSubtractionMatch.h (modified) (1 diff)
-
pmSubtractionStamps.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmStackReject.c
r18508 r19164 87 87 } 88 88 pmSubtractionKernels *kernel = kernels->data[i]; // Kernel of interest 89 if (!pmSubtractionConvolve(convRO, NULL, inRO, NULL, NULL, 0, region, kernel, false, true)) {89 if (!pmSubtractionConvolve(convRO, NULL, inRO, NULL, NULL, 0, 0, 1.0, region, kernel, false, true)) { 90 90 psError(PS_ERR_UNKNOWN, false, "Unable to convolve mask image in region %d.", i); 91 91 psFree(convRO); -
trunk/psModules/src/imcombine/pmSubtraction.c
r19148 r19164 249 249 psImage *subConv = psImageSubset(convolved, psRegionSet(size, -size, size, -size)); // Cut off the edges 250 250 251 if (threaded) { 252 psMutexLock(target); 253 } 254 psImage *subTarget = psImageSubset(target, region); // Target for this subregion 255 if (threaded) { 256 psMutexUnlock(target); 257 } 251 int xMin = region.x0, xMax = region.x1, yMin = region.y0, yMax = region.y1; // Bounds of region 258 252 if (background != 0.0) { 259 psBinaryOp(subTarget, subConv, "+", psScalarAlloc(background, PS_TYPE_F32)); 253 for (int yTarget = yMin, ySource = size; yTarget < yMax; yTarget++, ySource++) { 254 for (int xTarget = xMin, xSource = size; xTarget < xMax; xTarget++, xSource++) { 255 target->data.F32[yTarget][xTarget] = convolved->data.F32[ySource][xSource] + background; 256 } 257 } 260 258 } else { 261 int numBytes = subTarget->numCols* PSELEMTYPE_SIZEOF(PS_TYPE_F32); // Number of bytes to copy262 for (int y = 0; y < subTarget->numRows; y++) {263 memcpy( subTarget->data.F32[y], subConv->data.F32[y], numBytes);259 int numBytes = (xMax - xMin) * PSELEMTYPE_SIZEOF(PS_TYPE_F32); // Number of bytes to copy 260 for (int yTarget = yMin, ySource = size; yTarget < yMax; yTarget++, ySource++) { 261 memcpy(&target->data.F32[yTarget][xMin], &convolved->data.F32[ySource][size], numBytes); 264 262 } 265 263 } 266 264 psFree(subConv); 267 265 psFree(convolved); 268 if (threaded) {269 psMutexLock(target);270 }271 psFree(subTarget);272 if (threaded) {273 psMutexUnlock(target);274 }275 266 276 267 return; … … 291 282 for (int v = -size; v <= size; v++) { 292 283 for (int u = -size; u <= size; u++) { 293 target->data.F32[y][x] += kernel->kernel[v][u] * 294 image->data.F32[y - v][x - u]; 284 target->data.F32[y][x] += kernel->kernel[v][u] * image->data.F32[y - v][x - u]; 295 285 } 296 286 } … … 303 293 static inline void convolveRegion(psImage *convImage, // Convolved image (output) 304 294 psImage *convWeight, // Convolved weight map (output), or NULL 295 psImage *convMask, // Convolve mask (output), or NULL 305 296 psKernel **kernelImage, // Convolution kernel for the image 306 297 psKernel **kernelWeight, // Convolution kernel for the weight map, or NULL … … 308 299 psImage *weight, // Weight map to convolve, or NULL 309 300 psImage *subMask, // Subtraction mask 310 psMaskType maskVal, // Mask value to apply in convolution311 301 const pmSubtractionKernels *kernels, // Kernels 312 302 psImage *polyValues, // Polynomial values 313 303 float background, // Background value to apply 314 304 psRegion region, // Region to convolve 305 float poorFrac, // Fraction for "poor" 315 306 bool useFFT, // Use FFT to convolve? 316 307 bool wantDual // Want the dual convolution? … … 318 309 { 319 310 *kernelImage = solvedKernel(*kernelImage, kernels, polyValues, wantDual); 320 if (weight ) {311 if (weight || subMask) { 321 312 *kernelWeight = varianceKernel(*kernelWeight, *kernelImage); 322 313 } 323 314 315 psMaskType maskSource; // Mask these values when 316 psMaskType maskTarget; // Set this mask value when convolving 317 if (kernels->mode == PM_SUBTRACTION_MODE_1 || (kernels->mode == PM_SUBTRACTION_MODE_DUAL && !wantDual)) { 318 maskSource = PM_SUBTRACTION_MASK_BAD_1; 319 maskTarget = PM_SUBTRACTION_MASK_CONVOLVE_BAD_1; 320 } else { 321 maskSource = PM_SUBTRACTION_MASK_BAD_2; 322 maskTarget = PM_SUBTRACTION_MASK_CONVOLVE_BAD_2; 323 } 324 325 // Convolve the image and weight 324 326 if (useFFT) { 325 327 // Use Fast Fourier Transform to do the convolution 326 328 // This provides a big speed-up for large kernels 327 328 convolveFFT(convImage, image, subMask, maskVal, *kernelImage, region, background, kernels->size); 329 convolveFFT(convImage, image, subMask, maskSource, *kernelImage, region, background, kernels->size); 329 330 if (weight) { 330 convolveFFT(convWeight, weight, subMask, mask Val, *kernelWeight, region, 0.0, kernels->size);331 convolveFFT(convWeight, weight, subMask, maskSource, *kernelWeight, region, 0.0, kernels->size); 331 332 } 332 333 } else { … … 334 335 if (weight) { 335 336 convolveDirect(convWeight, weight, *kernelWeight, region, 0.0, kernels->size); 337 } 338 } 339 340 // Convolve the mask for bad pixels 341 if (subMask && convMask) { 342 psKernel *kernel = *kernelWeight; // Kernel of interest 343 int xMin = kernel->xMin, xMax = kernel->xMax, yMin = kernel->yMin, yMax = kernel->yMax; // Bounds 344 345 // Determine the thresholds 346 double sumKernel2 = 0.0; // Sum of the kernel-squared 347 for (int y = yMin; y <= yMax; y++) { 348 for (int x = xMin; x <= xMax; x++) { 349 sumKernel2 += kernel->kernel[y][x]; 350 } 351 } 352 float threshold = sumKernel2 * poorFrac; // Threshold between poor and bad 353 354 // Get bounds of threshold region 355 // Start with the entire kernel, and keep reducing the size of the box until it drops below threshold 356 int box = kernels->size; // Size of box with bad pixels 357 for (double sumBox = sumKernel2; box > 0; box--) { 358 for (int x = -box; x <= box; x++) { 359 sumBox -= kernel->kernel[-box][x] + kernel->kernel[box][x]; 360 } 361 for (int y = -box + 1; y <= box - 1; y++) { 362 // Note: not doing corners 363 sumBox -= kernel->kernel[y][-box] + kernel->kernel[y][box]; 364 } 365 if (sumBox < threshold) { 366 break; 367 } 368 } 369 370 if (box > 0) { 371 bool threaded = pmSubtractionThreaded(); // Are we running threaded? 372 if (threaded) { 373 psMutexLock(subMask); 374 } 375 psImage *image = psImageSubset(subMask, psRegionSet(region.x0 + xMin, region.x1 + xMax, 376 region.y0 + yMin, region.y1 + yMax)); 377 if (threaded) { 378 psMutexUnlock(subMask); 379 } 380 381 psImage *convolved = psImageConvolveMask(NULL, image, maskSource, maskTarget, 382 -box, box, -box, box); // Convolved subtraction mask 383 384 if (threaded) { 385 psMutexLock(subMask); 386 } 387 psFree(image); 388 if (threaded) { 389 psMutexUnlock(subMask); 390 } 391 392 int colMin = region.x0, colMax = region.x1, rowMin = region.y0, rowMax = region.y1; // Bounds 393 int numBytes = (colMax - colMin) * PSELEMTYPE_SIZEOF(PS_TYPE_MASK); // Number of bytes to copy 394 395 // Since we're copying back into the source, we need to lock 396 if (threaded) { 397 psMutexLock(subMask); 398 } 399 for (int yTarget = rowMin, ySource = -yMin; yTarget < rowMax; yTarget++, ySource++) { 400 memcpy(&subMask->data.PS_TYPE_MASK_DATA[yTarget][colMin], 401 &convolved->data.PS_TYPE_MASK_DATA[ySource][-xMin], numBytes); 402 } 403 if (threaded) { 404 psMutexUnlock(subMask); 405 } 406 407 // No need to lock: we own this 408 psFree(convolved); 336 409 } 337 410 } … … 753 826 754 827 // XXX Put kernelImage, kernelWeight and polyValues on thread-dependent data 755 static bool subtractionConvolvePatch(int numCols, int numRows, int x0, int y0, 756 pmReadout *out1, pmReadout *out2, psImage *convMask, 757 const pmReadout *ro1, const pmReadout *ro2, psImage *subMask, 758 psMaskType blank, psMaskType maskSource, psMaskType maskTarget, 759 const psRegion *region, const pmSubtractionKernels *kernels, 760 bool doBG, bool useFFT) 828 static bool subtractionConvolvePatch(int numCols, int numRows, // Size of image 829 int x0, int y0, // Offsets for image 830 pmReadout *out1, pmReadout *out2, // Output readouts 831 psImage *convMask, // Output convolved mask 832 const pmReadout *ro1, const pmReadout *ro2, // Input readouts 833 psImage *subMask, // Input subtraction mask 834 psMaskType maskBad, // Mask value to give bad pixels 835 psMaskType maskPoor, // Mask value to give poor pixels 836 float poorFrac, // Fraction for "poor" 837 const psRegion *region, // Patch to convolve 838 const pmSubtractionKernels *kernels, // Kernels 839 bool doBG, // Add in background when convolving? 840 bool useFFT // Use FFT to do the convolution? 841 ) 761 842 { 762 843 int size = kernels->size; // Half-size of kernel … … 782 863 783 864 if (kernels->mode == PM_SUBTRACTION_MODE_1 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 784 convolveRegion(out1->image, out1->weight, &kernelImage, &kernelWeight, ro1->image, ro1->weight,785 subMask, maskSource, kernels, polyValues, background, *region, useFFT,786 false);865 convolveRegion(out1->image, out1->weight, convMask, &kernelImage, &kernelWeight, 866 ro1->image, ro1->weight, subMask, kernels, polyValues, background, 867 *region, poorFrac, useFFT, false); 787 868 } 788 869 if (kernels->mode == PM_SUBTRACTION_MODE_2 || kernels->mode == PM_SUBTRACTION_MODE_DUAL) { 789 convolveRegion(out2->image, out2->weight, &kernelImage, &kernelWeight, ro2->image, ro2->weight,790 subMask, maskSource, kernels, polyValues, background, *region, useFFT,791 kernels->mode == PM_SUBTRACTION_MODE_DUAL);870 convolveRegion(out2->image, out2->weight, convMask, &kernelImage, &kernelWeight, 871 ro2->image, ro2->weight, subMask, kernels, polyValues, background, 872 *region, poorFrac, useFFT, kernels->mode == PM_SUBTRACTION_MODE_DUAL); 792 873 } 793 874 … … 796 877 psFree(polyValues); 797 878 798 // Propagate the mask879 // Propagate the subtraction mask 799 880 if (subMask) { 800 881 psMaskType **target = convMask->data.PS_TYPE_MASK_DATA; // Target mask 801 882 psMaskType **source = subMask->data.PS_TYPE_MASK_DATA; // Source mask 802 883 884 psMaskType poor, bad; // Mask value for "poor" and "bad" pixels in subtraction mask 885 switch (kernels->mode) { 886 case PM_SUBTRACTION_MODE_1: 887 poor = PM_SUBTRACTION_MASK_CONVOLVE_1; 888 bad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_1 | PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2; 889 break; 890 case PM_SUBTRACTION_MODE_2: 891 poor = PM_SUBTRACTION_MASK_CONVOLVE_2; 892 bad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_2 | PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2; 893 break; 894 case PM_SUBTRACTION_MODE_DUAL: 895 poor = PM_SUBTRACTION_MASK_CONVOLVE_1 | PM_SUBTRACTION_MASK_CONVOLVE_1; 896 bad = PM_SUBTRACTION_MASK_CONVOLVE_BAD_1 | PM_SUBTRACTION_MASK_CONVOLVE_BAD_2 | 897 PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2; 898 break; 899 default: 900 psAbort("Unrecognised subtraction mode: %x", kernels->mode); 901 } 902 803 903 for (int y = yMin; y < yMax; y++) { 804 904 for (int x = xMin; x < xMax; x++) { 805 if (source[y][x] & maskTarget) { 806 target[y][x] |= blank; 905 // Pixels marked as "bad" shouldn't also be marked as "poor" 906 if (source[y][x] & bad) { 907 target[y][x] |= maskBad; 908 } else if (source[y][x] & poor){ 909 target[y][x] |= maskPoor; 807 910 } 808 911 } … … 848 951 const pmReadout *ro2 = args->data[8]; // Input readout 2 849 952 psImage *subMask = args->data[9]; // Subtraction mask 850 psMaskType blank = PS_SCALAR_VALUE(args->data[10], U8); // Output mask value851 psMaskType mask Source = PS_SCALAR_VALUE(args->data[11], U8); // Mask value corresponding to source image852 psMaskType maskTarget = PS_SCALAR_VALUE(args->data[12], U8); // Mask value corresponding to target image953 psMaskType maskBad = PS_SCALAR_VALUE(args->data[10], U8); // Output mask value for bad pixels 954 psMaskType maskPoor = PS_SCALAR_VALUE(args->data[11], U8); // Output mask value for poor pixels 955 float poorFrac = PS_SCALAR_VALUE(args->data[12], F32); // Fraction for "poor" 853 956 const psRegion *region = args->data[13]; // Region to convolve 854 957 const pmSubtractionKernels *kernels = args->data[14]; // Kernels … … 856 959 bool useFFT = PS_SCALAR_VALUE(args->data[16], U8); // Use FFT for convolution? 857 960 858 return subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, 859 ro1, ro2, subMask, blank, maskSource, maskTarget, 860 region, kernels, doBG, useFFT); 961 return subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, subMask, 962 maskBad, maskPoor, poorFrac, region, kernels, doBG, useFFT); 861 963 } 862 964 863 965 bool pmSubtractionConvolve(pmReadout *out1, pmReadout *out2, const pmReadout *ro1, const pmReadout *ro2, 864 psImage *subMask, psMaskType blank, const psRegion *region, 865 const pmSubtractionKernels *kernels, bool doBG, bool useFFT) 966 psImage *subMask, psMaskType maskBad, psMaskType maskPoor, float poorFrac, 967 const psRegion *region, const pmSubtractionKernels *kernels, 968 bool doBG, bool useFFT) 866 969 { 867 970 int numCols = 0, numRows = 0; // Image dimensions … … 998 1101 yMin = PS_MAX(region->y0, yMin); 999 1102 yMax = PS_MIN(region->y1, yMax); 1000 }1001 1002 psMaskType maskSource; // Mask these pixels when convolving1003 psMaskType maskTarget; // Mark these pixels as bad when propagating the subtractionMask1004 switch (kernels->mode) {1005 case PM_SUBTRACTION_MODE_1:1006 maskSource = PM_SUBTRACTION_MASK_BAD_1;1007 maskTarget = PM_SUBTRACTION_MASK_BAD_2 | PM_SUBTRACTION_MASK_CONVOLVE_1;1008 break;1009 case PM_SUBTRACTION_MODE_2:1010 maskSource = PM_SUBTRACTION_MASK_BAD_2;1011 maskTarget = PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_CONVOLVE_2;1012 break;1013 case PM_SUBTRACTION_MODE_DUAL:1014 maskSource = PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2;1015 maskTarget = PM_SUBTRACTION_MASK_CONVOLVE_1 | PM_SUBTRACTION_MASK_CONVOLVE_2;1016 break;1017 default:1018 psAbort("Unsupported subtraction mode: %x", kernels->mode);1019 1103 } 1020 1104 … … 1045 1129 psArrayAdd(args, 1, (pmReadout*)ro2); // Casting away const 1046 1130 psArrayAdd(args, 1, (psImage*)subMask); // Casting away const 1047 PS_ARRAY_ADD_SCALAR(args, blank, PS_TYPE_U8);1048 PS_ARRAY_ADD_SCALAR(args, mask Source, PS_TYPE_U8);1049 PS_ARRAY_ADD_SCALAR(args, maskTarget, PS_TYPE_U8);1131 PS_ARRAY_ADD_SCALAR(args, maskBad, PS_TYPE_U8); 1132 PS_ARRAY_ADD_SCALAR(args, maskPoor, PS_TYPE_U8); 1133 PS_ARRAY_ADD_SCALAR(args, poorFrac, PS_TYPE_F32); 1050 1134 psArrayAdd(args, 1, subRegion); 1051 1135 psArrayAdd(args, 1, (pmSubtractionKernels*)kernels); // Casting away const … … 1060 1144 } else { 1061 1145 subtractionConvolvePatch(numCols, numRows, x0, y0, out1, out2, convMask, ro1, ro2, subMask, 1062 blank, maskSource, maskTarget, subRegion, kernels, doBG, useFFT);1146 maskBad, maskPoor, poorFrac, subRegion, kernels, doBG, useFFT); 1063 1147 } 1064 1148 psFree(subRegion); -
trunk/psModules/src/imcombine/pmSubtraction.h
r19122 r19164 6 6 * @author GLG, MHPCC 7 7 * 8 * @version $Revision: 1.2 8$ $Name: not supported by cvs2svn $9 * @date $Date: 2008-08- 19 00:44:42$8 * @version $Revision: 1.29 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2008-08-22 22:45:36 $ 10 10 * Copyright 2004-207 Institute for Astronomy, University of Hawaii 11 11 */ … … 26 26 /// Mask values for the subtraction mask 27 27 typedef enum { 28 PM_SUBTRACTION_MASK_CLEAR = 0x00, // No masking29 PM_SUBTRACTION_MASK_BAD_1 = 0x01, // Image 1 is bad30 PM_SUBTRACTION_MASK_BAD_2 = 0x02, // Image 2 is bad31 PM_SUBTRACTION_MASK_CONVOLVE_1 = 0x04, // If image 1 is convolved, would bebad32 PM_SUBTRACTION_MASK_CONVOLVE_2 = 0x08, // If image 2 is convolved, would bebad33 PM_SUBTRACTION_MASK_ FOOTPRINT_1 = 0x10, // Bad pixel within the stamp footprint of image 134 PM_SUBTRACTION_MASK_ FOOTPRINT_2 = 0x20, // Bad pixel within the stamp footprint of image 235 PM_SUBTRACTION_MASK_BORDER = 0x40, // Image border36 PM_SUBTRACTION_MASK_REJ = 0x80, // Previously tried as a stamp, and rejected28 PM_SUBTRACTION_MASK_CLEAR = 0x00, // No masking 29 PM_SUBTRACTION_MASK_BAD_1 = 0x01, // Image 1 is bad 30 PM_SUBTRACTION_MASK_BAD_2 = 0x02, // Image 2 is bad 31 PM_SUBTRACTION_MASK_CONVOLVE_1 = 0x04, // If image 1 is convolved, would be poor or bad 32 PM_SUBTRACTION_MASK_CONVOLVE_2 = 0x08, // If image 2 is convolved, would be poor or bad 33 PM_SUBTRACTION_MASK_CONVOLVE_BAD_1 = 0x10, // If image 1 is convolved, would be bad 34 PM_SUBTRACTION_MASK_CONVOLVE_BAD_2 = 0x20, // If image 2 is convolved, would be bad 35 PM_SUBTRACTION_MASK_BORDER = 0x40, // Image border 36 PM_SUBTRACTION_MASK_REJ = 0x80, // Previously tried as a stamp, and rejected 37 37 } pmSubtractionMasks; 38 38 … … 104 104 const pmReadout *ro2, // Input image 2 105 105 psImage *subMask, ///< Subtraction mask (or NULL) 106 psMaskType blank, ///< Mask value for blank regions 106 psMaskType maskBad, ///< Mask value to give bad pixels 107 psMaskType maskPoor, ///< Mask value to give poor pixels 108 float poorFrac, ///< Fraction for "poor" 107 109 const psRegion *region, ///< Region to convolve (or NULL) 108 110 const pmSubtractionKernels *kernels, ///< Kernel parameters -
trunk/psModules/src/imcombine/pmSubtractionMask.c
r17729 r19164 138 138 139 139 if (!psImageConvolveMask(mask, mask, PM_SUBTRACTION_MASK_BAD_1, 140 PM_SUBTRACTION_MASK_CONVOLVE_1 | PM_SUBTRACTION_MASK_FOOTPRINT_1,140 PM_SUBTRACTION_MASK_CONVOLVE_1, 141 141 -size, size, -size, size)) { 142 142 psError(PS_ERR_UNKNOWN, false, "Unable to convolve bad pixels from mask 1."); … … 145 145 } 146 146 if (!psImageConvolveMask(mask, mask, PM_SUBTRACTION_MASK_BAD_2, 147 PM_SUBTRACTION_MASK_CONVOLVE_2 | PM_SUBTRACTION_MASK_FOOTPRINT_2,147 PM_SUBTRACTION_MASK_CONVOLVE_2, 148 148 -size, size, -size, size)) { 149 149 psError(PS_ERR_UNKNOWN, false, "Unable to convolve bad pixels from mask 2."); 150 psFree(mask);151 return NULL;152 }153 if (!psImageConvolveMask(mask, mask, PM_SUBTRACTION_MASK_CONVOLVE_1,154 PM_SUBTRACTION_MASK_FOOTPRINT_1,155 -footprint, footprint, -footprint, footprint)) {156 psError(PS_ERR_UNKNOWN, false, "Unable to reconvolve bad pixels from mask 1.");157 psFree(mask);158 return NULL;159 }160 if (!psImageConvolveMask(mask, mask, PM_SUBTRACTION_MASK_CONVOLVE_2,161 PM_SUBTRACTION_MASK_FOOTPRINT_2,162 -footprint, footprint, -footprint, footprint)) {163 psError(PS_ERR_UNKNOWN, false, "Unable to reconvolve bad pixels from mask 2.");164 150 psFree(mask); 165 151 return NULL; -
trunk/psModules/src/imcombine/pmSubtractionMatch.c
r18962 r19164 121 121 int inner, int ringsOrder, int binning, float penalty, 122 122 bool optimum, const psVector *optFWHMs, int optOrder, float optThreshold, 123 int iter, float rej, psMaskType mask Bad, psMaskType maskBlank,124 float badFrac, pmSubtractionMode mode)123 int iter, float rej, psMaskType maskVal, psMaskType maskBad, psMaskType maskPoor, 124 float poorFrac, float badFrac, pmSubtractionMode subMode) 125 125 { 126 if ( mode != PM_SUBTRACTION_MODE_2) {126 if (subMode != PM_SUBTRACTION_MODE_2) { 127 127 PM_ASSERT_READOUT_NON_NULL(conv1, false); 128 128 if (conv1->image) { … … 139 139 } 140 140 } 141 if ( mode != PM_SUBTRACTION_MODE_1) {141 if (subMode != PM_SUBTRACTION_MODE_1) { 142 142 PM_ASSERT_READOUT_NON_NULL(conv2, false); 143 143 if (conv2->image) { … … 190 190 PS_ASSERT_INT_POSITIVE(iter, false); 191 191 PS_ASSERT_FLOAT_LARGER_THAN(rej, 0.0, false); 192 // Don't care about maskVal 192 193 // Don't care about maskBad 193 // Don't care about maskBlank 194 // Don't care about maskPoor 195 PS_ASSERT_FLOAT_LARGER_THAN(poorFrac, 0.0, NULL); 196 PS_ASSERT_FLOAT_LESS_THAN_OR_EQUAL(poorFrac, 1.0, NULL); 194 197 if (isfinite(badFrac)) { 195 198 PS_ASSERT_FLOAT_LARGER_THAN(badFrac, 0.0, NULL); … … 230 233 memCheck("start"); 231 234 232 subMask = pmSubtractionMask(ro1->mask, ro2 ? ro2->mask : NULL, mask Bad, size, footprint,235 subMask = pmSubtractionMask(ro1->mask, ro2 ? ro2->mask : NULL, maskVal, size, footprint, 233 236 badFrac, useFFT); 234 237 if (!subMask) { … … 267 270 if (sources) { 268 271 stamps = pmSubtractionStampsSetFromSources(sources, subMask, region, footprint, 269 stampSpacing, mode);272 stampSpacing, subMode); 270 273 } else if (stampsName && strlen(stampsName) > 0) { 271 274 stamps = pmSubtractionStampsSetFromFile(stampsName, ro1->image, subMask, region, footprint, 272 stampSpacing, mode);275 stampSpacing, subMode); 273 276 } 274 277 … … 276 279 // doesn't matter. 277 280 if (!getStamps(&stamps, ro1, ro2, subMask, weight, NULL, threshold, stampSpacing, 278 size, footprint, mode)) {281 size, footprint, subMode)) { 279 282 goto MATCH_ERROR; 280 283 } 281 284 282 if ( mode == PM_SUBTRACTION_MODE_UNSURE) {285 if (subMode == PM_SUBTRACTION_MODE_UNSURE) { 283 286 // Get backgrounds 284 287 psStats *bgStats = psStatsAlloc(BG_STAT); // Statistics for background 285 288 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS, 0); // Random number generator 286 289 psVector *buffer = NULL;// Buffer for stats 287 if (!psImageBackground(bgStats, &buffer, ro1->image, ro1->mask, mask Bad, rng)) {290 if (!psImageBackground(bgStats, &buffer, ro1->image, ro1->mask, maskVal, rng)) { 288 291 psError(PS_ERR_UNKNOWN, false, "Unable to measure background of image 1."); 289 292 psFree(bgStats); … … 293 296 } 294 297 float bg1 = psStatsGetValue(bgStats, BG_STAT); // Background for image 1 295 if (!psImageBackground(bgStats, &buffer, ro2->image, ro2->mask, mask Bad, rng)) {298 if (!psImageBackground(bgStats, &buffer, ro2->image, ro2->mask, maskVal, rng)) { 296 299 psError(PS_ERR_UNKNOWN, false, "Unable to measure background of image 2."); 297 300 psFree(bgStats); … … 317 320 goto MATCH_ERROR; 318 321 } 319 mode = newMode;322 subMode = newMode; 320 323 } 321 324 … … 323 326 if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) { 324 327 kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder, 325 stamps, footprint, optThreshold, penalty, mode);328 stamps, footprint, optThreshold, penalty, subMode); 326 329 if (!kernels) { 327 330 psErrorClear(); … … 332 335 // Not an ISIS/GUNK kernel, or the optimum kernel search failed 333 336 kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders, 334 inner, binning, ringsOrder, penalty, mode);337 inner, binning, ringsOrder, penalty, subMode); 335 338 } 336 339 … … 344 347 } 345 348 346 if ( mode == PM_SUBTRACTION_MODE_1 || mode == PM_SUBTRACTION_MODE_DUAL) {349 if (subMode == PM_SUBTRACTION_MODE_1 || subMode == PM_SUBTRACTION_MODE_DUAL) { 347 350 psMetadataAddPtr(conv1->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_KERNEL, 348 351 PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Subtraction kernels", kernels); 349 352 psMetadataAddS32(conv1->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MODE, 350 PS_META_DUPLICATE_OK, "Subtraction kernels", mode);353 PS_META_DUPLICATE_OK, "Subtraction kernels", subMode); 351 354 psMetadataAddPtr(conv1->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, 352 355 PS_DATA_REGION | PS_META_DUPLICATE_OK, 353 356 "Region over which subtraction was performed", subRegion); 354 357 } 355 if ( mode == PM_SUBTRACTION_MODE_2 || mode == PM_SUBTRACTION_MODE_DUAL) {358 if (subMode == PM_SUBTRACTION_MODE_2 || subMode == PM_SUBTRACTION_MODE_DUAL) { 356 359 psMetadataAddPtr(conv2->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_KERNEL, 357 360 PS_DATA_UNKNOWN | PS_META_DUPLICATE_OK, "Subtraction kernels", kernels); 358 361 psMetadataAddS32(conv2->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_MODE, 359 PS_META_DUPLICATE_OK, "Subtraction kernels", mode);362 PS_META_DUPLICATE_OK, "Subtraction kernels", subMode); 360 363 psMetadataAddPtr(conv2->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_REGION, 361 364 PS_DATA_REGION | PS_META_DUPLICATE_OK, … … 374 377 375 378 if (!getStamps(&stamps, ro1, ro2, subMask, weight, region, threshold, stampSpacing, 376 size, footprint, mode)) {379 size, footprint, subMode)) { 377 380 goto MATCH_ERROR; 378 381 } … … 434 437 stamps = NULL; 435 438 436 if ( mode == PM_SUBTRACTION_MODE_1 || mode == PM_SUBTRACTION_MODE_DUAL) {439 if (subMode == PM_SUBTRACTION_MODE_1 || subMode == PM_SUBTRACTION_MODE_DUAL) { 437 440 psMetadataAddS32(conv1->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_STAMPS_NUM, 438 441 PS_META_DUPLICATE_OK, "Number of good stamps", numStamps); … … 440 443 PS_META_DUPLICATE_OK, "RMS deviation of stamps", rmsStamps); 441 444 } 442 if ( mode == PM_SUBTRACTION_MODE_2 || mode == PM_SUBTRACTION_MODE_DUAL) {445 if (subMode == PM_SUBTRACTION_MODE_2 || subMode == PM_SUBTRACTION_MODE_DUAL) { 443 446 psMetadataAddS32(conv2->analysis, PS_LIST_TAIL, PM_SUBTRACTION_ANALYSIS_STAMPS_NUM, 444 447 PS_META_DUPLICATE_OK, "Number of good stamps", numStamps); … … 454 457 int fullSize = 2 * size + 1 + 1; // Full size of kernel 455 458 int imageSize = (2 * KERNEL_MOSAIC + 1) * fullSize; 456 psImage *convKernels = psImageAlloc(( mode == PM_SUBTRACTION_MODE_DUAL ? 2 : 1) *459 psImage *convKernels = psImageAlloc((subMode == PM_SUBTRACTION_MODE_DUAL ? 2 : 1) * 457 460 imageSize - 1 + 458 ( mode == PM_SUBTRACTION_MODE_DUAL ? 4 : 0),461 (subMode == PM_SUBTRACTION_MODE_DUAL ? 4 : 0), 459 462 imageSize - 1, PS_TYPE_F32); 460 463 psImageInit(convKernels, NAN); … … 479 482 psFree(kernel); 480 483 481 if ( mode == PM_SUBTRACTION_MODE_DUAL) {484 if (subMode == PM_SUBTRACTION_MODE_DUAL) { 482 485 kernel = pmSubtractionKernelImage(kernels, (float)i / (float)KERNEL_MOSAIC, 483 486 (float)j / (float)KERNEL_MOSAIC, … … 534 537 535 538 psTrace("psModules.imcombine", 2, "Convolving...\n"); 536 if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, maskB lank, region, kernels,537 true, useFFT)) {539 if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, maskBad, maskPoor, poorFrac, 540 region, kernels, true, useFFT)) { 538 541 psError(PS_ERR_UNKNOWN, false, "Unable to convolve image."); 539 542 goto MATCH_ERROR; … … 541 544 542 545 // Set the variance factors 543 switch ( mode) {546 switch (subMode) { 544 547 case PM_SUBTRACTION_MODE_1: { 545 548 recordVarianceFactor(conv1, pmSubtractionVarianceFactor(kernels, 0.5, 0.5, false), … … 565 568 566 569 // There is data in the readout now 567 if ( mode == PM_SUBTRACTION_MODE_1 || mode == PM_SUBTRACTION_MODE_DUAL) {570 if (subMode == PM_SUBTRACTION_MODE_1 || subMode == PM_SUBTRACTION_MODE_DUAL) { 568 571 conv1->data_exists = true; 569 572 if (conv1->parent) { … … 572 575 } 573 576 } 574 if ( mode == PM_SUBTRACTION_MODE_2 || mode == PM_SUBTRACTION_MODE_DUAL) {577 if (subMode == PM_SUBTRACTION_MODE_2 || subMode == PM_SUBTRACTION_MODE_DUAL) { 575 578 conv2->data_exists = true; 576 579 if (conv2->parent) { … … 590 593 weight = NULL; 591 594 592 if (!pmSubtractionBorder(conv1->image, conv1->weight, conv1->mask, size, maskB lank)) {595 if (!pmSubtractionBorder(conv1->image, conv1->weight, conv1->mask, size, maskBad)) { 593 596 psError(PS_ERR_UNKNOWN, false, "Unable to set border of convolved image."); 594 597 goto MATCH_ERROR; … … 600 603 #ifdef TESTING 601 604 { 602 if ( mode == PM_SUBTRACTION_MODE_1 || mode == PM_SUBTRACTION_MODE_DUAL) {605 if (subMode == PM_SUBTRACTION_MODE_1 || subMode == PM_SUBTRACTION_MODE_DUAL) { 603 606 psFits *fits = psFitsOpen("convolved1.fits", "w"); 604 607 psFitsWriteImage(fits, NULL, conv1->image, 0, NULL); … … 606 609 } 607 610 608 if ( mode == PM_SUBTRACTION_MODE_2 || mode == PM_SUBTRACTION_MODE_DUAL) {611 if (subMode == PM_SUBTRACTION_MODE_2 || subMode == PM_SUBTRACTION_MODE_DUAL) { 609 612 psFits *fits = psFitsOpen("convolved2.fits", "w"); 610 613 psFitsWriteImage(fits, NULL, conv2->image, 0, NULL); -
trunk/psModules/src/imcombine/pmSubtractionMatch.h
r18962 r19164 46 46 int iter, ///< Rejection iterations 47 47 float rej, ///< Rejection threshold 48 psMaskType maskBad, ///< Value to mask 49 psMaskType maskBlank, ///< Mask for blank region 48 psMaskType maskVal, ///< Value to mask for input 49 psMaskType maskBad, ///< Mask for output bad pixels 50 psMaskType maskPoor, ///< Mask for output poor pixels 51 float poorFrac, ///< Fraction for "poor" 50 52 float badFrac, ///< Maximum fraction of bad input pixels to accept 51 53 pmSubtractionMode mode ///< Mode of subtraction; may be modified -
trunk/psModules/src/imcombine/pmSubtractionStamps.c
r17297 r19164 73 73 static bool checkStampMask(int x, int y, // Coordinates of stamp 74 74 const psImage *mask, // Mask 75 pmSubtractionMode mode // Mode for subtraction 75 pmSubtractionMode mode, // Mode for subtraction 76 int footprint // Footprint to check for Bad Stuff 76 77 ) 77 78 { … … 79 80 return true; 80 81 } 81 if (x < 0 || x >= mask->numCols || y < 0 || y >= mask->numRows) { 82 return false; 83 } 84 85 psMaskType maskVal = PM_SUBTRACTION_MASK_BORDER | PM_SUBTRACTION_MASK_REJ; // Mask value 82 83 bool clean = true; // Is the footprint clean? 84 int numCols = mask->numCols, numRows = mask->numRows; // Size of image 85 86 // Check the footprint bounds 87 if (x < footprint || x >= numCols - footprint || y < footprint || y >= numRows - footprint) { 88 clean = false; 89 } 90 91 // Determine mask value 92 psMaskType maskVal = PM_SUBTRACTION_MASK_BORDER | PM_SUBTRACTION_MASK_BAD_1 | PM_SUBTRACTION_MASK_BAD_2; 86 93 switch (mode) { 87 94 case PM_SUBTRACTION_MODE_1: 88 maskVal |= PM_SUBTRACTION_MASK_ FOOTPRINT_1;95 maskVal |= PM_SUBTRACTION_MASK_CONVOLVE_1; 89 96 break; 90 97 case PM_SUBTRACTION_MODE_2: 91 maskVal |= PM_SUBTRACTION_MASK_ FOOTPRINT_2;98 maskVal |= PM_SUBTRACTION_MASK_CONVOLVE_2; 92 99 break; 93 100 case PM_SUBTRACTION_MODE_UNSURE: 94 101 case PM_SUBTRACTION_MODE_DUAL: 95 maskVal |= PM_SUBTRACTION_MASK_ FOOTPRINT_1 | PM_SUBTRACTION_MASK_FOOTPRINT_2;102 maskVal |= PM_SUBTRACTION_MASK_CONVOLVE_1 | PM_SUBTRACTION_MASK_CONVOLVE_2; 96 103 break; 97 104 default: … … 99 106 } 100 107 101 return (mask->data.PS_TYPE_MASK_DATA[y][x] & maskVal) ? false : true; 108 // Check the immediate pixel 109 if (clean && (mask->data.PS_TYPE_MASK_DATA[y][x] & (maskVal | PM_SUBTRACTION_MASK_REJ))) { 110 clean = false; 111 } 112 113 int xMin = PS_MAX(x - footprint, 0), xMax = PS_MIN(x + footprint, numCols - 1); // Bounds in x 114 int yMin = PS_MAX(y - footprint, 0), yMax = PS_MIN(y + footprint, numRows - 1); // Bounds in y 115 116 // Check the footprint 117 if (clean) { 118 for (int j = yMin; j <= yMax; j++) { 119 for (int i = xMin; i <= xMax; i++) { 120 if (mask->data.PS_TYPE_MASK_DATA[j][i] & maskVal) { 121 clean = false; 122 goto CHECK_STAMP_MASK_DONE; 123 } 124 } 125 } 126 } 127 CHECK_STAMP_MASK_DONE: 128 129 if (!clean) { 130 // Mask the footprint, so we don't select something near it again 131 for (int j = yMin; j <= yMax; j++) { 132 for (int i = xMin; i <= xMax; i++) { 133 mask->data.PS_TYPE_MASK_DATA[j][i] |= PM_SUBTRACTION_MASK_REJ; 134 } 135 } 136 } 137 138 return clean; 102 139 } 103 140 … … 259 296 for (int y = subRegion->y0; y <= subRegion->y1; y++) { 260 297 for (int x = subRegion->x0; x <= subRegion->x1; x++) { 261 if (checkStampMask(x, y, subMask, mode ) && image->data.F32[y][x] > fluxStamp) {298 if (checkStampMask(x, y, subMask, mode, footprint) && image->data.F32[y][x] > fluxStamp) { 262 299 fluxStamp = image->data.F32[y][x]; 263 300 xStamp = x; … … 353 390 continue; 354 391 } 355 if (!checkStampMask(xPix, yPix, subMask, mode )) {392 if (!checkStampMask(xPix, yPix, subMask, mode, footprint)) { 356 393 // Not a good stamp 357 394 psTrace("psModules.imcombine", 9, "Rejecting input stamp (%d,%d) because bad mask",
Note:
See TracChangeset
for help on using the changeset viewer.
