LSSTApplications  10.0-2-g4f67435,11.0.rc2+1,11.0.rc2+12,11.0.rc2+3,11.0.rc2+4,11.0.rc2+5,11.0.rc2+6,11.0.rc2+7,11.0.rc2+8
LSSTDataManagementBasePackage
Ellipse.cc
Go to the documentation of this file.
1 // -*- LSST-C++ -*-
2 
3 /*
4  * LSST Data Management System
5  * Copyright 2008, 2009, 2010 LSST Corporation.
6  *
7  * This product includes software developed by the
8  * LSST Project (http://www.lsst.org/).
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the LSST License Statement and
21  * the GNU General Public License along with this program. If not,
22  * see <http://www.lsstcorp.org/LegalNotices/>.
23  */
24 
25 #include <cmath>
26 #include <fstream>
27 
32 
33 namespace lsst {
34 namespace meas {
35 namespace algorithms {
36 namespace shapelet {
37 
39  std::complex<double> c1, std::complex<double> g1, std::complex<double> m1,
40  std::complex<double> c2, std::complex<double> g2, std::complex<double> m2,
41  std::complex<double>& c3, std::complex<double>& g3,
42  std::complex<double>& m3)
43  {
44  // The first set (c1,g1,m1) effect a transformation:
45  //
46  // z' = exp(-m1)/sqrt(1-|g1|^2) ( z-c1 - g1 (z-c1)* )
47  //
48  // Now execute a second transformation (c2,g2,m2):
49  //
50  // z'' = exp(-m2)/sqrt(1-|g2|^2) *
51  // [ ( exp(-m1)/sqrt(1-|g1|^2) ( z-c1 - g1 (z-c1)* ) - c2 ) -
52  // g2 * ( exp(-m1)/sqrt(1-|g1|^2) ( z-c1 - g1 (z-c1)* ) - c2 )* ]
53  //
54  // We need to figure out what this corresponds to in terms of an
55  // effective:
56  // z'' = exp(-m3)/sqrt(1-|g3|^2) ( z-c3 - g3 (z-c3)* )
57  //
58  // This is pretty complicated, but we can do it in steps.
59  //
60  // First, just take the terms with z or z*:
61  //
62  // z'' = exp(-m2)/sqrt(1-|g2|^2)/sqrt(1-|g1|^2) *
63  // ( exp(-m1) (z - g1 z*) - g2 exp(-m1*) (z* - g1* z) )
64  // = exp(-m2)/sqrt(1-|g2|^2)/sqrt(1-|g1|^2) *
65  // ( (exp(-m1) + exp(-m1*) g1* g2) z -
66  // (exp(-m1) g1 + exp(-m1*) g2) z* )
67  // = exp(-m1-m2)/sqrt(1-|g2|^2)/sqrt(1-|g1|^2)
68  // ( (1 + R g1* g2) z - (g1 + R g2) z* )
69  // where R == exp(2i imag(m1))
70  //
71  // So,
72  //
73  // g3 = (g1 + R g2) / (1 + R g1* g2)
74  // exp(-m3) = exp(-m1-m2) (1+R g1* g2) sqrt(1-|g3|^2)/
75  // sqrt(1-|g1|^2) / sqrt(1-|g2|^2)
76  //
77  // The g terms simplify (after a bit of algebra):
78  // exp(-m3) = exp(-m1-m2) (1+R g1* g2)/|1+R g1* g2|
79  //
80  // Finally, the translation terms are a bit messy.
81  // The translation terms in the equation for z'' are:
82  //
83  // exp(-m2)/sqrt(1-|g2|^2) *
84  // [ ( exp(-m1)/sqrt(1-|g1|^2) ( -c1 - g1 (-c1)* ) - c2 ) -
85  // g2 * ( exp(-m1)/sqrt(1-|g1|^2) ( -c1 - g1 (-c1)* ) - c2 )* ]
86  //
87  // This is some value, which we set equal to:
88  //
89  // exp(-m3)/sqrt(1-|g3|^2) (-c3 - g3(-c3)* )
90  //
91  // So solving for c3 - g3 c3* is straightforward.
92  // c3 - g3 c3* = X
93  // c3* - g3* c3 = X*
94  // g3 c3* - |g3|^2 c3 = g3 X*
95  // c3 - |g3|^2 c3 = X + g3 X*
96  // c3 = (X + g3 X*) / (1-|g3|^2)
97  //
98 
99  dbg<<"Start CalculateShift\n";
100  dbg<<"c1,g1,m1 = "<<c1<<" "<<g1<<" "<<m1<<std::endl;
101  dbg<<"c2,g2,m2 = "<<c2<<" "<<g2<<" "<<m2<<std::endl;
102 
103  std::complex<double> Rg2 = std::polar(1.,2*imag(m1)) * g2;
104  double normg1 = norm(g1);
105  double normg2 = norm(g2);
106  std::complex<double> denom = 1.+conj(g1)*Rg2;
107  g3 = (g1+Rg2) / denom;
108  dbg<<"g3 = "<<g3<<std::endl;
109 
110  //xdbg<<"Miralda-Escude formula gives g3 = "<<addShears(g1,g2)<<std::endl;
111 
112  m3 = m1 + m2 - std::complex<double>(0.,1.)*arg(denom);
113  dbg<<"m3 = "<<m3<<std::endl;
114 
115  std::complex<double> X = -c1 - g1 * conj(-c1);
116  X = exp(-m1)/sqrt(1.-normg1) * X - c2;
117  X = exp(-m2)/sqrt(1.-normg2) * (X - g2 * conj(X));
118  double normg3 = norm(g3);
119  X /= -exp(-m3)/sqrt(1.-normg3);
120  c3 = (X + g3*conj(X)) / (1.-normg3);
121  dbg<<"c3 = "<<c3<<std::endl;
122  }
123 
125  const std::complex<double>& c1,
126  const std::complex<double>& g1,
127  const std::complex<double>& m1)
128  {
129  // Current values are c2, g2, m2.
130  // The model is that a round galaxy is first transformed by (c1,g1,m1).
131  // And then by the current values of (c2,g2,m2).
133  }
134 
136  const std::complex<double>& c2,
137  const std::complex<double>& g2,
138  const std::complex<double>& m2)
139  {
140  // Current values are c1, g1, m1.
141  // The model is that a round galaxy is first transformed by (c1,g1,m1).
142  // And then by the provided values of (c2,g2,m2).
144  }
145 
147  {
148  // This finds the rotation-free transformation that distorts a
149  // circle to the same final shape as the current transformation does.
150  // In otherwords, we move the rotation part from the end of the
151  // transformation to the beginning, since a rotation of a circle
152  // is a null operation.
153  //
154  // z' = exp(-m-it)/sqrt(1-|g|^2) ( z-c - g (z-c)* )
155  // = exp(-m)/sqrt(1-|g|^2) (exp(-it)(z-c) - g exp(-it) (z-c)*)
156  // = exp(-m)/sqrt(1-|g|^2) (exp(-it)(z-c) - g exp(-2it) (exp(-it)(z-c))*)
157  //
158  // So, g -> g exp(-2it)
159  // c -> c exp(-it)
160  // m -> m
161  // t -> 0
162 
163  if (imag(_mu) != 0.) {
164  std::complex<double> r = std::polar(1.,-imag(_mu));
165  _gamma *= r*r;
166  _cen *= r;
167  _mu = real(_mu);
168  }
169  }
170 
171 
172 
174  const std::vector<PixelList>& pix,
175  const std::vector<BVec>& psf,
176  int order, int order2, int maxm,
177  double sigma, long& flag, double thresh, DMatrix* cov)
178  { return doMeasure(pix,&psf,order,order2,maxm,sigma,flag,thresh,cov); }
179 
181  const std::vector<PixelList>& pix,
182  int order, int order2, int maxm,
183  double sigma, long& flag, double thresh, DMatrix* cov)
184  { return doMeasure(pix,0,order,order2,maxm,sigma,flag,thresh,cov); }
185 
187  const std::vector<PixelList>& pix,
188  const std::vector<BVec>* psf, BVec& b,
189  int order, int order2, int maxm, DMatrix* bCov) const
190  {
191  xdbg<<"Start MeasureShapelet: order = "<<order<<std::endl;
192  xdbg<<"b.order, sigma = "<<b.getOrder()<<", "<<b.getSigma()<<std::endl;
193  xdbg<<"el = "<<*this<<std::endl;
194  if (maxm < 0 || maxm > order) maxm = order;
195  xdbg<<"order = "<<order<<','<<order2<<','<<maxm<<std::endl;
196 
197  // ( u )' = exp(-mu)/sqrt(1-gsq) ( 1-g1 -g2 ) ( u-uc )
198  // ( v ) ( -g2 1+g1 ) ( v-vc )
199  //
200  // z' = u' + I v'
201  // = exp(-mu)/sqrt(1-gsq)
202  // [ (1-g1)(u-uc)-g2(v-vc)-Ig2(u-uc)+I(1+g1)(v-vc) ]
203  // = exp(-mu)/sqrt(1-gsq) [ z-zc - g1(z-zc)* -Ig2(z-zc)* ]
204  // = exp(-mu)/sqrt(1-gsq) ( z-zc - g (z-zc)* )
205 
206  double sigma = b.getSigma();
207  double gsq = std::norm(_gamma);
208  Assert(gsq < 1.);
209 
210  std::complex<double> m = exp(-_mu)/sqrt(1.-gsq);
211 
212  int nTot = 0;
213  const int nExp = pix.size();
214  for(int i=0;i<nExp;++i) nTot += pix[i].size();
215  dbg<<"ntot = "<<nTot<<" in "<<nExp<<" images\n";
216 
217  DVector I(nTot);
218  DVector W(nTot);
219  CDVector Z(nTot);
220 
221  for(int k=0,n=0;k<nExp;++k) {
222  double sigma_obs =
223  psf ?
224  sqrt(pow(sigma,2)+pow((*psf)[k].getSigma(),2)) :
225  sigma;
226  dbg<<"sigma_obs["<<k<<"] = "<<sigma_obs<<std::endl;
227 
228  const int nPix = pix[k].size();
229  for(int i=0;i<nPix;++i,++n) {
230  I(n) = pix[k][i].getFlux()*pix[k][i].getInverseSigma();
231  W(n) = pix[k][i].getInverseSigma();
232  std::complex<double> z1 = pix[k][i].getPos();
233  std::complex<double> z2 = m*((z1-_cen) - _gamma*conj(z1-_cen));
234  Z(n) = z2 / sigma_obs;
235  }
236  }
237  //xdbg<<"Z = "<<Z<<std::endl;
238  //xdbg<<"I = "<<I<<std::endl;
239  //xdbg<<"W = "<<W<<std::endl;
240 
241  int bsize = (order+1)*(order+2)/2;
242  xdbg<<"bsize = "<<bsize<<std::endl;
243  int bsize2 = (order2+1)*(order2+2)/2;
244  xdbg<<"bsize2 = "<<bsize2<<std::endl;
245 
246 #ifdef USE_TMV
247  // Figure out a permutation that puts all the m <= maxm first.
248  // I don't know how to do this with Eigen, but I don't really
249  // use maxm < order on a regular basis, so only implement this for TMV.
250  tmv::Permutation P(bsize);
251  int msize = bsize;
252  if (maxm < order) {
253  tmv::Vector<double> mvals(bsize);
254  for(int n=0,k=0;n<=order;++n) {
255  for(int m=n;m>=0;m-=2) {
256  mvals[k++] = m;
257  if (m > 0) mvals[k++] = m;
258  }
259  }
260  dbg<<"mvals = "<<mvals<<std::endl;
261  mvals.sort(P);
262  dbg<<"mvals => "<<mvals<<std::endl;
263  // 00 10 10 20 20 11 30 30 21 21 40 40 31 31 22 50 50 41 41 32 32
264  // n = 0 1 2 3 4 5 6
265  // 0size = 1 1 2 2 3 3 4 = (n)/2 + 1
266  // 1size = 1 3 4 6 7 9 10 = (3*(n-1))/2 + 3
267  // 2size = 1 3 6 8 11 13 16 = (5*(n-2))/2 + 6
268  // 3size = 1 3 6 10 13 17 20 = (7*(n-3))/2 + 10
269  // nsize = (n+1)*(n+2)/2
270  // msize = (m+1)*(m+2)/2 + (2*m+1)*(n-m)/2
271  msize = (maxm+1)*(maxm+2)/2 + (2*maxm+1)*(order-maxm)/2;
272  dbg<<"msize = "<<msize<<std::endl;
273  dbg<<"mvals["<<msize-1<<"] = "<<mvals[msize-1]<<std::endl;
274  dbg<<"mvals["<<msize<<"] = "<<mvals[msize]<<std::endl;
275  Assert(mvals[msize-1] == maxm);
276  Assert(mvals[msize] == maxm+1);
277  }
278 #endif
279 
280  DMatrix A(nTot,bsize);
281  Assert(nTot >= bsize); // Should have been addressed by calling routine.
282  //xdbg<<"A = "<<A<<std::endl;
283 
284  if (psf) {
285  for(int k=0,n=0,nx;k<nExp;++k,n=nx) {
286  xdbg<<"psf = "<<(*psf)[k]<<std::endl;
287  int psforder = (*psf)[k].getOrder();
288  int newpsforder = std::max(psforder,order2);
289  xdbg<<"psforder = "<<psforder<<std::endl;
290  xdbg<<"newpsforder = "<<newpsforder<<std::endl;
291  const double psfsigma = (*psf)[k].getSigma();
292  xdbg<<"sigma = "<<psfsigma<<std::endl;
293  BVec newpsf(newpsforder,psfsigma);
294  int psfsize = (*psf)[k].size();
295  int newpsfsize = newpsf.size();
296  xdbg<<"psfsize = "<<psfsize<<std::endl;
297  bool setnew = false;
298  if (_gamma != 0.) {
299  DMatrix S(newpsfsize,psfsize);
300  calculateGTransform(_gamma,newpsforder,psforder,S);
301  newpsf.vec() = S * (*psf)[k].vec();
302  setnew = true;
303  xdbg<<"newpsf = "<<newpsf<<std::endl;
304  }
305  if (real(_mu) != 0.) {
306  if (setnew) {
307  DMatrix D(newpsfsize,newpsfsize);
308  calculateMuTransform(real(_mu),newpsforder,D);
309  newpsf.vec() = D * newpsf.vec();
310  } else {
311  DMatrix D(newpsfsize,psfsize);
312  calculateMuTransform(real(_mu),newpsforder,psforder,D);
313  newpsf.vec() = D * (*psf)[k].vec();
314  setnew = true;
315  }
316  newpsf.vec() *= exp(2.*real(_mu));
317  xdbg<<"newpsf => "<<newpsf<<std::endl;
318  }
319  if (imag(_mu) != 0.) {
320  if (setnew) {
321 #ifdef USE_TMV
322  DBandMatrix R(newpsfsize,newpsfsize,1,1);
323 #else
324  DBandMatrix R(newpsfsize,newpsfsize);
325 #endif
326  calculateThetaTransform(imag(_mu),newpsforder,R);
327  newpsf.vec() = R * newpsf.vec();
328  } else {
329 #ifdef USE_TMV
330  DBandMatrix R(newpsfsize,psfsize,1,1);
331 #else
332  DBandMatrix R(newpsfsize,psfsize);
333 #endif
334  calculateThetaTransform(imag(_mu),newpsforder,psforder,R);
335  newpsf.vec() = R * (*psf)[k].vec();
336  setnew = true;
337  }
338  xdbg<<"newpsf => "<<newpsf<<std::endl;
339  }
340  DMatrix C(bsize2,bsize);
341  if (setnew) {
342  calculatePsfConvolve(newpsf,order2,order,b.getSigma(),C);
343  } else {
344  calculatePsfConvolve((*psf)[k],order2,order,b.getSigma(),C);
345  }
346 
347  const int nPix = pix[k].size();
348  nx = n+nPix;
349  DMatrix A1(nPix,bsize2);
350  makePsi(A1,Z.TMV_subVector(n,nx),order2,&W);
351  TMV_rowRange(A,n,nx) = A1 * C;
352  }
353  } else {
354  makePsi(A,TMV_vview(Z),order,&W);
355  }
356  const double MAX_CONDITION = 1.e8;
357 
358 #ifdef USE_TMV
359  A *= P.transpose();
360  tmv::MatrixView<double> Am = A.colRange(0,msize);
361  // I used to use SVD for this, rather than the QRP decomposition.
362  // But QRP is significantly faster, and the condition estimate
363  // produced is good enough for what we need here.
364  // TODO: I need to add a real condition estimator to division methods
365  // other than SVD in TMV. LAPACK has this functionality...
366  Am.saveDiv();
367  Am.divideUsing(tmv::QRP);
368  Am.qrpd();
369  xdbg<<"R diag = "<<Am.qrpd().getR().diag()<<std::endl;
370  if (
371 #if TMV_VERSION_AT_LEAST(0,65)
372  Am.qrpd().isSingular() ||
373 #else
374  // Fixed a bug in the isSingular function in v0.65.
375  // Until that is the standard TMV version for DES, use this instead:
376  (Am.qrpd().getR().minAbs2Element() <
377  1.e-16 * Am.qrpd().getR().maxAbs2Element()) ||
378 #endif
379  DiagMatrixViewOf(Am.qrpd().getR().diag()).condition() >
380  MAX_CONDITION) {
381  dbg<<"Poor condition in MeasureShapelet: \n";
382  dbg<<"R diag = "<<Am.qrpd().getR().diag()<<std::endl;
383  dbg<<"condition = "<<
384  DiagMatrixViewOf(Am.qrpd().getR().diag()).condition()<<
385  std::endl;
386  dbg<<"det = "<<Am.qrpd().det()<<std::endl;
387  return false;
388  }
389  b.vec().subVector(0,msize) = I/Am;
390  xdbg<<"b = "<<b<<std::endl;
391  xdbg<<"Norm(I) = "<<Norm(I)<<std::endl;
392  xdbg<<"Norm(Am*b) = "<<Norm(Am*b.vec().subVector(0,msize))<<std::endl;
393  xdbg<<"Norm(I-Am*b) = "<<Norm(I-Am*b.vec().subVector(0,msize))<<std::endl;
394  b.vec().subVector(msize,bsize).setZero();
395  b.vec() = P.transpose() * b.vec();
396  xdbg<<"b => "<<b<<std::endl;
397 
398  if (bCov) {
399  bCov->setZero();
400  Am.makeInverseATA(bCov->subMatrix(0,msize,0,msize));
401  *bCov = P.transpose() * (*bCov) * P;
402  }
403 #else
404  //const double sqrtEps = sqrt(std::numeric_limits<double>::epsilon());
405  Eigen::JacobiSVD<DMatrix> svd(A, Eigen::ComputeThinU | Eigen::ComputeThinV);
406  const DVector& svd_s = svd.singularValues();
407  double max = svd_s(0);
408  double min = svd_s(svd_s.size()-1);
409  if (max > MAX_CONDITION * min) {
410  xdbg<<"Poor condition in MeasureShapelet: \n";
411  xdbg<<"svd = "<<svd_s.transpose()<<std::endl;
412  xdbg<<"condition = "<<max/min<<std::endl;
413  return false;
414  }
415  // USVtb = I
416  // b = VS^-1UtI
417  DVector temp = svd.matrixU().transpose() * I;
418  temp = svd_s.array().inverse().matrix().asDiagonal() * temp;
419  b.vec().TMV_subVector(0,bsize) = svd.matrixV() * temp;
420 
421  if (bCov) {
422  bCov->setZero();
423  // (AtA)^-1 = (VSUt USVt)^-1 = (V S^2 Vt)^-1 = V S^-2 Vt
424  DMatrix temp2 =
425  svd_s.array().square().inverse().matrix().asDiagonal() * svd.matrixV().transpose();
426  bCov->TMV_subMatrix(0,bsize,0,bsize) = svd.matrixV() * temp2;
427  }
428 #endif
429  if (!(b(0) > 0.)) {
430  dbg<<"Calculated b vector has negative b(0):\n";
431  dbg<<"b = "<<b<<std::endl;
432  return false;
433  }
434  if (order < b.getOrder()) {
435  xdbg<<"Need to zero the rest of b\n";
436  xdbg<<"bsize = "<<bsize<<" b.size = "<<b.size()<<std::endl;
437  // Zero out the rest of the shapelet vector:
438  b.vec().TMV_subVector(bsize,b.size()).setZero();
439  }
440  xdbg<<"Done measure Shapelet\n";
441  xdbg<<"b = "<<b.vec()<<std::endl;
442  return true;
443  }
444 
446  const std::vector<PixelList>& pix,
447  const std::vector<BVec>* psf, BVec& b, int order, int order2,
448  double pixScale, DMatrix* bCov) const
449  {
450  xdbg<<"Start AltMeasureShapelet: order = "<<order<<std::endl;
451  xdbg<<"b.order, sigma = "<<b.getOrder()<<", "<<b.getSigma()<<std::endl;
452  xdbg<<"el = "<<*this<<std::endl;
453  xdbg<<"pixScale = "<<pixScale<<std::endl;
454  const int nExp = pix.size();
455 
456  const int bsize = (order+1)*(order+2)/2;
457  const int bsize2 = (order2+1)*(order2+2)/2;
458  b.vec().setZero();
459  double sigma = b.getSigma();
460 
461  double gsq = std::norm(_gamma);
462  Assert(gsq < 1.);
463  std::complex<double> m = exp(-_mu)/sqrt(1.-gsq);
464 
465  std::auto_ptr<DMatrix> cov1;
466  if (bCov) {
467  bCov->setZero();
468  cov1.reset(new DMatrix(bsize2,bsize2));
469  }
470 
471  for(int k=0;k<nExp;++k) {
472  const int nPix = pix[k].size();
473  DVector I(nPix);
474  CDVector Z(nPix);
475 
476  double sigma_obs =
477  psf ?
478  sqrt(pow(sigma,2)+pow((*psf)[k].getSigma(),2)) :
479  sigma;
480  dbg<<"sigma_obs = "<<sigma_obs<<std::endl;
481 
482  DDiagMatrix normD(bsize2);
483  double val = pow(pixScale/sigma_obs,2) * exp(-2.*real(_mu)) / nExp;
484  for(int n=0,i=0;n<=order2;++n) {
485  for(int p=n,q=0;p>=q;--p,++q,++i) {
486  if (p!=q) { normD(i) = val/2.; normD(++i) = val/2.; }
487  else normD(i) = val;
488  }
489  }
490 
491  for(int i=0;i<nPix;++i) {
492  I(i) = pix[k][i].getFlux();
493  std::complex<double> z1 = pix[k][i].getPos();
494  std::complex<double> z2 = m*((z1-_cen) - _gamma*conj(z1-_cen));
495  Z(i) = z2 / sigma_obs;
496  }
497 
498  DMatrix A(nPix,bsize2);
499  makePsi(A,TMV_vview(Z),order2);
500 
501  // b = C^-1 normD At I
502  DVector b1 = A.transpose() * I;
503  dbg<<"b1 = "<<b1<<std::endl;
504  b1 = normD EIGEN_asDiag() * b1;
505  dbg<<"b1 => "<<b1<<std::endl;
506 
507  if (bCov) {
508  // cov(I) = diag(sigma_i^2)
509  // Propagate this through to cov(b1)
510  // b1 = normD At I
511  // cov1 = normD At cov(I) A normD
512  DDiagMatrix W(nPix);
513  for(int i=0;i<nPix;++i) {
514  W(i) = 1./pix[k][i].getInverseSigma();
515  }
516  DMatrix temp = normD * A.transpose() * W;
517  *cov1 = temp * temp.transpose();
518  }
519 
520  if (psf) {
521  xdbg<<"psf = "<<(*psf)[k]<<std::endl;
522  int psforder = (*psf)[k].getOrder();
523  int newpsforder = std::max(psforder,order2);
524  xdbg<<"psforder = "<<psforder<<std::endl;
525  xdbg<<"newpsforder = "<<newpsforder<<std::endl;
526  const double psfsigma = (*psf)[k].getSigma();
527  xdbg<<"sigma = "<<psfsigma<<std::endl;
528  BVec newpsf(newpsforder,psfsigma);
529  int psfsize = (*psf)[k].size();
530  int newpsfsize = newpsf.size();
531  xdbg<<"psfsize = "<<psfsize<<std::endl;
532  bool setnew = false;
533  if (_gamma != 0.) {
534  DMatrix S(newpsfsize,psfsize);
535  calculateGTransform(_gamma,newpsforder,psforder,S);
536  newpsf.vec() = S * (*psf)[k].vec();
537  setnew = true;
538  xdbg<<"newpsf = "<<newpsf<<std::endl;
539  }
540  if (real(_mu) != 0.) {
541  if (setnew) {
542  DMatrix D(newpsfsize,newpsfsize);
543  calculateMuTransform(real(_mu),newpsforder,D);
544  newpsf.vec() = D * newpsf.vec();
545  } else {
546  DMatrix D(newpsfsize,psfsize);
547  calculateMuTransform(real(_mu),newpsforder,psforder,D);
548  newpsf.vec() = D * (*psf)[k].vec();
549  setnew = true;
550  }
551  newpsf.vec() *= exp(2.*real(_mu));
552  xdbg<<"newpsf => "<<newpsf<<std::endl;
553  }
554  if (imag(_mu) != 0.) {
555  if (setnew) {
556 #ifdef USE_TMV
557  DBandMatrix R(newpsfsize,newpsfsize,1,1);
558 #else
559  DBandMatrix R(newpsfsize,newpsfsize);
560 #endif
561  calculateThetaTransform(imag(_mu),newpsforder,R);
562  newpsf.vec() = R * newpsf.vec();
563  } else {
564 #ifdef USE_TMV
565  DBandMatrix R(newpsfsize,psfsize,1,1);
566 #else
567  DBandMatrix R(newpsfsize,psfsize);
568 #endif
569  calculateThetaTransform(imag(_mu),newpsforder,psforder,R);
570  newpsf.vec() = R * (*psf)[k].vec();
571  setnew = true;
572  }
573  xdbg<<"newpsf => "<<newpsf<<std::endl;
574  }
575 
576  DMatrix C(bsize2,bsize2);
577  if (setnew) {
578  calculatePsfConvolve(newpsf,order2,b.getSigma(),C);
579  } else {
580  calculatePsfConvolve((*psf)[k],order2,b.getSigma(),C);
581  }
582 #ifdef USE_TMV
583  b1 /= C;
584 #else
585  b1 = C.lu().solve(b1);
586 #endif
587  dbg<<"b1 /= C => "<<b1<<std::endl;
588  if (bCov) *cov1 = C.inverse() * (*cov1) * C;
589  }
590  b.vec() += b1.TMV_subVector(0,bsize);
591  if (bCov) *bCov += cov1->TMV_subMatrix(0,bsize,0,bsize);
592  }
593  if (!(b(0) > 0.)) {
594  dbg<<"Calculated b vector has negative b(0):\n";
595  dbg<<"b = "<<b<<std::endl;
596  return false;
597  }
598  if (order < b.getOrder()) {
599  xdbg<<"Need to zero the rest of b\n";
600  xdbg<<"bsize = "<<bsize<<" b.size = "<<b.size()<<std::endl;
601  // Zero out the rest of the shapelet vector:
602  b.vec().TMV_subVector(bsize,b.size()).setZero();
603  }
604  xdbg<<"Done (alt) measure Shapelet\n";
605  return true;
606  }
607 
609  const std::vector<PixelList>& pix,
610  const std::vector<BVec>& psf, BVec& b,
611  int order, int order2, int maxm, DMatrix* bCov) const
612  { return doMeasureShapelet(pix,&psf,b,order,order2,maxm,bCov); }
613 
615  const std::vector<PixelList>& pix, BVec& b,
616  int order, int order2, int maxm, DMatrix* bCov) const
617  { return doMeasureShapelet(pix,0,b,order,order2,maxm,bCov); }
618 
620  const std::vector<PixelList>& pix,
621  const std::vector<BVec>& psf, BVec& b, int order, int order2,
622  double pixScale, DMatrix* bCov) const
623  { return doAltMeasureShapelet(pix,&psf,b,order,order2,pixScale,bCov); }
624 
626  const std::vector<PixelList>& pix, BVec& b, int order, int order2,
627  double pixScale, DMatrix* bCov) const
628  { return doAltMeasureShapelet(pix,0,b,order,order2,pixScale,bCov); }
629 
630 
631 }}}}
bool doMeasure(const std::vector< PixelList > &pix, const std::vector< BVec > *psf, int order, int order2, int maxm, double sigma, long &flag, double thresh, DMatrix *cov=0)
Definition: Ellipse_meas.cc:39
#define TMV_vview(v)
Definition: MyMatrix.h:202
bool doAltMeasureShapelet(const std::vector< PixelList > &pix, const std::vector< BVec > *psf, BVec &bret, int order, int order2, double pixScale, DMatrix *bcov=0) const
Definition: Ellipse.cc:445
void postShiftBy(const std::complex< double > &cen, const std::complex< double > &gamma, const std::complex< double > &mu)
Definition: Ellipse.cc:135
T norm(const T &x)
Definition: Integrate.h:191
void calculateGTransform(std::complex< double > g, int order1, int order2, DMatrix &S)
Definition: BVec.cc:468
afw::table::Key< double > sigma
Definition: GaussianPsf.cc:43
void makePsi(DMatrix &psi, CDVectorView z, int order, const DVector *coeff=0)
Definition: PsiHelper.cc:226
void preShiftBy(const std::complex< double > &cen, const std::complex< double > &gamma, const std::complex< double > &mu)
Definition: Ellipse.cc:124
bool doMeasureShapelet(const std::vector< PixelList > &pix, const std::vector< BVec > *psf, BVec &bret, int order, int order2, int maxm, DMatrix *bcov=0) const
Definition: Ellipse.cc:186
void calculateThetaTransform(double theta, int order1, int order2, DBandMatrix &R)
Definition: BVec.cc:419
#define EIGEN_asDiag()
Definition: MyMatrix.h:180
tuple m
Definition: lsstimport.py:48
bool altMeasureShapelet(const std::vector< PixelList > &pix, const std::vector< BVec > &psf, BVec &bret, int order, int order2, double pixScale, DMatrix *bcov=0) const
Definition: Ellipse.cc:619
void CalculateShift(std::complex< double > c1, std::complex< double > g1, std::complex< double > m1, std::complex< double > c2, std::complex< double > g2, std::complex< double > m2, std::complex< double > &c3, std::complex< double > &g3, std::complex< double > &m3)
Definition: Ellipse.cc:38
bool measureShapelet(const std::vector< PixelList > &pix, BVec &bret, int order, int order2, int maxm, DMatrix *bcov=0) const
Definition: Ellipse.cc:614
afw::table::Key< double > b
#define TMV_rowRange(m, i1, i2)
Definition: MyMatrix.h:204
#define xdbg
Definition: dbg.h:70
bool measure(const std::vector< PixelList > &pix, int order, int order2, int maxm, double sigma, long &flag, double thresh, DMatrix *cov=0)
Definition: Ellipse.cc:180
void calculatePsfConvolve(const BVec &bpsf, int order1, int order2, double sigma, DMatrix &C)
Definition: BVec.cc:675
#define dbg
Definition: dbg.h:69
ImageT val
Definition: CR.cc:154
T real(const T &x)
Definition: Integrate.h:193
#define Assert(x)
Definition: dbg.h:73
void calculateMuTransform(double mu, int order1, int order2, DMatrix &D)
Definition: BVec.cc:227