- Timestamp:
- May 3, 2010, 8:50:52 AM (16 years ago)
- Location:
- branches/simtest_nebulous_branches
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/simtest_nebulous_branches
- Property svn:mergeinfo changed
-
branches/simtest_nebulous_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/simtest_nebulous_branches/psModules/src/objects/pmSourceMatch.c
r24262 r27840 8 8 9 9 #include "pmSource.h" 10 #include "pmErrorCodes.h" 10 11 11 12 #include "pmSourceMatch.h" … … 112 113 psFree(match->mag); 113 114 psFree(match->magErr); 115 psFree(match->x); 116 psFree(match->y); 114 117 psFree(match->image); 115 118 psFree(match->index); 119 psFree(match->mask); 116 120 } 117 121 … … 124 128 match->mag = psVectorAllocEmpty(ARRAY_BUFFER, PS_TYPE_F32); 125 129 match->magErr = psVectorAllocEmpty(ARRAY_BUFFER, PS_TYPE_F32); 130 match->x = psVectorAllocEmpty(ARRAY_BUFFER, PS_TYPE_F32); 131 match->y = psVectorAllocEmpty(ARRAY_BUFFER, PS_TYPE_F32); 126 132 match->image = psVectorAllocEmpty(ARRAY_BUFFER, PS_TYPE_U32); 127 133 match->index = psVectorAllocEmpty(ARRAY_BUFFER, PS_TYPE_U32); … … 133 139 void pmSourceMatchAdd(pmSourceMatch *match, // Match data 134 140 float mag, float magErr, // Magnitude and error 141 float x, float y, // Position 135 142 int image, // Image index 136 143 int index // Source index … … 141 148 match->mag = psVectorExtend(match->mag, match->mag->nalloc, 1); 142 149 match->magErr = psVectorExtend(match->magErr, match->magErr->nalloc, 1); 150 match->x = psVectorExtend(match->x, match->x->nalloc, 1); 151 match->y = psVectorExtend(match->y, match->y->nalloc, 1); 143 152 match->image = psVectorExtend(match->image, match->image->nalloc, 1); 144 153 match->index = psVectorExtend(match->index, match->index->nalloc, 1); … … 147 156 match->mag->data.F32[num] = mag; 148 157 match->magErr->data.F32[num] = magErr; 158 match->x->data.F32[num] = x; 159 match->y->data.F32[num] = y; 149 160 match->image->data.S32[num] = image; 150 161 match->index->data.S32[num] = index; … … 172 183 for (int i = 0; i < numImages; i++) { 173 184 psArray *sources = sourceArrays->data[i]; // Sources in image 174 if (!sources ) {185 if (!sources || sources->n == 0) { 175 186 continue; 176 187 } … … 192 203 pmSourceMatch *match = pmSourceMatchAlloc(); // Match data 193 204 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 194 i, indices->data.S32[j]);205 xImage->data.F32[j], yImage->data.F32[j], i, indices->data.S32[j]); 195 206 matches->data[j] = match; 196 207 } … … 212 223 pmSourceMatch *match = pmSourceMatchAlloc(); // Match data 213 224 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 214 i, indices->data.S32[j]);225 xImage->data.F32[j], yImage->data.F32[j], i, indices->data.S32[j]); 215 226 matches->data[k] = match; 216 227 } … … 221 232 } else { 222 233 // Match with the master list 223 psTree *tree = psTreePlant(2, SOURCES_MAX_LEAF, xMaster, yMaster); // kd Tree with sources234 psTree *tree = psTreePlant(2, SOURCES_MAX_LEAF, PS_TREE_EUCLIDEAN, xMaster, yMaster); // kd Tree 224 235 long numMatch = 0; // Number of matches 225 236 … … 238 249 pmSourceMatch *match = matches->data[index]; // Match data 239 250 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 240 i, indices->data.S32[j]);251 xImage->data.F32[j], yImage->data.F32[j], i, indices->data.S32[j]); 241 252 numMatch++; 242 253 } else { … … 244 255 pmSourceMatch *match = pmSourceMatchAlloc(); // Match data 245 256 pmSourceMatchAdd(match, magImage->data.F32[j], magErrImage->data.F32[j], 246 i, indices->data.S32[j]);257 xImage->data.F32[j], yImage->data.F32[j], i, indices->data.S32[j]); 247 258 xMaster->data.F32[numMaster] = xImage->data.F32[j]; 248 259 yMaster->data.F32[numMaster] = yImage->data.F32[j]; … … 262 273 psFree(magImage); 263 274 psFree(magErrImage); 264 } 275 psFree(indices); 276 } 277 278 psFree(xMaster); 279 psFree(yMaster); 280 psFree(boundsMaster); 265 281 266 282 if (cullSingles) { … … 304 320 pmSourceMatch *match = matches->data[i]; // Match of interest 305 321 for (int j = 0; j < match->num && !source; j++) { 306 if (!isfinite(match->mag->data.F32[j]) || !isfinite(match->magErr->data.F32[j])) { 322 if (!isfinite(match->mag->data.F32[j]) || !isfinite(match->magErr->data.F32[j]) || 323 !isfinite(match->x->data.F32[j]) || !isfinite(match->y->data.F32[j])) { 307 324 continue; 308 325 } … … 365 382 double star = 0.0, starErr = 0.0; // Accumulators for star 366 383 for (int j = 0; j < match->num; j++) { 367 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] ) {384 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_SOURCE_MATCH_MASK_PHOT) { 368 385 continue; 369 386 } … … 396 413 pmSourceMatch *match = matches->data[i]; // Matched stars 397 414 for (int j = 0; j < match->num; j++) { 398 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] ) {415 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_SOURCE_MATCH_MASK_PHOT) { 399 416 continue; 400 417 } … … 424 441 pmSourceMatch *match = matches->data[i]; // Matched stars 425 442 for (int j = 0; j < match->num; j++) { 426 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] ) {443 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_SOURCE_MATCH_MASK_PHOT) { 427 444 continue; 428 445 } … … 543 560 pmSourceMatch *match = matches->data[i]; // Matched stars 544 561 for (int j = 0; j < match->num; j++) { 545 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] ) {562 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_SOURCE_MATCH_MASK_PHOT) { 546 563 continue; 547 564 } … … 564 581 if (PS_SQR(dev) > starClip * (PS_SQR(magErr) + sysErr2)) { 565 582 numRejected++; 566 match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] = 0xFF;583 match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] |= PM_SOURCE_MATCH_MASK_PHOT; 567 584 } 568 585 } … … 599 616 int numImages = zp->n; // Number of images 600 617 int numStars = matches->n; // Number of stars 618 psVector *badImage = psVectorAlloc(numImages, PS_TYPE_U8); // Bad image? 619 psVectorInit(badImage, 0); 620 621 // Check for data integrity 622 { 623 psVector *num = psVectorAlloc(numImages, PS_TYPE_S32); // Number of stars per image 624 psVectorInit(num, 0); 625 for (int i = 0; i < numStars; i++) { 626 pmSourceMatch *match = matches->data[i]; // Matched stars 627 for (int j = 0; j < match->num; j++) { 628 int index = match->image->data.U32[j]; // Image index 629 psAssert(index >= 0 && index < numImages, "Bad index: %d", index); 630 num->data.S32[index]++; 631 } 632 } 633 int numGood = 0; // Number of good images 634 for (int i = 0; i < numImages; i++) { 635 if (num->data.S32[i] == 0 || !isfinite(zp->data.F32[i])) { 636 badImage->data.U8[i] = 0xFF; 637 continue; 638 } 639 numGood++; 640 } 641 psFree(num); 642 if (numGood == 0) { 643 psError(PM_ERR_DATA, true, "No images with good stars."); 644 psFree(badImage); 645 return false; 646 } 647 } 648 601 649 psVector *trans = psVectorAlloc(numImages, PS_TYPE_F32); // Transparencies for each image, magnitudes 602 650 psVectorInit(trans, 0.0); 603 651 psVector *photo = psVectorAlloc(numImages, PS_TYPE_U8); // Photometric determination for each image 604 652 psVectorInit(photo, 0); 605 psVector *badImage = psVectorAlloc(numImages, PS_TYPE_U8); // Bad image?606 psVectorInit(badImage, 0);607 653 psVector *stars = psVectorAlloc(numStars, PS_TYPE_F32); // Magnitudes for each star 608 654 … … 627 673 return NULL; 628 674 } 629 psTrace("psModules.objects", 3, "Pass 1: Determined %d/%d are photometric ", numPhoto, numImages);675 psTrace("psModules.objects", 3, "Pass 1: Determined %d/%d are photometric\n", numPhoto, numImages); 630 676 631 677 fracRej = sourceMatchRelphotReject(trans, stars, matches, zp, photo, badImage, rej1, sys1); 632 psTrace("psModules.objects", 3, "Pass 1: %f%% of measurements rejected ", fracRej * 100);678 psTrace("psModules.objects", 3, "Pass 1: %f%% of measurements rejected\n", fracRej * 100); 633 679 634 680 chi2 = sourceMatchRelphotIterate(trans, stars, badImage, matches, zp, photo, sys1); … … 649 695 return NULL; 650 696 } 651 psTrace("psModules.objects", 3, "Pass 2: Determined %d/%d are photometric ", numPhoto, numImages);697 psTrace("psModules.objects", 3, "Pass 2: Determined %d/%d are photometric\n", numPhoto, numImages); 652 698 653 699 fracRej = sourceMatchRelphotReject(trans, stars, matches, zp, photo, badImage, rej2, sys2); 654 psTrace("psModules.objects", 3, "Pass 2: %f%% of measurements rejected ", fracRej * 100);700 psTrace("psModules.objects", 3, "Pass 2: %f%% of measurements rejected\n", fracRej * 100); 655 701 656 702 chi2 = sourceMatchRelphotIterate(trans, stars, badImage, matches, zp, photo, sys2); … … 668 714 return trans; 669 715 } 716 717 718 // Iterate on the star positions and image shifts 719 // Returns the solution chi^2 720 static float sourceMatchRelastroIterate(psVector *xShift, psVector *yShift, // Shift for image 721 psVector *xStar, psVector *yStar, // Position for star 722 const psArray *matches // Array of matches 723 ) 724 { 725 psAssert(matches, "Need list of matches"); 726 727 int numImages = xShift->n; // Number of images 728 int numStars = matches->n; // Number of stars 729 730 psAssert(xShift && xShift->type.type == PS_TYPE_F32 && yShift && yShift->type.type == PS_TYPE_F32, 731 "Need shifts"); 732 psAssert(yShift->n == numImages, "Not enough shifts: %ld\n", yShift->n); 733 psAssert(xStar && xStar->type.type == PS_TYPE_F32 && yStar && yStar->type.type == PS_TYPE_F32, 734 "Need star positions"); 735 psAssert(xStar->n == numStars && yStar->n == numStars, "Not enough stars\n"); 736 737 // Solve the star positions 738 psVectorInit(xStar, NAN); 739 psVectorInit(yStar, NAN); 740 psVector *starMask = psVectorAlloc(numStars, PS_TYPE_U8); // Mask for stars 741 psVectorInit(starMask, 0xFF); 742 int numGoodStars = 0; // Number of stars with good measurements 743 for (int i = 0; i < numStars; i++) { 744 pmSourceMatch *match = matches->data[i]; // Matched stars 745 int numMeasurements = 0; // Number of unmasked measurements for star 746 double xSum = 0.0, ySum = 0.0; // Accumulators for star 747 for (int j = 0; j < match->num; j++) { 748 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_SOURCE_MATCH_MASK_ASTRO) { 749 continue; 750 } 751 numMeasurements++; 752 int index = match->image->data.U32[j]; // Image index 753 754 xSum += match->x->data.F32[j] - xShift->data.F32[index]; 755 ySum += match->y->data.F32[j] - yShift->data.F32[index]; 756 } 757 if (numMeasurements > 1) { 758 // It's only a good star (contributing to the chi^2) if there's more than 1 measurement 759 numGoodStars++; 760 xStar->data.F32[i] = xSum / numMeasurements; 761 yStar->data.F32[i] = ySum / numMeasurements; 762 starMask->data.U8[i] = 0; 763 } 764 } 765 766 // Solve for the shifts 767 psVectorInit(xShift, 0.0); 768 psVectorInit(yShift, 0.0); 769 psVector *num = psVectorAlloc(numImages, PS_TYPE_S32); // Number of stars 770 psVectorInit(num, 0); 771 for (int i = 0; i < numStars; i++) { 772 if (starMask->data.U8[i]) { 773 continue; 774 } 775 pmSourceMatch *match = matches->data[i]; // Matched stars 776 for (int j = 0; j < match->num; j++) { 777 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_SOURCE_MATCH_MASK_ASTRO) { 778 continue; 779 } 780 int index = match->image->data.U32[j]; // Image index 781 782 xShift->data.F32[index] += match->x->data.F32[j] - xStar->data.F32[i]; 783 yShift->data.F32[index] += match->y->data.F32[j] - yStar->data.F32[i]; 784 num->data.S32[index]++; 785 } 786 } 787 for (int i = 0; i < numImages; i++) { 788 xShift->data.F32[i] /= num->data.S32[i]; 789 yShift->data.F32[i] /= num->data.S32[i]; 790 psTrace("psModules.objects", 3, "Shift for image %d: %f,%f\n", 791 i, xShift->data.F32[i], yShift->data.F32[i]); 792 } 793 psFree(num); 794 795 // Once more through to evaluate chi^2 796 float chi2 = 0.0; // chi^2 for iteration 797 int dof = 0; // Degrees of freedom 798 for (int i = 0; i < numStars; i++) { 799 pmSourceMatch *match = matches->data[i]; // Matched stars 800 if (starMask->data.U8[i]) { 801 continue; 802 } 803 for (int j = 0; j < match->num; j++) { 804 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j]) { 805 continue; 806 } 807 808 int index = match->image->data.U32[j]; // Image index 809 float dx = match->x->data.F32[j] - xShift->data.F32[index] - xStar->data.F32[i]; 810 float dy = match->y->data.F32[j] - yShift->data.F32[index] - yStar->data.F32[i]; 811 812 chi2 += PS_SQR(dx) + PS_SQR(dy); 813 dof++; 814 } 815 } 816 dof -= numGoodStars + numImages; 817 chi2 /= dof; 818 819 return chi2; 820 } 821 822 // Reject star measurements 823 // Returns the fraction of measurements that were rejected 824 static float sourceMatchRelastroReject(const psVector *xShift, const psVector *yShift, // Shifts for each image 825 const psVector *xStar, const psVector *yStar, // Positions for each star 826 const psArray *matches, // Array of matches 827 float chi2, // chi^2 from fit 828 float rej // Rejection threshold 829 ) 830 { 831 psAssert(matches, "Need list of matches"); 832 833 int numImages = xShift->n; // Number of images 834 int numStars = matches->n; // Number of stars 835 836 psAssert(xShift && xShift->type.type == PS_TYPE_F32 && yShift && yShift->type.type == PS_TYPE_F32, 837 "Need shifts"); 838 psAssert(yShift->n == numImages, "Not enough shifts: %ld\n", yShift->n); 839 psAssert(xStar && xStar->type.type == PS_TYPE_F32 && yStar && yStar->type.type == PS_TYPE_F32, 840 "Need star positions"); 841 psAssert(xStar->n == numStars && yStar->n == numStars, "Not enough stars\n"); 842 843 int numRejected = 0; // Number rejected 844 int numMeasurements = 0; // Number of measurements 845 846 float thresh = PS_SQR(rej) * chi2; // Threshold for rejection 847 848 for (int i = 0; i < numStars; i++) { 849 pmSourceMatch *match = matches->data[i]; // Matched stars 850 for (int j = 0; j < match->num; j++) { 851 if (match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] & PM_SOURCE_MATCH_MASK_ASTRO) { 852 continue; 853 } 854 numMeasurements++; 855 int index = match->image->data.U32[j]; // Image index 856 857 float dx = match->x->data.F32[j] - xShift->data.F32[index] - xStar->data.F32[i]; 858 float dy = match->y->data.F32[j] - yShift->data.F32[index] - yStar->data.F32[i]; 859 860 if (PS_SQR(dx) + PS_SQR(dy) > thresh) { 861 numRejected++; 862 match->mask->data.PS_TYPE_VECTOR_MASK_DATA[j] |= PM_SOURCE_MATCH_MASK_ASTRO; 863 } 864 } 865 } 866 867 return (float)numRejected / (float)numMeasurements; 868 } 869 870 psArray *pmSourceMatchRelastro(const psArray *matches, // Array of matches 871 int numImages, // Number of images 872 float tol, // Relative tolerance for convergence 873 int iter1, // Number of iterations for pass 1 874 float rej1, // Limit on rejection between iterations for pass 1 875 int iter2, // Number of iterations for pass 2 876 float rej2, // Limit on rejection between iterations for pass 2 877 float rejLimit // Limit on rejection between iterations 878 ) 879 { 880 PS_ASSERT_ARRAY_NON_NULL(matches, NULL); 881 882 int numStars = matches->n; // Number of stars 883 psVector *xShift = psVectorAlloc(numImages, PS_TYPE_F32); // x shift for each image 884 psVector *yShift = psVectorAlloc(numImages, PS_TYPE_F32); // y shift for each image 885 psVectorInit(xShift, 0.0); 886 psVectorInit(yShift, 0.0); 887 psVector *xStar = psVectorAlloc(numStars, PS_TYPE_F32); // x position for each star 888 psVector *yStar = psVectorAlloc(numStars, PS_TYPE_F32); // y position for each star 889 890 float chi2 = sourceMatchRelastroIterate(xShift, yShift, xStar, yStar, matches); // chi^2 for solution 891 psTrace("psModules.objects", 1, "Initial: chi^2 = %f\n", chi2); 892 float lastChi2 = INFINITY; // chi^2 on last iteration 893 float fracRej = INFINITY; // Fraction of measurements rejected 894 895 // In the first passes, the shifts are not well deteremined: use high systematic error and 896 // rejection thresholds 897 for (int i = 0; i < iter1; i++) { 898 fracRej = sourceMatchRelastroReject(xShift, yShift, xStar, yStar, matches, chi2, rej1); 899 psTrace("psModules.objects", 3, "Pass 1: %f%% of measurements rejected\n", fracRej * 100); 900 901 chi2 = sourceMatchRelastroIterate(xShift, yShift, xStar, yStar, matches); 902 psTrace("psModules.objects", 1, "Pass 1: iter = %d: chi^2 = %f rejected = %f\n", i, chi2, fracRej); 903 } 904 905 for (int i = 0; i < iter2 && (fabsf(lastChi2 - chi2) > tol * chi2 || fracRej > rejLimit); i++) { 906 lastChi2 = chi2; 907 908 fracRej = sourceMatchRelastroReject(xShift, yShift, xStar, yStar, matches, chi2, rej2); 909 psTrace("psModules.objects", 3, "Pass 2: %f%% of measurements rejected\n", fracRej * 100); 910 911 chi2 = sourceMatchRelastroIterate(xShift, yShift, xStar, yStar, matches); 912 psTrace("psModules.objects", 1, "Pass 2: iter = %d: chi^2 = %f rejected = %f\n", i, chi2, fracRej); 913 } 914 915 psFree(xStar); 916 psFree(yStar); 917 918 if (fabsf(lastChi2 - chi2) > tol * chi2 || fracRej > rejLimit) { 919 psWarning("Unable to converge to relphot solution (%f,%f)", (lastChi2 - chi2) / chi2, fracRej); 920 } 921 922 psArray *results = psArrayAlloc(numImages); // Array of results 923 for (int i = 0; i < numImages; i++) { 924 psVector *offset = results->data[i] = psVectorAlloc(2, PS_TYPE_F32); // Offset for image 925 offset->data.F32[0] = xShift->data.F32[i]; 926 offset->data.F32[1] = yShift->data.F32[i]; 927 } 928 psFree(xShift); 929 psFree(yShift); 930 931 return results; 932 } 933
Note:
See TracChangeset
for help on using the changeset viewer.
