28 #include <CCfits/CCfits>
37 #include "WlVersion.h"
38 #include "WriteParam.h"
43 namespace algorithms {
47 int order,
double x,
double xMin,
double xMax)
50 double newX = (2.*x-xMin-xMax)/(xMax-xMin);
52 if(order>0) temp[1] = newX;
53 for(
int i=2;i<=order;++i) {
54 temp[i] = ((2.*i-1.)*newX*temp[i-1] - (i-1.)*temp[i-2])/i;
61 int fitOrder, Position pos,
const Bounds& bounds,
DVectorView pRow)
64 int fitOrder, Position pos,
const Bounds& bounds,
DVector& pRow)
67 Assert(
int(pRow.size()) == (fitOrder+1)*(fitOrder+2)/2);
69 definePXY(fitOrder,pos.getX(),bounds.getXMin(),bounds.getXMax());
71 definePXY(fitOrder,pos.getY(),bounds.getYMin(),bounds.getYMax());
73 for(
int n=0;n<=fitOrder;++n) {
74 for(
int p=n,q=n-p;q<=n;--p,++q) {
75 Assert(pq <
int(pRow.size()));
76 pRow(pq) = px[p]*py[q];
80 Assert(pq ==
int(pRow.size()));
84 const std::vector<Position>& pos,
85 const std::vector<BVec>& psf,
86 const std::vector<double>& nu,
87 std::vector<long>& flags)
89 const int nStars = pos.size();
91 const double nSigmaClip =
_params.
read(
"fitpsf_nsigma_outlier",3);
104 const double chisqLevel = 0.14*psfSize + 2.13;
106 const double outlierThresh = nSigmaClip * nSigmaClip * chisqLevel;
107 dbg<<
"outlierThresh = "<<outlierThresh<<std::endl;
109 int nGoodPsf, nOutliers, dof;
118 for(
int n=0;n<nStars;++n)
if ( flags[n]==0 ) {
124 dbg<<
"ngoodpsf = 0 in FittedPsf::calculate\n";
134 for(
int n=0;n<nStars;++n)
if ( flags[n]==0 ) {
135 Assert(
int(psf[n].size()) == psfSize);
137 mM.row(i) = psf[n].vec() - *
_avePsf;
138 inverseSigma(i) = nu[n];
146 int nPcaTot = std::min(nGoodPsf,psfSize);
150 _mV.reset(
new tmv::Matrix<double,tmv::RowMajor>(nPcaTot,psfSize));
151 if (nGoodPsf > psfSize) {
152 SV_Decompose(mU.view(),mS.view(),_mV->view(),
true);
155 SV_Decompose(_mV->transpose(),mS.view(),mU.transpose());
157 xdbg<<
"In FittedPSF: SVD S = "<<mS.diag()<<std::endl;
159 DMatrix mU(mM.TMV_colsize(),nPcaTot);
161 if (nGoodPsf > psfSize) {
162 Eigen::JacobiSVD<DMatrix> svd(
163 TMV_colRange(mM,0,nPcaTot), Eigen::ComputeThinU | Eigen::ComputeThinV
166 mS = svd.singularValues();
169 Eigen::JacobiSVD<DMatrix> svd(
170 mM, Eigen::ComputeThinU | Eigen::ComputeThinV
173 mS = svd.singularValues();
180 dbg<<
"npca = "<<
_nPca<<
" from parameter file\n";
182 double thresh = mS(0);
184 thresh *=
double(
_params[
"fitpsf_pca_thresh"]);
185 else thresh *= std::numeric_limits<double>::epsilon();
186 dbg<<
"thresh = "<<thresh<<std::endl;
188 if (mS(
_nPca) < thresh)
break;
193 mU.colRange(0,
_nPca) *= mS.subDiagMatrix(0,
_nPca);
197 xdbg<<
"After U *= S\n";
200 while (nGoodPsf <= _fitSize && _fitSize > 1) {
203 dbg<<
"Too few good stars... reducing order of fit to "<<
209 for(
int n=0;n<nStars;++n)
if ( flags[n]==0 ) {
210 xdbg<<
"n = "<<n<<
" / "<<nStars<<std::endl;
214 DVector mProwi(mP.TMV_rowsize());
216 mP.row(i) = mProwi.transpose();
222 xdbg<<
"after mP = sigma * mP\n";
230 xdbg<<
"Done making FittedPSF\n";
236 xdbg<<
"Checking for outliers:\n";
241 for(
int n=0;n<nStars;++n)
if ( flags[n]==0 ) {
242 const BVec& data = psf[n];
249 cov += diff * diff.transpose();
254 dbg<<
"chisq calculation #1 = "<<chisq<<std::endl;
261 cov.divideUsing(tmv::SV);
264 dbg<<
"cov S = "<<cov.svd().getS().diag()<<std::endl;
266 Eigen::JacobiSVD<DMatrix> cov_svd(cov, Eigen::ComputeThinU | Eigen::ComputeThinV);
274 for(
int n=0;n<nStars;++n)
if ( flags[n]==0 ) {
275 const BVec& data = psf[n];
280 double dev = diff * cov.inverse() * diff;
283 temp = cov_svd.solve(diff);
284 double dev = (diff.transpose() * temp)(0,0);
287 if (dev > outlierThresh) {
288 xdbg<<
"n = "<<n<<
" is an outlier.\n";
289 xdbg<<
"data = "<<data.
vec()<<std::endl;
290 xdbg<<
"fit = "<<fit<<std::endl;
291 xdbg<<
"diff = "<<diff<<std::endl;
293 xdbg<<
"diff/cov = "<<diff/cov<<std::endl;
295 xdbg<<
"diff/cov = "<<temp<<std::endl;
297 xdbg<<
"dev = "<<dev<<std::endl;
299 flags[n] |= PSF_INTERP_OUTLIER;
302 dbg<<
"ngoodpsf = "<<nGoodPsf<<std::endl;
303 dbg<<
"nOutliers = "<<nOutliers<<std::endl;
304 dbg<<
"chisq calculation #2 = "<<chisq<<std::endl;
306 }
while (nOutliers > 0);
310 _params(params), _psfOrder(_params.read<int>(
"psf_order")),
311 _fitOrder(_params.read<int>(
"fitpsf_order")),
312 _fitSize((_fitOrder+1)*(_fitOrder+2)/2)
321 double bi = b1 * _mV->col(i,0,
_nPca);
324 DVector b1 = _f->transpose() * P;
338 b = b1 * _mV->rowRange(0,
_nPca);
341 DVector b1 = _f->transpose() * P;
Eigen::Block< DVector, Eigen::Dynamic, 1 > DVectorView
void calculate(const std::vector< Position > &pos, const std::vector< BVec > &psf, const std::vector< double > &nu, std::vector< long > &flags)
const ConfigFile & _params
#define EIGEN_ToScalar(m)
FittedPsf(const ConfigFile ¶ms)
std::auto_ptr< DVector > _avePsf
double interpolateSingleElement(Position pos, int i) const
bool keyExists(const std::string &key) const
#define TMV_colRange(m, j1, j2)
std::auto_ptr< DMatrix > _f
Eigen::Block< DMatrix > DMatrixView
void interpolateVector(Position pos, DVectorView b) const
std::auto_ptr< DMatrix > _mV_transpose
afw::table::Key< double > b
void read(std::istream &is)
#define EIGEN_Transpose(m)