lsst.meas.extensions.psfex  13.0-5-gd2c5893+6
 All Classes Namespaces Files Functions Variables Friends Macros Groups
fieldImpl.cc
Go to the documentation of this file.
1 // -*- lsst-C++ -*-
2 #include <cstring>
3 #include "lsst/meas/extensions/psfex/Field.hh"
4 #include "wcslib/wcs.h"
5 #undef PI
6 #include "lsst/afw/image/Wcs.h"
7 
8 extern "C" {
9  #include "globals.h"
10 }
11 
12 namespace lsst { namespace meas { namespace extensions { namespace psfex {
13 
14 Field::Field(std::string const& ident) :
15  impl(NULL), _isInitialized(false)
16 {
17  QCALLOC(impl, fieldstruct, 1);
18  impl->next = 0;
19 
20  strcpy(impl->catname, ident.c_str());
21  impl->rcatname = impl->catname;
22 #if 0
23  strncpy(impl->rtcatname, impl->rcatname, sizeof(impl->rtcatname) - 1);
24  strncpy(impl->ident, "??", sizeof(impl->ident) - 1);
25 #elif 1
26  if (!(impl->rcatname = strrchr(impl->catname, '/'))) {
27  impl->rcatname = impl->catname;
28  } else {
29  ++impl->rcatname;
30  }
31 
32  strncpy(impl->rtcatname, impl->rcatname, sizeof(impl->rtcatname) - 1);
33  {
34  char *pstr=strrchr(impl->rtcatname, '.');
35  if (pstr) {
36  *pstr = '\0';
37  }
38  }
39 
40  strncpy(impl->ident, "??", sizeof(impl->ident) - 1);
41 #endif
42 
43  impl->ndet = 0;
44  impl->psf = NULL;
45  impl->wcs = NULL;
46 
47  _finalize();
48 }
49 
50 Field::~Field()
51 {
52  for (int i = 0; i != impl->next; ++i) {
53  free(impl->wcs[i]); // psfex's wcs isn't quite the same as ours ...
54  impl->wcs[i] = NULL; // ... so don't let psfex free it
55  }
56  field_end(impl);
57  impl = NULL;
58 }
59 
60 /************************************************************************************************************/
61 
62 void
63 Field::_finalize(bool force)
64 {
65  if (force || !_isInitialized) {
66  field_init_finalize(impl);
67  _isInitialized = true;
68  }
69 }
70 
71 /************************************************************************************************************/
72 
73 std::vector<Psf>
74 Field::getPsfs() const
75 {
76  if (_psfs.empty()) {
77  _psfs.reserve(impl->next);
78  for (int i = 0; i != impl->next; ++i) {
79  _psfs.push_back(Psf(impl->psf[i]));
80  }
81  }
82 
83  return _psfs;
84 }
85 
86 /************************************************************************************************************/
87 //
88 // This class exists solely so that I can recover the protected data member _wcsInfo
89 //
90 namespace {
91 struct PsfUnpack : private lsst::afw::image::Wcs {
92  PsfUnpack(lsst::afw::image::Wcs const& wcs) : Wcs(wcs) { }
93  const struct wcsprm* getWcsInfo() { return _wcsInfo; }
94 };
95 }
96 
97 void
98 Field::addExt(lsst::afw::image::Wcs const& wcs_,
99  int const naxis1, int const naxis2,
100  int const nobj)
101 {
102  QREALLOC(impl->psf, psfstruct *, impl->next + 1);
103  impl->psf[impl->next] = 0;
104  QREALLOC(impl->wcs, wcsstruct *, impl->next + 1);
105  impl->wcs[impl->next] = 0;
106  /*
107  * We're going to fake psfex's wcsstruct object. We only need enough of it for field_locate
108  */
109  PsfUnpack wcsUnpacked(wcs_);
110  struct wcsprm const* wcsPrm = wcsUnpacked.getWcsInfo();
111  QMALLOC(impl->wcs[impl->next], wcsstruct, 1);
112  wcsstruct *wcs = impl->wcs[impl->next];
113 
114  wcs->naxis = wcsPrm->naxis;
115  wcs->naxisn[0] = naxis1;
116  wcs->naxisn[1] = naxis2;
117 
118  for (int i = 0; i != wcs->naxis; ++i) {
119  strncpy(wcs->ctype[i], wcsPrm->ctype[i], sizeof(wcs->ctype[i]) - 1);
120  strncpy(wcs->cunit[i], wcsPrm->cunit[i], sizeof(wcs->cunit[i]) - 1);
121  wcs->crval[i] = wcsPrm->crval[i];
122 
123  wcs->cdelt[i] = wcsPrm->cdelt[i];
124  wcs->crpix[i] = wcsPrm->crpix[i];
125  wcs->crder[i] = wcsPrm->crder[i];
126  wcs->csyer[i] = wcsPrm->csyer[i];
127  wcs->crval[i] = wcsPrm->crval[i];
128  }
129  for (int i = 0; i != wcs->naxis*wcs->naxis; ++i) {
130  wcs->cd[i] = wcsPrm->cd[i];
131  }
132  wcs->longpole = wcsPrm->lonpole;
133  wcs->latpole = wcsPrm->latpole;
134  wcs->lat = wcsPrm->lat;
135  wcs->lng = wcsPrm->lng;
136  wcs->equinox = wcsPrm->equinox;
137 
138  CONST_PTR(afw::coord::Coord) center = wcs_.pixelToSky(afw::geom::Point2D(0.5*naxis1, 0.5*naxis2));
139  wcs->wcsscalepos[0] = center->getLongitude().asDegrees();
140  wcs->wcsscalepos[1] = center->getLatitude().asDegrees();
141 
142  double maxradius = 0.0; // Maximum distance to wcsscalepos
143  for (int x = 0; x <= 1; ++x) {
144  for (int y = 0; y <= 1; ++y) {
145  afw::geom::Point2D point(x*naxis1, y*naxis2); // Corner
146  double const radius = center->angularSeparation(*wcs_.pixelToSky(point)).asDegrees();
147  if (radius > maxradius) {
148  maxradius = radius;
149  }
150  }
151  }
152  wcs->wcsmaxradius = maxradius;
153 
154  impl->ndet += nobj;
155 
156  ++impl->next;
157 }
158 
159 }}}}