Changeset 5048 for trunk/psphot/src/pmObjects_EAM.c
- Timestamp:
- Sep 13, 2005, 3:35:20 PM (21 years ago)
- File:
-
- 1 edited
-
trunk/psphot/src/pmObjects_EAM.c (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psphot/src/pmObjects_EAM.c
r4977 r5048 6 6 * @author EAM, IfA: significant modifications. 7 7 * 8 * @version $Revision: 1. 4$ $Name: not supported by cvs2svn $9 * @date $Date: 2005-09- 08 04:32:40 $8 * @version $Revision: 1.5 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2005-09-14 01:35:20 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 603 603 members. 604 604 *****************************************************************************/ 605 pmSource *pmSourceLocalSky(const psImage *image, 606 const pmPeak *peak, 607 psStatsOptions statsOptions, 608 psF32 innerRadius, 609 psF32 outerRadius) 610 { 611 PS_ASSERT_IMAGE_NON_NULL(image, NULL); 612 PS_ASSERT_IMAGE_TYPE(image, PS_TYPE_F32, NULL); 613 PS_ASSERT_PTR_NON_NULL(peak, NULL); 614 PS_FLOAT_COMPARE(0.0, innerRadius, NULL); 615 PS_FLOAT_COMPARE(innerRadius, outerRadius, NULL); 616 psS32 innerRadiusS32 = (psS32) innerRadius; 617 psS32 outerRadiusS32 = (psS32) outerRadius; 618 619 // 620 // We define variables for code readability. 621 // 622 // XXX: Since the peak->xy coords are in image, not subImage coords, 623 // these variables should be renamed for clarity (imageCenterRow, etc). 624 // 625 // peak->x,y is guaranteed to be on image 626 psS32 SubImageCenterRow = peak->y; 627 psS32 SubImageCenterCol = peak->x; 628 629 // XXX EAM : I added this code to stay on the image. So did George 630 // XXX EAM : EndRow is *exclusive* of pixel region (ie, last pixel + 1) 631 // XXX EAM : dropped the Annulus width (not needed) 632 // XXX EAM : dropped off-boundary tests (not needed) 633 psS32 SubImageStartRow = PS_MAX (0, SubImageCenterRow - outerRadiusS32); 634 psS32 SubImageEndRow = PS_MIN (image->numRows, SubImageCenterRow + outerRadiusS32 + 1); 635 psS32 SubImageStartCol = PS_MAX (0, SubImageCenterCol - outerRadiusS32); 636 psS32 SubImageEndCol = PS_MIN (image->numCols, SubImageCenterCol + outerRadiusS32 + 1); 637 // 638 // Grab a subimage of the original image of size (2 * outerRadius). 639 // 640 // XXX EAM : merged psImageSubset & psRegionSet 641 // XXX EAM : cast for image is needed because of const (above) 642 psImage *subImage = psImageSubset((psImage *) image, psRegionSet(SubImageStartCol, 643 SubImageEndCol, 644 SubImageStartRow, 645 SubImageEndRow)); 646 647 psImage *subImageMask = psImageAlloc(subImage->numCols, 648 subImage->numRows, 649 PS_TYPE_U8); 650 // XXX EAM : for consistency, mask needs col0,row0 set to match image 651 // XXX EAM : CONFLICT between psLib and code requirement. FIX PSLIB!!! 652 // subImageMask->col0 = subImage->col0; 653 // subImageMask->row0 = subImage->row0; 654 psAbort ("pmObjects", "must fix this error before psphot will work!!!\n"); 655 656 // 657 // Loop through the subimage mask & initialize PSPHOT_MASK_INVALID 658 // 659 for (psS32 row = 0 ; row < subImageMask->numRows; row++) { 660 for (psS32 col = 0 ; col < subImageMask->numCols; col++) { 661 subImageMask->data.U8[row][col] = PSPHOT_MASK_INVALID; 662 } 663 } 664 665 // 666 // Loop through the subimage, mask off pixels in the inner square. 667 // XXX this uses a static mask value of 0 668 // XXX EAM : this was wrong: it masked the wrong pixels at the edge of the image 669 // XXX EAM : this masks the pixels in the center region 670 // XXX EAM : should we be using psImageMaskRegion ??? 671 psS32 StartRow = PS_MAX (0, SubImageCenterRow - subImageMask->row0 - innerRadiusS32); 672 psS32 EndRow = PS_MIN (subImageMask->numRows, SubImageCenterRow - subImageMask->row0 + innerRadiusS32 + 1); 673 psS32 StartCol = PS_MAX (0, SubImageCenterCol - subImageMask->col0 - innerRadiusS32); 674 psS32 EndCol = PS_MIN (subImageMask->numCols, SubImageCenterCol - subImageMask->col0 + innerRadiusS32 + 1); 675 for (psS32 row = StartRow; row < EndRow; row++) { 676 for (psS32 col = StartCol; col < EndCol; col++) { 677 subImageMask->data.U8[row][col] = PSPHOT_MASK_CLEAR; 678 } 679 } 680 681 // XXX EAM : make this trace information?? 682 // for (psS32 row = 0 ; row < subImage->numRows; row++) { 683 // for (psS32 col = 0 ; col < subImage->numCols; col++) { 684 // printf("(%d) ", subImageMask->data.U8[row][col]); 685 // } 686 // printf("\n"); 687 // } 688 689 // 690 // Allocate the myStats structure, then call psImageStats(), which will 691 // calculate the specified statistic. 692 // 605 bool pmSourceLocalSky (pmSource *source, 606 psStatsOptions statsOptions, 607 psF32 Radius) 608 { 609 610 psImage *image = source->pixels; 611 psImage *mask = source->mask; 612 pmPeak *peak = source->peak; 613 psRegion srcRegion; 614 615 // XXX EAM : psRegionXXX funcs should take value not ptr 616 srcRegion = psRegionForSquare (peak->x, peak->y, Radius); 617 srcRegion = psRegionForImage (mask, &srcRegion); 618 619 psImageMaskRegion (mask, &srcRegion, "OR", PSPHOT_MASK_MARKED); 693 620 psStats *myStats = psStatsAlloc(statsOptions); 694 myStats = psImageStats(myStats, subImage, subImageMask, 1); 695 696 // 697 // Create the output mySource, and set appropriate members. 698 // 699 pmSource *mySource = pmSourceAlloc(); 700 mySource->peak = (pmPeak *) peak; 701 mySource->moments = pmMomentsAlloc(); 621 myStats = psImageStats(myStats, image, mask, 0xff); 622 psImageMaskRegion (mask, &srcRegion, "AND", ~PSPHOT_MASK_MARKED); 623 702 624 psF64 tmpF64; 703 625 p_psGetStatValue(myStats, &tmpF64); 704 mySource->moments->Sky = (psF32) tmpF64; 705 mySource->pixels = subImage; 706 mySource->mask = subImageMask; 707 708 // 709 // Free things. XXX: This should be static memory. 710 // 711 psFree(myStats); 712 713 return(mySource); 714 } 715 716 /****************************************************************************** 717 bool checkRadius(*peak, radius, x, y): private function which simply 718 determines if the (x, y) point is within the radius of the specified peak. 719 720 XXX: macro this for performance. 721 *****************************************************************************/ 722 static bool checkRadius(pmPeak *peak, 723 psF32 radius, 724 psS32 x, 725 psS32 y) 726 { 727 if (PS_SQR(radius) >= (psF32) (PS_SQR(x - peak->x) + PS_SQR(y - peak->y))) { 728 return(true); 729 } 730 731 return(false); 626 psFree (myStats); 627 628 if (isnan(tmpF64)) return (false); 629 source->moments = pmMomentsAlloc(); 630 source->moments->Sky = (psF32) tmpF64; 631 return (true); 732 632 } 733 633 … … 762 662 pmSource->peak 763 663 pmSource->pixels 664 pmSource->noise 665 pmSource->mask 764 666 765 667 XXX: The peak calculations are done in image coords, not subImage coords. 766 668 767 XXX: mask values? 768 *****************************************************************************/ 669 XXX EAM : this version clips input pixels on S/N 670 XXX EAM : this version returns false for several reasons 671 *****************************************************************************/ 672 # define VALID_RADIUS(X,Y,RAD2) (((RAD2) >= (PS_SQR(X) + PS_SQR(Y))) ? 1 : 0) 673 769 674 bool pmSourceMoments(pmSource *source, 770 675 psF32 radius) 771 676 { 772 PS_ASSERT_PTR_NON_NULL(source, NULL); 773 PS_ASSERT_PTR_NON_NULL(source->peak, NULL); 774 PS_ASSERT_PTR_NON_NULL(source->pixels, NULL); 677 // PS_PTR_CHECK_NULL(source, NULL); 678 // PS_PTR_CHECK_NULL(source->peak, NULL); 679 // PS_PTR_CHECK_NULL(source->pixels, NULL); 680 // PS_PTR_CHECK_NULL(source->noise, NULL); 775 681 PS_FLOAT_COMPARE(0.0, radius, NULL); 776 682 … … 791 697 // XY = SUM (x - xc)*(y - yc)*(z - sky) 792 698 // 793 psF32 Sum = 0.0;794 699 psF32 peakPixel = -PS_MAX_F32; 795 700 psS32 numPixels = 0; 701 psF32 Sum = 0.0; 796 702 psF32 X1 = 0.0; 797 703 psF32 Y1 = 0.0; … … 799 705 psF32 Y2 = 0.0; 800 706 psF32 XY = 0.0; 801 psF32 x = 0; 802 psF32 y = 0; 803 // 707 psF32 x = 0; 708 psF32 y = 0; 709 psF32 R2 = PS_SQR(radius); 710 711 psF32 xPeak = source->peak->x; 712 psF32 yPeak = source->peak->y; 713 804 714 // XXX why do I get different results for these two methods of finding Sx? 805 715 // XXX Sx, Sy would be better measured if we clip pixels close to sky … … 809 719 // proceed with the moments calculation. need to do two loops for a 810 720 // numerically stable result. first loop: get the sums. 811 // 721 // XXX EAM : mask == 0 is valid 722 812 723 for (psS32 row = 0; row < source->pixels->numRows ; row++) { 813 724 for (psS32 col = 0; col < source->pixels->numCols ; col++) { 814 // XXX EAM : mask == 0 is valid815 725 if ((source->mask != NULL) && (source->mask->data.U8[row][col])) continue; 816 psS32 imgColCoord = col + source->pixels->col0; 817 psS32 imgRowCoord = row + source->pixels->row0; 818 if (checkRadius(source->peak, 819 radius, 820 imgColCoord, 821 imgRowCoord)) { 822 psF32 xDiff = (psF32) (imgColCoord - source->peak->x); 823 psF32 yDiff = (psF32) (imgRowCoord - source->peak->y); 824 psF32 pDiff = source->pixels->data.F32[row][col] - sky; 825 826 Sum+= pDiff; 827 X1+= xDiff * pDiff; 828 Y1+= yDiff * pDiff; 829 XY+= xDiff * yDiff * pDiff; 830 831 X2+= PS_SQR(xDiff) * pDiff; 832 Y2+= PS_SQR(yDiff) * pDiff; 833 834 if (source->pixels->data.F32[row][col] > peakPixel) { 835 peakPixel = source->pixels->data.F32[row][col]; 836 } 837 numPixels++; 838 } 726 727 psF32 xDiff = col + source->pixels->col0 - xPeak; 728 psF32 yDiff = row + source->pixels->row0 - yPeak; 729 730 // XXX EAM : calculate xDiff, yDiff up front; 731 // radius is just a function of (xDiff, yDiff) 732 if (!VALID_RADIUS(xDiff, yDiff, R2)) continue; 733 734 psF32 pDiff = source->pixels->data.F32[row][col] - sky; 735 736 // XXX EAM : check for valid S/N in pixel 737 // XXX EAM : should this limit be user-defined? 738 if (pDiff / sqrt(source->noise->data.F32[row][col]) < 1) continue; 739 740 Sum += pDiff; 741 X1 += xDiff * pDiff; 742 Y1 += yDiff * pDiff; 743 XY += xDiff * yDiff * pDiff; 744 745 X2 += PS_SQR(xDiff) * pDiff; 746 Y2 += PS_SQR(yDiff) * pDiff; 747 748 peakPixel = PS_MAX (source->pixels->data.F32[row][col], peakPixel); 749 numPixels++; 839 750 } 840 751 } 841 752 // XXX EAM - the limit is a bit arbitrary. make it user defined? 842 753 if ((numPixels < 3) || (Sum <= 0)) { 843 psTrace (".psModules.pmSourceMoments", 5, "no valid pixels for source\n");844 return (false);754 psTrace (".psModules.pmSourceMoments", 5, "no valid pixels for source\n"); 755 return (false); 845 756 } 846 757 … … 857 768 y = Y1/Sum; 858 769 if ((fabs(x) > radius) || (fabs(y) > radius)) { 859 psTrace (".psModules.pmSourceMoments", 5, 860 "large centroid swing; invalid peak %d, %d\n", 861 source->peak->x, source->peak->y); 862 return (false); 863 } 864 865 source->moments->x = x + ((psF32) source->peak->x); 866 source->moments->y = y + ((psF32) source->peak->y); 867 770 psTrace (".psModules.pmSourceMoments", 5, 771 "large centroid swing; invalid peak %d, %d\n", 772 source->peak->x, source->peak->y); 773 return (false); 774 } 775 776 source->moments->x = x + xPeak; 777 source->moments->y = y + yPeak; 778 779 // XXX EAM : Sxy needs to have x*y subtracted 868 780 source->moments->Sxy = XY/Sum - x*y; 869 781 source->moments->Sum = Sum; … … 919 831 *****************************************************************************/ 920 832 833 // XXX EAM include a S/N cutoff in selecting the sources? 921 834 pmPSFClump pmSourcePSFClump(psArray *sources, psMetadata *metadata) 922 835 { … … 1123 1036 bool big = (sigX > (clump.X - clump.dX)) && (sigY > (clump.Y - clump.dY)); 1124 1037 if ((Nsatpix > 1) && big) { 1125 tmpSrc->type |= P S_SOURCE_SATSTAR;1038 tmpSrc->type |= PM_SOURCE_SATSTAR; 1126 1039 Nsatstar ++; 1127 1040 continue; … … 1130 1043 // saturated object (not a star, eg bleed trails, hot pixels) 1131 1044 if (Nsatpix > 1) { 1132 tmpSrc->type |= P S_SOURCE_SATURATED;1045 tmpSrc->type |= PM_SOURCE_SATURATED; 1133 1046 Nsat ++; 1134 1047 continue; … … 1139 1052 // only set candidate defects if 1140 1053 if ((sigX < 0.05) || (sigY < 0.05)) { 1141 tmpSrc->type |= P S_SOURCE_DEFECT;1054 tmpSrc->type |= PM_SOURCE_DEFECT; 1142 1055 Ncr ++; 1143 1056 continue; … … 1146 1059 // likely unsaturated galaxy (too large to be stellar) 1147 1060 if ((sigX > (clump.X + 3*clump.dX)) || (sigY > (clump.Y + 3*clump.dY))) { 1148 tmpSrc->type |= P S_SOURCE_GALAXY;1061 tmpSrc->type |= PM_SOURCE_GALAXY; 1149 1062 Ngal ++; 1150 1063 continue; … … 1159 1072 psF32 radius = hypot ((sigX-clump.X)/clump.dX, (sigY-clump.Y)/clump.dY); 1160 1073 if ((SN > PSF_SN_LIM) && (radius < 1.5)) { 1161 tmpSrc->type |= P S_SOURCE_PSFSTAR;1074 tmpSrc->type |= PM_SOURCE_PSFSTAR; 1162 1075 Npsf ++; 1163 1076 continue; … … 1165 1078 1166 1079 // random type of star 1167 tmpSrc->type |= P S_SOURCE_OTHER;1080 tmpSrc->type |= PM_SOURCE_OTHER; 1168 1081 } 1169 1082 … … 1197 1110 XXX: The circle will have a diameter of (1+radius). This is different from 1198 1111 the pmSourceSetLocal() function. 1112 1113 XXX: this should probably use the psImageMaskCircle Function for consistency 1199 1114 *****************************************************************************/ 1200 1115 bool pmSourceSetPixelsCircle(pmSource *source, … … 1537 1452 XXX EAM : fit the specified model (not necessarily the one in source) 1538 1453 *****************************************************************************/ 1539 bool pmSourceFitModel (pmSource *source,1540 pmModel *model,1541 const bool PSF)1454 bool pmSourceFitModel_v5(pmSource *source, 1455 pmModel *model, 1456 const bool PSF) 1542 1457 { 1543 1458 PS_ASSERT_PTR_NON_NULL(source, false); … … 1554 1469 // tests below could be conditions (!NULL) 1555 1470 1556 pmModelFunc modelFunc = pmModelFunc_GetFunction (model->type);1557 1558 1471 psVector *params = model->params; 1559 1472 psVector *dparams = model->dparams; 1560 1473 psVector *paramMask = NULL; 1474 1475 pmModelFunc modelFunc = pmModelFunc_GetFunction (model->type); 1561 1476 1562 1477 int nParams = PSF ? params->n - 4 : params->n; … … 1615 1530 } 1616 1531 1617 psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F32); 1532 // XXX EAM : covar must be F64? 1533 psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F64); 1618 1534 1619 1535 psTrace (".pmObjects.pmSourceFitModel", 5, "fitting function\n"); … … 1621 1537 for (int i = 0; i < dparams->n; i++) { 1622 1538 if ((paramMask != NULL) && paramMask->data.U8[i]) continue; 1623 dparams->data.F32[i] = sqrt(covar->data.F 32[i][i]);1539 dparams->data.F32[i] = sqrt(covar->data.F64[i][i]); 1624 1540 } 1625 1541 … … 1640 1556 // XXX EAM get the Gauss-Newton distance for fixed model parameters 1641 1557 if (paramMask != NULL) { 1642 psVector *delta = psVectorAlloc (params->n, PS_TYPE_F 32);1558 psVector *delta = psVectorAlloc (params->n, PS_TYPE_F64); 1643 1559 psMinimizeGaussNewtonDelta (delta, params, NULL, x, y, yErr, modelFunc); 1644 1560 for (int i = 0; i < dparams->n; i++) { 1645 1561 if (!paramMask->data.U8[i]) continue; 1646 dparams->data.F32[i] = delta->data.F 32[i];1562 dparams->data.F32[i] = delta->data.F64[i]; 1647 1563 } 1648 1564 psFree (delta); … … 1655 1571 psFree(covar); 1656 1572 psFree(paramMask); 1573 1574 rc = (onPic && fitStatus); 1575 return(rc); 1576 } 1577 1578 // XXX EAM : new version with parameter range limits and noise enhancement 1579 bool pmSourceFitModel (pmSource *source, 1580 pmModel *model, 1581 const bool PSF) 1582 { 1583 PS_ASSERT_PTR_NON_NULL(source, false); 1584 PS_ASSERT_PTR_NON_NULL(source->moments, false); 1585 PS_ASSERT_PTR_NON_NULL(source->peak, false); 1586 PS_ASSERT_PTR_NON_NULL(source->pixels, false); 1587 PS_ASSERT_PTR_NON_NULL(source->mask, false); 1588 PS_ASSERT_PTR_NON_NULL(source->noise, false); 1589 1590 // XXX EAM : is it necessary for the mask & noise to exist? the 1591 // tests below could be conditions (!NULL) 1592 1593 psBool fitStatus = true; 1594 psBool onPic = true; 1595 psBool rc = true; 1596 psF32 Ro, ymodel; 1597 1598 psVector *params = model->params; 1599 psVector *dparams = model->dparams; 1600 psVector *paramMask = NULL; 1601 1602 pmModelFunc modelFunc = pmModelFunc_GetFunction (model->type); 1603 1604 // XXX EAM : I need to use the sky value to constrain the noise model 1605 int nParams = PSF ? params->n - 4 : params->n; 1606 psF32 So = params->data.F32[0]; 1607 1608 // find the number of valid pixels 1609 // XXX EAM : this loop and the loop below could just be one pass 1610 // using the psArrayAdd and psVectorExtend functions 1611 psS32 count = 0; 1612 for (psS32 i = 0; i < source->pixels->numRows; i++) { 1613 for (psS32 j = 0; j < source->pixels->numCols; j++) { 1614 if (source->mask->data.U8[i][j] == 0) { 1615 count++; 1616 } 1617 } 1618 } 1619 if (count < nParams + 1) { 1620 psTrace (".pmObjects.pmSourceFitModel", 4, "insufficient valid pixels\n"); 1621 return(false); 1622 } 1623 1624 // construct the coordinate and value entries 1625 psArray *x = psArrayAlloc(count); 1626 psVector *y = psVectorAlloc(count, PS_TYPE_F32); 1627 psVector *yErr = psVectorAlloc(count, PS_TYPE_F32); 1628 psS32 tmpCnt = 0; 1629 for (psS32 i = 0; i < source->pixels->numRows; i++) { 1630 for (psS32 j = 0; j < source->pixels->numCols; j++) { 1631 if (source->mask->data.U8[i][j] == 0) { 1632 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 1633 // XXX: Convert i/j to image space: 1634 // XXX EAM: coord order is (x,y) == (col,row) 1635 coord->data.F32[0] = (psF32) (j + source->pixels->col0); 1636 coord->data.F32[1] = (psF32) (i + source->pixels->row0); 1637 x->data[tmpCnt] = (psPtr *) coord; 1638 y->data.F32[tmpCnt] = source->pixels->data.F32[i][j]; 1639 1640 // compare observed flux to model flux to adjust weight 1641 ymodel = modelFunc (NULL, model->params, coord); 1642 1643 // this test enhances the noise based on deviation from the model flux 1644 Ro = 1.0 + fabs (y->data.F32[tmpCnt] - ymodel) / sqrt(PS_SQR(ymodel - So) + PS_SQR(So)); 1645 1646 // XXX EAM : note the wasted effort: we carry dY^2, take sqrt(), then 1647 // the minimization function calculates sq(). 1648 // should psMinimizeLMChi2 take dY^2? 1649 yErr->data.F32[tmpCnt] = sqrt (source->noise->data.F32[i][j] * Ro); 1650 tmpCnt++; 1651 } 1652 } 1653 } 1654 1655 psMinimization *myMin = psMinimizationAlloc(PM_SOURCE_FIT_MODEL_NUM_ITERATIONS, 1656 PM_SOURCE_FIT_MODEL_TOLERANCE); 1657 1658 // PSF model only fits first 4 parameters, FLT model fits all 1659 if (PSF) { 1660 paramMask = psVectorAlloc (params->n, PS_TYPE_U8); 1661 for (int i = 0; i < 4; i++) { 1662 paramMask->data.U8[i] = 0; 1663 } 1664 for (int i = 4; i < paramMask->n; i++) { 1665 paramMask->data.U8[i] = 1; 1666 } 1667 } 1668 1669 // XXX EAM : I've added three types of parameter range checks 1670 // XXX EAM : this requires my new psMinimization functions 1671 pmModelLimits modelLimits = pmModelLimits_GetFunction (model->type); 1672 psVector *beta_lim = NULL; 1673 psVector *params_min = NULL; 1674 psVector *params_max = NULL; 1675 1676 // XXX EAM : in this implementation, I pass in the limits with the covar matrix. 1677 // in the SDRS, I define a new psMinimization which will take these in 1678 psImage *covar = psImageAlloc (params->n, 3, PS_TYPE_F64); 1679 modelLimits (&beta_lim, ¶ms_min, ¶ms_max); 1680 for (int i = 0; i < params->n; i++) { 1681 covar->data.F64[0][i] = beta_lim->data.F32[i]; 1682 covar->data.F64[1][i] = params_min->data.F32[i]; 1683 covar->data.F64[2][i] = params_max->data.F32[i]; 1684 } 1685 1686 psTrace (".pmObjects.pmSourceFitModel", 5, "fitting function\n"); 1687 fitStatus = psMinimizeLMChi2_EAM(myMin, covar, params, paramMask, x, y, yErr, modelFunc); 1688 for (int i = 0; i < dparams->n; i++) { 1689 if ((paramMask != NULL) && paramMask->data.U8[i]) continue; 1690 dparams->data.F32[i] = sqrt(covar->data.F64[i][i]); 1691 } 1692 1693 // XXX EAM: we need to do something (give an error?) if rc is false 1694 // XXX EAM: psMinimizeLMChi2 does not check convergence 1695 1696 // XXX models can go insane: reject these 1697 onPic &= (params->data.F32[2] >= source->pixels->col0); 1698 onPic &= (params->data.F32[2] < source->pixels->col0 + source->pixels->numCols); 1699 onPic &= (params->data.F32[3] >= source->pixels->row0); 1700 onPic &= (params->data.F32[3] < source->pixels->row0 + source->pixels->numRows); 1701 1702 // XXX EAM: save the resulting chisq, nDOF, nIter 1703 model->chisq = myMin->value; 1704 model->nIter = myMin->iter; 1705 model->nDOF = y->n - nParams; 1706 1707 // XXX EAM get the Gauss-Newton distance for fixed model parameters 1708 if (paramMask != NULL) { 1709 psVector *delta = psVectorAlloc (params->n, PS_TYPE_F64); 1710 psMinimizeGaussNewtonDelta (delta, params, NULL, x, y, yErr, modelFunc); 1711 for (int i = 0; i < dparams->n; i++) { 1712 if (!paramMask->data.U8[i]) continue; 1713 dparams->data.F32[i] = delta->data.F64[i]; 1714 } 1715 } 1716 1717 psFree(paramMask); 1718 psFree(x); 1719 psFree(y); 1720 psFree(myMin); 1657 1721 1658 1722 rc = (onPic && fitStatus);
Note:
See TracChangeset
for help on using the changeset viewer.
