LSSTApplications  1.1.2+25,10.0+13,10.0+132,10.0+133,10.0+224,10.0+41,10.0+8,10.0-1-g0f53050+14,10.0-1-g4b7b172+19,10.0-1-g61a5bae+98,10.0-1-g7408a83+3,10.0-1-gc1e0f5a+19,10.0-1-gdb4482e+14,10.0-11-g3947115+2,10.0-12-g8719d8b+2,10.0-15-ga3f480f+1,10.0-2-g4f67435,10.0-2-gcb4bc6c+26,10.0-28-gf7f57a9+1,10.0-3-g1bbe32c+14,10.0-3-g5b46d21,10.0-4-g027f45f+5,10.0-4-g86f66b5+2,10.0-4-gc4fccf3+24,10.0-40-g4349866+2,10.0-5-g766159b,10.0-5-gca2295e+25,10.0-6-g462a451+1
LSSTDataManagementBasePackage
Public Types | Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Friends | List of all members
lsst.afw.image::Wcs Class Reference

Implementation of the WCS standard for a any projection. More...

#include <Wcs.h>

Inheritance diagram for lsst.afw.image::Wcs:
lsst.daf.base::Persistable lsst.daf.base::Citizen lsst.afw.table.io::PersistableFacade< Wcs > lsst.afw.table.io::Persistable lsst.afw.image::TanWcs lsst.afw.image::DistortedTanWcs

Public Types

typedef boost::shared_ptr< WcsPtr
 
typedef boost::shared_ptr< Wcs
const > 
ConstPtr
 
- Public Types inherited from lsst.daf.base::Persistable
typedef boost::shared_ptr
< Persistable
Ptr
 
- Public Types inherited from lsst.daf.base::Citizen
enum  { magicSentinel = 0xdeadbeef }
 
typedef unsigned long memId
 Type of the block's ID. More...
 
typedef memId(* memNewCallback )(const memId cid)
 A function used to register a callback. More...
 
typedef memId(* memCallback )(const Citizen *ptr)
 

Public Member Functions

 Wcs (lsst::afw::geom::Point2D const &crval, lsst::afw::geom::Point2D const &crpix, Eigen::Matrix2d const &CD, std::string const &ctype1="RA---TAN", std::string const &ctype2="DEC--TAN", double equinox=2000, std::string const &raDecSys="ICRS", std::string const &cunits1="deg", std::string const &cunits2="deg")
 Create a Wcs object with some known information. More...
 
virtual ~Wcs ()
 
virtual Ptr clone (void) const
 
bool operator== (Wcs const &other) const
 
bool operator!= (Wcs const &other) const
 
lsst::afw::coord::Coord::Ptr getSkyOrigin () const
 Returns CRVAL. This need not be the centre of the image. More...
 
lsst::afw::geom::Point2D getPixelOrigin () const
 Returns CRPIX (corrected to LSST convention). More...
 
Eigen::Matrix2d getCDMatrix () const
 Returns the CD matrix. More...
 
virtual void flipImage (int flipLR, int flipTB, lsst::afw::geom::Extent2I dimensions) const
 Flip CD matrix around the y-axis. More...
 
virtual void rotateImageBy90 (int nQuarter, lsst::afw::geom::Extent2I dimensions) const
 Rotate image by nQuarter times 90 degrees. More...
 
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.x. More...
 
bool isFlipped () const
 
double pixArea (lsst::afw::geom::Point2D pix00) const
 Sky area covered by a pixel at position pix00 in units of square degrees. More...
 
geom::Angle pixelScale () const
 Returns the pixel scale [Angle/pixel]. More...
 
boost::shared_ptr< coord::CoordpixelToSky (double pix1, double pix2) const
 Convert from pixel position to sky coordinates (e.g. RA/dec) More...
 
boost::shared_ptr< coord::CoordpixelToSky (lsst::afw::geom::Point2D const &pixel) const
 Convert from pixel position to sky coordinates (e.g. RA/dec) More...
 
void pixelToSky (double pixel1, double pixel2, geom::Angle &sky1, geom::Angle &sky2) const
 
geom::Point2D skyToPixel (geom::Angle sky1, geom::Angle sky2) const
 Convert from sky coordinates (e.g. RA/dec) to pixel positions. More...
 
geom::Point2D skyToPixel (coord::Coord const &coord) const
 Convert from sky coordinates (e.g. RA/dec) to pixel positions. More...
 
geom::Point2D skyToIntermediateWorldCoord (coord::Coord const &coord) const
 Convert from sky coordinates (e.g. RA/dec) to intermediate world coordinates. More...
 
virtual bool hasDistortion () const
 
geom::LinearTransform getLinearTransform () const
 
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. More...
 
geom::AffineTransform linearizePixelToSky (geom::Point2D const &pix, geom::AngleUnit skyUnit=geom::degrees) const
 Return the local linear approximation to Wcs::pixelToSky at a point given in pixel coordinates. More...
 
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. More...
 
geom::AffineTransform linearizeSkyToPixel (geom::Point2D const &pix, geom::AngleUnit skyUnit=geom::degrees) const
 Return the local linear approximation to Wcs::skyToPixel at a point given in pixel coordinates. More...
 
virtual void shiftReferencePixel (double dx, double dy)
 Move the pixel reference position by (dx, dy) More...
 
virtual void shiftReferencePixel (geom::Extent2D const &d)
 
virtual bool isPersistable () const
 Whether the Wcs is persistable using afw::table::io archives. More...
 
- Public Member Functions inherited from lsst.daf.base::Persistable
 Persistable (void)
 
virtual ~Persistable (void)
 
template<class Archive >
void serialize (Archive &, unsigned int const)
 
- Public Member Functions inherited from lsst.daf.base::Citizen
 Citizen (const std::type_info &)
 
 Citizen (Citizen const &)
 
 ~Citizen ()
 
Citizenoperator= (Citizen const &)
 
std::string repr () const
 Return a string representation of a Citizen. More...
 
void markPersistent (void)
 Mark a Citizen as persistent and not destroyed until process end. More...
 
memId getId () const
 Return the Citizen's ID. More...
 
- Public Member Functions inherited from lsst.afw.table.io::Persistable
void writeFits (std::string const &fileName, std::string const &mode="w") const
 Write the object to a regular FITS file. More...
 
void writeFits (fits::MemFileManager &manager, std::string const &mode="w") const
 Write the object to a FITS image in memory. More...
 
void writeFits (fits::Fits &fitsfile) const
 Write the object to an already-open FITS object. More...
 
virtual ~Persistable ()
 

Protected Member Functions

virtual std::string getPersistenceName () const
 Return the unique name used to persist this object and look up its factory. More...
 
virtual std::string getPythonModule () const
 Return the fully-qualified Python module that should be imported to guarantee that its factory is registered. More...
 
virtual void write (OutputArchiveHandle &handle) const
 Write the object to one or more catalogs. More...
 
virtual bool _isSubset (Wcs const &other) const
 
 Wcs ()
 Construct an invalid Wcs given no arguments. More...
 
 Wcs (boost::shared_ptr< lsst::daf::base::PropertySet const > const &fitsMetadata)
 
 Wcs (afw::table::BaseRecord const &record)
 
 Wcs (Wcs const &rhs)
 Copy constructor. More...
 
Wcsoperator= (const Wcs &)
 
virtual void pixelToSkyImpl (double pixel1, double pixel2, geom::Angle skyTmp[2]) const
 
virtual geom::Point2D skyToPixelImpl (geom::Angle sky1, geom::Angle sky2) const
 
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 Coord. More...
 
afw::coord::Coord::Ptr convertCoordToSky (coord::Coord const &coord) const
 
