33 namespace algorithms {
65 _sigma(sigma), _I(pix.size()), _Z(pix.size()), _W(pix.size()),
66 _Z1(pix.size()), _E(pix.size()), _Rsq(pix.size()), _f1(pix.size()),
67 _I1(I1), _xInit(xInit)
69 const int nPix = pix.
size();
70 for(
int i=0;i<nPix;++i) {
71 _Z(i) = pix[i].getPos();
72 _I(i) = pix[i].getFlux();
74 _W(i) = pix[i].getInverseSigma()*mask;
83 if ((x-
_xInit).TMV_subVector(0,3).TMV_normInf() > 2.) {
94 std::complex<double> zc(x[0],x[1]);
96 double I0 =
_I1 * x[3];
98 double m0 = exp(-mu)/
_sigma;
104 _Z1.TMV_addToAll(-m0*zc);
106 const int nPix = _Z.size();
107 for(
int i=0;i<nPix;++i) {
110 _E[i] = exp(-rsq/2.);
116 _f1.array() *=
_W.array();
127 Assert(df.TMV_colsize() ==
_Z.size());
128 Assert(df.TMV_rowsize() == 4);
131 double I0 =
_I1 * x[3];
132 double m0 = exp(-mu)/
_sigma;
145 df.col(0) = -m0 *
_Z1.realPart();
146 df.col(1) = -m0 *
_Z1.imagPart();
148 df.colRange(0,3) = I0 * DiagMatrixViewOf(
_E) * df.colRange(0,3);
149 df.col(3) = -
_I1 *
_E;
152 df.col(0).array() =
_W.array() *
_Z1.real().array();
153 df.col(0).array() = _E.array() * df.col(0).array();
154 df.col(0) *= -m0 * I0;
155 df.col(1).array() =
_W.array() *
_Z1.imag().array();
156 df.col(1).array() = _E.array() * df.col(1).array();
157 df.col(1) *= -m0 * I0;
158 df.col(2).array() =
_W.array() *
_Rsq.array();
159 df.col(2).array() = _E.array() * df.col(2).array();
161 df.col(3).array() =
_W.array() * _E.array();
178 xdbg<<
"Current centroid = "<<
_cen<<std::endl;
179 xdbg<<
"Current mu = "<<
_mu<<std::endl;
180 xdbg<<
"sigma = "<<sigma<<std::endl;
181 const int nPix = pix.
size();
189 std::complex<double> Iz = 0.;
191 double sig2 = sigma * exp(
real(
_mu));
192 for(
int i=0;i<nPix;++i) {
194 Iz += wt * pix[i].getFlux() * (pix[i].getPos()-
_cen);
195 I += wt * pix[i].getFlux();
196 if (std::abs(pix[i].getPos()-
_cen) < 2.)
197 xdbg<<pix[i].getPos()<<
" "<<pix[i].getFlux()<<std::endl;
199 xdbg<<
"Iz = "<<Iz<<
", I = "<<I<<std::endl;
203 if (!(I > 0.))
return;
205 std::complex<double> zc = Iz / I;
207 if (!(std::abs(zc) < 2.))
return;
209 xdbg<<
"Initial offset to centroid = "<<zc<<std::endl;
211 xdbg<<
"But centroid is fixed, so don't apply.\n";
216 xdbg<<
"zc = "<<zc<<std::endl;
222 for(
int i=0;i<nPix;++i) {
223 double wt = exp(-
std::norm((pix[i].getPos()-zc)/sig2)/2.);
224 Iz += wt * pix[i].getFlux() * (pix[i].getPos()-zc);
225 Irr += wt * pix[i].getFlux() *
std::norm(pix[i].getPos()-zc);
226 I += wt * pix[i].getFlux();
229 xdbg<<
"Iz = "<<Iz<<
", Irr = "<<Irr<<
", I = "<<I<<
", W = "<<W<<std::endl;
231 std::complex<double> zc1 = Iz/I;
232 double S = Irr/I -
norm(zc1);
234 xdbg<<
"S = "<<S<<std::endl;
235 double exp2mu = S / 2. / (sig2*sig2);
236 xdbg<<
"exp2mu/(1+exp2mu) = "<<exp2mu<<std::endl;
240 else if (exp2mu < 0.8)
241 exp2mu = 1./(1./exp2mu-1.);
247 xdbg<<
"exp2mu = "<<exp2mu<<std::endl;
248 if (exp2mu <= 0.) exp2mu = 1.;
250 double m =
log(exp2mu)/2.;
251 xdbg<<
"mu = "<<m<<std::endl;
257 xdbg<<
"Approx cen = "<<zc<<std::endl;
258 xdbg<<
"Approx mu = "<<m<<std::endl;
261 double I0 = (I/W)*(1.+exp2mu)/exp2mu /
262 exp(-
norm(zc1)*(1.+exp2mu)/(2.*sig2*sig2));
264 std::complex<double> zc =
_cen;
269 double minx = 1.e100, maxx = -1.e100, miny = 1.e100, maxy = -1.e100;
270 for(
int i=0;i<nPix;++i) {
271 if (
real(pix[i].getPos()) < minx) minx =
real(pix[i].getPos());
272 if (
real(pix[i].getPos()) > maxx) maxx =
real(pix[i].getPos());
273 if (imag(pix[i].getPos()) < miny) miny = imag(pix[i].getPos());
274 if (imag(pix[i].getPos()) > maxy) maxy = imag(pix[i].getPos());
275 double wt = exp(-
std::norm(pix[i].getPos()/sigma)/2.);
277 obs += pix[i].getFlux() * mask;
279 double pixarea = (maxx-minx)*(maxy-miny)/nPix;
280 xdbg<<
"pixarea = "<<pixarea<<std::endl;
281 xdbg<<
"obs = "<<obs<<std::endl;
282 xdbg<<
"model = "<<model<<std::endl;
283 double I0 = 2.*obs / model;
286 xdbg<<
"Initial I0 estimate = "<<I0<<std::endl;
288 xdbg<<
"Warning: small or negative I0: "<<I0<<
" -- Use 1.0\n";
295 x[0] =
std::real(zc); x[1] = std::imag(zc);
313 s.
setFTol(1.e-4 * (1.e-4 + std::abs(x[3])));
317 std::complex<double> cenNew(x[0],x[1]);
320 if (std::abs(cenNew-
_cen) > 2.) {
321 dbg<<
"Warning: large centroid shift in CrudeMeasure\n";
322 dbg<<
"Old centroid = "<<
_cen<<
", new centroid = "<<cenNew<<std::endl;
323 cenNew =
_cen + 2.*(cenNew -
_cen)/std::abs(cenNew-
_cen);
324 dbg<<
"Scaling back to "<<cenNew<<std::endl;
327 if (std::abs(muNew-
real(
_mu)) > 2.) {
328 dbg<<
"Warning: large scale change in CrudeMeasure\n";
329 dbg<<
"Old mu = "<<
_mu<<
", new mu = "<<muNew<<std::endl;
331 dbg<<
"Scaling back to "<<muNew<<std::endl;
334 xdbg<<
"Crude cen = "<<cenNew<<std::endl;
335 xdbg<<
"Crude mu = "<<muNew<<std::endl;
342 const std::vector<PixelList>& pix,
double sigma)
345 const int nPixList = pix.size();
346 for(
int i=0;i<nPixList;++i) nPix += pix[i].size();
348 for(
int i=0,k=0;i<nPixList;++i)
349 for(
size_t j=0;j<pix[i].size();++j,++k)
350 allPix[k] = pix[i][j];
357 std::complex<double> zPeak = 0.;
358 const int nPix = pix.
size();
359 for(
int i=0;i<nPix;++i)
if (std::abs(pix[i].getPos()) < maxR) {
360 if (pix[i].getFlux() > IPeak) {
361 zPeak = pix[i].getPos();
362 IPeak = pix[i].getFlux();
Eigen::VectorXcd CDVector
virtual void noUseCholesky()
virtual void setTau(double tau)
virtual bool solve(DVector &x, DVector &f) const
virtual void setOutput(std::ostream &os)
void crudeMeasure(const PixelList &pix, double sigma)
afw::table::Key< double > sigma
void peakCentroid(const PixelList &pix, double maxr)
void calculateJ(const DVector &x, const DVector &f, DMatrix &df) const
virtual void setTol(double fTol, double gTol)
virtual void setDelta0(double delta0)
virtual void setFTol(double fTol)
virtual void setMinStep(double minStep)
CrudeSolver(const PixelList &pix, double sigma, double I1, DVector &xinit)
std::complex< double > _cen
void calculateF(const DVector &x, DVector &f) const
std::ostream *const dbgout
#define EIGEN_Transpose(m)
std::complex< double > _mu