- Timestamp:
- Sep 15, 2009, 4:03:13 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/20090715/psModules/src/imcombine/pmSubtractionMatch.c
r24292 r25407 10 10 #include "pmHDU.h" 11 11 #include "pmFPA.h" 12 #include "pmHDUUtils.h" 12 13 #include "pmSubtractionParams.h" 13 14 #include "pmSubtractionKernels.h" … … 58 59 59 60 60 static bool getStamps(pmSubtractionStampList **stamps, // Stamps to read61 const pmReadout *ro1, // Readout 162 const pmReadout *ro2, // Readout 263 const psImage *subMask, // Mask for subtraction, or NULL64 psImage *variance, // Variance map65 const psRegion *region, // Region of interest, or NULL66 float thresh1, // Threshold for stamp finding on readout 167 float thresh2, // Threshold for stamp finding on readout 268 float stampSpacing, // Spacing between stamps69 int size, // Kernel half-size70 int footprint, // Convolution footprint for stamps71 pmSubtractionMode mode // Mode for subtraction61 static bool subtractionGetStamps(pmSubtractionStampList **stamps, // Stamps to read 62 const pmReadout *ro1, // Readout 1 63 const pmReadout *ro2, // Readout 2 64 const psImage *subMask, // Mask for subtraction, or NULL 65 psImage *variance, // Variance map 66 const psRegion *region, // Region of interest, or NULL 67 float thresh1, // Threshold for stamp finding on readout 1 68 float thresh2, // Threshold for stamp finding on readout 2 69 float stampSpacing, // Spacing between stamps 70 int size, // Kernel half-size 71 int footprint, // Convolution footprint for stamps 72 pmSubtractionMode mode // Mode for subtraction 72 73 ) 73 74 { … … 163 164 } 164 165 166 static void subtractionAnalysisUpdate(pmReadout *conv1, pmReadout *conv2, // Convolved images 167 const psMetadata *analysis, // Analysis metadata 168 const psMetadata *header // Header metadata 169 ) 170 { 171 if (conv1) { 172 conv1->analysis = psMetadataCopy(conv1->analysis, analysis); 173 } 174 if (conv2) { 175 conv2->analysis = psMetadataCopy(conv2->analysis, analysis); 176 } 177 178 if (conv1 && conv1->parent) { 179 pmHDU *hdu = pmHDUFromCell(conv1->parent); 180 if (hdu) { 181 hdu->header = psMetadataCopy(hdu->header, header); 182 } 183 } 184 if (conv2 && conv2->parent) { 185 pmHDU *hdu = pmHDUFromCell(conv2->parent); 186 if (hdu) { 187 hdu->header = psMetadataCopy(hdu->header, header); 188 } 189 } 190 191 return; 192 } 165 193 166 194 … … 253 281 254 282 psMetadata *outAnalysis = psMetadataAlloc(); // Output analysis values 283 psMetadata *outHeader = psMetadataAlloc(); // Output header values 255 284 256 285 psTrace("psModules.imcombine", 2, "Convolving...\n"); … … 259 288 psRegion *region = regions->data[i]; // Region of interest 260 289 261 if (!pmSubtractionAnalysis(outAnalysis, kernel, region, ro1->image->numCols, ro1->image->numRows)) { 290 if (!pmSubtractionAnalysis(outAnalysis, outHeader, kernel, region, 291 ro1->image->numCols, ro1->image->numRows)) { 262 292 psError(PS_ERR_UNKNOWN, false, "Unable to generate QA data"); 263 293 psFree(outAnalysis); 294 psFree(outHeader); 264 295 psFree(subMask); 265 296 psFree(kernels); … … 272 303 psError(PS_ERR_UNKNOWN, false, "Unable to convolve image."); 273 304 psFree(outAnalysis); 305 psFree(outHeader); 274 306 psFree(subMask); 275 307 psFree(kernels); … … 283 315 psFree(regions); 284 316 285 if (conv1) { 286 psMetadataCopy(conv1->analysis, outAnalysis); 287 } 288 if (conv2) { 289 psMetadataCopy(conv2->analysis, outAnalysis); 290 } 317 subtractionAnalysisUpdate(conv1, conv2, outAnalysis, outHeader); 291 318 psFree(outAnalysis); 319 psFree(outHeader); 292 320 293 321 return true; … … 369 397 pmSubtractionKernels *kernels = NULL; // Kernel basis functions 370 398 psMetadata *analysis = psMetadataAlloc(); // QA data 399 psMetadata *header = psMetadataAlloc(); // QA data for header 371 400 372 401 int numCols = ro1->image->numCols, numRows = ro1->image->numRows; // Image dimensions … … 442 471 // We get the stamps here; we will also attempt to get stamps at the first iteration, but it 443 472 // doesn't matter. 444 if (! getStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2,473 if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, NULL, stampThresh1, stampThresh2, 445 474 stampSpacing, size, footprint, subMode)) { 446 475 goto MATCH_ERROR; 447 476 } 448 477 478 479 // Define kernel basis functions 480 if (optimum && (type == PM_SUBTRACTION_KERNEL_ISIS || type == PM_SUBTRACTION_KERNEL_GUNK)) { 481 kernels = pmSubtractionKernelsOptimumISIS(type, size, inner, spatialOrder, optFWHMs, optOrder, 482 stamps, footprint, optThreshold, penalty, subMode); 483 if (!kernels) { 484 psErrorClear(); 485 psWarning("Unable to derive optimum ISIS kernel --- switching to default."); 486 } 487 } 488 if (kernels == NULL) { 489 // Not an ISIS/GUNK kernel, or the optimum kernel search failed 490 kernels = pmSubtractionKernelsGenerate(type, size, spatialOrder, isisWidths, isisOrders, 491 inner, binning, ringsOrder, penalty, subMode); 492 } 493 494 memCheck("kernels"); 495 449 496 if (subMode == PM_SUBTRACTION_MODE_UNSURE) { 497 #if 0 450 498 // Get backgrounds 451 499 psStats *bgStats = psStatsAlloc(BG_STAT); // Statistics for background … … 469 517 470 518 pmSubtractionMode newMode = pmSubtractionOrder(stamps, bg1, bg2); // Subtraction mode to use 519 #endif 520 pmSubtractionMode newMode = pmSubtractionBestMode(&stamps, &kernels, subMask, rej); 471 521 switch (newMode) { 472 522 case PM_SUBTRACTION_MODE_1: … … 483 533 } 484 534 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 502 535 int numRejected = -1; // Number of rejected stamps in each iteration 503 536 for (int k = 0; k < iter && numRejected != 0; k++) { 504 537 psLogMsg("psModules.imcombine", PS_LOG_INFO, "Iteration %d.", k); 505 538 506 if (!getStamps(&stamps, ro1, ro2, subMask, variance, region, stampThresh1, stampThresh2, 507 stampSpacing, size, footprint, subMode)) { 539 if (!subtractionGetStamps(&stamps, ro1, ro2, subMask, variance, region, 540 stampThresh1, stampThresh2, stampSpacing, 541 size, footprint, subMode)) { 508 542 goto MATCH_ERROR; 509 543 } … … 535 569 536 570 psTrace("psModules.imcombine", 3, "Rejecting stamps...\n"); 537 numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej , footprint);571 numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej); 538 572 if (numRejected < 0) { 539 573 psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps."); … … 557 591 goto MATCH_ERROR; 558 592 } 559 pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN , footprint);593 pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN); 560 594 psFree(deviations); 561 595 } … … 565 599 memCheck("solution"); 566 600 567 if (!pmSubtractionAnalysis(analysis, kernels, region, numCols, numRows)) {601 if (!pmSubtractionAnalysis(analysis, header, kernels, region, numCols, numRows)) { 568 602 psError(PS_ERR_UNKNOWN, false, "Unable to generate QA data"); 569 603 goto MATCH_ERROR; … … 601 635 memCheck("convolution"); 602 636 603 if (conv1) { 604 psMetadataCopy(conv1->analysis, analysis); 605 } 606 if (conv2) { 607 psMetadataCopy(conv2->analysis, analysis); 608 } 637 subtractionAnalysisUpdate(conv1, conv2, analysis, header); 609 638 psFree(analysis); 639 psFree(header); 610 640 611 641 #ifdef TESTING … … 629 659 MATCH_ERROR: 630 660 psFree(analysis); 661 psFree(header); 631 662 psFree(region); 632 663 psFree(regionString); … … 842 873 return mode; 843 874 } 875 876 877 // Test a subtraction mode by performing a single iteration 878 static bool subtractionModeTest(pmSubtractionStampList *stamps, // Stamps to use to find best mode 879 pmSubtractionKernels *kernels, // Kernel description 880 const char *description, // Description for trace 881 psImage *subMask, // Subtraction mask 882 float rej // Rejection threshold 883 ) 884 { 885 assert(stamps); 886 assert(kernels); 887 888 psTrace("psModules.imcombine", 3, "Calculating %s equation...\n", description); 889 if (!pmSubtractionCalculateEquation(stamps, kernels)) { 890 psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation."); 891 return false; 892 } 893 894 psTrace("psModules.imcombine", 3, "Solving %s equation...\n", description); 895 if (!pmSubtractionSolveEquation(kernels, stamps)) { 896 psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation."); 897 return false; 898 } 899 900 psTrace("psModules.imcombine", 3, "Calculate %s deviations...\n", description); 901 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 902 if (!deviations) { 903 psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations."); 904 return false; 905 } 906 907 psTrace("psModules.imcombine", 3, "Rejecting %s stamps...\n", description); 908 long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, rej); 909 if (numRejected < 0) { 910 psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps."); 911 psFree(deviations); 912 return false; 913 } 914 psFree(deviations); 915 916 if (numRejected > 0) { 917 // Allow re-fit with reduced stamps set 918 psTrace("psModules.imcombine", 3, "Resolving %s equation...\n", description); 919 if (!pmSubtractionSolveEquation(kernels, stamps)) { 920 psError(PS_ERR_UNKNOWN, false, "Unable to calculate least-squares equation."); 921 return false; 922 } 923 psTrace("psModules.imcombine", 3, "Recalculate %s deviations...\n", description); 924 psVector *deviations = pmSubtractionCalculateDeviations(stamps, kernels); // Stamp deviations 925 if (!deviations) { 926 psError(PS_ERR_UNKNOWN, false, "Unable to calculate deviations."); 927 return false; 928 } 929 psTrace("psModules.imcombine", 3, "Measuring %s quality...\n", description); 930 long numRejected = pmSubtractionRejectStamps(kernels, stamps, deviations, subMask, NAN); 931 if (numRejected < 0) { 932 psError(PS_ERR_UNKNOWN, false, "Unable to reject stamps."); 933 psFree(deviations); 934 return false; 935 } 936 psFree(deviations); 937 } 938 939 return true; 940 } 941 942 943 pmSubtractionMode pmSubtractionBestMode(pmSubtractionStampList **stamps, pmSubtractionKernels **kernels, 944 const psImage *subMask, float rej) 945 { 946 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(*stamps, PM_SUBTRACTION_MODE_ERR); 947 PM_ASSERT_SUBTRACTION_KERNELS_NON_NULL(*kernels, PM_SUBTRACTION_MODE_ERR); 948 949 // Copies of the inputs 950 pmSubtractionStampList *stamps1 = pmSubtractionStampListCopy(*stamps); 951 pmSubtractionKernels *kernels1 = pmSubtractionKernelsCopy(*kernels); 952 psImage *subMask1 = psImageCopy(NULL, subMask, subMask->type.type); 953 kernels1->mode = PM_SUBTRACTION_MODE_1; 954 955 if (!subtractionModeTest(stamps1, kernels1, "convolve 1", subMask1, rej)) { 956 psError(PS_ERR_UNKNOWN, false, "Unable to test subtraction with convolution of image 1"); 957 psFree(stamps1); 958 psFree(kernels1); 959 psFree(subMask1); 960 return PM_SUBTRACTION_MODE_ERR; 961 } 962 psFree(subMask1); 963 964 // Copies of the inputs 965 pmSubtractionStampList *stamps2 = pmSubtractionStampListCopy(*stamps); 966 pmSubtractionKernels *kernels2 = pmSubtractionKernelsCopy(*kernels); 967 psImage *subMask2 = psImageCopy(NULL, subMask, subMask->type.type); 968 kernels2->mode = PM_SUBTRACTION_MODE_2; 969 970 if (!subtractionModeTest(stamps2, kernels2, "convolve 2", subMask2, rej)) { 971 psError(PS_ERR_UNKNOWN, false, "Unable to test subtraction with convolution of image 2"); 972 psFree(stamps2); 973 psFree(kernels2); 974 psFree(subMask2); 975 psFree(stamps1); 976 psFree(kernels1); 977 return PM_SUBTRACTION_MODE_ERR; 978 } 979 psFree(subMask2); 980 981 982 pmSubtractionStampList *bestStamps = NULL; // Best choice for stamps 983 pmSubtractionKernels *bestKernels = NULL; // Best choice for kernels 984 psLogMsg("psModules.imcombine", PS_LOG_INFO, 985 "Image 1: %f +/- %f from %d stamps\nImage 2: %f +/- %f from %d stamps\n", 986 kernels1->mean, kernels1->rms, kernels1->numStamps, 987 kernels2->mean, kernels2->rms, kernels2->numStamps); 988 989 if (kernels1->mean < kernels2->mean) { 990 bestStamps = stamps1; 991 bestKernels = kernels1; 992 } else { 993 bestStamps = stamps2; 994 bestKernels = kernels2; 995 } 996 997 psFree(*stamps); 998 psFree(*kernels); 999 *stamps = psMemIncrRefCounter(bestStamps); 1000 *kernels = psMemIncrRefCounter(bestKernels); 1001 1002 psFree(stamps1); 1003 psFree(stamps2); 1004 psFree(kernels1); 1005 psFree(kernels2); 1006 1007 return bestKernels->mode; 1008 } 1009
Note:
See TracChangeset
for help on using the changeset viewer.