virtual geom::AffineTransform linearizePixelToSkyInternal (geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
 
virtual geom::AffineTransform linearizeSkyToPixelInternal (geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
 
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. More...
 
void _initWcs ()
 
void _setWcslibParams ()
 
- Protected Member Functions inherited from lsst.afw.table.io::Persistable
 Persistable ()
 
 Persistable (Persistable const &other)
 
void operator= (Persistable const &other)
 

Protected Attributes

struct wcsprm * _wcsInfo
 
int _nWcsInfo
 
int _relax
 Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details. More...
 
int _wcsfixCtrl
 Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes. More...
 
int _wcshdrCtrl
 Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details. More...
 
int _nReject
 
coord::CoordSystem _coordSystem
 

Private Member Functions

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. More...
 

Friends

class WcsFactory
 
Wcs::Ptr makeWcs (boost::shared_ptr< lsst::daf::base::PropertySet > const &fitsMetadata, bool stripMetadata)
 Create a Wcs of the correct class using a FITS header. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from lsst.daf.base::Citizen
static bool hasBeenCorrupted ()
 Check all allocated blocks for corruption. More...
 
static memId getNextMemId ()
 Return the memId of the next object to be allocated. More...
 
static int init ()
 Called once when the memory system is being initialised. More...
 
static int census (int, memId startingMemId=0)
 How many active Citizens are there? More...
 
static void census (std::ostream &stream, memId startingMemId=0)
 Print a list of all active Citizens to stream, sorted by ID. More...
 
static const std::vector
< const Citizen * > * 
census ()
 Return a (newly allocated) std::vector of active Citizens sorted by ID. More...
 
static memId setNewCallbackId (memId id)
 Call the NewCallback when block is allocated. More...
 
static memId setDeleteCallbackId (memId id)
 Call the current DeleteCallback when block is deleted. More...
 
static memNewCallback setNewCallback (memNewCallback func)
 Set the NewCallback function. More...
 
static memCallback setDeleteCallback (memCallback func)
 Set the DeleteCallback function. More...
 
static memCallback setCorruptionCallback (memCallback func)
 Set the CorruptionCallback function. More...
 
- Static Public Member Functions inherited from lsst.afw.table.io::PersistableFacade< Wcs >
static boost::shared_ptr< WcsreadFits (fits::Fits &fitsfile)
 Read an object from an already open FITS object. More...
 
static boost::shared_ptr< WcsreadFits (std::string const &fileName, int hdu=0)
 Read an object from a regular FITS file. More...
 
static boost::shared_ptr< WcsreadFits (fits::MemFileManager &manager, int hdu=0)
 Read an object from a FITS file in memory. More...
 
- Protected Types inherited from lsst.afw.table.io::Persistable
typedef io::OutputArchiveHandle OutputArchiveHandle
 

Detailed Description

Implementation of the WCS standard for a any projection.

Implements a single representation of the World Coordinate System of a two dimensional image The standard is defined in two papers

In its simplest sense, Wcs is used to convert from position in the sky (in right ascension and declination) to pixel position on an image (and back again). It is, however, much more general than that and can understand a myriad of different coordinate systems.

A wcs can be constructed from a reference position (crval, crpix) and a translation matrix. Alternatively, if you have the header from a FITS file, you can create a Wcs object with the makeWcs() function. This function determines whether your Wcs is one the subset of projection systems that is dealt with specially by LSST, and creates an object of the correct class. Otherwise, a pointer to a Wcs object is returned. Most astronomical images use tangent plane projection, so makeWcs() returns a TanWcs object pointer

* import lsst.afw.image as afwImg
* fitsHeader = afwImg.readMetadata(filename)
*
* if 0:
* #This doesn't work
* wcs = afwImg.Wcs(fitsHeader)
*
* wcs = afwImg.makeWcs(fitsHeader)
*
* pixelPosition = wcs.skyToPixel(ra, dec)
* skyPosition = wcs.skyToPixel(xPosition, yPosition)
*

o[ This class is implemented in by calls to the wcslib library by Mark Calabretta http://www.atnf.csiro.au/people/mcalabre/WCS/

Note that we violate the WCS standard in one minor way. The standard states that none of the CRPIX or CRVAL keywords are required, for the header to be valid, and the appropriate values should be set to 0.0 if the keywords are absent. This is a recipe for painful bugs in analysis, so we violate the standard by insisting that the keywords CRPIX[1,2] and CRVAL[1,2] are present when reading a header (keywords CRPIX1a etc are also accepted)

Definition at line 107 of file Wcs.h.

Member Typedef Documentation

typedef boost::shared_ptr<Wcs const> lsst.afw.image::Wcs::ConstPtr

Definition at line 114 of file Wcs.h.

typedef boost::shared_ptr<Wcs> lsst.afw.image::Wcs::Ptr

Definition at line 113 of file Wcs.h.

Constructor & Destructor Documentation

Wcs::Wcs ( lsst::afw::geom::Point2D const &  crval,
lsst::afw::geom::Point2D const &  crpix,
Eigen::Matrix2d const &  CD,
std::string const &  ctype1 = "RA---TAN",
std::string const &  ctype2 = "DEC--TAN",
double  equinox = 2000,
std::string const &  raDecSys = "ICRS",
std::string const &  cunits1 = "deg",
std::string const &  cunits2 = "deg" 
)

Create a Wcs object with some known information.

Parameters
crvalThe sky position of the reference point
crpixThe pixel position corresponding to crval in LSST units
CDMatrix describing transformations from pixel to sky positions
ctype1Projection system used (see description of Wcs)
ctype2Projection system used (see description of Wcs)
equinoxEquinox of coordinate system, eg 2000 (Julian) or 1950 (Besselian)
raDecSysSystem used to describe right ascension or declination, e.g FK4, FK5 or ICRS
cunits1Units of sky position. One of deg, arcmin or arcsec
cunits2Units of sky position. One of deg, arcmin or arcsec
Note
LSST units are zero indexed while FITs units are 1 indexed. So a value of crpix stored in a fits header of 127,127 corresponds to a pixel position in LSST units of 128, 128

Definition at line 148 of file Wcs.cc.

152  :
153  daf::base::Citizen(typeid(this)),
154  _wcsInfo(NULL),
155  _nWcsInfo(0),
156  _relax(0),
157  _wcsfixCtrl(0),
158  _wcshdrCtrl(0),
159  _nReject(0),
160  _coordSystem(static_cast<afwCoord::CoordSystem>(-1))
161 {
163  initWcsLib(crval, crpix, CD,
164  ctype1, ctype2,
165  equinox, raDecSys,
166  cunits1, cunits2);
167  _initWcs();
168 }
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:393
void _setWcslibParams()
Definition: Wcs.cc:68
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
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.
Definition: Wcs.cc:371
table::Key< std::string > ctype2
Definition: Wcs.cc:1045
table::Key< table::Point< double > > crval
Definition: Wcs.cc:1041
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
table::Key< double > equinox
Definition: Wcs.cc:1046
table::Key< table::Point< double > > crpix
Definition: Wcs.cc:1042
void _initWcs()
Definition: Wcs.cc:117
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:392
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:394
table::Key< std::string > ctype1
Definition: Wcs.cc:1044
Wcs::~Wcs ( )
virtual

Definition at line 555 of file Wcs.cc.

555  {
556  if (_wcsInfo != NULL) {
557  wcsvfree(&_nWcsInfo, &_wcsInfo);
558  }
559 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
lsst.afw.image::Wcs::Wcs ( )
protected

Construct an invalid Wcs given no arguments.

Definition at line 87 of file Wcs.cc.

87  :
88  daf::base::Citizen(typeid(this)),
89  _wcsInfo(NULL), _nWcsInfo(0), _relax(0), _wcsfixCtrl(0), _wcshdrCtrl(0), _nReject(0),
90  _coordSystem(static_cast<afwCoord::CoordSystem>(-1)) {
92  _initWcs();
93 }
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:393
void _setWcslibParams()
Definition: Wcs.cc:68
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
void _initWcs()
Definition: Wcs.cc:117
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:392
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:394
Wcs::Wcs ( boost::shared_ptr< lsst::daf::base::PropertySet const > const &  fitsMetadata)
protected

Create a Wcs from a fits header. Don't call this directly. Use makeWcs() instead, which will figure out which (if any) sub-class of Wcs is appropriate

Definition at line 98 of file Wcs.cc.

98  :
99  daf::base::Citizen(typeid(this)),
100  _wcsInfo(NULL),
101  _nWcsInfo(0),
102  _relax(0),
103  _wcsfixCtrl(0),
104  _wcshdrCtrl(0),
105  _nReject(0),
106  _coordSystem(static_cast<afwCoord::CoordSystem>(-1))
107 {
109 
110  initWcsLibFromFits(fitsMetadata);
111  _initWcs();
112 }
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:393
void _setWcslibParams()
Definition: Wcs.cc:68
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
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.
Definition: Wcs.cc:172
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
void _initWcs()
Definition: Wcs.cc:117
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:392
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:394
lsst.afw.image::Wcs::Wcs ( afw::table::BaseRecord const &  record)
explicitprotected

Definition at line 1109 of file Wcs.cc.

1109  :
1110  daf::base::Citizen(typeid(this)),
1111  _wcsInfo(NULL),
1112  _nWcsInfo(0),
1113  _relax(0),
1114  _wcsfixCtrl(0),
1115  _wcshdrCtrl(0),
1116  _nReject(0),
1117  _coordSystem(static_cast<afw::coord::CoordSystem>(-1))
1118 {
1119  WcsPersistenceHelper const & keys = WcsPersistenceHelper::get();
1120  if (!record.getSchema().contains(keys.schema)) {
1121  throw LSST_EXCEPT(
1122  afw::table::io::MalformedArchiveError,
1123  "Incorrect schema for Wcs persistence"
1124  );
1125  }
1126  _setWcslibParams();
1127  Eigen::Matrix2d cd = Eigen::Map<Eigen::Matrix2d const>(record[keys.cd].getData());
1128  initWcsLib(
1129  record.get(keys.crval), record.get(keys.crpix), cd,
1130  record.get(keys.ctype1), record.get(keys.ctype2),
1131  record.get(keys.equinox), record.get(keys.radesys),
1132  record.get(keys.cunit1), record.get(keys.cunit2)
1133  );
1134  _initWcs();
1135 }
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:393
table::Key< table::Array< double > > cd
Definition: Wcs.cc:1043
void _setWcslibParams()
Definition: Wcs.cc:68
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
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.
Definition: Wcs.cc:371
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
void _initWcs()
Definition: Wcs.cc:117
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:392
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:394
Wcs::Wcs ( afwImg::Wcs const &  rhs)
protected

Copy constructor.

Definition at line 464 of file Wcs.cc.

464  :
465  daf::base::Citizen(typeid(this)),
466  _wcsInfo(NULL),
467  _nWcsInfo(rhs._nWcsInfo),
468  _relax(rhs._relax),
469  _wcsfixCtrl(rhs._wcsfixCtrl),
470  _wcshdrCtrl(rhs._wcshdrCtrl),
471  _nReject(rhs._nReject),
472  _coordSystem(static_cast<afwCoord::CoordSystem>(-1))
473 {
474 
475  if (rhs._nWcsInfo > 0) {
476  _wcsInfo = static_cast<struct wcsprm *>(calloc(rhs._nWcsInfo, sizeof(struct wcsprm)));
477  if (_wcsInfo == NULL) {
478  throw LSST_EXCEPT(lsst::pex::exceptions::MemoryError, "Cannot allocate WCS info");
479  }
480 
481  _wcsInfo->flag = -1;
482  int alloc = 1; //Unconditionally allocate memory when calling
483  for (int i = 0; i != rhs._nWcsInfo; ++i) {
484  int status = wcscopy(alloc, &rhs._wcsInfo[i], &_wcsInfo[i]);
485  if (status != 0) {
486  wcsvfree(&i, &_wcsInfo);
487  throw LSST_EXCEPT(lsst::pex::exceptions::MemoryError,
488  (boost::format("Could not copy WCS: wcscopy status = %d : %s") %
489  status % wcs_errmsg[status]).str());
490  }
491  }
492  }
493  _initWcs();
494 }
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:393
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
void _initWcs()
Definition: Wcs.cc:117
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:392
int status
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:394

Member Function Documentation

void Wcs::_initWcs ( )
protected

Definition at line 117 of file Wcs.cc.

118 {
119  if (_wcsInfo) {
121 
122  // tell WCSlib that values have been updated
123  _wcsInfo->flag = 0;
124  // and then tell it to do its internal magic.
125  int status = wcsset(_wcsInfo);
126  if (status != 0) {
127  throw LSST_EXCEPT(except::RuntimeError,
128  (boost::format("Failed to setup wcs structure with wcsset. Status %d: %s") %
129  status % wcs_errmsg[status] ).str());
130  }
131  }
132 }
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int status
CoordSystem makeCoordEnum(std::string const system)
A utility function to get the enum value of a coordinate system from a string name.
Definition: Coord.cc:116
bool Wcs::_isSubset ( Wcs const &  other) const
protectedvirtual

Reimplemented in lsst.afw.image::TanWcs.

Definition at line 530 of file Wcs.cc.

530  {
531  CHECK_NULLS(_wcsInfo, rhs._wcsInfo);
532  CHECK_NULLS(_wcsInfo->crval, rhs._wcsInfo->crval);
533  CHECK_NULLS(_wcsInfo->cd, rhs._wcsInfo->cd);
534  CHECK_NULLS(_wcsInfo->crpix, rhs._wcsInfo->crpix);
535  CHECK_NULLS(_wcsInfo->cunit, rhs._wcsInfo->cunit);
536  CHECK_NULLS(_wcsInfo->ctype, rhs._wcsInfo->ctype);
537  return _nWcsInfo == rhs._nWcsInfo &&
538  _coordSystem == rhs._coordSystem &&
539  _wcsInfo->naxis == rhs._wcsInfo->naxis &&
540  _wcsInfo->equinox == rhs._wcsInfo->equinox &&
541  _wcsInfo->altlin == rhs._wcsInfo->altlin &&
542  compareArrays(_wcsInfo->crval, rhs._wcsInfo->crval, 2) &&
543  compareArrays(_wcsInfo->crpix, rhs._wcsInfo->crpix, 2) &&
544  compareArrays(_wcsInfo->cd, rhs._wcsInfo->cd, 4) &&
545  compareStringArrays(_wcsInfo->cunit, rhs._wcsInfo->cunit, 2) &&
546  compareStringArrays(_wcsInfo->ctype, rhs._wcsInfo->ctype, 2) &&
548  _wcsInfo->crval[1] * afwGeom::degrees) ==
549  rhs.skyToPixel(_wcsInfo->crval[0] * afwGeom::degrees,
550  _wcsInfo->crval[1] * afwGeom::degrees) &&
551  *pixelToSky(_wcsInfo->crpix[0], _wcsInfo->crpix[1]) ==
552  *rhs.pixelToSky(_wcsInfo->crpix[0], _wcsInfo->crpix[1]);
553 }
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g. RA/dec) to pixel positions.
Definition: Wcs.cc:788
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g. RA/dec)
Definition: Wcs.cc:864
AngleUnit const degrees
Definition: Angle.h:92
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
#define CHECK_NULLS(a, b)
Definition: Wcs.cc:519
void lsst.afw.image::Wcs::_setWcslibParams ( )
protected

Definition at line 68 of file Wcs.cc.

69 {
70  _wcsfixCtrl = // ctrl for wcsfix
71  2; // Translate "H" to "h"
72  _wcshdrCtrl = // ctrl for wcspih
73  2; // Report each rejected keyrecord and the reason why it was rejected
74  _relax = // relax parameter for wcspih;
75  WCSHDR_all; // Accept all extensions recognized by the parser
76 }
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:393
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:392
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:394
Wcs::Ptr Wcs::clone ( void  ) const
virtual

Reimplemented in lsst.afw.image::TanWcs, and lsst.afw.image::DistortedTanWcs.

Definition at line 562 of file Wcs.cc.

562  {
563  return Wcs::Ptr(new Wcs(*this));
564 }
boost::shared_ptr< Wcs > Ptr
Definition: Wcs.h:113
Wcs()
Construct an invalid Wcs given no arguments.
Definition: Wcs.cc:87
afwCoord::Coord::Ptr Wcs::convertCoordToSky ( coord::Coord const &  coord) const
protected

Given a Coord (as a shared pointer), return the sky position in the correct coordinate system for this Wcs.

Definition at line 784 of file Wcs.cc.

784  {
785  return coord.convert(_coordSystem);
786 }
coord::CoordSystem _coordSystem
Definition: Wcs.h:396
void Wcs::flipImage ( int  flipLR,
int  flipTB,
lsst::afw::geom::Extent2I  dimensions 
) const
virtual

Flip CD matrix around the y-axis.

Reimplemented in lsst.afw.image::DistortedTanWcs.

Definition at line 601 of file Wcs.cc.

601  {
602  assert(_wcsInfo);
603 
604  int const naxis = _wcsInfo->naxis;
605 
606  //If naxis != 2, I'm not sure if any of what follows is correct
607  assert(naxis == 2);
608  if (flipLR) {
609  _wcsInfo->cd[0] = -_wcsInfo->cd[0];
610  _wcsInfo->cd[2] = -_wcsInfo->cd[2];
611  _wcsInfo->crpix[0] = -_wcsInfo->crpix[0] + dimensions.getX();
612  }
613  if (flipTB) {
614  _wcsInfo->cd[1] = -_wcsInfo->cd[1];
615  _wcsInfo->cd[3] = -_wcsInfo->cd[3];
616  _wcsInfo->crpix[1] = -_wcsInfo->crpix[1]+dimensions.getY();
617  }
618 
619  // tells libwcs to invalidate cached data, since transformation has been modified
620  _wcsInfo->flag = 0;
621 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
Eigen::Matrix2d Wcs::getCDMatrix ( ) const

Returns the CD matrix.

Definition at line 583 of file Wcs.cc.

583  {
584  assert(_wcsInfo);
585  int const naxis = _wcsInfo->naxis;
586 
587  //If naxis != 2, I'm not sure if any of what follows is correct
588  assert(naxis == 2);
589 
590  Eigen::Matrix2d C;
591 
592  for (int i=0; i< naxis; ++i){
593  for (int j=0; j<naxis; ++j) {
594  C(i,j) = _wcsInfo->cd[ (i*naxis) + j ];
595  }
596  }
597 
598  return C;
599 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
PropertyList::Ptr Wcs::getFitsMetadata ( ) const
virtual

Return a PropertyList containing FITS header keywords that can be used to save the Wcs.x.

Reimplemented in lsst.afw.image::TanWcs.

Definition at line 674 of file Wcs.cc.

674  {
676 }
static lsst::daf::base::PropertyList::Ptr generatePropertySet(lsst::afw::image::Wcs const &wcs)
lsst::afw::geom::LinearTransform Wcs::getLinearTransform ( ) const

Return the linear part of the Wcs, the CD matrix in FITS-speak, as an AffineTransform.

Definition at line 1014 of file Wcs.cc.

1015 {
1017 }
A 2D linear coordinate transformation.
Eigen::Matrix2d getCDMatrix() const
Returns the CD matrix.
Definition: Wcs.cc:583
std::string lsst.afw.image::Wcs::getPersistenceName ( ) const
protectedvirtual

Return the unique name used to persist this object and look up its factory.

Must be less than ArchiveIndexSchema::MAX_NAME_LENGTH characters.

Reimplemented from lsst.afw.table.io::Persistable.

Reimplemented in lsst.afw.image::TanWcs.

Definition at line 1080 of file Wcs.cc.

1080 { return getWcsPersistenceName(); }
GeomPoint Wcs::getPixelOrigin ( ) const

Returns CRPIX (corrected to LSST convention).

Definition at line 575 of file Wcs.cc.

575  {
576  assert(_wcsInfo);
577  //Convert from fits units back to lsst units
578  double p1 = _wcsInfo->crpix[0] + fitsToLsstPixels;
579  double p2 = _wcsInfo->crpix[1] + fitsToLsstPixels;
580  return afwGeom::Point2D(p1, p2);
581 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
const int fitsToLsstPixels
Definition: Wcs.cc:79
Point< double, 2 > Point2D
Definition: Point.h:286
std::string lsst.afw.image::Wcs::getPythonModule ( ) const
protectedvirtual

Return the fully-qualified Python module that should be imported to guarantee that its factory is registered.

Must be less than ArchiveIndexSchema::MAX_MODULE_LENGTH characters.

Will be ignored if empty.

Reimplemented from lsst.afw.table.io::Persistable.

Definition at line 1082 of file Wcs.cc.

1082 { return "lsst.afw.image"; }
CoordPtr Wcs::getSkyOrigin ( ) const

Returns CRVAL. This need not be the centre of the image.

Definition at line 570 of file Wcs.cc.

570  {
571  assert(_wcsInfo);
572  return makeCorrectCoord(_wcsInfo->crval[0] * afwGeom::degrees, _wcsInfo->crval[1] * afwGeom::degrees);
573 }
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...
Definition: Wcs.cc:885
AngleUnit const degrees
Definition: Angle.h:92
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
virtual bool lsst.afw.image::Wcs::hasDistortion ( ) const
inlinevirtual

Reimplemented in lsst.afw.image::TanWcs, and lsst.afw.image::DistortedTanWcs.

Definition at line 220 of file Wcs.h.

220 { return false;};
void Wcs::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 
)
private

Manually initialise a wcs struct using values passed by the constructor.

Parameters
crvalThe sky position of the reference point
crpixThe pixel position corresponding to crval in LSST units
CDMatrix describing transformations from pixel to sky positions
ctype1Projection system used (see description of Wcs)
ctype2Projection system used (see description of Wcs)
equinoxEquinox of coordinate system, eg 2000 (Julian) or 1950 (Besselian)
raDecSysSystem used to describe right ascension or declination, e.g FK4, FK5 or ICRS
cunits1Units of sky position. One of deg, arcmin or arcsec
cunits2Units of sky position. One of deg, arcmin or arcsec

Definition at line 371 of file Wcs.cc.

374  {
375 
376  //Check CD is a valid size
377  if( (CD.rows() != 2) || (CD.cols() != 2) ) {
378  string msg = "CD is not a 2x2 matrix";
379  throw LSST_EXCEPT(except::InvalidParameterError, msg);
380  }
381 
382  //Check that cunits are legitimate values
383  bool isValid = (cunits1 == "deg");
384  isValid |= (cunits1 == "arcmin");
385  isValid |= (cunits1 == "arcsec");
386  isValid |= (cunits1 == "mas");
387 
388  if (!isValid) {
389  string msg = "CUNITS1 must be one of {deg|arcmin|arcsec|mas}";
390  throw LSST_EXCEPT(except::InvalidParameterError, msg);
391  }
392 
393  isValid = (cunits2 == "deg");
394  isValid |= (cunits2 == "arcmin");
395  isValid |= (cunits2 == "arcsec");
396  isValid |= (cunits2 == "mas");
397 
398  if (!isValid) {
399  string msg = "CUNITS2 must be one of {deg|arcmin|arcsec|mas}";
400  throw LSST_EXCEPT(except::InvalidParameterError, msg);
401  }
402 
403  //Initialise the wcs struct
404  _wcsInfo = static_cast<struct wcsprm *>(malloc(sizeof(struct wcsprm)));
405  if (_wcsInfo == NULL) {
406  throw LSST_EXCEPT(except::MemoryError, "Cannot allocate WCS info");
407  }
408 
409  _wcsInfo->flag = -1;
410  int status = wcsini(true, 2, _wcsInfo); //2 indicates a naxis==2, a two dimensional image
411  if(status != 0) {
412  throw LSST_EXCEPT(except::MemoryError,
413  (boost::format("Failed to allocate memory with wcsini. Status %d: %s") %
414  status % wcs_errmsg[status] ).str());
415  }
416 
417  //Set crval, crpix and CD. Internally to the class, we use fits units for consistency with
418  //wcslib.
419  _wcsInfo->crval[0] = crval.getX();
420  _wcsInfo->crval[1] = crval.getY();
421  _wcsInfo->crpix[0] = crpix.getX() + lsstToFitsPixels;
422  _wcsInfo->crpix[1] = crpix.getY() + lsstToFitsPixels;
423 
424  //Set the CD matrix
425  for (int i=0; i<2; ++i) {
426  for (int j=0; j<2; ++j) {
427  _wcsInfo->cd[(2*i) + j] = CD(i,j);
428  }
429  }
430 
431  //Specify that we have a CD matrix, but no PC or CROTA
432  _wcsInfo->altlin = 2;
433  _wcsInfo->flag = 0; //values have been updated
434 
435  //This is a work around for what I think is a bug in wcslib. ->types is neither
436  //initialised or set to NULL by default, so if I try to delete a Wcs object,
437  //wcslib then attempts to free non-existent space, and the code can crash.
438  _wcsInfo->types = NULL;
439 
440  //Set the coordinate system
441  strncpy(_wcsInfo->ctype[0], ctype1.c_str(), STRLEN);
442  strncpy(_wcsInfo->ctype[1], ctype2.c_str(), STRLEN);
443  strncpy(_wcsInfo->radesys, raDecSys.c_str(), STRLEN);
444  _wcsInfo->equinox = equinox;
445 
446  //Set the units
447  strncpy(_wcsInfo->cunit[0], cunits1.c_str(), STRLEN);
448  strncpy(_wcsInfo->cunit[1], cunits2.c_str(), STRLEN);
449 
450  _nWcsInfo = 1; //Specify that we have only one coordinate representation
451 
452  //Tell wcslib that we are need to set up internal values
453  status=wcsset(_wcsInfo);
454  if(status != 0) {
455  throw LSST_EXCEPT(except::RuntimeError,
456  (boost::format("Failed to setup wcs structure with wcsset. Status %d: %s") %
457  status % wcs_errmsg[status] ).str());
458 
459  }
460 }
const int lsstToFitsPixels
Definition: Wcs.cc:78
table::Key< std::string > ctype2
Definition: Wcs.cc:1045
table::Key< table::Point< double > > crval
Definition: Wcs.cc:1041
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
table::Key< double > equinox
Definition: Wcs.cc:1046
table::Key< table::Point< double > > crpix
Definition: Wcs.cc:1042
const int STRLEN
Definition: Wcs.cc:65
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int status
table::Key< std::string > ctype1
Definition: Wcs.cc:1044
void Wcs::initWcsLibFromFits ( boost::shared_ptr< lsst::daf::base::PropertySet const > const &  fitsMetadata)
protected

Parse a fits header, extract the relevant metadata and create a Wcs object.

Access control for the input header

We want to hack up the input, and in order to do so we need to do a deep copy on it. We only want to do that copy once, and would like to avoid doing it altogether.

Return a readable version of the metadata

Return a writable version of the metadata

Ctor

Definition at line 172 of file Wcs.cc.

172  {
177  class HeaderAccess {
178  public:
180  CONST_PTR(lsst::daf::base::PropertySet) const& toRead() { return _constHeader; }
182  PTR(lsst::daf::base::PropertySet) const& toWrite() {
183  if (!_hackHeader) {
184  _hackHeader = _constHeader->deepCopy();
185  _constHeader = _hackHeader;
186  }
187  return _hackHeader;
188  }
189 
191  HeaderAccess(CONST_PTR(lsst::daf::base::PropertySet) const& header) :
192  _constHeader(header), _hackHeader() {}
193 
194  private:
196  PTR(lsst::daf::base::PropertySet) _hackHeader;
197  };
198 
199  HeaderAccess access(header);
200 
201  // Some headers (e.g. SDSS ones from FNAL) have EQUINOX as a string. Fix this,
202  // as wcslib 4.4.4 refuses to handle it
203  {
204  std::string const& key = "EQUINOX";
205  if (access.toRead()->exists(key) && access.toRead()->typeOf(key) == typeid(std::string)) {
206  double equinox = ::atof(access.toRead()->getAsString(key).c_str());
207  access.toWrite()->set(key, equinox);
208  }
209  }
210 
211  //Check header isn't empty
212  int nCards = lsst::afw::formatters::countFitsHeaderCards(access.toRead());
213  if (nCards <= 0) {
214  string msg = "Could not parse FITS WCS: no header cards found";
215  throw LSST_EXCEPT(except::InvalidParameterError, msg);
216  }
217 
218  // Scamp produces PVi_xx header cards that are inconsistent with WCS Paper 2
219  // and cause WCSLib to choke. Aggressively, rename all PV keywords to X_PV
220  for (int j=1; j<3; j++) {
221  for (int i=0; i<=99; i++) {
222  std::string key = (boost::format("PV%i_%i") % j % i).str();
223  if (!access.toRead()->exists(key)) {
224  break;
225  }
226  double val = access.toRead()->getAsDouble(key);
227  access.toWrite()->remove(key);
228  access.toWrite()->add("X_"+key, val);
229  }
230  }
231 
232  //While the standard does not insist on CRVAL and CRPIX being present, it
233  //is almost certain their absence indicates a problem.
234  //Check for CRPIX
235  if( !access.toRead()->exists("CRPIX1") && !access.toRead()->exists("CRPIX1a")) {
236  string msg = "Neither CRPIX1 not CRPIX1a found";
237  throw LSST_EXCEPT(except::InvalidParameterError, msg);
238  }
239 
240  if( !access.toRead()->exists("CRPIX2") && !access.toRead()->exists("CRPIX2a")) {
241  string msg = "Neither CRPIX2 not CRPIX2a found";
242  throw LSST_EXCEPT(except::InvalidParameterError, msg);
243  }
244 
245  //And the same for CRVAL
246  if( !access.toRead()->exists("CRVAL1") && !access.toRead()->exists("CRVAL1a")) {
247  string msg = "Neither CRVAL1 not CRVAL1a found";
248  throw LSST_EXCEPT(except::InvalidParameterError, msg);
249  }
250 
251  if( !access.toRead()->exists("CRVAL2") && !access.toRead()->exists("CRVAL2a")) {
252  string msg = "Neither CRVAL2 not CRVAL2a found";
253  throw LSST_EXCEPT(except::InvalidParameterError, msg);
254  }
255  /*
256  * According to Greisen and Calabretta (A&A 395, 1061–1075 (2002)) it's illegal to mix PCi_j and CDi_j
257  * headers; unfortunately Subaru puts both in its headers. It actually uses PC001002 instead of PC1_2
258  * (dating to a proposed FITS standard from 1996) and at least sometimes fails to include CDELT[12],
259  * so the CD and PC matrices are inconsistent
260  *
261  * If we detect any part of a CD matrix, delete all PC matrices
262  */
263  if(access.toRead()->exists("CD1_1") || access.toRead()->exists("CD1_2") ||
264  access.toRead()->exists("CD2_1") || access.toRead()->exists("CD2_2")) {
265  for (int i = 1; i <= 2; ++i) {
266  for (int j = 1; j <= 2; ++j) {
267  std::string key = (boost::format("PC%i_%i") % j % i).str();
268  if (access.toRead()->exists(key)) {
269  double const val = access.toRead()->getAsDouble(key);
270  access.toWrite()->remove(key);
271  access.toWrite()->add("X_" + key, val);
272  }
273 
274  key = (boost::format("PC%03d%03d") % j % i).str();
275  if (access.toRead()->exists(key)) {
276  double const val = access.toRead()->getAsDouble(key);
277  access.toWrite()->remove(key);
278  access.toWrite()->add("X_" + key, val);
279  }
280  }
281  }
282  }
283 
284  //Pass the header into wcslib's formatter to extract & setup the Wcs. First need
285  //to convert to a C style string, so the compile doesn't complain about constness
286  std::string metadataStr = lsst::afw::formatters::formatFitsProperties(access.toRead());
287  // We own the data, and wcslib is slack about constness, so no qualms with casting away const
288  char *hdrString = const_cast<char*>(metadataStr.c_str());
289  //printf("wcspih string:\n%s\n", hdrString);
290 
291  nCards = lsst::afw::formatters::countFitsHeaderCards(access.toRead()); // we may have dropped some
292  int pihStatus = wcspih(hdrString, nCards, _relax, _wcshdrCtrl, &_nReject, &_nWcsInfo, &_wcsInfo);
293 
294  if (pihStatus != 0) {
295  throw LSST_EXCEPT(except::RuntimeError,
296  (boost::format("Could not parse FITS WCS: wcspih status = %d (%s)") %
297  pihStatus % wcs_errmsg[pihStatus]).str());
298  }
299 
300  //Run wcsfix on _wcsInfo to try and fix any problems it knows about.
301  const int *naxes = NULL; // should be {NAXIS1, NAXIS2, ...} to check cylindrical projections
302  int stats[NWCSFIX]; // status returns from wcsfix
303  int fixStatus = wcsfix(_wcsfixCtrl, naxes, _wcsInfo, stats);
304  if (fixStatus != 0) {
305  std::stringstream errStream;
306  errStream << "Could not parse FITS WCS: wcsfix failed " << std::endl;
307  for (int ii = 0; ii < NWCSFIX; ++ii) {
308  if (stats[ii] >= 0) {
309  errStream << "\t" << ii << ": " << stats[ii] << " " << wcsfix_errmsg[stats[ii]] << std::endl;
310  } else {
311  errStream << "\t" << ii << ": " << stats[ii] << std::endl;
312  }
313  }
314  }
315 
316  //The Wcs standard requires a default value for RADESYS if the keyword
317  //doesn't exist in header, but wcslib doesn't set it. So we do so here. This code
318  //conforms to Calabretta & Greisen 2002 \S 3.1
319  if (!(access.toRead()->exists("RADESYS") || access.toRead()->exists("RADESYSa"))) {
320  // If RADECSYS exists, use that (counter to Calabretta & Greisen 2002 \S 3.1, but commonly used).
321  // If equinox exist and < 1984, use FK4. If >= 1984, use FK5
322  if (access.toRead()->exists("RADECSYS")) {
323  strncpy(_wcsInfo->radesys, access.toRead()->getAsString("RADECSYS").c_str(), STRLEN);
324  } else if (access.toRead()->exists("EQUINOX") || access.toRead()->exists("EQUINOXa")) {
325  std::string const EQUINOX = access.toRead()->exists("EQUINOX") ? "EQUINOX" : "EQUINOXa";
326  double const equinox = access.toRead()->getAsDouble(EQUINOX);
327  if(equinox < 1984) {
328  strncpy(_wcsInfo->radesys, "FK4", STRLEN);
329  } else {
330  strncpy(_wcsInfo->radesys, "FK5", STRLEN);
331  }
332  } else {
333  //If Equinox doesn't exist, default to ICRS
334  strncpy(_wcsInfo->radesys, "ICRS", STRLEN);
335  }
336  }
337  // strip trailing whitespace
338  {
339  for(int i = strlen(_wcsInfo->radesys) - 1; i >= 0; i--) {
340  if (isspace(_wcsInfo->radesys[i])) {
341  _wcsInfo->radesys[i] = '\0';
342  }
343  }
344  }
345  //
346  // If there are no CDi_j cards in the header, set CDi_j from PCi_j
347  // CDi_j == CDELTi*PCi_j
348  //
349  if ((_wcsInfo->altlin & 2) == 0) { // no CDi_j cards were found in the header
350  double const *cdelt = _wcsInfo->cdelt;
351  double const *pc = _wcsInfo->pc;
352  double *cd = _wcsInfo->cd;
353 
354  cd[0] = cdelt[0]*pc[0]; // 1_1
355  cd[1] = cdelt[0]*pc[1]; // 1_2
356  cd[2] = cdelt[1]*pc[2]; // 2_1
357  cd[3] = cdelt[1]*pc[3]; // 2_2
358  }
359 }
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:393
#define CONST_PTR(...)
Definition: base.h:47
table::Key< table::Array< double > > cd
Definition: Wcs.cc:1043
#define PTR(...)
Definition: base.h:41
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
table::Key< double > equinox
Definition: Wcs.cc:1046
const int STRLEN
Definition: Wcs.cc:65
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:392
Class for storing generic metadata.
Definition: PropertySet.h:82
std::string formatFitsProperties(boost::shared_ptr< lsst::daf::base::PropertySet const > const &prop)
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:394
ImageT val
Definition: CR.cc:154
int countFitsHeaderCards(boost::shared_ptr< lsst::daf::base::PropertySet const > const &prop)
bool Wcs::isFlipped ( ) const

Does the Wcs follow the convention of North=Up, East=Left?

The conventional sense for a WCS image is to have North up and East to the left, or at least to be able to rotate the image to that orientation. It is possible to create a "flipped" WCS, where East points right when the image is rotated such that North is up. Flipping a WCS is akin to producing a mirror image. This function tests whether the image is flipped or not.

Definition at line 678 of file Wcs.cc.

678  {
679  // We calculate the determinant of the CD (i.e the rotation and scaling)
680  // matrix. If this determinant is positive, then the image can be rotated
681  // to a position where increasing the right ascension and declination
682  // increases the horizontal and vertical pixel position. In this case the
683  // image is flipped.
684  assert(_wcsInfo);
685  double det = (_wcsInfo->cd[0] * _wcsInfo->cd[3]) - (_wcsInfo->cd[1] * _wcsInfo->cd[2]);
686 
687  if (det == 0) {
688  throw(LSST_EXCEPT(except::RuntimeError, "Wcs CD matrix is singular"));
689  }
690 
691  return (det > 0);
692 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
bool lsst.afw.image::Wcs::isPersistable ( ) const
virtual

Whether the Wcs is persistable using afw::table::io archives.

Reimplemented from lsst.afw.table.io::Persistable.

Reimplemented in lsst.afw.image::DistortedTanWcs.

Definition at line 1102 of file Wcs.cc.

1102  {
1103  if (_wcsInfo[0].naxis != 2) return false;
1104  if (std::strcmp(_wcsInfo[0].cunit[0], "deg") != 0) return false;
1105  if (std::strcmp(_wcsInfo[0].cunit[1], "deg") != 0) return false;
1106  return true;
1107 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
lsst::afw::geom::AffineTransform Wcs::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.

The local linear approximation is defined such the following is true (ignoring floating-point errors):

* wcs.linearizePixelToSky(sky, skyUnit)(wcs.skyToPixel(sky)) == sky.getPosition(skyUnit);
*

(recall that AffineTransform::operator() is matrix multiplication with the augmented point (x,y,1)).

This is currently implemented as a numerical derivative, but we should specialise the Wcs class (or rather its implementation) to handle "simple" cases such as TAN-SIP analytically

Parameters
[in]coordPosition in sky coordinates where transform is desired.
[in]skyUnitUnits to use for sky coordinates; units of matrix elements will be skyUnits/pixel.

Definition at line 940 of file Wcs.cc.

943  {
944  return linearizePixelToSkyInternal(skyToPixel(coord), coord, skyUnit);
945 }
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g. RA/dec) to pixel positions.
Definition: Wcs.cc:788
virtual geom::AffineTransform linearizePixelToSkyInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:957
lsst::afw::geom::AffineTransform Wcs::linearizePixelToSky ( geom::Point2D const &  pix,
geom::AngleUnit  skyUnit = geom::degrees 
) const

Return the local linear approximation to Wcs::pixelToSky at a point given in pixel coordinates.

The local linear approximation is defined such the following is true (ignoring floating-point errors):

* wcs.linearizePixelToSky(pix, skyUnit)(pix) == wcs.pixelToSky(pix).getPosition(skyUnit)
*

(recall that AffineTransform::operator() is matrix multiplication with the augmented point (x,y,1)).

This is currently implemented as a numerical derivative, but we should specialise the Wcs class (or rather its implementation) to handle "simple" cases such as TAN-SIP analytically

Parameters
[in]pixPosition in pixel coordinates where transform is desired.
[in]skyUnitUnits to use for sky coordinates; units of matrix elements will be skyUnits/pixel.

Definition at line 946 of file Wcs.cc.

949  {
950  return linearizePixelToSkyInternal(pix, *pixelToSky(pix), skyUnit);
951 }
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g. RA/dec)
Definition: Wcs.cc:864
virtual geom::AffineTransform linearizePixelToSkyInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:957
lsst::afw::geom::AffineTransform Wcs::linearizePixelToSkyInternal ( geom::Point2D const &  pix,
coord::Coord const &  coord,
geom::AngleUnit  skyUnit 
) const
protectedvirtual

Definition at line 957 of file Wcs.cc.

961  {
962  //
963  // Figure out the (0, 0), (0, 1), and (1, 0) ra/dec coordinates of the corners of a square drawn in pixel
964  // It'd be better to centre the square at sky00, but that would involve another conversion between sky and
965  // pixel coordinates so I didn't bother
966  //
967  const double side = 10; // length of the square's sides in pixels
968  GeomPoint const sky00 = coord.getPosition(skyUnit);
969  typedef std::pair<lsst::afw::geom::Angle, lsst::afw::geom::Angle> AngleAngle;
970  AngleAngle const dsky10 = coord.getTangentPlaneOffset(*pixelToSky(pix00 + afwGeom::Extent2D(side, 0)));
971  AngleAngle const dsky01 = coord.getTangentPlaneOffset(*pixelToSky(pix00 + afwGeom::Extent2D(0, side)));
972 
973  Eigen::Matrix2d m;
974  m(0, 0) = dsky10.first.asAngularUnits(skyUnit)/side;
975  m(0, 1) = dsky01.first.asAngularUnits(skyUnit)/side;
976  m(1, 0) = dsky10.second.asAngularUnits(skyUnit)/side;
977  m(1, 1) = dsky01.second.asAngularUnits(skyUnit)/side;
978 
979  Eigen::Vector2d sky00v;
980  sky00v << sky00.getX(), sky00.getY();
981  Eigen::Vector2d pix00v;
982  pix00v << pix00.getX(), pix00.getY();
983  //return lsst::afw::geom::AffineTransform(m, lsst::afw::geom::Extent2D(sky00v - m * pix00v));
984  return lsst::afw::geom::AffineTransform(m, (sky00v - m * pix00v));
985 }
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g. RA/dec)
Definition: Wcs.cc:864
An affine coordinate transformation consisting of a linear transformation and an offset.
lsst::afw::geom::AffineTransform Wcs::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.

The local linear approximation is defined such the following is true (ignoring floating-point errors):

* wcs.linearizeSkyToPixel(sky, skyUnit)(sky.getPosition(skyUnit)) == wcs.skyToPixel(sky)
*

(recall that AffineTransform::operator() is matrix multiplication with the augmented point (x,y,1)).

This is currently implemented as a numerical derivative, but we should specialise the Wcs class (or rather its implementation) to handle "simple" cases such as TAN-SIP analytically

Parameters
[in]coordPosition in sky coordinates where transform is desired.
[in]skyUnitUnits to use for sky coordinates; units of matrix elements will be pixels/skyUnit.

Definition at line 987 of file Wcs.cc.

990  {
991  return linearizeSkyToPixelInternal(skyToPixel(coord), coord, skyUnit);
992 }
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g. RA/dec) to pixel positions.
Definition: Wcs.cc:788
virtual geom::AffineTransform linearizeSkyToPixelInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:1005
lsst::afw::geom::AffineTransform Wcs::linearizeSkyToPixel ( geom::Point2D const &  pix,
geom::AngleUnit  skyUnit = geom::degrees 
) const

Return the local linear approximation to Wcs::skyToPixel at a point given in pixel coordinates.

The local linear approximation is defined such the following is true (ignoring floating-point errors):

* wcs.linearizeSkyToPixel(pix, skyUnit)(wcs.pixelToSky(pix).getPosition(skyUnit)) == pix
*

(recall that AffineTransform::operator() is matrix multiplication with the augmented point (x,y,1)).

This is currently implemented as a numerical derivative, but we should specialise the Wcs class (or rather its implementation) to handle "simple" cases such as TAN-SIP analytically

Parameters
[in]pixPosition in pixel coordinates where transform is desired.
[in]skyUnitUnits to use for sky coordinates; units of matrix elements will be pixels/skyUnit.

Definition at line 994 of file Wcs.cc.

997  {
998  return linearizeSkyToPixelInternal(pix, *pixelToSky(pix), skyUnit);
999 }
virtual geom::AffineTransform linearizeSkyToPixelInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:1005
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g. RA/dec)
Definition: Wcs.cc:864
lsst::afw::geom::AffineTransform Wcs::linearizeSkyToPixelInternal ( geom::Point2D const &  pix,
coord::Coord const &  coord,
geom::AngleUnit  skyUnit 
) const
protectedvirtual

