Changeset 18962 for trunk/psModules/src/imcombine/pmSubtractionMatch.c
- Timestamp:
- Aug 8, 2008, 8:10:29 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/imcombine/pmSubtractionMatch.c
r18348 r18962 16 16 #include "pmSubtraction.h" 17 17 #include "pmSubtractionMask.h" 18 #include "pmSubtractionThreads.h" 18 19 #include "pmSubtractionMatch.h" 20 19 21 20 22 #define KERNEL_MOSAIC 2 // Half-number of kernel instances in the mosaic image … … 631 633 float bg, // Background in image 632 634 int size, // Maximum size 633 psArray **models, // Buffer of models634 psVector **modelSums // Buffer of model sums635 const psArray *models, // Buffer of models 636 const psVector *modelSums // Buffer of model sums 635 637 ) 636 638 { … … 639 641 assert(modelSums); 640 642 641 int xMin = kernel->xMin, xMax = kernel->xMax; // Bounds in x 642 int yMin = kernel->yMin, yMax = kernel->yMax; // Bounds in y 643 644 // Generate models 645 if (!*models) { 646 assert(!*modelSums); 647 *models = psArrayAlloc(size); 648 *modelSums = psVectorAlloc(size, PS_TYPE_F64); 649 for (int sigma = 0; sigma < size; sigma++) { 650 psKernel *model = psKernelAlloc(xMin, xMax, yMin, yMax); // Gaussian model 651 float invSigma2 = 1.0 / (float)PS_SQR(1 + sigma); // Inverse sigma squared 652 double sumGG = 0.0; // Sum of square of Gaussian 653 for (int y = yMin; y <= yMax; y++) { 654 int y2 = PS_SQR(y); // y squared 655 for (int x = xMin; x <= xMax; x++) { 656 float rad2 = PS_SQR(x) + y2; // Radius squared 657 float value = expf(-rad2 * invSigma2); // Model value 658 model->kernel[y][x] = value; 659 sumGG += PS_SQR(value); 660 } 661 } 662 (*models)->data[sigma] = model; 663 (*modelSums)->data.F64[sigma] = sumGG; 664 } 665 } 643 int xMin = -size, xMax = size; // Bounds in x 644 int yMin = -size, yMax = size; // Bounds in y 666 645 667 646 // Fit gaussians of varying widths to the image, record the chi^2 … … 669 648 for (int sigma = 0; sigma < size; sigma++) { 670 649 double sumFG = 0.0; // Sum for calculating the normalisation of the Gaussian 671 psKernel *model = (*models)->data[sigma]; // Model of interest650 psKernel *model = models->data[sigma]; // Model of interest 672 651 for (int y = yMin; y <= yMax; y++) { 673 652 for (int x = xMin; x <= xMax; x++) { … … 675 654 } 676 655 } 677 float norm = sumFG / (*modelSums)->data.F64[sigma]; // Normalisation for Gaussian656 float norm = sumFG * modelSums->data.F64[sigma]; // Normalisation for Gaussian 678 657 double sumDev2 = 0.0; // Sum of square deviations 679 658 for (int y = yMin; y <= yMax; y++) { … … 700 679 } 701 680 681 682 bool pmSubtractionOrderStamp(psVector *ratios, psVector *mask, const pmSubtractionStampList *stamps, 683 const psArray *models, const psVector *modelSums, 684 int index, float bg1, float bg2) 685 { 686 PS_ASSERT_VECTOR_NON_NULL(ratios, false); 687 PS_ASSERT_VECTOR_NON_NULL(mask, false); 688 PS_ASSERT_VECTORS_SIZE_EQUAL(ratios, mask, false); 689 PM_ASSERT_SUBTRACTION_STAMP_LIST_NON_NULL(stamps, false); 690 PS_ASSERT_INT_NONNEGATIVE(index, false); 691 PS_ASSERT_INT_LESS_THAN(index, stamps->num, false); 692 PS_ASSERT_ARRAY_NON_NULL(models, false); 693 PS_ASSERT_VECTOR_NON_NULL(modelSums, false); 694 PS_ASSERT_VECTOR_SIZE(modelSums, models->n, false); 695 696 pmSubtractionStamp *stamp = stamps->stamps->data[index]; // Stamp of interest 697 psAssert(stamp->status == PM_SUBTRACTION_STAMP_CALCULATE || stamp->status == PM_SUBTRACTION_STAMP_USED, 698 "We checked this earlier."); 699 700 // Widths of stars 701 int width1 = subtractionOrderWidth(stamp->image1, bg1, stamps->footprint, models, modelSums); 702 int width2 = subtractionOrderWidth(stamp->image2, bg2, stamps->footprint, models, modelSums); 703 704 if (width1 == 0 || width2 == 0) { 705 ratios->data.F32[index] = NAN; 706 mask->data.PS_TYPE_MASK_DATA[index] = 0xff; 707 } else { 708 ratios->data.F32[index] = (float)width1 / (float)width2; 709 mask->data.PS_TYPE_MASK_DATA[index] = 0; 710 } 711 712 return true; 713 } 714 715 bool pmSubtractionOrderThread(const psThreadJob *job) 716 { 717 PS_ASSERT_THREAD_JOB_NON_NULL(job, false); 718 719 psVector *ratios = job->args->data[0]; // Ratios of widths 720 psVector *mask = job->args->data[1]; // Mask for ratios 721 const pmSubtractionStampList *stamps = job->args->data[2]; // List of stamps 722 const psArray *models = job->args->data[3]; // Gaussian models 723 const psVector *modelSums = job->args->data[4]; // Gaussian model sums 724 int index = PS_SCALAR_VALUE(job->args->data[5], S32); // Stamp index 725 float bg1 = PS_SCALAR_VALUE(job->args->data[6], F32); // Background of image 1 726 float bg2 = PS_SCALAR_VALUE(job->args->data[7], F32); // Background of image 2 727 728 return pmSubtractionOrderStamp(ratios, mask, stamps, models, modelSums, index, bg1, bg2); 729 } 730 702 731 pmSubtractionMode pmSubtractionOrder(pmSubtractionStampList *stamps, float bg1, float bg2) 703 732 { … … 706 735 psVector *mask = psVectorAlloc(stamps->num, PS_TYPE_MASK); // Mask for stamps 707 736 psVector *ratios = psVectorAlloc(stamps->num, PS_TYPE_F32); // Ratios of widths 708 psArray *models = NULL; // Gaussian models 709 psVector *modelSums = NULL; // Gaussian model sums 737 738 // Generate models 739 int size = stamps->footprint; // Maximum size 740 psArray *models = psArrayAlloc(size); // Gaussian models 741 psVector *modelSums = psVectorAlloc(size, PS_TYPE_F64); // Gaussian model sums 742 for (int sigma = 0; sigma < size; sigma++) { 743 psKernel *model = psKernelAlloc(-size, size, -size, size); // Gaussian model 744 float invSigma2 = 1.0 / (float)PS_SQR(1 + sigma); // Inverse sigma squared 745 double sumGG = 0.0; // Sum of square of Gaussian 746 for (int y = -size; y <= size; y++) { 747 int y2 = PS_SQR(y); // y squared 748 for (int x = -size; x <= size; x++) { 749 float rad2 = PS_SQR(x) + y2; // Radius squared 750 float value = expf(-rad2 * invSigma2); // Model value 751 model->kernel[y][x] = value; 752 sumGG += PS_SQR(value); 753 } 754 } 755 models->data[sigma] = model; 756 modelSums->data.F64[sigma] = 1.0 / sumGG; 757 } 758 759 // Fit models to stamps 710 760 for (int i = 0; i < stamps->num; i++) { 711 761 pmSubtractionStamp *stamp = stamps->stamps->data[i]; // Stamp of interest … … 715 765 } 716 766 717 // Widths of stars 718 int width1 = subtractionOrderWidth(stamp->image1, bg1, stamps->footprint, &models, &modelSums); 719 int width2 = subtractionOrderWidth(stamp->image2, bg2, stamps->footprint, &models, &modelSums); 720 721 if (width1 == 0 || width2 == 0) { 722 ratios->data.F32[i] = NAN; 723 mask->data.PS_TYPE_MASK_DATA[i] = 0xff; 767 if (pmSubtractionThreaded()) { 768 psThreadJob *job = psThreadJobAlloc("PSMODULES_SUBTRACTION_ORDER"); 769 psArrayAdd(job->args, 1, ratios); 770 psArrayAdd(job->args, 1, mask); 771 psArrayAdd(job->args, 1, stamps); 772 psArrayAdd(job->args, 1, models); 773 psArrayAdd(job->args, 1, modelSums); 774 PS_ARRAY_ADD_SCALAR(job->args, i, PS_TYPE_S32); 775 PS_ARRAY_ADD_SCALAR(job->args, bg1, PS_TYPE_F32); 776 PS_ARRAY_ADD_SCALAR(job->args, bg2, PS_TYPE_F32); 777 if (!psThreadJobAddPending(job)) { 778 psFree(job); 779 return false; 780 } 781 psFree(job); 724 782 } else { 725 ratios->data.F32[i] = (float)width1 / (float)width2; 726 mask->data.PS_TYPE_MASK_DATA[i] = 0; 727 } 728 } 783 if (!pmSubtractionOrderStamp(ratios, mask, stamps, models, modelSums, i, bg1, bg2)) { 784 psError(PS_ERR_UNKNOWN, false, "Unable to measure PSF width for stamp %d", i); 785 psFree(models); 786 psFree(modelSums); 787 psFree(ratios); 788 psFree(mask); 789 return false; 790 } 791 } 792 } 793 794 if (!psThreadPoolWait(true)) { 795 psError(PS_ERR_UNKNOWN, false, "Error waiting for threads."); 796 psFree(models); 797 psFree(modelSums); 798 psFree(ratios); 799 psFree(mask); 800 return false; 801 } 802 729 803 psFree(models); 730 804 psFree(modelSums);
Note:
See TracChangeset
for help on using the changeset viewer.
