30 #include "boost/format.hpp"
32 #include "wcslib/wcs.h"
33 #include "wcslib/wcsfix.h"
34 #include "wcslib/wcshdr.h"
50 namespace except = lsst::pex::exceptions;
52 namespace afwCoord = lsst::afw::coord;
53 namespace afwGeom = lsst::afw::geom;
89 daf::base::Citizen(typeid(this)),
90 _wcsInfo(NULL), _nWcsInfo(0), _relax(0), _wcsfixCtrl(0), _wcshdrCtrl(0), _nReject(0),
91 _coordSystem(static_cast<afwCoord::
CoordSystem>(-1)) {
100 daf::base::Citizen(typeid(this)),
107 _coordSystem(static_cast<afwCoord::
CoordSystem>(-1))
129 (
boost::format(
"Failed to setup wcs structure with wcsset. Status %d: %s") %
130 status % wcs_errmsg[status] ).str());
151 double equinox, std::string
const & raDecSys,
152 std::string
const & cunits1, std::string
const & cunits2
154 daf::base::Citizen(typeid(this)),
161 _coordSystem(static_cast<afwCoord::
CoordSystem>(-1))
185 _hackHeader = _constHeader->deepCopy();
186 _constHeader = _hackHeader;
193 _constHeader(header), _hackHeader() {}
200 HeaderAccess access(header);
207 std::string
const& key =
"EQUINOX";
208 if (access.toRead()->exists(key) && access.toRead()->typeOf(key) ==
typeid(std::string)) {
209 auto equinoxStr = access.toRead()->getAsString(key).c_str();
210 double equinox = ::atof(equinoxStr[0] ==
'J' ? equinoxStr + 1 : equinoxStr);
211 access.toWrite()->set(key, equinox);
218 string msg =
"Could not parse FITS WCS: no header cards found";
219 throw LSST_EXCEPT(except::InvalidParameterError, msg);
225 if( !access.toRead()->exists(
"CRPIX1") && !access.toRead()->exists(
"CRPIX1a")) {
226 string msg =
"Neither CRPIX1 not CRPIX1a found";
227 throw LSST_EXCEPT(except::InvalidParameterError, msg);
230 if( !access.toRead()->exists(
"CRPIX2") && !access.toRead()->exists(
"CRPIX2a")) {
231 string msg =
"Neither CRPIX2 not CRPIX2a found";
232 throw LSST_EXCEPT(except::InvalidParameterError, msg);
236 if( !access.toRead()->exists(
"CRVAL1") && !access.toRead()->exists(
"CRVAL1a")) {
237 string msg =
"Neither CRVAL1 not CRVAL1a found";
238 throw LSST_EXCEPT(except::InvalidParameterError, msg);
241 if( !access.toRead()->exists(
"CRVAL2") && !access.toRead()->exists(
"CRVAL2a")) {
242 string msg =
"Neither CRVAL2 not CRVAL2a found";
243 throw LSST_EXCEPT(except::InvalidParameterError, msg);
253 if(access.toRead()->exists(
"CD1_1") || access.toRead()->exists(
"CD1_2") ||
254 access.toRead()->exists(
"CD2_1") || access.toRead()->exists(
"CD2_2")) {
255 for (
int i = 1; i <= 2; ++i) {
256 for (
int j = 1; j <= 2; ++j) {
258 if (access.toRead()->exists(key)) {
259 double const val = access.toRead()->getAsDouble(key);
260 access.toWrite()->remove(key);
261 access.toWrite()->add(
"X_" + key, val);
265 if (access.toRead()->exists(key)) {
266 double const val = access.toRead()->getAsDouble(key);
267 access.toWrite()->remove(key);
268 access.toWrite()->add(
"X_" + key, val);
278 char *hdrString =
const_cast<char*
>(metadataStr.c_str());
284 if (pihStatus != 0) {
286 (
boost::format(
"Could not parse FITS WCS: wcspih status = %d (%s)") %
287 pihStatus % wcs_errmsg[pihStatus]).str());
291 const int *naxes = NULL;
294 if (fixStatus != 0) {
295 std::stringstream errStream;
296 errStream <<
"Could not parse FITS WCS: wcsfix failed " << std::endl;
297 for (
int ii = 0; ii < NWCSFIX; ++ii) {
298 if (stats[ii] >= 0) {
299 errStream <<
"\t" << ii <<
": " << stats[ii] <<
" " << wcsfix_errmsg[stats[ii]] << std::endl;
301 errStream <<
"\t" << ii <<
": " << stats[ii] << std::endl;
309 if (!(access.toRead()->exists(
"RADESYS") || access.toRead()->exists(
"RADESYSa"))) {
312 if (access.toRead()->exists(
"RADECSYS")) {
313 strncpy(
_wcsInfo->radesys, access.toRead()->getAsString(
"RADECSYS").c_str(),
STRLEN);
314 }
else if (access.toRead()->exists(
"EQUINOX") || access.toRead()->exists(
"EQUINOXa")) {
315 std::string
const EQUINOX = access.toRead()->exists(
"EQUINOX") ?
"EQUINOX" :
"EQUINOXa";
316 double const equinox = access.toRead()->getAsDouble(EQUINOX);
329 for(
int i = strlen(
_wcsInfo->radesys) - 1; i >= 0; i--) {
330 if (isspace(
_wcsInfo->radesys[i])) {
340 double const *cdelt =
_wcsInfo->cdelt;
344 cd[0] = cdelt[0]*pc[0];
345 cd[1] = cdelt[0]*pc[1];
346 cd[2] = cdelt[1]*pc[2];
347 cd[3] = cdelt[1]*pc[3];
363 double equinox, std::string
const & raDecSys,
364 std::string
const & cunits1, std::string
const & cunits2) {
367 if( (CD.rows() != 2) || (CD.cols() != 2) ) {
368 string msg =
"CD is not a 2x2 matrix";
369 throw LSST_EXCEPT(except::InvalidParameterError, msg);
373 bool isValid = (cunits1 ==
"deg");
374 isValid |= (cunits1 ==
"arcmin");
375 isValid |= (cunits1 ==
"arcsec");
376 isValid |= (cunits1 ==
"mas");
379 string msg =
"CUNITS1 must be one of {deg|arcmin|arcsec|mas}";
380 throw LSST_EXCEPT(except::InvalidParameterError, msg);
383 isValid = (cunits2 ==
"deg");
384 isValid |= (cunits2 ==
"arcmin");
385 isValid |= (cunits2 ==
"arcsec");
386 isValid |= (cunits2 ==
"mas");
389 string msg =
"CUNITS2 must be one of {deg|arcmin|arcsec|mas}";
390 throw LSST_EXCEPT(except::InvalidParameterError, msg);
394 _wcsInfo =
static_cast<struct wcsprm *
>(malloc(
sizeof(
struct wcsprm)));
396 throw LSST_EXCEPT(except::MemoryError,
"Cannot allocate WCS info");
403 (
boost::format(
"Failed to allocate memory with wcsini. Status %d: %s") %
404 status % wcs_errmsg[status] ).str());
415 for (
int i=0; i<2; ++i) {
416 for (
int j=0; j<2; ++j) {
446 (
boost::format(
"Failed to setup wcs structure with wcsset. Status %d: %s") %
447 status % wcs_errmsg[status] ).str());
455 daf::base::Citizen(typeid(this)),
457 _nWcsInfo(rhs._nWcsInfo),
459 _wcsfixCtrl(rhs._wcsfixCtrl),
460 _wcshdrCtrl(rhs._wcshdrCtrl),
461 _nReject(rhs._nReject),
462 _coordSystem(static_cast<afwCoord::
CoordSystem>(-1))
466 _wcsInfo =
static_cast<struct wcsprm *
>(calloc(rhs.
_nWcsInfo,
sizeof(
struct wcsprm)));
468 throw LSST_EXCEPT(lsst::pex::exceptions::MemoryError,
"Cannot allocate WCS info");
473 for (
int i = 0; i != rhs.
_nWcsInfo; ++i) {
477 throw LSST_EXCEPT(lsst::pex::exceptions::MemoryError,
478 (
boost::format(
"Could not copy WCS: wcscopy status = %d : %s") %
479 status % wcs_errmsg[status]).str());
487 if (&other ==
this)
return true;
498 inline bool compareArrays(
double const * a,
double const *
b,
int n) {
499 for (
int i = 0; i < n; ++i)
if (a[i] != b[i])
return false;
503 template <
typename T>
504 inline bool compareStringArrays(T a, T b,
int n) {
505 for (
int i = 0; i < n; ++i)
if (strcmp(a[i], b[i]) != 0)
return false;
509 #define CHECK_NULLS(a, b) \
512 if ((b) == NULL) return true; \
515 if ((b) == NULL) return false; \
582 for (
int i=0; i< naxis; ++i){
583 for (
int j=0; j<naxis; ++j) {
584 C(i,j) =
_wcsInfo->cd[ (i*naxis) + j ];
617 while (nQuarter < 0 ) {
635 switch (nQuarter%4) {
643 _wcsInfo->crpix[0] = -crpy + dimensions.getY() + 1;
651 _wcsInfo->crpix[0] = -crpx + dimensions.getX() + 1;
652 _wcsInfo->crpix[1] = -crpy + dimensions.getY() + 1;
660 _wcsInfo->crpix[1] = -crpx + dimensions.getX() + 1;
682 throw(
LSST_EXCEPT(except::RuntimeError,
"Wcs CD matrix is singular"));
688 static double square(
double x) {
699 const double side = 1;
718 double area = sqrt(square(dx[1]*dy[2] - dx[2]*dy[1]) +
719 square(dx[2]*dy[0] - dx[0]*dy[2]) +
720 square(dx[0]*dy[1] - dx[1]*dy[0]));
722 return area / square(side) * square(180. /
afwGeom::PI);
752 status = wcss2p(
_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
755 (
boost::format(
"sky coordinates %s, %s degrees is not valid for this WCS")
762 (
boost::format(
"Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
801 skyTmp[
_wcsInfo->lng] = sky->getLongitude().asDegrees();
802 skyTmp[
_wcsInfo->lat] = sky->getLatitude() .asDegrees();
807 imgcrd[0] = imgcrd[1] = -1e6;
812 status = wcss2p(
_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
815 (
boost::format(
"Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
816 status % skyTmp[0] % skyTmp[1] % wcs_errmsg[status]).str());
843 status = wcsp2s(
_wcsInfo, 1, 2, pixTmp, imgcrd, &phi, &theta, sky, &status);
846 (
boost::format(
"Error: wcslib returned a status code of %d at pixel %s, %s: %s") %
847 status % pixel1 % pixel2 % wcs_errmsg[status]).str());
855 return pixelToSky(pixel.getX(), pixel.getY());
882 int const ncompare = 4;
887 if (strncmp(type,
"RA--", ncompare) == 0) {
889 if(strcmp(radesys,
"ICRS") == 0) {
892 if(strcmp(radesys,
"FK5") == 0) {
896 (
boost::format(
"Can't create Coord object: Unrecognised radesys %s") %
900 }
else if (strncmp(type,
"GLON", ncompare) == 0) {
902 }
else if (strncmp(type,
"ELON", ncompare) == 0) {
904 }
else if (strncmp(type,
"DEC-", ncompare) == 0) {
908 if(strcmp(radesys,
"ICRS") == 0) {
911 if(strcmp(radesys,
"FK5") == 0) {
915 (
boost::format(
"Can't create Coord object: Unrecognised radesys %s") %
918 }
else if (strncmp(type,
"GLAT", ncompare) == 0) {
920 }
else if (strncmp(type,
"ELAT", ncompare) == 0) {
925 (
boost::format(
"Can't create Coord object: Unrecognised sys %s") %
961 const double side = 10;
963 typedef std::pair<lsst::afw::geom::Angle, lsst::afw::geom::Angle> AngleAngle;
968 m(0, 0) = dsky10.first.asAngularUnits(skyUnit)/side;
969 m(0, 1) = dsky01.first.asAngularUnits(skyUnit)/side;
970 m(1, 0) = dsky10.second.asAngularUnits(skyUnit)/side;
971 m(1, 1) = dsky01.second.asAngularUnits(skyUnit)/side;
973 Eigen::Vector2d sky00v;
974 sky00v << sky00.getX(), sky00.getY();
975 Eigen::Vector2d pix00v;
976 pix00v << pix00.getX(), pix00.getY();
1015 namespace lsst {
namespace afw {
namespace image {
1020 explicit WcsFactory(std::string
const &
name) : table::io::PersistableFactory(name) {}
1023 InputArchive const & archive,
1024 CatalogVector const & catalogs
1033 struct WcsPersistenceHelper :
private boost::noncopyable {
1037 table::Key< table::Array<double> >
cd;
1045 static WcsPersistenceHelper
const &
get() {
1046 static WcsPersistenceHelper instance;
1051 WcsPersistenceHelper() :
1053 crval(table::PointKey<double>::addFields(
schema,
"crval",
"celestial reference point",
"degrees")),
1054 crpix(table::PointKey<double>::addFields(
schema,
"crpix",
"pixel reference point",
"pixels")),
1055 cd(
schema.addField< table::Array<double> >(
1056 "cd",
"linear transform matrix, ordered (1_1, 2_1, 1_2, 2_2)", 4)),
1057 ctype1(
schema.addField< std::string >(
"ctype1",
"coordinate type", 72)),
1058 ctype2(
schema.addField< std::string >(
"ctype2",
"coordinate type", 72)),
1059 equinox(
schema.addField< double >(
"equinox",
"equinox of coordinates")),
1060 radesys(
schema.addField< std::string >(
"radesys",
"coordinate system for equinox", 72)),
1061 cunit1(
schema.addField< std::string >(
"cunit1",
"coordinate units", 72)),
1062 cunit2(
schema.addField< std::string >(
"cunit2",
"coordinate units", 72))
1064 schema.getCitizen().markPersistent();
1068 std::string getWcsPersistenceName() {
return "Wcs"; }
1070 WcsFactory registration(getWcsPersistenceName());
1079 WcsPersistenceHelper
const & keys = WcsPersistenceHelper::get();
1083 record->set(keys.crpix, getPixelOrigin());
1084 Eigen::Matrix2d cdIn = getCDMatrix();
1085 Eigen::Map<Eigen::Matrix2d> cdOut((*record)[keys.cd].getData());
1087 record->set(keys.ctype1, std::string(_wcsInfo[0].ctype[0]));
1088 record->set(keys.ctype2, std::string(_wcsInfo[0].ctype[1]));
1089 record->set(keys.equinox, _wcsInfo[0].equinox);
1090 record->set(keys.radesys, std::string(_wcsInfo[0].radesys));
1091 record->set(keys.cunit1, std::string(_wcsInfo[0].cunit[0]));
1092 record->set(keys.cunit2, std::string(_wcsInfo[0].cunit[1]));
1097 if (_wcsInfo[0].naxis != 2)
return false;
1098 if (std::strcmp(_wcsInfo[0].cunit[0],
"deg") != 0)
return false;
1099 if (std::strcmp(_wcsInfo[0].cunit[1],
"deg") != 0)
return false;
1105 if (!_mayBePersistable()) {
1113 daf::base::Citizen(typeid(this)),
1120 _coordSystem(static_cast<afw::coord::
CoordSystem>(-1))
1122 WcsPersistenceHelper
const & keys = WcsPersistenceHelper::get();
1125 afw::table::io::MalformedArchiveError,
1126 "Incorrect schema for Wcs persistence"
1130 Eigen::Matrix2d
cd = Eigen::Map<Eigen::Matrix2d const>(record[keys.cd].getData());
1132 record.
get(keys.crval), record.
get(keys.crpix),
cd,
1133 record.
get(keys.ctype1), record.
get(keys.ctype2),
1134 record.
get(keys.equinox), record.
get(keys.radesys),
1135 record.
get(keys.cunit1), record.
get(keys.cunit2)
1142 WcsPersistenceHelper
const & keys = WcsPersistenceHelper::get();
1146 PTR(
Wcs) result(
new Wcs(catalogs.front().front()));
1193 wcsMetaData->set(
"CRVAL1" + wcsName, x0,
"Column pixel of Reference Pixel");
1194 wcsMetaData->set(
"CRVAL2" + wcsName, y0,
"Row pixel of Reference Pixel");
1195 wcsMetaData->set(
"CRPIX1" + wcsName, 1,
"Column Pixel Coordinate of Reference");
1196 wcsMetaData->set(
"CRPIX2" + wcsName, 1,
"Row Pixel Coordinate of Reference");
1197 wcsMetaData->set(
"CTYPE1" + wcsName,
"LINEAR",
"Type of projection");
1198 wcsMetaData->set(
"CTYPE2" + wcsName,
"LINEAR",
"Type of projection");
1199 wcsMetaData->set(
"CUNIT1" + wcsName,
"PIXEL",
"Column unit");
1200 wcsMetaData->set(
"CUNIT2" + wcsName,
"PIXEL",
"Row unit");
1221 if (metadata->
getAsDouble(
"CRPIX1" + wcsName) == 1 &&
1224 x0 = metadata->
getAsInt(
"CRVAL1" + wcsName);
1225 y0 = metadata->
getAsInt(
"CRVAL2" + wcsName);
1229 metadata->
remove(
"CRVAL1" + wcsName);
1230 metadata->
remove(
"CRVAL2" + wcsName);
1231 metadata->
remove(
"CRPIX1" + wcsName);
1232 metadata->
remove(
"CRPIX2" + wcsName);
1233 metadata->
remove(
"CTYPE1" + wcsName);
1234 metadata->
remove(
"CTYPE1" + wcsName);
1235 metadata->
remove(
"CUNIT1" + wcsName);
1236 metadata->
remove(
"CUNIT2" + wcsName);
1238 }
catch(lsst::pex::exceptions::NotFoundError &) {
1258 std::vector<std::string> paramNames = wcsMetadata->paramNames();
1259 paramNames.push_back(
"CDELT1");
1260 paramNames.push_back(
"CDELT2");
1261 paramNames.push_back(
"LTV1");
1262 paramNames.push_back(
"LTV2");
1263 paramNames.push_back(
"PC001001");
1264 paramNames.push_back(
"PC001002");
1265 paramNames.push_back(
"PC002001");
1266 paramNames.push_back(
"PC002002");
1267 for (std::vector<std::string>::const_iterator ptr = paramNames.begin(); ptr != paramNames.end(); ++ptr) {
1285 : XYTransform(), _dst(dst), _src(src)
1291 return boost::make_shared<XYTransformFromWcsPair>(_dst->clone(), _src->clone());
1304 return _dst->skyToPixel(*
x);
1310 return _src->skyToPixel(*
x);
1316 return boost::make_shared<XYTransformFromWcsPair> (_src, _dst);
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
geom::Point2I getImageXY0FromMetadata(std::string const &wcsName, lsst::daf::base::PropertySet *metadata)
const int lsstToFitsPixels
boost::shared_ptr< Coord > Ptr
Schema getSchema() const
Return the Schema that holds this record's fields and keys.
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
table::Key< std::string > name
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
geom::AffineTransform linearizePixelToSky(coord::Coord const &coord, geom::AngleUnit skyUnit=geom::degrees) const
Return the local linear approximation to Wcs::pixelToSky at a point given in sky coordinates.
WcsFactory(std::string const &name)
table::Key< table::Array< double > > cd
An object passed to Persistable::write to allow it to persist itself.
virtual void remove(std::string const &name)
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
AngleUnit const radians
constant with units of radians
virtual void pixelToSkyImpl(double pixel1, double pixel2, geom::Angle skyTmp[2]) const
coord::CoordSystem _coordSystem
A custom container class for records, based on std::vector.
Class for storing ordered metadata with comments.
boost::shared_ptr< Wcs > Ptr
A base class for factory classes used to reconstruct objects from records.
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g. RA/dec) to pixel positions.
afw::coord::Coord::Ptr convertCoordToSky(coord::Coord const &coord) const
std::pair< lsst::afw::geom::Angle, lsst::afw::geom::Angle > getTangentPlaneOffset(Coord const &c) const
Get the offset on the tangent plane.
virtual bool _isSubset(Wcs const &other) const
lsst::afw::geom::Point2D GeomPoint
afw::coord::Coord::Ptr makeCorrectCoord(geom::Angle sky0, geom::Angle sky1) const
Given a sky position, use the values stored in ctype and radesys to return the correct sub-class of C...
void initWcsLibFromFits(boost::shared_ptr< lsst::daf::base::PropertySet const > const &fitsMetadata)
Parse a fits header, extract the relevant metadata and create a Wcs object.
table::PointKey< double > crval
void initWcsLib(geom::Point2D const &crval, geom::Point2D const &crpix, Eigen::Matrix2d const &CD, std::string const &ctype1, std::string const &ctype2, double equinox, std::string const &raDecSys, std::string const &cunits1, std::string const &cunits2)
Manually initialise a wcs struct using values passed by the constructor.
virtual geom::AffineTransform linearizeSkyToPixelInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
table::Key< std::string > radesys
geom::Point2D skyToIntermediateWorldCoord(coord::Coord const &coord) const
Convert from sky coordinates (e.g. RA/dec) to intermediate world coordinates.
virtual Ptr clone(void) const
Implementation of the WCS standard for a any projection.
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g. RA/dec)
lsst::daf::base::PropertyList PropertyList
table::Key< std::string > ctype2
A class used to convert scalar POD types such as double to Angle.
virtual void shiftReferencePixel(double dx, double dy)
Move the pixel reference position by (dx, dy)
boost::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
virtual geom::Point2D skyToPixelImpl(geom::Angle sky1, geom::Angle sky2) const
table::Key< table::Array< Kernel::Pixel > > image
A base class for objects that can be persisted via afw::table::io Archive classes.
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
lsst::daf::base::PropertySet PropertySet
virtual std::string getPythonModule() const
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
virtual boost::shared_ptr< lsst::daf::base::PropertyList > getFitsMetadata() const
Return a PropertyList containing FITS header keywords that can be used to save the Wcs...
int getAsInt(std::string const &name) const
afw::table::PointKey< int > dimensions
int contains(Schema const &other, int flags=EQUAL_KEYS) const
Test whether the given schema is a subset of this.
virtual bool isPersistable() const
Whether the Wcs is persistable using afw::table::io archives.
boost::shared_ptr< PropertyList > Ptr
virtual void rotateImageBy90(int nQuarter, lsst::afw::geom::Extent2I dimensions) const
Rotate image by nQuarter times 90 degrees.
table::Key< double > equinox
bool operator==(Wcs const &other) const
#define CHECK_NULLS(a, b)
Eigen::Matrix2d getCDMatrix() const
Returns the CD matrix.
geom::Angle pixelScale() const
Returns the pixel scale [Angle/pixel].
lsst::afw::geom::Point2D getPixelOrigin() const
Returns CRPIX (corrected to LSST convention).
const int fitsToLsstPixels
Coord::Ptr makeCoord(CoordSystem const system, lsst::afw::geom::Angle const ra, lsst::afw::geom::Angle const dec, double const epoch)
Factory function to create a Coord of arbitrary type with decimal RA,Dec.
virtual void flipImage(int flipLR, int flipTB, lsst::afw::geom::Extent2I dimensions) const
Flip CD matrix around the y-axis.
boost::shared_ptr< lsst::daf::base::PropertyList > createTrivialWcsAsPropertySet(std::string const &wcsName, int const x0=0, int const y0=0)
lsst::afw::coord::Coord::Ptr getSkyOrigin() const
Returns CRVAL. This need not be the centre of the image.
virtual geom::AffineTransform linearizePixelToSkyInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
void shift(Extent< T, N > const &offset)
Shift the point by the given offset.
lsst::afw::image::Wcs Wcs
#define LSST_EXCEPT(type,...)
A vector of catalogs used by Persistable.
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Base class for all records.
geom::LinearTransform getLinearTransform() const
Wcs()
Construct an invalid Wcs given no arguments.
double getAsDouble(std::string const &name) const
const double PixelZeroPos
FITS uses 1.0, SDSS uses 0.5, LSST uses 0.0 (http://dev.lsstcorp.org/trac/wiki/BottomLeftPixelProposa...
Class for storing generic metadata.
double pixArea(lsst::afw::geom::Point2D pix00) const
Sky area covered by a pixel at position pix00 in units of square degrees.
geom::AffineTransform linearizeSkyToPixel(coord::Coord const &coord, geom::AngleUnit skyUnit=geom::degrees) const
Return the local linear approximation to Wcs::skyToPixel at a point given in sky coordinates.
afw::table::Key< double > b
lsst::afw::image::XYTransformFromWcsPair XYTransformFromWcsPair
table::Key< std::string > cunit1
Point< double, 2 > Point2D
CoordSystem makeCoordEnum(std::string const system)
A utility function to get the enum value of a coordinate system from a string name.
table::PointKey< int > pixel
double const PI
The ratio of a circle's circumference to diameter.
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
Coord::Ptr convert(CoordSystem system) const
Convert to a specified Coord type.
int stripWcsKeywords(boost::shared_ptr< lsst::daf::base::PropertySet > const &metadata, boost::shared_ptr< Wcs const > const &wcs)
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
lsst::afw::coord::Coord::Ptr CoordPtr
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
table::Key< std::string > ctype1
lsst::afw::geom::Point2D getPosition(lsst::afw::geom::AngleUnit unit=lsst::afw::geom::degrees) const
Return our contents in a Point2D object.
bool _mayBePersistable() const
Perform basic checks on whether *this might be persistable.
Include files required for standard LSST Exception handling.
table::Key< std::string > cunit2
table::PointKey< double > crpix
Functions to handle coordinates.