Implementation for the overloaded public linearizeSkyToPixel methods, requiring both a pixel coordinate and the corresponding sky coordinate.

Definition at line 1005 of file Wcs.cc.

1009  {
1010  lsst::afw::geom::AffineTransform inverse = linearizePixelToSkyInternal(pix00, coord, skyUnit);
1011  return inverse.invert();
1012 }
AffineTransform const invert() const
An affine coordinate transformation consisting of a linear transformation and an offset.
virtual geom::AffineTransform linearizePixelToSkyInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:957
CoordPtr Wcs::makeCorrectCoord ( geom::Angle  sky0,
geom::Angle  sky1 
) const
protected

Given a sky position, use the values stored in ctype and radesys to return the correct sub-class of Coord.

Definition at line 885 of file Wcs.cc.

885  {
886 
887  //Construct a coord object of the correct type
888  int const ncompare = 4; // we only care about type's first 4 chars
889  char *type = _wcsInfo->ctype[0];
890  char *radesys = _wcsInfo->radesys;
891  double equinox = _wcsInfo->equinox;
892 
893  if (strncmp(type, "RA--", ncompare) == 0) { // Our default. If it's often something else, consider
894  ; // using an tr1::unordered_map
895  if(strcmp(radesys, "ICRS") == 0) {
896  return afwCoord::makeCoord(afwCoord::ICRS, sky0, sky1);
897  }
898  if(strcmp(radesys, "FK5") == 0) {
899  return afwCoord::makeCoord(afwCoord::FK5, sky0, sky1, equinox);
900  } else {
901  throw LSST_EXCEPT(except::RuntimeError,
902  (boost::format("Can't create Coord object: Unrecognised radesys %s") %
903  radesys).str());
904  }
905 
906  } else if (strncmp(type, "GLON", ncompare) == 0) {
907  return afwCoord::makeCoord(afwCoord::GALACTIC, sky0, sky1);
908  } else if (strncmp(type, "ELON", ncompare) == 0) {
909  return afwCoord::makeCoord(afwCoord::ECLIPTIC, sky0, sky1, equinox);
910  } else if (strncmp(type, "DEC-", ncompare) == 0) {
911  //check for the case where the ctypes are swapped. Note how sky0 and sky1 are swapped as well
912 
913  //Our default
914  if(strcmp(radesys, "ICRS") == 0) {
915  return afwCoord::makeCoord(afwCoord::ICRS, sky1, sky0);
916  }
917  if(strcmp(radesys, "FK5") == 0) {
918  return afwCoord::makeCoord(afwCoord::FK5, sky1, sky0, equinox);
919  } else {
920  throw LSST_EXCEPT(except::RuntimeError,
921  (boost::format("Can't create Coord object: Unrecognised radesys %s") %
922  radesys).str());
923  }
924  } else if (strncmp(type, "GLAT", ncompare) == 0) {
925  return afwCoord::makeCoord(afwCoord::GALACTIC, sky1, sky0);
926  } else if (strncmp(type, "ELAT", ncompare) == 0) {
927  return afwCoord::makeCoord(afwCoord::ECLIPTIC, sky1, sky0, equinox);
928  } else {
929  //Give up in disgust
930  throw LSST_EXCEPT(except::RuntimeError,
931  (boost::format("Can't create Coord object: Unrecognised sys %s") %
932  type).str());
933  }
934 
935  //Can't get here
936  assert(0);
937 }
table::Key< std::string > radesys
Definition: Wcs.cc:1047
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
table::Key< double > equinox
Definition: Wcs.cc:1046
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.
Definition: Coord.cc:1210
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
bool lsst.afw.image::Wcs::operator!= ( Wcs const &  other) const
inline

