LSSTApplications  10.0+286,10.0+36,10.0+46,10.0-2-g4f67435,10.1+152,10.1+37,11.0,11.0+1,11.0-1-g47edd16,11.0-1-g60db491,11.0-1-g7418c06,11.0-2-g04d2804,11.0-2-g68503cd,11.0-2-g818369d,11.0-2-gb8b8ce7
LSSTDataManagementBasePackage
Pixel.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 
28 
29 namespace lsst {
30 namespace meas {
31 namespace algorithms {
32 namespace shapelet {
33 
34 #if 0
35  void getPixList(
36  const Image<double>& im, PixelList& pix,
37  const Position cen, double sky, double noise, double gain,
38  const Image<double>* weightImage, const Transformation& trans,
39  double aperture, double xOffset, double yOffset, long& flag)
40  {
41  xdbg<<"Start GetPixList\n";
42  if (weightImage) {
43  xdbg<<"Using weight image for pixel noise.\n";
44  } else {
45  xdbg<<"noise = "<<noise<<std::endl;
46  xdbg<<"gain = "<<gain<<std::endl;
47  }
48 
50  trans.getDistortion(cen,D);
51  // This gets us from chip coordinates to sky coordinates:
52  // ( u ) = D ( x )
53  // ( v ) ( y )
54  xdbg<<"D = "<<D<<std::endl;
55  double det = std::abs(D.TMV_det());
56  double pixScale = sqrt(det); // arsec/pixel
57  xdbg<<"pixscale = "<<pixScale<<std::endl;
58 
59  // xAp,yAp are the maximum deviation from the center in x,y
60  // such that u'^2+v'^2 = aperture^2
61  double xAp = aperture * sqrt(D(1,0)*D(1,0) + D(1,1)*D(1,1))/det;
62  double yAp = aperture * sqrt(D(0,0)*D(0,0) + D(0,1)*D(0,1))/det;
63  xdbg<<"aperture = "<<aperture<<std::endl;
64  xdbg<<"xap = "<<xAp<<", yap = "<<yAp<<std::endl;
65 
66  int xMin = im.getXMin();
67  int yMin = im.getYMin();
68 
69  double xCen = cen.getX();
70  double yCen = cen.getY();
71  xdbg<<"cen = "<<xCen<<" "<<yCen<<std::endl;
72  xdbg<<"xmin, ymin = "<<xMin<<" "<<yMin<<std::endl;
73  // xCen,yCen are given on a 1-based grid.
74  // ie. where the lower left corner pixel is (1,1), rather than (0,0).
75  // The easiest way to do this is to just decrease xCen,yCen by 1 each:
76  //--xCen; --yCen;
77  // This is now handled by parameters xOffset and yOffset, which are
78  // set from the parameters: cat_x_offset and cat_y_offset
79  xCen -= xOffset;
80  yCen -= yOffset;
81 
82  int i1 = int(floor(xCen-xAp-xMin));
83  int i2 = int(ceil(xCen+xAp-xMin));
84  int j1 = int(floor(yCen-yAp-yMin));
85  int j2 = int(ceil(yCen+yAp-yMin));
86  xdbg<<"i1,i2,j1,j2 = "<<i1<<','<<i2<<','<<j1<<','<<j2<<std::endl;
87 
88  if (i1 < 0) { i1 = 0; flag |= EDGE; }
89  if (i2 > int(im.getMaxI())) { i2 = im.getMaxI(); flag |= EDGE; }
90  if (j1 < 0) { j1 = 0; flag |= EDGE; }
91  if (j2 > int(im.getMaxJ())) { j2 = im.getMaxJ(); flag |= EDGE; }
92  xdbg<<"i1,i2,j1,j2 => "<<i1<<','<<i2<<','<<j1<<','<<j2<<std::endl;
93 
94  double apsq = aperture*aperture;
95 
96  // Do this next loop in two passes. First figure out which
97  // pixels we want to use. Then we can resize pix to the full size
98  // we will need, and go back through and enter the pixels.
99  // This saves us a lot of resizing calls in vector, which are
100  // both slow and can fragment the memory.
101  xdbg<<"nx = "<<i2-i1+1<<std::endl;
102  xdbg<<"ny = "<<j2-j1+1<<std::endl;
103  Assert(i2-i1+1 >= 0);
104  Assert(j2-j1+1 >= 0);
105  std::vector<std::vector<bool> > shouldUsePix(
106  i2-i1+1,std::vector<bool>(j2-j1+1,false));
107  int nPix = 0;
108 
109  double chipX = xMin+i1-xCen;
110  double peak = 0.;
111  for(int i=i1;i<=i2;++i,chipX+=1.) {
112  double chipY = yMin+j1-yCen;
113  double u = D(0,0)*chipX+D(0,1)*chipY;
114  double v = D(1,0)*chipX+D(1,1)*chipY;
115  for(int j=j1;j<=j2;++j,u+=D(0,1),v+=D(1,1)) {
116  double rsq = u*u+v*v;
117  if (rsq <= apsq) {
118  shouldUsePix[i-i1][j-j1] = true;
119  ++nPix;
120  if (im(i,j) > peak) peak = im(i,j);
121  }
122  }
123  }
124 
125  xdbg<<"npix = "<<nPix<<std::endl;
126  pix.resize(nPix);
127 
128  xdbg<<"pixlist size = "<<nPix<<" = "<<nPix*sizeof(Pixel)<<
129  " bytes = "<<nPix*sizeof(Pixel)/1024.<<" KB\n";
130 
131  int k=0;
132  chipX = xMin+i1-xCen;
133  xdbg<<"Bright pixels are:\n";
134  peak -= sky;
135  for(int i=i1;i<=i2;++i,chipX+=1.) {
136  double chipY = yMin+j1-yCen;
137  double u = D(0,0)*chipX+D(0,1)*chipY;
138  double v = D(1,0)*chipX+D(1,1)*chipY;
139  for(int j=j1;j<=j2;++j,u+=D(0,1),v+=D(1,1)) {
140  if (shouldUsePix[i-i1][j-j1]) {
141  double flux = im(i,j)-sky;
142  double inverseVariance;
143  if (weightImage) {
144  inverseVariance = (*weightImage)(i,j);
145  } else {
146  double var = noise;
147  if (gain != 0.) var += im(i,j)/gain;
148  inverseVariance = 1./var;
149  }
150  if (inverseVariance > 0.0) {
151  double inverseSigma = sqrt(inverseVariance);
152  Assert(k < int(pix.size()));
153  Pixel p(u,v,flux,inverseSigma);
154  pix[k++] = p;
155  if (flux > peak / 10.) {
156  xdbg<<p.getPos()<<" "<<p.getFlux()<<std::endl;
157  }
158  }
159  }
160  }
161  }
162  Assert(k <= int(pix.size()));
163  // Not necessarily == because we skip pixels with 0.0 variance
164  pix.resize(k);
165  Assert(k == int(pix.size()));
166  nPix = pix.size(); // may have changed.
167  xdbg<<"npix => "<<nPix<<std::endl;
168  if (nPix < 10) flag |= LT10PIX;
169  }
170 
171  double getLocalSky(
172  const Image<double>& bkg,
173  const Position cen, const Transformation& trans, double aperture,
174  double xOffset, double yOffset, long& flag)
175  {
176  // This function is very similar in structure to the above getPixList
177  // function. It does the same thing with the distortion and the
178  // aperture and such.
179  // The return value is the mean sky value within the aperture.
180 
181  xdbg<<"Start GetLocalSky\n";
182 
183  DSmallMatrix22 D;
184  trans.getDistortion(cen,D);
185 
186  double det = std::abs(D.TMV_det());
187  double pixScale = sqrt(det); // arcsec/pixel
188  xdbg<<"pixscale = "<<pixScale<<std::endl;
189 
190  // xAp,yAp are the maximum deviation from the center in x,y
191  // such that u^2+v^2 = aperture^2
192  double xAp = aperture / det *
193  sqrt(D(0,0)*D(0,0) + D(0,1)*D(0,1));
194  double yAp = aperture / det *
195  sqrt(D(1,0)*D(1,0) + D(1,1)*D(1,1));
196  xdbg<<"aperture = "<<aperture<<std::endl;
197  xdbg<<"xap = "<<xAp<<", yap = "<<yAp<<std::endl;
198 
199  int xMin = bkg.getXMin();
200  int yMin = bkg.getYMin();
201 
202  double xCen = cen.getX();
203  double yCen = cen.getY();
204  xdbg<<"cen = "<<xCen<<" "<<yCen<<std::endl;
205  xdbg<<"xmin, ymin = "<<xMin<<" "<<yMin<<std::endl;
206  xCen -= xOffset;
207  yCen -= yOffset;
208 
209  int i1 = int(floor(xCen-xAp-xMin));
210  int i2 = int(ceil(xCen+xAp-xMin));
211  int j1 = int(floor(yCen-yAp-yMin));
212  int j2 = int(ceil(yCen+yAp-yMin));
213  xdbg<<"i1,i2,j1,j2 = "<<i1<<','<<i2<<','<<j1<<','<<j2<<std::endl;
214  if (i1 < 0) { i1 = 0; }
215  if (i2 > int(bkg.getMaxI())) { i2 = bkg.getMaxI(); }
216  if (j1 < 0) { j1 = 0; }
217  if (j2 > int(bkg.getMaxJ())) { j2 = bkg.getMaxJ(); }
218  xdbg<<"i1,i2,j1,j2 => "<<i1<<','<<i2<<','<<j1<<','<<j2<<std::endl;
219 
220  double apsq = aperture*aperture;
221 
222  xdbg<<"nx = "<<i2-i1+1<<std::endl;
223  xdbg<<"ny = "<<j2-j1+1<<std::endl;
224  Assert(i2-i1+1 >= 0);
225  Assert(j2-j1+1 >= 0);
226 
227  double meanSky = 0.;
228  int nPix = 0;
229 
230  double chipX = xMin+i1-xCen;
231  for(int i=i1;i<=i2;++i,chipX+=1.) {
232  double chipY = yMin+j1-yCen;
233  double u = D(0,0)*chipX+D(0,1)*chipY;
234  double v = D(1,0)*chipX+D(1,1)*chipY;
235  for(int j=j1;j<=j2;++j,u+=D(0,1),v+=D(1,1)) {
236  // u,v are in arcsec
237  double rsq = u*u + v*v;
238  if (rsq <= apsq) {
239  meanSky += bkg(i,j);
240  ++nPix;
241  }
242  }
243  }
244 
245  xdbg<<"nPix = "<<nPix<<std::endl;
246  if (nPix == 0) { flag |= BKG_NOPIX; return 0.; }
247 
248  meanSky /= nPix;
249  xdbg<<"meansky = "<<meanSky<<std::endl;
250  return meanSky;
251  }
252 #endif
253 
255  PixelList& pix, const PixelList& allPix,
256  std::complex<double> cen_offset, std::complex<double> shear,
257  double aperture, long& flag)
258  {
259  // Select a subset of allPix that are within the given aperture
260  const int nTot = allPix.size();
261  xdbg<<"Start GetSubPixList\n";
262  xdbg<<"allPix has "<<nTot<<" objects\n";
263  xdbg<<"new aperture = "<<aperture<<std::endl;
264  xdbg<<"cen_offset = "<<cen_offset<<std::endl;
265  xdbg<<"shear = "<<shear<<std::endl;
266 
267  double normg = norm(shear);
268  double g1 = real(shear);
269  double g2 = imag(shear);
270  double apsq = aperture*aperture;
271 
272  // Do this next loop in two passes. First figure out which
273  // pixels we want to use. Then we can resize pix to the full size
274  // we will need, and go back through and enter the pixels.
275  // This saves us a lot of resizing calls in vector, which are
276  // both slow and can fragment the memory.
277  std::vector<bool> shouldUsePix(nTot,false);
278  int nPix = 0;
279 
280  double peak = 0.;
281  for(int i=0;i<nTot;++i) {
282  std::complex<double> z = allPix[i].getPos() - cen_offset;
283  double u = real(z);
284  double v = imag(z);
285  // (1 + |g|^2) (u^2+v^2) - 2g1 (u^2-v^2) - 2g2 (2uv)
286  // u,v are in arcsec
287  double usq = u*u;
288  double vsq = v*v;
289  double rsq = (1.+normg)*(usq+vsq) - 2.*g1*(usq-vsq) - 4.*g2*u*v;
290  rsq /= (1.-normg);
291  if (rsq <= apsq) {
292  //xdbg<<"u,v = "<<u<<','<<v<<" rsq = "<<rsq<<std::endl;
293  shouldUsePix[i] = true;
294  ++nPix;
295  if (allPix[i].getFlux() > peak) peak = allPix[i].getFlux();
296  }
297  }
298 
299  xdbg<<"npix = "<<nPix<<std::endl;
300  pix.resize(nPix);
301 
302  xdbg<<"pixlist size = "<<nPix<<" = "<<nPix*sizeof(Pixel)<<
303  " bytes = "<<nPix*sizeof(Pixel)/1024.<<" KB\n";
304 
305  int k=0;
306  xdbg<<"Bright pixels are:\n";
307  for(int i=0;i<nTot;++i) if(shouldUsePix[i]) {
308  Pixel p = allPix[i];
309  p.setPos(p.getPos() - cen_offset);
310  pix[k++] = p;
311  if (p.getFlux() > peak / 10.) {
312  xdbg<<p.getPos()<<" "<<p.getFlux()<<std::endl;
313  }
314  }
315  Assert(k == int(pix.size()));
316 
317  if (nPix < 10) flag |= LT10PIX;
318  }
319 
320 }}}}
std::complex< double > getPos() const
Definition: Pixel.h:47
T norm(const T &x)
Definition: Integrate.h:191
void setPos(const std::complex< double > &pos)
Definition: Pixel.h:53
Extent< int, N > ceil(Extent< double, N > const &input)
void getSubPixList(PixelList &pix, const PixelList &allPix, std::complex< double > cen_offset, std::complex< double > shear, double aperture, long &flag)
Definition: Pixel.cc:254
Extent< int, N > floor(Extent< double, N > const &input)
Eigen::Matrix< double, 2, 2 > DSmallMatrix22
Definition: MyMatrix.h:135
#define xdbg
Definition: dbg.h:70
T real(const T &x)
Definition: Integrate.h:193
#define Assert(x)
Definition: dbg.h:73