- Timestamp:
- May 3, 2010, 8:45:22 AM (16 years ago)
- Location:
- branches/simmosaic_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simmosaic_branches
- Property svn:mergeinfo changed
-
branches/simmosaic_branches/psModules
-
Property svn:mergeinfo
set to (toggle deleted branches)
/trunk/psModules merged eligible /branches/eam_branches/stackphot.20100406/psModules 27623-27653 /branches/pap_delete/psModules 27530-27595
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/simmosaic_branches/psModules/src/imcombine/pmSubtractionMatch.c
r24292 r27839 10 10 #include "pmHDU.h" 11 11 #include "pmFPA.h" 12 #include "pmHDUUtils.h" 12 13 #include "pmSubtractionParams.h" 13 14 #include "pmSubtractionKernels.h" … … 27 28 static bool useFFT = true; // Do convolutions using FFT 28 29 30 # define SEPARATE 0 31 # if (SEPARATE) 32 # define SUBMODE PM_SUBTRACTION_EQUATION_NORM 33 # else 34 # define SUBMODE PM_SUBTRACTION_EQUATION_ALL 35 # endif 29 36 30 37 //#define TESTING … … 58 65 59 66 60 static bool getStamps(pmSubtractionStampList **stamps, // Stamps to read 61 const pmReadout *ro1, // Readout 1 62 const pmReadout *ro2, // Readout 2 63 const psImage *subMask, // Mask for subtraction, or NULL 64 psImage *variance, // Variance map 65 const psRegion *region, // Region of interest, or NULL 66 float thresh1, // Threshold for stamp finding on readout 1 67 float thresh2, // Threshold for stamp finding on readout 2 68 float stampSpacing, // Spacing between stamps 69 int size, // Kernel half-size 70 int footprint, // Convolution footprint for stamps 71 pmSubtractionMode mode // Mode for subtraction 67 static bool subtractionGetStamps(pmSubtractionStampList **stamps, // Stamps to read 68 const pmReadout *ro1, // Readout 1 69 const pmReadout *ro2, // Readout 2 70 const psImage *subMask, // Mask for subtraction, or NULL 71 psImage *variance, // Variance map 72 const psRegion *region, // Region of interest 73 float thresh1, // Threshold for stamp finding on readout 1 74 float thresh2, // Threshold for stamp finding on readout 2 75 float stampSpacing, // Spacing between stamps 76 float normFrac, // Fraction of flux in window for normalisation window 77 float sysError, // Relative systematic error in images 78 float skyError, // Relative systematic error in images 79 int size, // Kernel half-size 80 int footprint, // Convolution footprint for stamps 81 pmSubtractionMode mode // Mode for subtraction 72 82 ) 73 83 { 84 PS_ASSERT_PTR_NON_NULL(stamps, false); 85 PM_ASSERT_READOUT_NON_NULL(ro1, false); 86 PM_ASSERT_READOUT_NON_NULL(ro2, false); 87 PS_ASSERT_IMAGE_NON_NULL(subMask, false); 88 PS_ASSERT_IMAGE_NON_NULL(variance, false); 89 PS_ASSERT_PTR_NON_NULL(region, false); 90 74 91 psTrace("psModules.imcombine", 3, "Finding stamps...\n"); 75 92 … … 77 94 78 95 *stamps = pmSubtractionStampsFind(*stamps, image1, image2, subMask, region, thresh1, thresh2, 79 size, footprint, stampSpacing, mode);96 size, footprint, stampSpacing, normFrac, sysError, skyError, mode); 80 97 if (!*stamps) { 81 98 psError(psErrorCodeLast(), false, "Unable to find stamps."); … … 86 103 87 104 psTrace("psModules.imcombine", 3, "Extracting stamps...\n"); 88 if (!pmSubtractionStampsExtract(*stamps, ro1->image, ro2 ? ro2->image : NULL, variance, size)) {89 psError( PS_ERR_UNKNOWN, false, "Unable to extract stamps.");105 if (!pmSubtractionStampsExtract(*stamps, ro1->image, ro2->image, variance, size, *region)) { 106 psError(psErrorCodeLast(), false, "Unable to extract stamps."); 90 107 return false; 91 108 } … … 100 117 const pmReadout *ro1, const pmReadout *ro2, // Input images 101 118 int stride, // Size for convolution patches 102 float sysError, // Relative systematic error 119 float normFrac, // Fraction of window for normalisation window 120 float sysError, // Systematic error in images 121 float skyError, // Systematic error in images 122 float kernelError, // Systematic error in kernel 123 float covarFrac, // Fraction for kernel truncation before covariance 103 124 psImageMaskType maskVal, // Value to mask for input 104 125 psImageMaskType maskBad, // Mask for output bad pixels … … 111 132 if (subMode != PM_SUBTRACTION_MODE_2) { 112 133 PM_ASSERT_READOUT_NON_NULL(conv1, false); 134 PM_ASSERT_READOUT_NON_NULL(ro1, false); 135 PM_ASSERT_READOUT_IMAGE(ro1, false); 113 136 if (conv1->image) { 114 137 psFree(conv1->image); … … 126 149 if (subMode != PM_SUBTRACTION_MODE_1) { 127 150 PM_ASSERT_READOUT_NON_NULL(conv2, false); 151 PM_ASSERT_READOUT_NON_NULL(ro2, false); 152 PM_ASSERT_READOUT_IMAGE(ro2, false); 128 153 if (conv2->image) { 129 154 psFree(conv2->image); … … 140 165 } 141 166 142 PM_ASSERT_READOUT_NON_NULL(ro1, false); 143 PM_ASSERT_READOUT_NON_NULL(ro2, false); 144 PM_ASSERT_READOUT_IMAGE(ro1, false); 145 PM_ASSERT_READOUT_IMAGE(ro2, false); 146 PS_ASSERT_IMAGES_SIZE_EQUAL(ro1->image, ro2->image, false); 167 if (ro1 && ro2) { 168 PS_ASSERT_IMAGES_SIZE_EQUAL(ro1->image, ro2->image, false); 169 } 147 170 PS_ASSERT_INT_NONNEGATIVE(stride, false); 171 if (isfinite(normFrac)) { 172 PS_ASSERT_FLOAT_LARGER_THAN(normFrac, 0.0, false); 173 PS_ASSERT_FLOAT_LESS_THAN(normFrac, 1.0, false); 174 } 148 175 if (isfinite(sysError)) { 149 176 PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(sysError, 0.0, false); 150 177 PS_ASSERT_FLOAT_LESS_THAN(sysError, 1.0, false); 151 178 } 179 if (isfinite(sysError)) { 180 PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(skyError, 0.0, false); 181 } 182 if (isfinite(kernelError)) { 183 PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(kernelError, 0.0, false); 184 PS_ASSERT_FLOAT_LESS_THAN(kernelError, 1.0, false); 185 } 186 PS_ASSERT_FLOAT_LARGER_THAN_OR_EQUAL(covarFrac, 0.0, false); 187 PS_ASSERT_FLOAT_LESS_THAN(covarFrac, 1.0, false); 152 188 // Don't care about maskVal 153 189 // Don't care about maskBad … … 164 200 165 201 202 /// Allocate images, as required 203 static void subtractionMatchAlloc(pmReadout *conv1, pmReadout *conv2, // Output readouts 204 const pmReadout *ro1, const pmReadout *ro2, // Input readouts 205 const psImage *subMask, // Subtraction mask 206 psImageMaskType maskBad, // Mask value for bad pixels 207 pmSubtractionMode subMode, // Subtraction mode 208 int numCols, int numRows // Size of image 209 ) 210 { 211 if (subMode == PM_SUBTRACTION_MODE_1 || subMode == PM_SUBTRACTION_MODE_UNSURE || 212 subMode == PM_SUBTRACTION_MODE_DUAL) { 213 if (!conv1->image) { 214 conv1->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); 215 } 216 psImageInit(conv1->image, NAN); 217 if (ro1->variance) { 218 if (!conv1->variance) { 219 conv1->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32); 220 } 221 psImageInit(conv1->variance, NAN); 222 } 223 if (subMask) { 224 if (!conv1->mask) { 225 conv1->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK); 226 } 227 psImageInit(conv1->mask, maskBad); 228 } 229 } 230 if (subMode == PM_SUBTRACTION_MODE_2 || subMode == PM_SUBTRACTION_MODE_UNSURE || 231 subMode == PM_SUBTRACTION_MODE_DUAL) { 232 if (!conv2->image) { 233 conv2->image = psImageAlloc(numCols, numRows, PS_TYPE_F32); 234 } 235 psImageInit(conv2->image, NAN); 236 if (ro2->variance) { 237 if (!conv2->variance) { 238 conv2->variance = psImageAlloc(numCols, numRows, PS_TYPE_F32); 239 } 240 psImageInit(conv2->variance, NAN); 241 } 242 if (subMask) { 243 if (!conv2->mask) { 244 conv2->mask = psImageAlloc(numCols, numRows, PS_TYPE_IMAGE_MASK); 245 } 246 psImageInit(conv2->mask, maskBad); 247 } 248 } 249 250 return; 251 } 252 253 254 static void subtractionAnalysisUpdate(pmReadout *conv1, pmReadout *conv2, // Convolved images 255 const psMetadata *analysis, // Analysis metadata 256 const psMetadata *header // Header metadata 257 ) 258 { 259 if (conv1) { 260 conv1->analysis = psMetadataCopy(conv1->analysis, analysis); 261 } 262 if (conv2) { 263 conv2->analysis = psMetadataCopy(conv2->analysis, analysis); 264 } 265 266 if (conv1 && conv1->parent) { 267 pmHDU *hdu = pmHDUFromCell(conv1->parent); 268 if (hdu) { 269 hdu->header = psMetadataCopy(hdu->header, header); 270 } 271 } 272 if (conv2 && conv2->parent) { 273 pmHDU *hdu = pmHDUFromCell(conv2->parent); 274 if (hdu) { 275 hdu->header = psMetadataCopy(hdu->header, header); 276 } 277 } 278 279 return; 280 } 281 282 bool pmSubtractionMaskInvalid (const pmReadout *readout, psImageMaskType maskVal) { 283 284 if (!readout) return true; 285 286 psImage *image = readout->image; 287 psImage *mask = readout->mask; 288 psImage *variance = readout->variance; 289 for (int y = 0; y < image->numRows; y++) { 290 for (int x = 0; x < image->numCols; x++) { 291 if (mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] & maskVal) continue; 292 bool valid = false; 293 valid = isfinite(image->data.F32[y][x]); 294 if (variance) { 295 valid &= isfinite(variance->data.F32[y][x]); 296 } 297 if (valid) continue; 298 mask->data.PS_TYPE_IMAGE_MASK_DATA[y][x] = maskVal; 299 } 300 } 301 302 return true; 303 } 166 304 167 305 bool pmSubtractionMatchPrecalc(pmReadout *conv1, pmReadout *conv2, const pmReadout *ro1, const pmReadout *ro2, 168 psMetadata *analysis, int stride, float sysError,306 psMetadata *analysis, int stride, float kernelError, float covarFrac, 169 307 psImageMaskType maskVal, psImageMaskType maskBad, psImageMaskType maskPoor, 170 308 float poorFrac, float badFrac) … … 182 320 while ((item = psMetadataGetAndIncrement(iter))) { 183 321 if (item->type != PS_DATA_UNKNOWN) { 184 psError(P S_ERR_BAD_PARAMETER_TYPE, true, "Unexpected type for kernel.");322 psError(PM_ERR_PROG, true, "Unexpected type for kernel."); 185 323 psFree(iter); 186 324 psFree(kernelList); … … 202 340 } 203 341 if (psListLength(kernelList) == 0) { 204 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Unable to find kernels");342 psError(PM_ERR_PROG, true, "Unable to find kernels"); 205 343 psFree(kernelList); 206 344 return false; … … 217 355 while ((item = psMetadataGetAndIncrement(iter))) { 218 356 if (item->type != PS_DATA_REGION) { 219 psError(P S_ERR_BAD_PARAMETER_TYPE, true, "Unexpected type for region.");357 psError(PM_ERR_PROG, true, "Unexpected type for region."); 220 358 psFree(iter); 221 359 psFree(kernels); … … 229 367 } 230 368 if (regions->n != kernels->n) { 231 psError(P S_ERR_BAD_PARAMETER_VALUE, true, "Differing number of kernels (%ld) and regions (%ld)",369 psError(PM_ERR_PROG, true, "Differing number of kernels (%ld) and regions (%ld)", 232 370 kernels->n, regions->n); 233 371 psFree(regions); … … 236 374 } 237 375 238 if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, sysError, maskVal, maskBad, maskPoor,239 poorFrac, badFrac, mode)) {376 if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, NAN, NAN, NAN, kernelError, covarFrac, 377 maskVal, maskBad, maskPoor, poorFrac, badFrac, mode)) { 240 378 psFree(kernels); 241 379 psFree(regions); … … 243 381 } 244 382 245 psImage *subMask = pmSubtractionMask(ro1->mask, ro2 ? ro2->mask : NULL, maskVal, size, 0, 383 int numCols, numRows; // Size of image 384 if (ro1) { 385 numCols = ro1->image->numCols; 386 numRows = ro1->image->numRows; 387 } else if (ro2) { 388 numCols = ro2->image->numCols; 389 numRows = ro2->image->numRows; 390 } else { 391 psAbort("No input image provided."); 392 } 393 394 pmSubtractionMaskInvalid(ro1, maskVal); 395 pmSubtractionMaskInvalid(ro2, maskVal); 396 397 // General background subtraction, since this is done in pmSubtractionMatch 398 { 399 psRandom *rng = psRandomAlloc(PS_RANDOM_TAUS); // Random number generator 400 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); // Statistics for background 401 if (ro1) { 402 psStatsInit(bg); 403 if (!psImageBackground(bg, NULL, ro1->image, ro1->mask, maskVal, rng)) { 404 psError(PM_ERR_DATA, false, "Unable to measure background statistics."); 405 psFree(bg); 406 psFree(rng); 407 return false; 408 } 409 psBinaryOp(ro1->image, ro1->image, "-", psScalarAlloc((float)bg->robustMedian, PS_TYPE_F32)); 410 } 411 if (ro2) { 412 psStatsInit(bg); 413 if (!psImageBackground(bg, NULL, ro2->image, ro2->mask, maskVal, rng)) { 414 psError(PM_ERR_DATA, false, "Unable to measure background statistics."); 415 psFree(bg); 416 psFree(rng); 417 return false; 418 } 419 psBinaryOp(ro2->image, ro2->image, "-", psScalarAlloc((float)bg->robustMedian, PS_TYPE_F32)); 420 } 421 psFree(bg); 422 psFree(rng); 423 } 424 425 psRegion bounds = psRegionSet(NAN, NAN, NAN, NAN); // Bounds of valid pixels 426 427 psImage *subMask = pmSubtractionMask(&bounds, ro1, ro2, maskVal, size, 0, 246 428 badFrac, mode); // Subtraction mask 247 429 if (!subMask) { … … 253 435 254 436 psMetadata *outAnalysis = psMetadataAlloc(); // Output analysis values 437 psMetadata *outHeader = psMetadataAlloc(); // Output header values 438 439 subtractionMatchAlloc(conv1, conv2, ro1, ro2, subMask, maskBad, mode, numCols, numRows); 255 440 256 441 psTrace("psModules.imcombine", 2, "Convolving...\n"); … … 259 444 psRegion *region = regions->data[i]; // Region of interest 260 445 261 if (!pmSubtractionAnalysis(outAnalysis, kernel, region, ro1->image->numCols, ro1->image->numRows)) {262 psError( PS_ERR_UNKNOWN, false, "Unable to generate QA data");446 if (!pmSubtractionAnalysis(outAnalysis, outHeader, kernel, region, numCols, numRows)) { 447 psError(psErrorCodeLast(), false, "Unable to generate QA data"); 263 448 psFree(outAnalysis); 449 psFree(outHeader); 264 450 psFree(subMask); 265 451 psFree(kernels); … … 269 455 270 456 if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, stride, maskBad, maskPoor, poorFrac, 271 sysError, region, kernel, true, useFFT)) {272 psError( PS_ERR_UNKNOWN, false, "Unable to convolve image.");457 kernelError, covarFrac, region, kernel, true, useFFT)) { 458 psError(psErrorCodeLast(), false, "Unable to convolve image."); 273 459 psFree(outAnalysis); 460 psFree(outHeader); 274 461 psFree(subMask); 275 462 psFree(kernels); … … 283 470 psFree(regions); 284 471 285 if (conv1) { 286 psMetadataCopy(conv1->analysis, outAnalysis); 287 } 288 if (conv2) { 289 psMetadataCopy(conv2->analysis, outAnalysis); 290 } 472 subtractionAnalysisUpdate(conv1, conv2, outAnalysis, outHeader); 291 473 psFree(outAnalysis); 474 psFree(outHeader); 292 475 293 476 return true; … … 302 485 int inner, int ringsOrder, int binning, float penalty, 303 486 bool optimum, const psVector *optFWHMs, int optOrder, float optThreshold, 304 int iter, float rej, float sysError, psImageMaskType maskVal, psImageMaskType maskBad, 487 int iter, float rej, float normFrac, float sysError, float skyError, 488 float kernelError, float covarFrac, psImageMaskType maskVal, psImageMaskType maskBad, 305 489 psImageMaskType maskPoor, float poorFrac, float badFrac, pmSubtractionMode subMode) 306 490 { 307 if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, sysError, maskVal, maskBad, maskPoor,308 poorFrac, badFrac, subMode)) {491 if (!subtractionMatchCheck(conv1, conv2, ro1, ro2, stride, normFrac, sysError, skyError, kernelError, 492 covarFrac, maskVal, maskBad, maskPoor, poorFrac, badFrac, subMode)) { 309 493 return false; 310 494 } 495 496 // We need both inputs 497 PM_ASSERT_READOUT_NON_NULL(ro1, false); 498 PM_ASSERT_READOUT_NON_NULL(ro2, false); 311 499 312 500 PS_ASSERT_INT_NONNEGATIVE(footprint, false); … … 364 552 // Putting important variable declarations here, since they are freed after a "goto" if there is an error. 365 553 psImage *subMask = NULL; // Mask for subtraction 366 psRegion *region = NULL;// Iso-kernel region554 psRegion *region = psRegionAlloc(NAN, NAN, NAN, NAN); // Iso-kernel region 367 555 psString regionString = NULL; // String for region 368 556 pmSubtractionStampList *stamps = NULL; // Stamps for matching PSF 369 557 pmSubtractionKernels *kernels = NULL; // Kernel basis functions 370 558 psMetadata *analysis = psMetadataAlloc(); // QA data 559 psMetadata *header = psMetadataAlloc(); // QA data for header 371 560 372 561 int numCols = ro1->image->numCols, numRows = ro1->image->numRows; // Image dimensions … … 376 565 memCheck("start"); 377 566 378 subMask = pmSubtractionMask(ro1->mask, ro2 ? ro2->mask : NULL, maskVal, size, footprint, 379 badFrac, subMode); 567 pmSubtractionMaskInvalid(ro1, maskVal); 568 pmSubtractionMaskInvalid(ro2, maskVal); 569 570 psRegion bounds = psRegionSet(NAN, NAN, NAN, NAN); // Bounds of valid pixels 571 572 subMask = pmSubtractionMask(&bounds, ro1, ro2, maskVal, size, footprint, badFrac, subMode); 380 573 if (!subMask) { 381 574 psError(psErrorCodeLast(), false, "Unable to generate subtraction mask."); … … 387 580 // Get region of interest 388 581 int xRegions = 1, yRegions = 1; // Number of iso-kernel regions 389 float xRegionSize = 0, yRegionSize = 0; // Size of iso-kernel regions582 float xRegionSize = NAN, yRegionSize = NAN; // Size of iso-kernel regions 390 583 if (isfinite(regionSize) && regionSize != 0.0) { 391 xRegions = numCols / regionSize + 1; 392 yRegions = numRows / regionSize + 1; 393 xRegionSize = (float)numCols / (float)xRegions; 394 yRegionSize = (float)numRows / (float)yRegions; 395 region = psRegionAlloc(NAN, NAN, NAN, NAN); 396 } 397 584 xRegions = (bounds.x1 - bounds.x0) / regionSize + 1; 585 yRegions = (bounds.y1 - bounds.y0) / regionSize + 1; 586 xRegionSize = (float)(bounds.x1 - bounds.x0) / (float)xRegions; 587 yRegionSize = (float)(bounds.y1 - bounds.y0) / (float)yRegions; 588 } else { 589 xRegionSize = bounds.x1 - bounds.x0; 590 yRegionSize = bounds.y1 - bounds.y0; 591 } 592 593 // General background subtraction and measurement of stamp threshold 398 594 float stampThresh1 = NAN, stampThresh2 = NAN; // Stamp thresholds for images 399 595 { 400 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for backgroun 596 psStats *bg = psStatsAlloc(PS_STAT_ROBUST_MEDIAN | PS_STAT_ROBUST_STDEV); // Statistics for background 401 597 if (ro1) { 598 psStatsInit(bg); 402 599 if (!psImageBackground(bg, NULL, ro1->image, ro1->mask, maskVal, rng)) { 403 psError(P S_ERR_UNKNOWN, false, "Unable to measure background statistics.");600 psError(PM_ERR_DATA, false, "Unable to measure background statistics."); 404 601 psFree(bg); 405 602 goto MATCH_ERROR; 406 603 } 407 stampThresh1 = bg->robustMedian + threshold * bg->robustStdev; 604 stampThresh1 = threshold * bg->robustStdev; 605 psBinaryOp(ro1->image, ro1->image, "-", psScalarAlloc((float)bg->robustMedian, PS_TYPE_F32)); 408 606 } 409 607 if (ro2) { 608 psStatsInit(bg); 410 609 if (!psImageBackground(bg, NULL, ro2->image, ro2->mask, maskVal, rng)) { 411 psError(P S_ERR_UNKNOWN, false, "Unable to measure background statistics.");610 psError(PM_ERR_DATA, false, "Unable to measure background statistics."); 412 611 psFree(bg); 413 612 goto MATCH_ERROR; 414 613 } 415 stampThresh2 = bg->robustMedian + threshold * bg->robustStdev; 614 stampThresh2 = threshold * bg->robustStdev; 615 psBinaryOp(ro2->image, ro2->image, "-", psScalarAlloc((float)bg->robustMedian, PS_TYPE_F32)); 416 616 } 417 617 psFree(bg); 418 618 } 619 620 subtractionMatchAlloc(conv1, conv2, ro1, ro2, subMask, maskBad, subMode, numCols, numRows); 419 621 420 622 // Iterate over iso-kernel regions … … 423 625 psTrace("psModules.imcombine", 1, "Subtracting region %d of %d...\n", 424 626 j * xRegions + i + 1, xRegions * yRegions); 425 if (region) {426 *region = psRegionSet((int)(i * xRegionSize),(int)((i + 1) * xRegionSize),427 (int)(j * yRegionSize), (int)((j + 1) * yRegionSize));428 psFree(regionString);429 regionString = psRegionToString(*region);430 psTrace("psModules.imcombine", 3, "Iso-kernel region: %s out of %d,%d\n",431 regionString, numCols, numRows);432 }627 *region = psRegionSet(bounds.x0 + (int)(i * xRegionSize), 628 bounds.x0 + (int)((i + 1) * xRegionSize), 629 bounds.y0 + (int)(j * yRegionSize), 630 bounds.y0 + (int)((j + 1) * yRegionSize)); 631 psFree(regionString); 632 regionString = psRegionToString(*region); 633 psLogMsg("psModules.imcombine", PS_LOG_DETAIL, "Iso-kernel region: %s out of %d,%d\n", 634 regionString, numCols, numRows); 433 635 434 636 if (stampsName && strlen(stampsName) > 0) { 435 637 stamps = pmSubtractionStampsSetFromFile(stampsName, ro1->image, subMask, region, size, 436 footprint, stampSpacing, subMode); 638 footprint, stampSpacing, normFrac, 639 sysError, skyError, subMode); 437 640 } else if (sources) { 438 641 stamps = pmSubtractionStampsSetFromSources(sources, ro1->image, subMask, region, size, 439 footprint, stampSpacing, subMode); 642 footprint, stampSpacing, normFrac, 643 sysError, skyError, subMode); 440 644 } 441 645 442 646 // We get the stamps here; we will also attempt to get stamps at the first iteration, but it 443 647 // doesn't matter. 444 if (! getStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2,445 stampSpacing, size, footprint, subMode)) {648 if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region, stampThresh1, stampThresh2, 649 stampSpacing, normFrac, sysError, skyError, size, footprint, subMode)) { 446 650 goto MATCH_ERROR; 447 651 } 448 652 653 654 // generate the window function from the set of stamps 655 if (!pmSubtractionStampsGetWindow(stamps, size)) { 656 psError(psErrorCodeLast(), false, "Unable to get stamp window."); 657 goto MATCH_ERROR; 658 } 659 660 // Define kernel basis functions 661 if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) { 662 kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, 663 optFWHMs, optOrder, stamps, footprint, 664 optThreshold, penalty, bounds, subMode); 665 if (!kernels) { 666 psErrorClear(); 667 psWarning("Unable to derive optimum ISIS kernel --- switching to default."); 668 } 669 } 670 if (kernels == NULL) { 671 // Not an ISIS/GUNK kernel, or the optimum kernel search failed 672 kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders, 673 inner, binning, ringsOrder, penalty, bounds, subMode); 674 // pmSubtractionVisualShowKernels(kernels); 675 } 676 677 memCheck("kernels"); 678 449 679 if (subMode == PM_SUBTRACTION_MODE_UNSURE) { 680 #if 0 450 681 // Get backgrounds 451 682 psStats *bgStats = psStatsAlloc(BG_STAT); // Statistics for background 452 683 psVector *buffer = NULL;// Buffer for stats 453 684 if (!psImageBackground(bgStats, &buffer, ro1->image, ro1->mask, maskVal, rng)) { 454 psError(P S_ERR_UNKNOWN, false, "Unable to measure background of image 1.");685 psError(PM_ERR_DATA, false, "Unable to measure background of image 1."); 455 686 psFree(bgStats); 456 687 psFree(buffer); … … 459 690 float bg1 = psStatsGetValue(bgStats, BG_STAT); // Background for image 1 460 691 if (!psImageBackground(bgStats, &buffer, ro2->image, ro2->mask, maskVal, rng)) { 461 psError(P S_ERR_UNKNOWN, false, "Unable to measure background of image 2.");692 psError(PM_ERR_DATA, false, "Unable to measure background of image 2."); 462 693 psFree(bgStats); 463 694 psFree(buffer); … … 469 700 470 701 pmSubtractionMode newMode = pmSubtractionOrder(stamps, bg1, bg2); // Subtraction mode to use 702 #endif 703 pmSubtractionMode newMode = pmSubtractionBestMode(&stamps, &kernels, subMask, rej); 471 704 switch (newMode) { 472 705 case PM_SUBTRACTION_MODE_1: … … 477 710 break; 478 711 default: 479 psError( PS_ERR_UNKNOWN, false, "Unable to determine subtraction order.");712 psError(psErrorCodeLast(), false, "Unable to determine subtraction order."); 480 713 goto MATCH_ERROR; 481 714 } 482 715 subMode = newMode; 483 716 } 484 485 // Define kernel basis functions486 if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) {487 kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder,488 stamps, footprint, optThreshold, penalty, subMode);489 if (!kernels) {490 psErrorClear();491 psWarning("Unable to derive optimum ISIS kernel --- switching to default.");492 }493 }494 if (kernels == NULL) {495 // Not an ISIS/GUNK kernel, or the optimum kernel search failed496 kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders,497 inner, binning, ringsOrder, penalty, subMode);498 }499 500 memCheck("kernels");501 717 502 718 int numRejected = -1; // Number of rejected stamps in each iteration … … 504 720 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Iteration %d.", k); 505 721 506 if (!getStamps(&stamps, ro1, ro2, subMask, variance, region, stampThresh1, stampThresh2, 507 stampSpacing, size, footprint, subMode)) { 508 goto MATCH_ERROR; 509 } 510 511 psTrace("psModules.imcombine", 3, "Calculating equation...\n"); 512 if (!pmSubtractionCalculateEquation(stamps, kernels)) { 513 psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation."); 514 goto MATCH_ERROR; 515 } 516 722 if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region, 723 stampThresh1, stampThresh2, stampSpacing, normFrac, 724 sysError, skyError, size, footprint, subMode)) { 725 goto MATCH_ERROR; 726 } 727 728 // generate the window function from the set of stamps 729 if (!pmSubtractionStampsGetWindow(stamps, size)) { 730 psError(psErrorCodeLast(), false, "Unable to get stamps window."); 731 goto MATCH_ERROR; 732 } 733 734 // XXX step 1: calculate normalization 735 psTrace("psModules.imcombine", 3, "Calculating equation for normalization...\n"); 736 if (!pmSubtractionCalculateEquation(stamps, kernels, SUBMODE)) { 737 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 738 goto MATCH_ERROR; 739 } 740 741 psTrace("psModules.imcombine", 3, "Solving equation for normalization...\n"); 742 if (!pmSubtractionSolveEquation(kernels, stamps, SUBMODE)) { 743 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 744 goto MATCH_ERROR; 745 } 746 memCheck(" solve equation"); 747 748 # if (SEPARATE) 749 // set USED -> CALCULATE 750 pmSubtractionStampsResetStatus (stamps); 751 752 // XXX step 2: calculate kernel parameters 753 psTrace("psModules.imcombine", 3, "Calculating equation for kernels...\n"); 754 if (!pmSubtractionCalculateEquation(stamps, kernels, PM_SUBTRACTION_EQUATION_KERNELS)) { 755 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 756 goto MATCH_ERROR; 757 } 517 758 memCheck(" calculate equation"); 518 759 519 psTrace("psModules.imcombine", 3, "Solving equation...\n"); 520 521 if (!pmSubtractionSolveEquation(kernels, stamps)) { 522 psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation."); 523 goto MATCH_ERROR; 524 } 525 760 psTrace("psModules.imcombine", 3, "Solving equation for kernels...\n"); 761 if (!pmSubtractionSolveEquation(kernels, stamps, PM_SUBTRACTION_EQUATION_KERNELS)) { 762 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 763 goto MATCH_ERROR; 764 } 526 765 memCheck(" solve equation"); 527 766 # endif 528 767 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 529 768 if (!deviations) { 530 psError( PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");769 psError(psErrorCodeLast(), false, "Unable to calculate deviations."); 531 770 goto MATCH_ERROR; 532 771 } … … 535 774 536 775 psTrace("psModules.imcombine", 3, "Rejecting stamps...\n"); 537 numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej , footprint);776 numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej); 538 777 if (numRejected < 0) { 539 psError( PS_ERR_UNKNOWN, false, "Unable to reject stamps.");778 psError(psErrorCodeLast(), false, "Unable to reject stamps."); 540 779 psFree(deviations); 541 780 goto MATCH_ERROR; … … 546 785 } 547 786 787 // if we hit the max number of iterations and we have rejected stamps, re-solve 548 788 if (numRejected > 0) { 549 psTrace("psModules.imcombine", 3, "Solving equation...\n"); 550 if (!pmSubtractionSolveEquation(kernels, stamps)) { 551 psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation."); 552 goto MATCH_ERROR; 553 } 789 // XXX step 1: calculate normalization 790 psTrace("psModules.imcombine", 3, "Calculating equation for normalization...\n"); 791 if (!pmSubtractionCalculateEquation(stamps, kernels, SUBMODE)) { 792 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 793 goto MATCH_ERROR; 794 } 795 796 // solve normalization 797 psTrace("psModules.imcombine", 3, "Solving equation for kernels...\n"); 798 if (!pmSubtractionSolveEquation(kernels, stamps, SUBMODE)) { 799 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 800 goto MATCH_ERROR; 801 } 802 803 # if (SEPARATE) 804 // set USED -> CALCULATE 805 pmSubtractionStampsResetStatus (stamps); 806 807 // XXX step 2: calculate kernel parameters 808 psTrace("psModules.imcombine", 3, "Calculating equation for normalization...\n"); 809 if (!pmSubtractionCalculateEquation(stamps, kernels, PM_SUBTRACTION_EQUATION_KERNELS)) { 810 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 811 goto MATCH_ERROR; 812 } 813 814 // solve kernel parameters 815 psTrace("psModules.imcombine", 3, "Solving equation for kernels...\n"); 816 if (!pmSubtractionSolveEquation(kernels, stamps, PM_SUBTRACTION_EQUATION_KERNELS)) { 817 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 818 goto MATCH_ERROR; 819 } 820 memCheck(" solve equation"); 821 # endif 554 822 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 555 823 if (!deviations) { 556 psError( PS_ERR_UNKNOWN, false, "Unable to calculate deviations.");557 goto MATCH_ERROR; 558 } 559 pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN , footprint);824 psError(psErrorCodeLast(), false, "Unable to calculate deviations."); 825 goto MATCH_ERROR; 826 } 827 pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN); 560 828 psFree(deviations); 561 829 } … … 565 833 memCheck("solution"); 566 834 567 if (!pmSubtractionAnalysis(analysis, kernels, region, numCols, numRows)) {568 psError( PS_ERR_UNKNOWN, false, "Unable to generate QA data");835 if (!pmSubtractionAnalysis(analysis, header, kernels, region, numCols, numRows)) { 836 psError(psErrorCodeLast(), false, "Unable to generate QA data"); 569 837 goto MATCH_ERROR; 570 838 } … … 574 842 psTrace("psModules.imcombine", 2, "Convolving...\n"); 575 843 if (!pmSubtractionConvolve(conv1, conv2, ro1, ro2, subMask, stride, maskBad, maskPoor, poorFrac, 576 sysError, region, kernels, true, useFFT)) {577 psError( PS_ERR_UNKNOWN, false, "Unable to convolve image.");844 kernelError, covarFrac, region, kernels, true, useFFT)) { 845 psError(psErrorCodeLast(), false, "Unable to convolve image."); 578 846 goto MATCH_ERROR; 579 847 } … … 594 862 variance = NULL; 595 863 596 if ( !pmSubtractionBorder(conv1->image, conv1->variance, conv1->mask, size, maskBad)) {597 psError( PS_ERR_UNKNOWN, false, "Unable to set border of convolved image.");864 if (conv1 && !pmSubtractionBorder(conv1->image, conv1->variance, conv1->mask, size, maskBad)) { 865 psError(psErrorCodeLast(), false, "Unable to set border of convolved image."); 598 866 goto MATCH_ERROR; 599 867 } 868 if (conv2 && !pmSubtractionBorder(conv2->image, conv2->variance, conv2->mask, size, maskBad)) { 869 psError(psErrorCodeLast(), false, "Unable to set border of convolved image."); 870 goto MATCH_ERROR; 871 } 600 872 601 873 memCheck("convolution"); 602 874 603 if (conv1) { 604 psMetadataCopy(conv1->analysis, analysis); 605 } 606 if (conv2) { 607 psMetadataCopy(conv2->analysis, analysis); 608 } 875 subtractionAnalysisUpdate(conv1, conv2, analysis, header); 609 876 psFree(analysis); 877 psFree(header); 610 878 611 879 #ifdef TESTING … … 629 897 MATCH_ERROR: 630 898 psFree(analysis); 899 psFree(header); 631 900 psFree(region); 632 901 psFree(regionString); … … 797 1066 } else { 798 1067 if (!pmSubtractionOrderStamp(ratios, mask, stamps, models, modelSums, i, bg1, bg2)) { 799 psError( PS_ERR_UNKNOWN, false, "Unable to measure PSF width for stamp %d", i);1068 psError(psErrorCodeLast(), false, "Unable to measure PSF width for stamp %d", i); 800 1069 psFree(models); 801 1070 psFree(modelSums); … … 808 1077 809 1078 if (!psThreadPoolWait(true)) { 810 psError( PS_ERR_UNKNOWN, false, "Error waiting for threads.");1079 psError(psErrorCodeLast(), false, "Error waiting for threads."); 811 1080 psFree(models); 812 1081 psFree(modelSums); … … 821 1090 psStats *stats = psStatsAlloc(PS_STAT_ROBUST_MEDIAN); 822 1091 if (!psVectorStats(stats, ratios, NULL, mask, 0xff)) { 823 psError( PS_ERR_UNKNOWN, false, "Unable to calculate statistics for moments ratio.");1092 psError(psErrorCodeLast(), false, "Unable to calculate statistics for moments ratio."); 824 1093 psFree(mask); 825 1094 psFree(ratios); … … 842 1111 return mode; 843 1112 } 1113 1114 1115 // Test a subtraction mode by performing a single iteration 1116 static bool subtractionModeTest(pmSubtractionStampList *stamps, // Stamps to use to find best mode 1117 pmSubtractionKernels *kernels, // Kernel description 1118 const char *description, // Description for trace 1119 psImage *subMask, // Subtraction mask 1120 float rej // Rejection threshold 1121 ) 1122 { 1123 assert(stamps); 1124 assert(kernels); 1125 1126 psTrace("psModules.imcombine", 3, "Calculating %s normalization equation...\n", description); 1127 if (!pmSubtractionCalculateEquation(stamps, kernels, SUBMODE)) { 1128 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1129 return false; 1130 } 1131 1132 psTrace("psModules.imcombine", 3, "Solving %s normalization equation...\n", description); 1133 if (!pmSubtractionSolveEquation(kernels, stamps, SUBMODE)) { 1134 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1135 return false; 1136 } 1137 1138 # if (SEPARATE) 1139 // set USED -> CALCULATE 1140 pmSubtractionStampsResetStatus (stamps); 1141 1142 psTrace("psModules.imcombine", 3, "Calculating %s kernel coeffs equation...\n", description); 1143 if (!pmSubtractionCalculateEquation(stamps, kernels, PM_SUBTRACTION_EQUATION_KERNELS)) { 1144 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1145 return false; 1146 } 1147 1148 psTrace("psModules.imcombine", 3, "Solving %s kernel coeffs equation...\n", description); 1149 if (!pmSubtractionSolveEquation(kernels, stamps, PM_SUBTRACTION_EQUATION_KERNELS)) { 1150 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1151 return false; 1152 } 1153 # endif 1154 1155 psTrace("psModules.imcombine", 3, "Calculate %s deviations...\n", description); 1156 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 1157 if (!deviations) { 1158 psError(psErrorCodeLast(), false, "Unable to calculate deviations."); 1159 return false; 1160 } 1161 1162 psTrace("psModules.imcombine", 3, "Rejecting %s stamps...\n", description); 1163 long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej); 1164 if (numRejected < 0) { 1165 psError(psErrorCodeLast(), false, "Unable to reject stamps."); 1166 psFree(deviations); 1167 return false; 1168 } 1169 psFree(deviations); 1170 1171 if (numRejected > 0) { 1172 // Allow re-fit with reduced stamps set 1173 psTrace("psModules.imcombine", 3, "Calculating %s normalization equation...\n", description); 1174 if (!pmSubtractionCalculateEquation(stamps, kernels, PM_SUBTRACTION_EQUATION_ALL)) { 1175 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1176 return false; 1177 } 1178 1179 psTrace("psModules.imcombine", 3, "Resolving %s equation...\n", description); 1180 if (!pmSubtractionSolveEquation(kernels, stamps, PM_SUBTRACTION_EQUATION_ALL)) { 1181 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1182 return false; 1183 } 1184 psTrace("psModules.imcombine", 3, "Recalculate %s deviations...\n", description); 1185 1186 # if (SEPARATE) 1187 // set USED -> CALCULATE 1188 pmSubtractionStampsResetStatus (stamps); 1189 1190 psTrace("psModules.imcombine", 3, "Calculating %s normalization equation...\n", description); 1191 if (!pmSubtractionCalculateEquation(stamps, kernels, PM_SUBTRACTION_EQUATION_KERNELS)) { 1192 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1193 return false; 1194 } 1195 1196 psTrace("psModules.imcombine", 3, "Resolving %s equation...\n", description); 1197 if (!pmSubtractionSolveEquation(kernels, stamps, PM_SUBTRACTION_EQUATION_KERNELS)) { 1198 psError(psErrorCodeLast(), false, "Unable to calculate least-squares equation."); 1199 return false; 1200 } 1201 psTrace("psModules.imcombine", 3, "Recalculate %s deviations...\n", description); 1202 # endif 1203 1204 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 1205 if (!deviations) { 1206 psError(psErrorCodeLast(), false, "Unable to calculate deviations."); 1207 return false; 1208 } 1209 psTrace("psModules.imcombine", 3, "Measuring %s quality...\n", description); 1210 long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN); 1211 if (numRejected < 0) { 1212 psError(psErrorCodeLast(), false, "Unable to reject stamps."); 1213 psFree(deviations); 1214 return false; 1215 } 1216 psFree(deviations); 1217 } 1218 1219 return true; 1220 } 1221 1222 1223 pmSubtractionMode pmSubtractionBestMode(pmSubtractionStampList **stamps, pmSubtractionKernels **kernels, 1224 const psImage *subMask, float rej) 1225 { 1226 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(*stamps, PM_SUBTRACTION_MODE_ERR); 1227 PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(*kernels, PM_SUBTRACTION_MODE_ERR); 1228 1229 // Copies of the inputs 1230 pmSubtractionStampList *stamps1 = pmSubtractionStampListCopy(*stamps); 1231 pmSubtractionKernels *kernels1 = pmSubtractionKernelsCopy(*kernels); 1232 psImage *subMask1 = psImageCopy(NULL, subMask, subMask->type.type); 1233 kernels1->mode = PM_SUBTRACTION_MODE_1; 1234 1235 if (!subtractionModeTest(stamps1, kernels1, "convolve 1", subMask1, rej)) { 1236 psError(psErrorCodeLast(), false, "Unable to test subtraction with convolution of image 1"); 1237 psFree(stamps1); 1238 psFree(kernels1); 1239 psFree(subMask1); 1240 return PM_SUBTRACTION_MODE_ERR; 1241 } 1242 psFree(subMask1); 1243 1244 // Copies of the inputs 1245 pmSubtractionStampList *stamps2 = pmSubtractionStampListCopy(*stamps); 1246 pmSubtractionKernels *kernels2 = pmSubtractionKernelsCopy(*kernels); 1247 psImage *subMask2 = psImageCopy(NULL, subMask, subMask->type.type); 1248 kernels2->mode = PM_SUBTRACTION_MODE_2; 1249 1250 if (!subtractionModeTest(stamps2, kernels2, "convolve 2", subMask2, rej)) { 1251 psError(psErrorCodeLast(), false, "Unable to test subtraction with convolution of image 2"); 1252 psFree(stamps2); 1253 psFree(kernels2); 1254 psFree(subMask2); 1255 psFree(stamps1); 1256 psFree(kernels1); 1257 return PM_SUBTRACTION_MODE_ERR; 1258 } 1259 psFree(subMask2); 1260 1261 1262 pmSubtractionStampList *bestStamps = NULL; // Best choice for stamps 1263 pmSubtractionKernels *bestKernels = NULL; // Best choice for kernels 1264 psLogMsg("psModules.imcombine", PS_LOG_INFO, 1265 "Image 1: %f +/- %f from %d stamps\nImage 2: %f +/- %f from %d stamps\n", 1266 kernels1->mean, kernels1->rms, kernels1->numStamps, 1267 kernels2->mean, kernels2->rms, kernels2->numStamps); 1268 1269 if (kernels1->mean < kernels2->mean) { 1270 bestStamps = stamps1; 1271 bestKernels = kernels1; 1272 } else { 1273 bestStamps = stamps2; 1274 bestKernels = kernels2; 1275 } 1276 1277 psFree(*stamps); 1278 psFree(*kernels); 1279 *stamps = psMemIncrRefCounter(bestStamps); 1280 *kernels = psMemIncrRefCounter(bestKernels); 1281 1282 psFree(stamps1); 1283 psFree(stamps2); 1284 psFree(kernels1); 1285 psFree(kernels2); 1286 1287 return bestKernels->mode; 1288 } 1289 1290 1291 bool pmSubtractionParamsScale(int *kernelSize, int *stampSize, psVector *widths, 1292 float fwhm1, float fwhm2, float scaleRef, float scaleMin, float scaleMax) 1293 { 1294 PS_ASSERT_PTR_NON_NULL(kernelSize, false); 1295 PS_ASSERT_PTR_NON_NULL(stampSize, false); 1296 PS_ASSERT_VECTOR_NON_NULL(widths, false); 1297 PS_ASSERT_VECTOR_TYPE(widths, PS_TYPE_F32, false); 1298 PS_ASSERT_FLOAT_LARGER_THAN(fwhm1, 0.0, false); 1299 PS_ASSERT_FLOAT_LARGER_THAN(fwhm2, 0.0, false); 1300 PS_ASSERT_FLOAT_LARGER_THAN(scaleRef, 0.0, false); 1301 PS_ASSERT_FLOAT_LARGER_THAN(scaleMin, 0.0, false); 1302 PS_ASSERT_FLOAT_LARGER_THAN(scaleMax, 0.0, false); 1303 PS_ASSERT_FLOAT_LARGER_THAN(scaleMax, scaleMin, false); 1304 1305 // float diff = sqrtf(PS_SQR(PS_MAX(fwhm1, fwhm2)) - PS_SQR(PS_MIN(fwhm1, fwhm2))); // Difference 1306 float scale = PS_MAX(fwhm1, fwhm2) / scaleRef; // Scaling factor 1307 1308 if (isfinite(scaleMin) && scale < scaleMin) { 1309 scale = scaleMin; 1310 } 1311 if (isfinite(scaleMax) && scale > scaleMax) { 1312 scale = scaleMax; 1313 } 1314 1315 for (int i = 0; i < widths->n; i++) { 1316 widths->data.F32[i] *= scale; 1317 } 1318 *kernelSize = *kernelSize * scale + 0.5; 1319 *stampSize = *stampSize * scale + 0.5; 1320 1321 psLogMsg("psModules.imcombine", PS_LOG_INFO, 1322 "Scaling kernel parameters by %f: %d %d", scale, *kernelSize, *stampSize); 1323 1324 return true; 1325 }
Note:
See TracChangeset
for help on using the changeset viewer.