Definition at line 135 of file Wcs.h.

135 { return !(*this == other); }
Wcs& lsst.afw.image::Wcs::operator= ( const Wcs )
protected
bool Wcs::operator== ( Wcs const &  other) const

Definition at line 496 of file Wcs.cc.

496  {
497  if (&other == this) return true;
498  // We do a bidirectional test with a virtual member function in case one of us is a derived
499  // class with members we don't know about here.
500  // This is not the most efficient possible implementation, but I think it's the easiest one
501  // with which to ensure correctness, and I think that's more important in this case.
502  return this->_isSubset(other) && other._isSubset(*this);
503 }
virtual bool _isSubset(Wcs const &other) const
Definition: Wcs.cc:530
double Wcs::pixArea ( lsst::afw::geom::Point2D  pix00) const

Sky area covered by a pixel at position pix00 in units of square degrees.

Parameters
pix00The pixel point where the area is desired

Definition at line 698 of file Wcs.cc.

699  {
700  //
701  // Figure out the (0, 0), (0, 1), and (1, 0) ra/dec coordinates of the corners of a square drawn in pixel
702  // It'd be better to centre the square at sky00, but that would involve another conversion between sky and
703  // pixel coordinates so I didn't bother
704  //
705  const double side = 1; // length of the square's sides in pixels
706 
707  // Work in 3-space to avoid RA wrapping and pole issues.
708  afwGeom::Point3D v0 = pixelToSky(pix00)->getVector();
709 
710  // Step by "side" in x and y pixel directions...
711  GeomPoint px(pix00);
712  GeomPoint py(pix00);
713  px.shift(afwGeom::Extent2D(side, 0));
714  py.shift(afwGeom::Extent2D(0, side));
715  // Push the points through the WCS, and find difference in 3-space.
716  afwGeom::Extent3D dx = pixelToSky(px)->getVector() - v0;
717  afwGeom::Extent3D dy = pixelToSky(py)->getVector() - v0;
718 
719  // Compute |cross product| = area of parallelogram with sides dx,dy
720  // FIXME -- this is slightly incorrect -- it's making the small-angle
721  // approximation, taking the distance *through* the unit sphere
722  // rather than over its surface.
723  // This is in units of ~radians^2
724  double area = sqrt(square(dx[1]*dy[2] - dx[2]*dy[1]) +
725  square(dx[2]*dy[0] - dx[0]*dy[2]) +
726  square(dx[0]*dy[1] - dx[1]*dy[0]));
727 
728  return area / square(side) * square(180. / afwGeom::PI);
729 }
double dx
Definition: ImageUtils.cc:90
double dy
Definition: ImageUtils.cc:90
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g. RA/dec)
Definition: Wcs.cc:864
A coordinate class intended to represent absolute positions.
Definition: PSF.h:39
double const PI
The ratio of a circle&#39;s circumference to diameter.
Definition: Angle.h:18
afwGeom::Angle Wcs::pixelScale ( ) const

