Changeset 5829
- Timestamp:
- Dec 22, 2005, 4:23:00 PM (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_rel9_b0/psModules/src/objects/pmObjects.c
r5806 r5829 6 6 * @author EAM, IfA: significant modifications. 7 7 * 8 * @version $Revision: 1.3.4. 2$ $Name: not supported by cvs2svn $9 * @date $Date: 2005-12- 17 20:41:29$8 * @version $Revision: 1.3.4.3 $ $Name: not supported by cvs2svn $ 9 * @date $Date: 2005-12-23 02:23:00 $ 10 10 * 11 11 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 132 132 tmp->mask = NULL; 133 133 tmp->moments = NULL; 134 tmp->blends = NULL; 134 135 tmp->modelPSF = NULL; 135 136 tmp->modelFLT = NULL; … … 1115 1116 // Nsigma should be user-configured parameter 1116 1117 bool big = (sigX > (clump.X - clump.dX)) && (sigY > (clump.Y - clump.dY)); 1118 big = true; 1117 1119 if ((Nsatpix > 1) && big) { 1118 1120 tmpSrc->type = PM_SOURCE_STAR; … … 1571 1573 #define PM_SOURCE_FIT_MODEL_NUM_ITERATIONS 15 1572 1574 #define PM_SOURCE_FIT_MODEL_TOLERANCE 0.1 1573 /****************************************************************************** 1574 pmSourceFitModel(source, model): must create the appropiate arguments to the 1575 LM minimization routines for the various p_pmMinLM_XXXXXX_Vec() functions. 1576 1577 XXX: should there be a mask value? 1578 XXX EAM : fit the specified model (not necessarily the one in source) 1579 *****************************************************************************/ 1580 bool pmSourceFitModel_v5(pmSource *source, 1581 pmModel *model, 1582 const bool PSF) 1575 bool pmSourceFitModel (pmSource *source, 1576 pmModel *model, 1577 const bool PSF) 1583 1578 { 1584 1579 psTrace(__func__, 3, "---- %s() begin ----\n", __func__); … … 1589 1584 PS_ASSERT_PTR_NON_NULL(source->mask, false); 1590 1585 PS_ASSERT_PTR_NON_NULL(source->weight, false); 1586 1587 // XXX EAM : is it necessary for the mask & weight to exist? the 1588 // tests below could be conditions (!NULL) 1589 1591 1590 psBool fitStatus = true; 1592 1591 psBool onPic = true; 1593 1592 psBool rc = true; 1594 1593 1595 // XXX EAM : is it necessary for the mask & weight to exist? the1596 // tests below could be conditions (!NULL)1597 1598 1594 psVector *params = model->params; 1599 1595 psVector *dparams = model->dparams; … … 1602 1598 pmModelFunc modelFunc = pmModelFunc_GetFunction (model->type); 1603 1599 1604 int nParams = PSF ? params->n - 4 : params->n; 1605 1606 // find the number of valid pixels 1607 // XXX EAM : this loop and the loop below could just be one pass 1608 // using the psArrayAdd and psVectorExtend functions 1609 psS32 count = 0; 1600 int nParams = PSF ? 4 : params->n; 1601 1602 // maximum number of valid pixels 1603 psS32 nPix = source->pixels->numRows * source->pixels->numCols; 1604 1605 // construct the coordinate and value entries 1606 psArray *x = psArrayAlloc(nPix); 1607 psVector *y = psVectorAlloc(nPix, PS_TYPE_F32); 1608 psVector *yErr = psVectorAlloc(nPix, PS_TYPE_F32); 1609 1610 nPix = 0; 1610 1611 for (psS32 i = 0; i < source->pixels->numRows; i++) { 1611 1612 for (psS32 j = 0; j < source->pixels->numCols; j++) { 1612 if (source->mask->data.U8[i][j] == 0) { 1613 count++; 1614 } 1615 } 1616 } 1617 if (count < nParams + 1) { 1613 if (source->mask->data.U8[i][j]) { 1614 continue; 1615 } 1616 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 1617 1618 // Convert i/j to image space: 1619 coord->data.F32[0] = (psF32) (j + source->pixels->col0); 1620 coord->data.F32[1] = (psF32) (i + source->pixels->row0); 1621 x->data[nPix] = (psPtr *) coord; 1622 y->data.F32[nPix] = source->pixels->data.F32[i][j]; 1623 1624 // psMinimizeLMChi2 takes wt = 1/dY^2 1625 if (source->weight->data.F32[i][j] == 0) { 1626 continue; 1627 } 1628 yErr->data.F32[nPix] = 1.0 / source->weight->data.F32[i][j]; 1629 nPix++; 1630 } 1631 } 1632 if (nPix < nParams + 1) { 1618 1633 psTrace (".pmObjects.pmSourceFitModel", 4, "insufficient valid pixels\n"); 1619 1634 psTrace(__func__, 3, "---- %s(false) end ----\n", __func__); 1620 1635 model->status = PM_MODEL_BADARGS; 1636 psFree (x); 1637 psFree (y); 1638 psFree (yErr); 1621 1639 return(false); 1622 1640 } 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 yErr->data.F32[tmpCnt] = sqrt (source->weight->data.F32[i][j]); 1640 // XXX EAM : note the wasted effort: we carry dY^2, take sqrt(), then 1641 // the minimization function calculates sq() 1642 tmpCnt++; 1643 } 1644 } 1645 } 1641 x->n = nPix; 1642 y->n = nPix; 1643 yErr->n = nPix; 1646 1644 1647 1645 psMinimization *myMin = psMinimizationAlloc(PM_SOURCE_FIT_MODEL_NUM_ITERATIONS, … … 1659 1657 } 1660 1658 1661 // XXX EAM : covar must be F64? 1662 psImage *covar = psImageAlloc (params->n, params->n, PS_TYPE_F64); 1663 1664 psTrace (".pmObjects.pmSourceFitModel", 5, "fitting function\n"); 1665 fitStatus = psMinimizeLMChi2(myMin, covar, params, paramMask, x, y, yErr, modelFunc); 1666 for (int i = 0; i < dparams->n; i++) { 1667 if ((paramMask != NULL) && paramMask->data.U8[i]) 1668 continue; 1669 dparams->data.F32[i] = sqrt(covar->data.F64[i][i]); 1670 } 1671 1672 // save the resulting chisq, nDOF, nIter 1673 model->chisq = myMin->value; 1674 model->nIter = myMin->iter; 1675 model->nDOF = y->n - nParams; 1676 1677 // get the Gauss-Newton distance for fixed model parameters 1678 if (paramMask != NULL) { 1679 psVector *delta = psVectorAlloc (params->n, PS_TYPE_F64); 1680 psMinimizeGaussNewtonDelta (delta, params, NULL, x, y, yErr, modelFunc); 1681 for (int i = 0; i < dparams->n; i++) { 1682 if (!paramMask->data.U8[i]) 1683 continue; 1684 dparams->data.F32[i] = delta->data.F64[i]; 1685 } 1686 psFree (delta); 1687 } 1688 1689 // set the model success or failure status 1690 if (!fitStatus) { 1691 model->status = PM_MODEL_NONCONVERGE; 1692 } else { 1693 model->status = PM_MODEL_SUCCESS; 1694 } 1695 1696 // 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 if (!onPic) { 1702 model->status = PM_MODEL_OFFIMAGE; 1703 } 1704 1705 source->mode |= PM_SOURCE_FITTED; 1706 1707 psFree(x); 1708 psFree(y); 1709 psFree(yErr); 1710 psFree(myMin); 1711 psFree(covar); 1712 psFree(paramMask); 1713 1714 rc = (onPic && fitStatus); 1715 psTrace(__func__, 3, "---- %s(%d) end ----\n", __func__, rc); 1716 return(rc); 1717 } 1718 1719 // XXX EAM : new version with parameter range limits and weight enhancement 1720 bool pmSourceFitModel (pmSource *source, 1721 pmModel *model, 1722 const bool PSF) 1723 { 1724 psTrace(__func__, 3, "---- %s() begin ----\n", __func__); 1725 PS_ASSERT_PTR_NON_NULL(source, false); 1726 PS_ASSERT_PTR_NON_NULL(source->moments, false); 1727 PS_ASSERT_PTR_NON_NULL(source->peak, false); 1728 PS_ASSERT_PTR_NON_NULL(source->pixels, false); 1729 PS_ASSERT_PTR_NON_NULL(source->mask, false); 1730 PS_ASSERT_PTR_NON_NULL(source->weight, false); 1731 1732 // XXX EAM : is it necessary for the mask & weight to exist? the 1733 // tests below could be conditions (!NULL) 1734 1735 psBool fitStatus = true; 1736 psBool onPic = true; 1737 psBool rc = true; 1738 // psF32 Ro, ymodel; 1739 1740 psVector *params = model->params; 1741 psVector *dparams = model->dparams; 1742 psVector *paramMask = NULL; 1743 1744 pmModelFunc modelFunc = pmModelFunc_GetFunction (model->type); 1745 1746 // XXX EAM : I need to use the sky value to constrain the weight model 1747 int nParams = PSF ? params->n - 4 : params->n; 1748 // psF32 So = params->data.F32[0]; 1749 1750 // find the number of valid pixels 1751 // XXX EAM : this loop and the loop below could just be one pass 1752 // using the psArrayAdd and psVectorExtend functions 1753 psS32 count = 0; 1754 for (psS32 i = 0; i < source->pixels->numRows; i++) { 1755 for (psS32 j = 0; j < source->pixels->numCols; j++) { 1756 if (source->mask->data.U8[i][j] == 0) { 1757 count++; 1758 } 1759 } 1760 } 1761 if (count < nParams + 1) { 1762 psTrace (".pmObjects.pmSourceFitModel", 4, "insufficient valid pixels\n"); 1763 psTrace(__func__, 3, "---- %s(false) end ----\n", __func__); 1764 model->status = PM_MODEL_BADARGS; 1765 return(false); 1766 } 1767 1768 // construct the coordinate and value entries 1769 psArray *x = psArrayAlloc(count); 1770 psVector *y = psVectorAlloc(count, PS_TYPE_F32); 1771 psVector *yErr = psVectorAlloc(count, PS_TYPE_F32); 1772 psS32 tmpCnt = 0; 1773 for (psS32 i = 0; i < source->pixels->numRows; i++) { 1774 for (psS32 j = 0; j < source->pixels->numCols; j++) { 1775 if (source->mask->data.U8[i][j] == 0) { 1776 psVector *coord = psVectorAlloc(2, PS_TYPE_F32); 1777 // XXX: Convert i/j to image space: 1778 // XXX EAM: coord order is (x,y) == (col,row) 1779 coord->data.F32[0] = (psF32) (j + source->pixels->col0); 1780 coord->data.F32[1] = (psF32) (i + source->pixels->row0); 1781 x->data[tmpCnt] = (psPtr *) coord; 1782 y->data.F32[tmpCnt] = source->pixels->data.F32[i][j]; 1783 1784 // compare observed flux to model flux to adjust weight 1785 // ymodel = modelFunc (NULL, model->params, coord); 1786 1787 // this test enhances the weight based on deviation from the model flux 1788 // Ro = 1.0 + sqrt (fabs (y->data.F32[tmpCnt] - ymodel) / (PS_SQR(ymodel - So) + 1.0)); 1789 1790 // psMinimizeLMChi2_EAM takes wt = 1/dY^2 1791 if (source->weight->data.F32[i][j] == 0) { 1792 yErr->data.F32[tmpCnt] = 0.0; 1793 } else { 1794 // yErr->data.F32[tmpCnt] = 1.0 / (source->weight->data.F32[i][j] * Ro); 1795 yErr->data.F32[tmpCnt] = 1.0 / source->weight->data.F32[i][j]; 1796 } 1797 tmpCnt++; 1798 } 1799 } 1800 } 1801 1802 psMinimization *myMin = psMinimizationAlloc(PM_SOURCE_FIT_MODEL_NUM_ITERATIONS, 1803 PM_SOURCE_FIT_MODEL_TOLERANCE); 1804 1805 // PSF model only fits first 4 parameters, FLT model fits all 1806 if (PSF) { 1807 paramMask = psVectorAlloc (params->n, PS_TYPE_U8); 1808 for (int i = 0; i < 4; i++) { 1809 paramMask->data.U8[i] = 0; 1810 } 1811 for (int i = 4; i < paramMask->n; i++) { 1812 paramMask->data.U8[i] = 1; 1813 } 1814 } 1815 1816 // XXX EAM : I've added three types of parameter range checks 1817 // XXX EAM : this requires my new psMinimization functions 1659 // Set the parameter range checks 1818 1660 pmModelLimits modelLimits = pmModelLimits_GetFunction (model->type); 1819 1661 psVector *beta_lim = NULL; … … 1839 1681 } 1840 1682 1841 // XXX EAM: we need to do something (give an error?) if rc is false 1842 // XXX EAM: psMinimizeLMChi2 does not check convergence 1843 1844 // XXX EAM: save the resulting chisq, nDOF, nIter 1683 // save the resulting chisq, nDOF, nIter 1845 1684 model->chisq = myMin->value; 1846 1685 model->nIter = myMin->iter; 1847 1686 model->nDOF = y->n - nParams; 1848 1687 1849 // XXX EAMget the Gauss-Newton distance for fixed model parameters1688 // get the Gauss-Newton distance for fixed model parameters 1850 1689 if (paramMask != NULL) { 1851 1690 psVector *delta = psVectorAlloc (params->n, PS_TYPE_F64); … … 1865 1704 } 1866 1705 1867 // XXXmodels can go insane: reject these1706 // models can go insane: reject these 1868 1707 onPic &= (params->data.F32[2] >= source->pixels->col0); 1869 1708 onPic &= (params->data.F32[2] < source->pixels->col0 + source->pixels->numCols);
Note:
See TracChangeset
for help on using the changeset viewer.
