31 #include "boost/format.hpp"
33 #include "wcslib/wcs.h"
34 #include "wcslib/wcsfix.h"
35 #include "wcslib/wcshdr.h"
51 namespace except = lsst::pex::exceptions;
53 namespace afwCoord = lsst::afw::coord;
54 namespace afwGeom = lsst::afw::geom;
90 daf::base::Citizen(typeid(this)),
91 _wcsInfo(NULL), _nWcsInfo(0), _relax(0), _wcsfixCtrl(0), _wcshdrCtrl(0), _nReject(0),
102 daf::base::Citizen(typeid(this)),
109 _coordSystem(afwCoord::
UNKNOWN)
123 std::string
ctype1 = std::string(
_wcsInfo->ctype[0]).substr(0, 4);
126 if (ctype1[0] ==
'G') {
129 }
else if (ctype1[0] ==
'E') {
143 (
boost::format(
"Failed to setup wcs structure with wcsset. Status %d: %s") %
144 status % wcs_errmsg[status] ).str());
165 double equinox, std::string
const & raDecSys,
166 std::string
const & cunits1, std::string
const & cunits2
168 daf::base::Citizen(typeid(this)),
175 _coordSystem(afwCoord::
UNKNOWN)
199 _hackHeader = _constHeader->deepCopy();
200 _constHeader = _hackHeader;
207 _constHeader(header), _hackHeader() {}
214 HeaderAccess access(header);
221 std::string
const& key =
"EQUINOX";
222 if (access.toRead()->exists(key) && access.toRead()->typeOf(key) ==
typeid(std::string)) {
223 auto equinoxStr = access.toRead()->getAsString(key).c_str();
224 double equinox = ::atof(equinoxStr[0] ==
'J' ? equinoxStr + 1 : equinoxStr);
225 access.toWrite()->set(key, equinox);
232 string msg =
"Could not parse FITS WCS: no header cards found";
233 throw LSST_EXCEPT(except::InvalidParameterError, msg);
239 if( !access.toRead()->exists(
"CRPIX1") && !access.toRead()->exists(
"CRPIX1a")) {
240 string msg =
"Neither CRPIX1 not CRPIX1a found";
241 throw LSST_EXCEPT(except::InvalidParameterError, msg);
244 if( !access.toRead()->exists(
"CRPIX2") && !access.toRead()->exists(
"CRPIX2a")) {
245 string msg =
"Neither CRPIX2 not CRPIX2a found";
246 throw LSST_EXCEPT(except::InvalidParameterError, msg);
250 if( !access.toRead()->exists(
"CRVAL1") && !access.toRead()->exists(
"CRVAL1a")) {
251 string msg =
"Neither CRVAL1 not CRVAL1a found";
252 throw LSST_EXCEPT(except::InvalidParameterError, msg);
255 if( !access.toRead()->exists(
"CRVAL2") && !access.toRead()->exists(
"CRVAL2a")) {
256 string msg =
"Neither CRVAL2 not CRVAL2a found";
257 throw LSST_EXCEPT(except::InvalidParameterError, msg);
267 if(access.toRead()->exists(
"CD1_1") || access.toRead()->exists(
"CD1_2") ||
268 access.toRead()->exists(
"CD2_1") || access.toRead()->exists(
"CD2_2")) {
269 for (
int i = 1; i <= 2; ++i) {
270 for (
int j = 1; j <= 2; ++j) {
272 if (access.toRead()->exists(key)) {
273 double const val = access.toRead()->getAsDouble(key);
274 access.toWrite()->remove(key);
275 access.toWrite()->add(
"X_" + key, val);
279 if (access.toRead()->exists(key)) {
280 double const val = access.toRead()->getAsDouble(key);
281 access.toWrite()->remove(key);
282 access.toWrite()->add(
"X_" + key, val);
292 char *hdrString =
const_cast<char*
>(metadataStr.c_str());
298 if (pihStatus != 0) {
300 (
boost::format(
"Could not parse FITS WCS: wcspih status = %d (%s)") %
301 pihStatus % wcs_errmsg[pihStatus]).str());
305 const int *naxes = NULL;
308 if (fixStatus != 0) {
309 std::stringstream errStream;
310 errStream <<
"Could not parse FITS WCS: wcsfix failed " << std::endl;
311 for (
int ii = 0; ii < NWCSFIX; ++ii) {
312 if (stats[ii] >= 0) {
313 errStream <<
"\t" << ii <<
": " << stats[ii] <<
" " << wcsfix_errmsg[stats[ii]] << std::endl;
315 errStream <<
"\t" << ii <<
": " << stats[ii] << std::endl;
323 if (!(access.toRead()->exists(
"RADESYS") || access.toRead()->exists(
"RADESYSa"))) {
326 if (access.toRead()->exists(
"RADECSYS")) {
327 strncpy(
_wcsInfo->radesys, access.toRead()->getAsString(
"RADECSYS").c_str(),
STRLEN);
328 }
else if (access.toRead()->exists(
"EQUINOX") || access.toRead()->exists(
"EQUINOXa")) {
329 std::string
const EQUINOX = access.toRead()->exists(
"EQUINOX") ?
"EQUINOX" :
"EQUINOXa";
330 double const equinox = access.toRead()->getAsDouble(EQUINOX);
343 for(
int i = strlen(
_wcsInfo->radesys) - 1; i >= 0; i--) {
344 if (isspace(
_wcsInfo->radesys[i])) {
354 double const *cdelt =
_wcsInfo->cdelt;
358 cd[0] = cdelt[0]*pc[0];
359 cd[1] = cdelt[0]*pc[1];
360 cd[2] = cdelt[1]*pc[2];
361 cd[3] = cdelt[1]*pc[3];
377 double equinox, std::string
const & raDecSys,
378 std::string
const & cunits1, std::string
const & cunits2) {
381 if( (CD.rows() != 2) || (CD.cols() != 2) ) {
382 string msg =
"CD is not a 2x2 matrix";
383 throw LSST_EXCEPT(except::InvalidParameterError, msg);
387 bool isValid = (cunits1 ==
"deg");
388 isValid |= (cunits1 ==
"arcmin");
389 isValid |= (cunits1 ==
"arcsec");
390 isValid |= (cunits1 ==
"mas");
393 string msg =
"CUNITS1 must be one of {deg|arcmin|arcsec|mas}";
394 throw LSST_EXCEPT(except::InvalidParameterError, msg);
397 isValid = (cunits2 ==
"deg");
398 isValid |= (cunits2 ==
"arcmin");
399 isValid |= (cunits2 ==
"arcsec");
400 isValid |= (cunits2 ==
"mas");
403 string msg =
"CUNITS2 must be one of {deg|arcmin|arcsec|mas}";
404 throw LSST_EXCEPT(except::InvalidParameterError, msg);
408 _wcsInfo =
static_cast<struct wcsprm *
>(malloc(
sizeof(
struct wcsprm)));
410 throw LSST_EXCEPT(except::MemoryError,
"Cannot allocate WCS info");
417 (
boost::format(
"Failed to allocate memory with wcsini. Status %d: %s") %
418 status % wcs_errmsg[status] ).str());
429 for (
int i=0; i<2; ++i) {
430 for (
int j=0; j<2; ++j) {
460 (
boost::format(
"Failed to setup wcs structure with wcsset. Status %d: %s") %
461 status % wcs_errmsg[status] ).str());
469 daf::base::Citizen(typeid(this)),
471 _nWcsInfo(rhs._nWcsInfo),
473 _wcsfixCtrl(rhs._wcsfixCtrl),
474 _wcshdrCtrl(rhs._wcshdrCtrl),
475 _nReject(rhs._nReject),
476 _coordSystem(afwCoord::
UNKNOWN)
480 _wcsInfo =
static_cast<struct wcsprm *
>(calloc(rhs.
_nWcsInfo,
sizeof(
struct wcsprm)));
482 throw LSST_EXCEPT(lsst::pex::exceptions::MemoryError,
"Cannot allocate WCS info");
486 for (
int i = 0; i != rhs.
_nWcsInfo; ++i) {
491 throw LSST_EXCEPT(lsst::pex::exceptions::MemoryError,
492 (
boost::format(
"Could not copy WCS: wcscopy status = %d : %s") %
493 status % wcs_errmsg[status]).str());
501 if (&other ==
this)
return true;
512 inline bool compareArrays(
double const * a,
double const *
b,
int n) {
513 for (
int i = 0; i < n; ++i)
if (a[i] != b[i])
return false;
517 template <
typename T>
518 inline bool compareStringArrays(T a, T b,
int n) {
519 for (
int i = 0; i < n; ++i)
if (strcmp(a[i], b[i]) != 0)
return false;
523 #define CHECK_NULLS(a, b) \
526 if ((b) == NULL) return true; \
529 if ((b) == NULL) return false; \
596 for (
int i=0; i< naxis; ++i){
597 for (
int j=0; j<naxis; ++j) {
598 C(i,j) =
_wcsInfo->cd[ (i*naxis) + j ];
631 while (nQuarter < 0 ) {
649 switch (nQuarter%4) {
657 _wcsInfo->crpix[0] = -crpy + dimensions.getY() + 1;
665 _wcsInfo->crpix[0] = -crpx + dimensions.getX() + 1;
666 _wcsInfo->crpix[1] = -crpy + dimensions.getY() + 1;
674 _wcsInfo->crpix[1] = -crpx + dimensions.getX() + 1;
696 throw(
LSST_EXCEPT(except::RuntimeError,
"Wcs CD matrix is singular"));
702 static double square(
double x) {
713 const double side = 1;
732 double area = sqrt(square(dx[1]*dy[2] - dx[2]*dy[1]) +
733 square(dx[2]*dy[0] - dx[0]*dy[2]) +
734 square(dx[0]*dy[1] - dx[1]*dy[0]));
736 return area / square(side) * square(180. /
afwGeom::PI);
766 status = wcss2p(
_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
769 (
boost::format(
"sky coordinates %s, %s degrees is not valid for this WCS")
776 (
boost::format(
"Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
792 Wcs::convertCoordToSky(afwCoord::
Coord const & coord)
const {
793 return coord.convert(_coordSystem, _wcsInfo->equinox);
815 skyTmp[
_wcsInfo->lng] = sky->getLongitude().asDegrees();
816 skyTmp[
_wcsInfo->lat] = sky->getLatitude() .asDegrees();
821 imgcrd[0] = imgcrd[1] = -1e6;
826 status = wcss2p(
_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
829 (
boost::format(
"Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
830 status % skyTmp[0] % skyTmp[1] % wcs_errmsg[status]).str());
843 return std::numeric_limits<double>::quiet_NaN();
871 status = wcsp2s(
_wcsInfo, 1, 2, pixTmp, imgcrd, &phi, &theta, sky, &status);
874 (
boost::format(
"Error: wcslib returned a status code of %d at pixel %s, %s: %s") %
875 status % pixel1 % pixel2 % wcs_errmsg[status]).str());
883 return pixelToSky(pixel.getX(), pixel.getY());
924 (
boost::format(
"Can't create Coord object: Unrecognised coordinate system %s") %
956 const double side = 10;
958 typedef std::pair<lsst::afw::geom::Angle, lsst::afw::geom::Angle> AngleAngle;
963 m(0, 0) = dsky10.first.asAngularUnits(skyUnit)/side;
964 m(0, 1) = dsky01.first.asAngularUnits(skyUnit)/side;
965 m(1, 0) = dsky10.second.asAngularUnits(skyUnit)/side;
966 m(1, 1) = dsky01.second.asAngularUnits(skyUnit)/side;
968 Eigen::Vector2d sky00v;
969 sky00v << sky00.getX(), sky00.getY();
970 Eigen::Vector2d pix00v;
971 pix00v << pix00.getX(), pix00.getY();
1010 namespace lsst {
namespace afw {
namespace image {
1015 explicit WcsFactory(std::string
const &
name) : table::io::PersistableFactory(name) {}
1018 InputArchive const & archive,
1019 CatalogVector const & catalogs
1028 struct WcsPersistenceHelper {
1032 table::Key< table::Array<double> >
cd;
1040 static WcsPersistenceHelper
const &
get() {
1041 static WcsPersistenceHelper instance;
1046 WcsPersistenceHelper (
const WcsPersistenceHelper&) =
delete;
1047 WcsPersistenceHelper& operator=(
const WcsPersistenceHelper&) =
delete;
1050 WcsPersistenceHelper (WcsPersistenceHelper&&) =
delete;
1051 WcsPersistenceHelper& operator=(WcsPersistenceHelper&&) =
delete;
1054 WcsPersistenceHelper() :
1056 crval(table::PointKey<double>::addFields(
schema,
"crval",
"celestial reference point",
"deg")),
1057 crpix(table::PointKey<double>::addFields(
schema,
"crpix",
"pixel reference point",
"pixel")),
1058 cd(
schema.addField< table::Array<double> >(
1059 "cd",
"linear transform matrix, ordered (1_1, 2_1, 1_2, 2_2)", 4)),
1060 ctype1(
schema.addField< std::string >(
"ctype1",
"coordinate type", 72)),
1061 ctype2(
schema.addField< std::string >(
"ctype2",
"coordinate type", 72)),
1062 equinox(
schema.addField< double >(
"equinox",
"equinox of coordinates")),
1063 radesys(
schema.addField< std::string >(
"radesys",
"coordinate system for equinox", 72)),
1064 cunit1(
schema.addField< std::string >(
"cunit1",
"coordinate units", 72)),
1065 cunit2(
schema.addField< std::string >(
"cunit2",
"coordinate units", 72))
1067 schema.getCitizen().markPersistent();
1071 std::string getWcsPersistenceName() {
return "Wcs"; }
1073 WcsFactory registration(getWcsPersistenceName());
1082 WcsPersistenceHelper
const & keys = WcsPersistenceHelper::get();
1086 record->set(keys.crpix, getPixelOrigin());
1087 Eigen::Matrix2d cdIn = getCDMatrix();
1088 Eigen::Map<Eigen::Matrix2d> cdOut((*record)[keys.cd].getData());
1090 record->set(keys.ctype1, std::string(_wcsInfo[0].ctype[0]));
1091 record->set(keys.ctype2, std::string(_wcsInfo[0].ctype[1]));
1092 record->set(keys.equinox, _wcsInfo[0].equinox);
1093 record->set(keys.radesys, std::string(_wcsInfo[0].radesys));
1094 record->set(keys.cunit1, std::string(_wcsInfo[0].cunit[0]));
1095 record->set(keys.cunit2, std::string(_wcsInfo[0].cunit[1]));
1100 if (_wcsInfo[0].naxis != 2)
return false;
1101 if (std::strcmp(_wcsInfo[0].cunit[0],
"deg") != 0)
return false;
1102 if (std::strcmp(_wcsInfo[0].cunit[1],
"deg") != 0)
return false;
1108 if (!_mayBePersistable()) {
1116 daf::base::Citizen(typeid(this)),
1123 _coordSystem(static_cast<afw::coord::
CoordSystem>(-1))
1125 WcsPersistenceHelper
const & keys = WcsPersistenceHelper::get();
1128 afw::table::io::MalformedArchiveError,
1129 "Incorrect schema for Wcs persistence"
1133 Eigen::Matrix2d
cd = Eigen::Map<Eigen::Matrix2d const>(record[keys.cd].getData());
1135 record.
get(keys.crval), record.
get(keys.crpix),
cd,
1136 record.
get(keys.ctype1), record.
get(keys.ctype2),
1137 record.
get(keys.equinox), record.
get(keys.radesys),
1138 record.
get(keys.cunit1), record.
get(keys.cunit2)
1145 WcsPersistenceHelper
const & keys = WcsPersistenceHelper::get();
1149 PTR(
Wcs) result(
new Wcs(catalogs.front().front()));
1196 wcsMetaData->set(
"CRVAL1" + wcsName, x0,
"Column pixel of Reference Pixel");
1197 wcsMetaData->set(
"CRVAL2" + wcsName, y0,
"Row pixel of Reference Pixel");
1198 wcsMetaData->set(
"CRPIX1" + wcsName, 1,
"Column Pixel Coordinate of Reference");
1199 wcsMetaData->set(
"CRPIX2" + wcsName, 1,
"Row Pixel Coordinate of Reference");
1200 wcsMetaData->set(
"CTYPE1" + wcsName,
"LINEAR",
"Type of projection");
1201 wcsMetaData->set(
"CTYPE2" + wcsName,
"LINEAR",
"Type of projection");
1202 wcsMetaData->set(
"CUNIT1" + wcsName,
"PIXEL",
"Column unit");
1203 wcsMetaData->set(
"CUNIT2" + wcsName,
"PIXEL",
"Row unit");
1224 if (metadata->
getAsDouble(
"CRPIX1" + wcsName) == 1 &&
1227 x0 = metadata->
getAsInt(
"CRVAL1" + wcsName);
1228 y0 = metadata->
getAsInt(
"CRVAL2" + wcsName);
1232 metadata->
remove(
"CRVAL1" + wcsName);
1233 metadata->
remove(
"CRVAL2" + wcsName);
1234 metadata->
remove(
"CRPIX1" + wcsName);
1235 metadata->
remove(
"CRPIX2" + wcsName);
1236 metadata->
remove(
"CTYPE1" + wcsName);
1237 metadata->
remove(
"CTYPE1" + wcsName);
1238 metadata->
remove(
"CUNIT1" + wcsName);
1239 metadata->
remove(
"CUNIT2" + wcsName);
1241 }
catch(lsst::pex::exceptions::NotFoundError &) {
1261 std::vector<std::string> paramNames = wcsMetadata->paramNames();
1262 paramNames.push_back(
"CDELT1");
1263 paramNames.push_back(
"CDELT2");
1264 paramNames.push_back(
"LTV1");
1265 paramNames.push_back(
"LTV2");
1266 paramNames.push_back(
"PC001001");
1267 paramNames.push_back(
"PC001002");
1268 paramNames.push_back(
"PC002001");
1269 paramNames.push_back(
"PC002002");
1270 for (std::vector<std::string>::const_iterator ptr = paramNames.begin(); ptr != paramNames.end(); ++ptr) {
1288 : XYTransform(), _dst(dst), _src(src), _isSameSkySystem(dst->isSameSkySystem(*src))
1294 return std::make_shared<XYTransformFromWcsPair>(_dst->clone(), _src->clone());
1303 _src->pixelToSky(pixel[0], pixel[1], sky0, sky1);
1304 return _dst->skyToPixel(sky0, sky1);
1307 return _dst->skyToPixel(*coordPtr);
1316 _dst->pixelToSky(pixel[0], pixel[1], sky0, sky1);
1317 return _src->skyToPixel(sky0, sky1);
1320 return _src->skyToPixel(*coordPtr);
1327 return std::make_shared<XYTransformFromWcsPair> (_src, _dst);
const int lsstToFitsPixels
double getEquinox() const
lsst::afw::coord::Coord Coord
table::Key< std::string > name
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)
virtual void pixelToSkyImpl(double pixel1, double pixel2, geom::Angle skyTmp[2]) const
A custom container class for records, based on std::vector.
Class for storing ordered metadata with comments.
afw::table::Schema schema
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.
virtual bool _isSubset(Wcs const &other) const
lsst::afw::geom::Point2D GeomPoint
boost::shared_ptr< afw::coord::Coord > 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.
boost::shared_ptr< lsst::daf::base::PropertyList > createTrivialWcsAsPropertySet(std::string const &wcsName, int const x0, int const y0)
table::PointKey< double > crval
Point< double, 2 > Point2D
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.
std::pair< lsst::afw::geom::Angle, lsst::afw::geom::Angle > getTangentPlaneOffset(Coord const &c) const
Get the offset on the tangent plane.
virtual geom::AffineTransform linearizeSkyToPixelInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
virtual void write(OutputArchiveHandle &handle) const
Write the object to one or more catalogs.
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.
Implementation of the WCS standard for a any projection.
afw::coord::CoordSystem getCoordSystem() const
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
bool _mayBePersistable() const
Perform basic checks on whether *this might be persistable.
boost::shared_ptr< afw::coord::Coord > convertCoordToSky(coord::Coord const &coord) const
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)
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.
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...
int getAsInt(std::string const &name) const
afw::table::PointKey< int > dimensions
afwGeom::Point2I getImageXY0FromMetadata(std::string const &wcsName, lsst::daf::base::PropertySet *metadata)
double const PI
The ratio of a circle's circumference to diameter.
void shift(Extent< T, N > const &offset)
Shift the point by the given offset.
virtual void rotateImageBy90(int nQuarter, lsst::afw::geom::Extent2I dimensions) const
Rotate image by nQuarter times 90 degrees.
table::Key< double > equinox
AngleUnit const radians
constant with units of radians
bool isSameSkySystem(Wcs const &wcs) const
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].
Wcs()
Construct an invalid Wcs given no arguments.
lsst::afw::geom::Point2D getPosition(lsst::afw::geom::AngleUnit unit=lsst::afw::geom::degrees) const
Return our contents in a Point2D object.
lsst::afw::geom::Point2D getPixelOrigin() const
Returns CRPIX (corrected to LSST convention).
const int fitsToLsstPixels
virtual void flipImage(int flipLR, int flipTB, lsst::afw::geom::Extent2I dimensions) const
Flip CD matrix around the y-axis.
boost::shared_ptr< lsst::afw::coord::Coord > 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
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
lsst::afw::image::Wcs Wcs
virtual std::string getPersistenceName() const
Return the unique name used to persist this object and look up its factory.
bool _skyAxesSwapped
if true then the sky axes are swapped
#define LSST_EXCEPT(type,...)
A vector of catalogs used by Persistable.
Base class for all records.
int contains(Schema const &other, int flags=EQUAL_KEYS) const
Test whether the given schema is a subset of this.
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
geom::LinearTransform getLinearTransform() const
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
double getAsDouble(std::string const &name) const
Class for storing generic metadata.
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
boost::shared_ptr< Coord > 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.
boost::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
virtual bool isPersistable() const
Whether the Wcs is persistable using afw::table::io archives.
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
Field< T >::Value get(Key< T > const &key) const
Return the value of a field for the given key.
table::Key< std::string > cunit1
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
boost::shared_ptr< lsst::afw::coord::Coord > CoordPtr
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...
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
Include files required for standard LSST Exception handling.
int stripWcsKeywords(boost::shared_ptr< lsst::daf::base::PropertySet > const &metadata, boost::shared_ptr< Wcs const > const &wcs)
const double PixelZeroPos
FITS uses 1.0, SDSS uses 0.5, LSST uses 0.0 (http://dev.lsstcorp.org/trac/wiki/BottomLeftPixelProposa...
table::Key< std::string > ctype1
coord::CoordSystem _coordSystem
Schema getSchema() const
Return the Schema that holds this record's fields and keys.
table::Key< std::string > cunit2
table::PointKey< double > crpix
Functions to handle coordinates.