Returns the pixel scale [Angle/pixel].

Definition at line 731 of file Wcs.cc.

731  {
732  return sqrt(pixArea(getPixelOrigin())) * afwGeom::degrees;
733 }
AngleUnit const degrees
Definition: Angle.h:92
lsst::afw::geom::Point2D getPixelOrigin() const
Returns CRPIX (corrected to LSST convention).
Definition: Wcs.cc:575
double pixArea(lsst::afw::geom::Point2D pix00) const
Sky area covered by a pixel at position pix00 in units of square degrees.
Definition: Wcs.cc:698
CoordPtr Wcs::pixelToSky ( double  pix1,
double  pix2 
) const

Convert from pixel position to sky coordinates (e.g. RA/dec)

Convert a pixel position (e.g. x,y) to a celestial coordinate (e.g. RA/dec). The output coordinate system depends on the values of CTYPE used to construct the object. For RA/dec, the CTYPES should be RA—TAN and DEC–TAN.

Definition at line 864 of file Wcs.cc.

864  {
865  assert(_wcsInfo);
866 
867  afwGeom::Angle skyTmp[2];
868  pixelToSkyImpl(pixel1, pixel2, skyTmp);
869  return makeCorrectCoord(skyTmp[0], skyTmp[1]);
870 }
virtual void pixelToSkyImpl(double pixel1, double pixel2, geom::Angle skyTmp[2]) const
Definition: Wcs.cc:837
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...
Definition: Wcs.cc:885
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
CoordPtr Wcs::pixelToSky ( lsst::afw::geom::Point2D const &  pixel) const

Convert from pixel position to sky coordinates (e.g. RA/dec)

Convert a pixel position (e.g. x,y) to a celestial coordinate (e.g. RA/dec). The output coordinate system depends on the values of CTYPE used to construct the object. For RA/dec, the CTYPES should be RA—TAN and DEC–TAN.

Definition at line 860 of file Wcs.cc.

860  {
861  return pixelToSky(pixel.getX(), pixel.getY());
862 }
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from pixel position to sky coordinates (e.g. RA/dec)
Definition: Wcs.cc:864
table::Key< table::Point< int > > pixel
void Wcs::pixelToSky ( double  pixel1,
double  pixel2,
geom::Angle sky1,
geom::Angle sky2 
) const

Definition at line 872 of file Wcs.cc.

872  {
873  afwGeom::Angle skyTmp[2];
874  // HACK -- we shouldn't need to initialize these -- pixelToSkyImpl() sets them unless an
875  // exception is thrown -- but be safe.
876  skyTmp[0] = 0. * afwGeom::radians;
877  skyTmp[1] = 0. * afwGeom::radians;
878  pixelToSkyImpl(pixel1, pixel2, skyTmp);
879  sky1 = skyTmp[0];
880  sky2 = skyTmp[1];
881 }
AngleUnit const radians
constant with units of radians
Definition: Angle.h:91
virtual void pixelToSkyImpl(double pixel1, double pixel2, geom::Angle skyTmp[2]) const
Definition: Wcs.cc:837
void Wcs::pixelToSkyImpl ( double  pixel1,
double  pixel2,
geom::Angle  skyTmp[2] 
) const
protectedvirtual

Reimplemented in lsst.afw.image::TanWcs, and lsst.afw.image::DistortedTanWcs.

Definition at line 837 of file Wcs.cc.

838 {
839  assert(_wcsInfo);
840 
841  // wcslib assumes 1-indexed coordinates
842  double pixTmp[2] = { pixel1 - lsst::afw::image::PixelZeroPos + lsstToFitsPixels,
843  pixel2 - lsst::afw::image::PixelZeroPos + lsstToFitsPixels};
844  double imgcrd[2];
845  double phi, theta;
846 
847  double sky[2];
848  int status = 0;
849  status = wcsp2s(_wcsInfo, 1, 2, pixTmp, imgcrd, &phi, &theta, sky, &status);
850  if (status > 0) {
851  throw LSST_EXCEPT(except::RuntimeError,
852  (boost::format("Error: wcslib returned a status code of %d at pixel %s, %s: %s") %
853  status % pixel1 % pixel2 % wcs_errmsg[status]).str());
854  }
855  // FIXME -- _wcsInfo.lat, _wcsInfo.lng ?
856  skyTmp[0] = sky[0] * afwGeom::degrees;
857  skyTmp[1] = sky[1] * afwGeom::degrees;
858 }
const int lsstToFitsPixels
Definition: Wcs.cc:78
AngleUnit const degrees
Definition: Angle.h:92
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int status
const double PixelZeroPos
FITS uses 1.0, SDSS uses 0.5, LSST uses 0.0 (http://dev.lsstcorp.org/trac/wiki/BottomLeftPixelProposa...
Definition: ImageUtils.h:42
void Wcs::rotateImageBy90 ( int  nQuarter,
lsst::afw::geom::Extent2I  dimensions 
) const
virtual

Rotate image by nQuarter times 90 degrees.

Reimplemented in lsst.afw.image::DistortedTanWcs.

Definition at line 623 of file Wcs.cc.

623  {
624  assert(_wcsInfo);
625 
626  while (nQuarter < 0 ) {
627  nQuarter += 4;
628  }
629 
630 
631  int const naxis = _wcsInfo->naxis;
632 
633  //If naxis != 2, I'm not sure if any of what follows is correct
634  assert(naxis == 2);
635  double a = _wcsInfo->cd[0];
636  double b = _wcsInfo->cd[1];
637  double c = _wcsInfo->cd[2];
638  double d = _wcsInfo->cd[3];
639  double crpx = _wcsInfo->crpix[0];
640  double crpy = _wcsInfo->crpix[1];
641  switch (nQuarter%4) {
642  case 0:
643  break;
644  case 1:
645  _wcsInfo->cd[0] = -b;
646  _wcsInfo->cd[1] = a;
647  _wcsInfo->cd[2] = -d;
648  _wcsInfo->cd[3] = c;
649  _wcsInfo->crpix[0] = -crpy + dimensions.getY();
650  _wcsInfo->crpix[1] = crpx;
651  break;
652  case 2:
653  _wcsInfo->cd[0] = -a;
654  _wcsInfo->cd[1] = -b;
655  _wcsInfo->cd[2] = -c;
656  _wcsInfo->cd[3] = -d;
657  _wcsInfo->crpix[0] = -crpx + dimensions.getX();
658  _wcsInfo->crpix[1] = -crpy + dimensions.getY();
659  break;
660  case 3:
661  _wcsInfo->cd[0] = b;
662  _wcsInfo->cd[1] = -a;
663  _wcsInfo->cd[2] = d;
664  _wcsInfo->cd[3] = -c;
665  _wcsInfo->crpix[0] = crpy;
666  _wcsInfo->crpix[1] = -crpx + dimensions.getX();
667  break;
668  }
669 
670  // tells libwcs to invalidate cached data, since transformation has been modified
671  _wcsInfo->flag = 0;
672 }
int d
Definition: KDTree.cc:89
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
afw::table::Key< double > b
void Wcs::shiftReferencePixel ( double  dx,
double  dy 
)
virtual

Move the pixel reference position by (dx, dy)

Move the pixel reference position by (dx, dy) Used when persisting and retrieving sub-images. The lsst convention is that Wcs returns pixel position (which is based on position in the parent image), but the fits convention is to return pixel index (which is bases on position in the sub-image). In order that the fits files we create make sense to other fits viewers, we change to the fits convention when writing out images.

Used when persisting and retrieving sub-images. The LSST convention is that Wcs returns pixel position (which is based on position in the parent image), but the FITS convention is to return pixel index (which is bases on position in the sub-image). In order that the FITS files we create make sense to other FITS viewers, we change to the FITS convention when writing out images.

Reimplemented in lsst.afw.image::DistortedTanWcs.

Definition at line 1161 of file Wcs.cc.

1161  {
1162  assert(_wcsInfo);
1163  _wcsInfo->crpix[0] += dx;
1164  _wcsInfo->crpix[1] += dy;
1165 
1166  // tells libwcs to invalidate cached data, since transformation has been modified
1167  _wcsInfo->flag = 0;
1168 }
double dx
Definition: ImageUtils.cc:90
double dy
Definition: ImageUtils.cc:90
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
virtual void lsst.afw.image::Wcs::shiftReferencePixel ( geom::Extent2D const &  d)
inlinevirtual

Definition at line 321 of file Wcs.h.

321 { shiftReferencePixel(d.getX(), d.getY()); }
virtual void shiftReferencePixel(double dx, double dy)
Move the pixel reference position by (dx, dy)
Definition: Wcs.cc:1161
int d
Definition: KDTree.cc:89
GeomPoint Wcs::skyToIntermediateWorldCoord ( coord::Coord const &  coord) const

Convert from sky coordinates (e.g. RA/dec) to intermediate world coordinates.

Intermediate world coordinates are in DEGREES.

Definition at line 792 of file Wcs.cc.

792  {
793  assert(_wcsInfo);
794 
796  double skyTmp[2];
797  double imgcrd[2];
798  double phi, theta;
799  double pixTmp[2];
800 
801  /*
802  printf("skyToIWC: _coordSystem = %i\n", (int)_coordSystem);
803  printf("coord (%.3f, %.3f)\n", coord->getLongitude().asDegrees(), coord->getLatitude().asDegrees());
804  printf("->sky (%.3f, %.3f)\n", sky->getLongitude().asDegrees(), sky->getLatitude().asDegrees());
805  */
806 
807  skyTmp[_wcsInfo->lng] = sky->getLongitude().asDegrees();
808  skyTmp[_wcsInfo->lat] = sky->getLatitude() .asDegrees();
809 
810  //Estimate pixel coordinates
811  int stat[1];
812  int status = 0;
813  imgcrd[0] = imgcrd[1] = -1e6;
814  /*
815  printf(" skyTmp[] = (%.3f, %.3f)\n", skyTmp[0], skyTmp[1]);
816  printf(" _wcsInfo->lng,lat = %i, %i\n", _wcsInfo->lng, _wcsInfo->lat);
817  */
818  status = wcss2p(_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
819  if (status > 0) {
820  throw LSST_EXCEPT(except::RuntimeError,
821  (boost::format("Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
822  status % skyTmp[0] % skyTmp[1] % wcs_errmsg[status]).str());
823  }
824  /*
825  printf("->iwc (%.3f, %.3f)\n", imgcrd[0], imgcrd[1]);
826  printf("-> pix (%.2f, %.2f)\n", pixTmp[0], pixTmp[1]);
827  afwCoord::Coord::Ptr crval = getSkyOrigin();
828  printf("(crval is (%.3f, %.3f))\n", crval->getLongitude().asDegrees(), crval->getLatitude().asDegrees());
829  */
830  return GeomPoint(imgcrd[0], imgcrd[1]);
831 }
boost::shared_ptr< Coord > Ptr
Definition: Coord.h:72
afw::coord::Coord::Ptr convertCoordToSky(coord::Coord const &coord) const
Definition: Wcs.cc:784
lsst::afw::geom::Point2D GeomPoint
Definition: Wcs.cc:60
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int status
GeomPoint Wcs::skyToPixel ( geom::Angle  sky1,
geom::Angle  sky2 
) const

Convert from sky coordinates (e.g. RA/dec) to pixel positions.

Convert a sky position (e.g. RA/dec) to a pixel position. The exact meaning of sky1, sky2 and the return value depend on the properties of the wcs (i.e. the values of CTYPE1 and CTYPE2), but the inputs are usually RA/dec. The outputs are x and y pixel position.

ASSUMES the angles are in the appropriate coordinate system for this Wcs.

Definition at line 788 of file Wcs.cc.

788  {
789  return skyToPixelImpl(sky1, sky2);
790 }
virtual geom::Point2D skyToPixelImpl(geom::Angle sky1, geom::Angle sky2) const
Definition: Wcs.cc:738
GeomPoint Wcs::skyToPixel ( coord::Coord const &  coord) const

Convert from sky coordinates (e.g. RA/dec) to pixel positions.

Definition at line 777 of file Wcs.cc.

777  {
779  return skyToPixelImpl(sky->getLongitude(), sky->getLatitude());
780 }
boost::shared_ptr< Coord > Ptr
Definition: Coord.h:72
afw::coord::Coord::Ptr convertCoordToSky(coord::Coord const &coord) const
Definition: Wcs.cc:784
virtual geom::Point2D skyToPixelImpl(geom::Angle sky1, geom::Angle sky2) const
Definition: Wcs.cc:738
GeomPoint Wcs::skyToPixelImpl ( geom::Angle  sky1,
geom::Angle  sky2 
) const
protectedvirtual

Reimplemented in lsst.afw.image::TanWcs, and lsst.afw.image::DistortedTanWcs.

Definition at line 738 of file Wcs.cc.

740  {
741  assert(_wcsInfo);
742 
743  double skyTmp[2];
744  double imgcrd[2];
745  double phi, theta;
746  double pixTmp[2];
747  /*
748  printf("_skyCoordsReversed: %c\n", (_skyCoordsReversed ? 'T' : 'F'));
749  printf("wcsinfo.lat: %i, lng: %i\n", _wcsInfo->lat, _wcsInfo->lng);
750  */
751  // WCSLib is smart enough to notice and handle crazy SDSS CTYPE1 = DEC--TAN,
752  // by recording the indices of the long and lat coordinates.
753  skyTmp[_wcsInfo->lng] = sky1.asDegrees();
754  skyTmp[_wcsInfo->lat] = sky2.asDegrees();
755 
756  int stat[1];
757  int status = 0;
758  status = wcss2p(_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
759  if (status == 9) {
760  throw LSST_EXCEPT(except::DomainError,
761  (boost::format("sky coordinates %s, %s degrees is not valid for this WCS")
762  % sky1.asDegrees() % sky2.asDegrees()
763  ).str()
764  );
765  }
766  if (status > 0) {
767  throw LSST_EXCEPT(except::RuntimeError,
768  (boost::format("Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
769  status % sky1.asDegrees() % sky2.asDegrees() % wcs_errmsg[status]).str());
770  }
771 
772  // wcslib assumes 1-indexed coords
775 }
double asDegrees() const
Definition: Angle.h:124
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
const int fitsToLsstPixels
Definition: Wcs.cc:79
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int status
const double PixelZeroPos
FITS uses 1.0, SDSS uses 0.5, LSST uses 0.0 (http://dev.lsstcorp.org/trac/wiki/BottomLeftPixelProposa...
Definition: ImageUtils.h:42
Point< double, 2 > Point2D
Definition: Point.h:286
void lsst.afw.image::Wcs::write ( OutputArchiveHandle handle) const
protectedvirtual

Write the object to one or more catalogs.

The handle object passed to this function provides an interface for adding new catalogs and adding nested objects to the same archive (while checking for duplicates). See OutputArchiveHandle for more information.

Reimplemented from lsst.afw.table.io::Persistable.

Reimplemented in lsst.afw.image::TanWcs.

Definition at line 1084 of file Wcs.cc.

1084  {
1085  WcsPersistenceHelper const & keys = WcsPersistenceHelper::get();
1086  afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
1087  PTR(afw::table::BaseRecord) record = catalog.addNew();
1088  record->set(keys.crval, getSkyOrigin()->getPosition(afw::geom::degrees));
1089  record->set(keys.crpix, getPixelOrigin());
1090  Eigen::Matrix2d cdIn = getCDMatrix();
1091  Eigen::Map<Eigen::Matrix2d> cdOut((*record)[keys.cd].getData());
1092  cdOut = cdIn;
1093  record->set(keys.ctype1, std::string(_wcsInfo[0].ctype[0]));
1094  record->set(keys.ctype2, std::string(_wcsInfo[0].ctype[1]));
1095  record->set(keys.equinox, _wcsInfo[0].equinox);
1096  record->set(keys.radesys, std::string(_wcsInfo[0].radesys));
1097  record->set(keys.cunit1, std::string(_wcsInfo[0].cunit[0]));
1098  record->set(keys.cunit2, std::string(_wcsInfo[0].cunit[1]));
1099  handle.saveCatalog(catalog);
1100 }
table::Key< table::Array< double > > cd
Definition: Wcs.cc:1043
CatalogT< BaseRecord > BaseCatalog
Definition: fwd.h:61
table::Key< std::string > radesys
Definition: Wcs.cc:1047
#define PTR(...)
Definition: base.h:41
table::Key< std::string > ctype2
Definition: Wcs.cc:1045
table::Key< table::Point< double > > crval
Definition: Wcs.cc:1041
AngleUnit const degrees
Definition: Angle.h:92
struct wcsprm * _wcsInfo
Definition: Wcs.h:390
table::Key< double > equinox
Definition: Wcs.cc:1046
Eigen::Matrix2d getCDMatrix() const
Returns the CD matrix.
Definition: Wcs.cc:583
table::Key< table::Point< double > > crpix
Definition: Wcs.cc:1042
lsst::afw::geom::Point2D getPixelOrigin() const
Returns CRPIX (corrected to LSST convention).
Definition: Wcs.cc:575
lsst::afw::coord::Coord::Ptr getSkyOrigin() const
Returns CRVAL. This need not be the centre of the image.
Definition: Wcs.cc:570
table::Key< std::string > cunit1
Definition: Wcs.cc:1048
table::Key< std::string > ctype1
Definition: Wcs.cc:1044
table::Key< std::string > cunit2
Definition: Wcs.cc:1049

Friends And Related Function Documentation

Wcs::Ptr makeWcs ( boost::shared_ptr< lsst::daf::base::PropertySet > const &  fitsMetadata,
bool  stripMetadata 
)
friend

Create a Wcs of the correct class using a FITS header.

Set stripMetadata=true to remove processed keywords from the PropertySet.

friend class WcsFactory
friend

Definition at line 339 of file Wcs.h.

Member Data Documentation

coord::CoordSystem lsst.afw.image::Wcs::_coordSystem
protected

Definition at line 396 of file Wcs.h.

int lsst.afw.image::Wcs::_nReject
protected

Definition at line 395 of file Wcs.h.

int lsst.afw.image::Wcs::_nWcsInfo
protected

Definition at line 391 of file Wcs.h.

int lsst.afw.image::Wcs::_relax
protected

Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.

Definition at line 392 of file Wcs.h.

int lsst.afw.image::Wcs::_wcsfixCtrl
protected

Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.

Definition at line 393 of file Wcs.h.

int lsst.afw.image::Wcs::_wcshdrCtrl
protected

Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.

Definition at line 394 of file Wcs.h.

struct wcsprm* lsst.afw.image::Wcs::_wcsInfo
protected

Definition at line 390 of file Wcs.h.


The documentation for this class was generated from the following files: