LSSTApplications  8.0.0.0+107,8.0.0.1+13,9.1+18,9.2,master-g084aeec0a4,master-g0aced2eed8+6,master-g15627eb03c,master-g28afc54ef9,master-g3391ba5ea0,master-g3d0fb8ae5f,master-g4432ae2e89+36,master-g5c3c32f3ec+17,master-g60f1e072bb+1,master-g6a3ac32d1b,master-g76a88a4307+1,master-g7bce1f4e06+57,master-g8ff4092549+31,master-g98e65bf68e,master-ga6b77976b1+53,master-gae20e2b580+3,master-gb584cd3397+53,master-gc5448b162b+1,master-gc54cf9771d,master-gc69578ece6+1,master-gcbf758c456+22,master-gcec1da163f+63,master-gcf15f11bcc,master-gd167108223,master-gf44c96c709
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

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. More...
 
lsst::afw::geom::Point2D getPixelOrigin () const
 Returns CRPIX (corrected to LSST convention). More...
 
Eigen::Matrix2d getCDMatrix () const
 Returns CD matrix. You would never have guessed that from the name. 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
 
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 celestial coordinates to pixel coordinates. More...
 
boost::shared_ptr< coord::CoordpixelToSky (lsst::afw::geom::Point2D const &pixel) const
 Convert from celestial coordiantes to pixel coordinates. More...
 
void pixelToSky (double pixel1, double pixel2, geom::Angle &sky1, geom::Angle &sky2) const
 Convert from celestial coordiantes to pixel coordinates. More...
 
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...
 
void shiftReferencePixel (geom::Extent2D const &d)
 
void shiftReferencePixel (double dx, double 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. More...
 
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 &)
 
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...
 
virtual void pixelToSkyImpl (double pixel1, double pixel2, geom::Angle skyTmp[2]) const
 
virtual geom::Point2D skyToPixelImpl (geom::Angle sky1, geom::Angle sky2) const
 

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 }
void _setWcslibParams()
Definition: Wcs.cc:68
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:1089
table::Key< table::Point< double > > crval
Definition: Wcs.cc:1085
table::Key< double > equinox
Definition: Wcs.cc:1090
table::Key< table::Point< double > > crpix
Definition: Wcs.cc:1086
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:357
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:355
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:356
table::Key< std::string > ctype1
Definition: Wcs.cc:1088
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
coord::CoordSystem _coordSystem
Definition: Wcs.h:359
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:353
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 }
void _setWcslibParams()
Definition: Wcs.cc:68
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:357
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:355
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:356
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
coord::CoordSystem _coordSystem
Definition: Wcs.h:359
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 }
void _setWcslibParams()
Definition: Wcs.cc:68
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
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:357
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:355
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:356
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
coord::CoordSystem _coordSystem
Definition: Wcs.h:359
lsst::afw::image::Wcs::Wcs ( afw::table::BaseRecord const &  record)
explicitprotected

Definition at line 1153 of file Wcs.cc.

1153  :
1154  daf::base::Citizen(typeid(this)),
1155  _wcsInfo(NULL),
1156  _nWcsInfo(0),
1157  _relax(0),
1158  _wcsfixCtrl(0),
1159  _wcshdrCtrl(0),
1160  _nReject(0),
1161  _coordSystem(static_cast<afw::coord::CoordSystem>(-1))
1162 {
1163  WcsPersistenceHelper const & keys = WcsPersistenceHelper::get();
1164  if (!record.getSchema().contains(keys.schema)) {
1165  throw LSST_EXCEPT(
1166  afw::table::io::MalformedArchiveError,
1167  "Incorrect schema for Wcs persistence"
1168  );
1169  }
1170  _setWcslibParams();
1171  Eigen::Matrix2d cd = Eigen::Map<Eigen::Matrix2d const>(record[keys.cd].getData());
1172  initWcsLib(
1173  record.get(keys.crval), record.get(keys.crpix), cd,
1174  record.get(keys.ctype1), record.get(keys.ctype2),
1175  record.get(keys.equinox), record.get(keys.radesys),
1176  record.get(keys.cunit1), record.get(keys.cunit2)
1177  );
1178  _initWcs();
1179 }
void _setWcslibParams()
Definition: Wcs.cc:68
table::Key< table::Array< double > > cd
Definition: Wcs.cc:1087
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
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:357
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:355
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:356
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
coord::CoordSystem _coordSystem
Definition: Wcs.h:359
afw::table::SourceRecord * record
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 status
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:357
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:355
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:356
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
coord::CoordSystem _coordSystem
Definition: Wcs.h:359

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 }
int status
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
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
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
coord::CoordSystem _coordSystem
Definition: Wcs.h:359
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 }
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g ra/dec) to pixel positions.
Definition: Wcs.cc:808
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from celestial coordinates to pixel coordinates.
Definition: Wcs.cc:894
#define CHECK_NULLS(a, b)
Definition: Wcs.cc:519
AngleUnit const degrees
Definition: Angle.h:92
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
coord::CoordSystem _coordSystem
Definition: Wcs.h:359
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 _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:357
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:355
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:356
Wcs::Ptr Wcs::clone ( void  ) const
virtual

Reimplemented in lsst::afw::image::TanWcs.

Definition at line 562 of file Wcs.cc.

562  {
563  return Wcs::Ptr(new Wcs(*this));
564 }
Wcs()
Construct an invalid Wcs given no arguments.
Definition: Wcs.cc:87
boost::shared_ptr< Wcs > Ptr
Definition: Wcs.h:113
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 798 of file Wcs.cc.

798  {
799  return coord.convert(_coordSystem);
800 }
coord::CoordSystem _coordSystem
Definition: Wcs.h:359
void Wcs::flipImage ( int  flipLR,
int  flipTB,
lsst::afw::geom::Extent2I  dimensions 
) const
virtual

Flip CD matrix around the y-axis.

Definition at line 605 of file Wcs.cc.

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

Returns CD matrix. You would never have guessed that from the name.

Return the CD matrix.

Definition at line 587 of file Wcs.cc.

587  {
588  assert(_wcsInfo);
589  int const naxis = _wcsInfo->naxis;
590 
591  //If naxis != 2, I'm not sure if any of what follows is correct
592  assert(naxis == 2);
593 
594  Eigen::Matrix2d C;
595 
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 ];
599  }
600  }
601 
602  return C;
603 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
PropertyList::Ptr Wcs::getFitsMetadata ( ) const
virtual

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

Return the Wcs as a fits header.

Reimplemented in lsst::afw::image::TanWcs.

Definition at line 678 of file Wcs.cc.

678  {
680 }
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

See Also

Definition at line 1058 of file Wcs.cc.

1059 {
1061 }
A 2D linear coordinate transformation.
Eigen::Matrix2d getCDMatrix() const
Returns CD matrix. You would never have guessed that from the name.
Definition: Wcs.cc:587
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 1124 of file Wcs.cc.

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

Returns CRPIX (corrected to LSST convention).

Return crpix in the lsst convention. Note that this need not be the centre of the image.

Definition at line 577 of file Wcs.cc.

577  {
578  assert(_wcsInfo);
579  //Convert from fits units back to lsst units
580  double p1 = _wcsInfo->crpix[0] + fitsToLsstPixels;
581  double p2 = _wcsInfo->crpix[1] + fitsToLsstPixels;
582  return afwGeom::Point2D(p1, p2);
583 }
Point< double, 2 > Point2D
Definition: Point.h:277
const int fitsToLsstPixels
Definition: Wcs.cc:79
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
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 1126 of file Wcs.cc.

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

Returns CRVAL.

Return crval. Note that this need not be the centre of the image.

Definition at line 571 of file Wcs.cc.

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

Reimplemented in lsst::afw::image::TanWcs.

Definition at line 198 of file Wcs.h.

198 { 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 }
int status
const int lsstToFitsPixels
Definition: Wcs.cc:78
table::Key< std::string > ctype2
Definition: Wcs.cc:1089
table::Key< table::Point< double > > crval
Definition: Wcs.cc:1085
table::Key< double > equinox
Definition: Wcs.cc:1090
table::Key< table::Point< double > > crpix
Definition: Wcs.cc:1086
const int STRLEN
Definition: Wcs.cc:65
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
table::Key< std::string > ctype1
Definition: Wcs.cc:1088
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
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 }
#define PTR(...)
Definition: base.h:41
table::Key< table::Array< double > > cd
Definition: Wcs.cc:1087
table::Key< double > equinox
Definition: Wcs.cc:1090
const int STRLEN
Definition: Wcs.cc:65
#define CONST_PTR(...)
Definition: base.h:47
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
int _wcshdrCtrl
Controls messages to stderr from wcshdr (0 for none); see wcshdr.h for details.
Definition: Wcs.h:357
int _relax
Degree of permissiveness for wcspih (0 for strict); see wcshdr.h for details.
Definition: Wcs.h:355
Class for storing generic metadata.
Definition: PropertySet.h:82
int _wcsfixCtrl
Do potentially unsafe translations of non-standard unit strings? 0/1 = no/yes.
Definition: Wcs.h:356
std::string formatFitsProperties(boost::shared_ptr< lsst::daf::base::PropertySet const > const &prop)
ImageT val
Definition: CR.cc:154
int countFitsHeaderCards(boost::shared_ptr< lsst::daf::base::PropertySet const > const &prop)
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
bool Wcs::isFlipped ( ) const

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

This actually just measures the sign of the determinant of the CD matrix to determine the "handedness" of the coordinate system.

Returns the orientation of the Wcs

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.

It does so by calculating the determinant of the CD (i.e the rotation and scaling) matrix. If this determinant is positive, then the image can be rotated to a position where increasing the right ascension and declination increases the horizontal and vertical pixel position. In this case the image is flipped.

Definition at line 696 of file Wcs.cc.

696  {
697  assert(_wcsInfo);
698  double det = (_wcsInfo->cd[0] * _wcsInfo->cd[3]) - (_wcsInfo->cd[1] * _wcsInfo->cd[2]);
699 
700  if (det == 0) {
701  throw(LSST_EXCEPT(except::RuntimeError, "Wcs CD matrix is singular"));
702  }
703 
704  return (det > 0);
705 }
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
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.

Definition at line 1146 of file Wcs.cc.

1146  {
1147  if (_wcsInfo[0].naxis != 2) return false;
1148  if (std::strcmp(_wcsInfo[0].cunit[0], "deg") != 0) return false;
1149  if (std::strcmp(_wcsInfo[0].cunit[1], "deg") != 0) return false;
1150  return true;
1151 }
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
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 977 of file Wcs.cc.

980  {
981  return linearizePixelToSkyInternal(skyToPixel(coord), coord, skyUnit);
982 }
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g ra/dec) to pixel positions.
Definition: Wcs.cc:808
virtual geom::AffineTransform linearizePixelToSkyInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:994
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 983 of file Wcs.cc.

986  {
987  return linearizePixelToSkyInternal(pix, *pixelToSky(pix), skyUnit);
988 }
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from celestial coordinates to pixel coordinates.
Definition: Wcs.cc:894
virtual geom::AffineTransform linearizePixelToSkyInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:994
lsst::afw::geom::AffineTransform Wcs::linearizePixelToSkyInternal ( geom::Point2D const &  pix,
coord::Coord const &  coord,
geom::AngleUnit  skyUnit 
) const
protectedvirtual

Definition at line 994 of file Wcs.cc.

998  {
999  //
1000  // Figure out the (0, 0), (0, 1), and (1, 0) ra/dec coordinates of the corners of a square drawn in pixel
1001  // It'd be better to centre the square at sky00, but that would involve another conversion between sky and
1002  // pixel coordinates so I didn't bother
1003  //
1004  const double side = 10; // length of the square's sides in pixels
1005  GeomPoint const sky00 = coord.getPosition(skyUnit);
1006  typedef std::pair<lsst::afw::geom::Angle, lsst::afw::geom::Angle> AngleAngle;
1007  AngleAngle const dsky10 = coord.getTangentPlaneOffset(*pixelToSky(pix00 + afwGeom::Extent2D(side, 0)));
1008  AngleAngle const dsky01 = coord.getTangentPlaneOffset(*pixelToSky(pix00 + afwGeom::Extent2D(0, side)));
1009 
1010  Eigen::Matrix2d m;
1011  m(0, 0) = dsky10.first.asAngularUnits(skyUnit)/side;
1012  m(0, 1) = dsky01.first.asAngularUnits(skyUnit)/side;
1013  m(1, 0) = dsky10.second.asAngularUnits(skyUnit)/side;
1014  m(1, 1) = dsky01.second.asAngularUnits(skyUnit)/side;
1015 
1016  Eigen::Vector2d sky00v;
1017  sky00v << sky00.getX(), sky00.getY();
1018  Eigen::Vector2d pix00v;
1019  pix00v << pix00.getX(), pix00.getY();
1020  //return lsst::afw::geom::AffineTransform(m, lsst::afw::geom::Extent2D(sky00v - m * pix00v));
1021  return lsst::afw::geom::AffineTransform(m, (sky00v - m * pix00v));
1022 }
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from celestial coordinates to pixel coordinates.
Definition: Wcs.cc:894
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 1024 of file Wcs.cc.

1027  {
1028  return linearizeSkyToPixelInternal(skyToPixel(coord), coord, skyUnit);
1029 }
geom::Point2D skyToPixel(geom::Angle sky1, geom::Angle sky2) const
Convert from sky coordinates (e.g ra/dec) to pixel positions.
Definition: Wcs.cc:808
virtual geom::AffineTransform linearizeSkyToPixelInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:1042
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 1031 of file Wcs.cc.

1034  {
1035  return linearizeSkyToPixelInternal(pix, *pixelToSky(pix), skyUnit);
1036 }
virtual geom::AffineTransform linearizeSkyToPixelInternal(geom::Point2D const &pix, coord::Coord const &coord, geom::AngleUnit skyUnit) const
Definition: Wcs.cc:1042
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from celestial coordinates to pixel coordinates.
Definition: Wcs.cc:894
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 1042 of file Wcs.cc.

1046  {
1047  lsst::afw::geom::AffineTransform inverse = linearizePixelToSkyInternal(pix00, coord, skyUnit);
1048  return inverse.invert();
1049 }
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:994
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 922 of file Wcs.cc.

922  {
923 
924  //Construct a coord object of the correct type
925  int const ncompare = 4; // we only care about type's first 4 chars
926  char *type = _wcsInfo->ctype[0];
927  char *radesys = _wcsInfo->radesys;
928  double equinox = _wcsInfo->equinox;
929 
930  if (strncmp(type, "RA--", ncompare) == 0) { // Our default. If it's often something else, consider
931  ; // using an tr1::unordered_map
932  if(strcmp(radesys, "ICRS") == 0) {
933  return afwCoord::makeCoord(afwCoord::ICRS, sky0, sky1);
934  }
935  if(strcmp(radesys, "FK5") == 0) {
936  return afwCoord::makeCoord(afwCoord::FK5, sky0, sky1, equinox);
937  } else {
938  throw LSST_EXCEPT(except::RuntimeError,
939  (boost::format("Can't create Coord object: Unrecognised radesys %s") %
940  radesys).str());
941  }
942 
943  } else if (strncmp(type, "GLON", ncompare) == 0) {
944  return afwCoord::makeCoord(afwCoord::GALACTIC, sky0, sky1);
945  } else if (strncmp(type, "ELON", ncompare) == 0) {
946  return afwCoord::makeCoord(afwCoord::ECLIPTIC, sky0, sky1, equinox);
947  } else if (strncmp(type, "DEC-", ncompare) == 0) {
948  //check for the case where the ctypes are swapped. Note how sky0 and sky1 are swapped as well
949 
950  //Our default
951  if(strcmp(radesys, "ICRS") == 0) {
952  return afwCoord::makeCoord(afwCoord::ICRS, sky1, sky0);
953  }
954  if(strcmp(radesys, "FK5") == 0) {
955  return afwCoord::makeCoord(afwCoord::FK5, sky1, sky0, equinox);
956  } else {
957  throw LSST_EXCEPT(except::RuntimeError,
958  (boost::format("Can't create Coord object: Unrecognised radesys %s") %
959  radesys).str());
960  }
961  } else if (strncmp(type, "GLAT", ncompare) == 0) {
962  return afwCoord::makeCoord(afwCoord::GALACTIC, sky1, sky0);
963  } else if (strncmp(type, "ELAT", ncompare) == 0) {
964  return afwCoord::makeCoord(afwCoord::ECLIPTIC, sky1, sky0, equinox);
965  } else {
966  //Give up in disgust
967  throw LSST_EXCEPT(except::RuntimeError,
968  (boost::format("Can't create Coord object: Unrecognised sys %s") %
969  type).str());
970  }
971 
972  //Can't get here
973  assert(0);
974 }
table::Key< std::string > radesys
Definition: Wcs.cc:1091
table::Key< double > equinox
Definition: Wcs.cc:1090
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
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
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.

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 712 of file Wcs.cc.

713  {
714  //
715  // Figure out the (0, 0), (0, 1), and (1, 0) ra/dec coordinates of the corners of a square drawn in pixel
716  // It'd be better to centre the square at sky00, but that would involve another conversion between sky and
717  // pixel coordinates so I didn't bother
718  //
719  const double side = 1; // length of the square's sides in pixels
720 
721  // Work in 3-space to avoid RA wrapping and pole issues.
722  afwGeom::Point3D v0 = pixelToSky(pix00)->getVector();
723 
724  // Step by "side" in x and y pixel directions...
725  GeomPoint px(pix00);
726  GeomPoint py(pix00);
727  px.shift(afwGeom::Extent2D(side, 0));
728  py.shift(afwGeom::Extent2D(0, side));
729  // Push the points through the WCS, and find difference in 3-space.
730  afwGeom::Extent3D dx = pixelToSky(px)->getVector() - v0;
731  afwGeom::Extent3D dy = pixelToSky(py)->getVector() - v0;
732 
733  // Compute |cross product| = area of parallelogram with sides dx,dy
734  // FIXME -- this is slightly incorrect -- it's making the small-angle
735  // approximation, taking the distance *through* the unit sphere
736  // rather than over its surface.
737  // This is in units of ~radians^2
738  double area = sqrt(square(dx[1]*dy[2] - dx[2]*dy[1]) +
739  square(dx[2]*dy[0] - dx[0]*dy[2]) +
740  square(dx[0]*dy[1] - dx[1]*dy[0]));
741 
742  return area / square(side) * square(180. / afwGeom::PI);
743 }
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 celestial coordinates to pixel coordinates.
Definition: Wcs.cc:894
A coordinate class intended to represent absolute positions.
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 745 of file Wcs.cc.

745  {
746  return sqrt(pixArea(getPixelOrigin())) * afwGeom::degrees;
747 }
lsst::afw::geom::Point2D getPixelOrigin() const
Returns CRPIX (corrected to LSST convention).
Definition: Wcs.cc:577
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:712
AngleUnit const degrees
Definition: Angle.h:92
CoordPtr Wcs::pixelToSky ( double  pixel1,
double  pixel2 
) const

Convert from celestial coordinates to pixel coordinates.

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 894 of file Wcs.cc.

894  {
895  assert(_wcsInfo);
896 
897  afwGeom::Angle skyTmp[2];
898  pixelToSkyImpl(pixel1, pixel2, skyTmp);
899  return makeCorrectCoord(skyTmp[0], skyTmp[1]);
900 }
virtual void pixelToSkyImpl(double pixel1, double pixel2, geom::Angle skyTmp[2]) const
Definition: Wcs.cc:857
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:922
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
CoordPtr Wcs::pixelToSky ( lsst::afw::geom::Point2D const &  pixel) const

Convert from celestial coordiantes to pixel coordinates.

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 885 of file Wcs.cc.

885  {
886  return pixelToSky(pixel.getX(), pixel.getY());
887 }
boost::shared_ptr< coord::Coord > pixelToSky(double pix1, double pix2) const
Convert from celestial coordinates to pixel coordinates.
Definition: Wcs.cc:894
table::Key< table::Point< int > > pixel
void Wcs::pixelToSky ( double  pixel1,
double  pixel2,
geom::Angle sky1,
geom::Angle sky2 
) const

Convert from celestial coordiantes to pixel coordinates.

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

Note
This routine is designed for the knowledgeable user in need of performance; it's safer to call the version that returns a PTR(Coord).

Convert a pixel position (e.g x,y) to a celestial coordinate (e.g ra/dec)

Note
This routine is designed for the knowledgeable user in need of performance; it's safer to call the version that returns a CoordPtr

Definition at line 909 of file Wcs.cc.

909  {
910  afwGeom::Angle skyTmp[2];
911  // HACK -- we shouldn't need to initialize these -- pixelToSkyImpl() sets them unless an
912  // exception is thrown -- but be safe.
913  skyTmp[0] = 0. * afwGeom::radians;
914  skyTmp[1] = 0. * afwGeom::radians;
915  pixelToSkyImpl(pixel1, pixel2, skyTmp);
916  sky1 = skyTmp[0];
917  sky2 = skyTmp[1];
918 }
virtual void pixelToSkyImpl(double pixel1, double pixel2, geom::Angle skyTmp[2]) const
Definition: Wcs.cc:857
AngleUnit const radians
constant with units of radians
Definition: Angle.h:91
void Wcs::pixelToSkyImpl ( double  pixel1,
double  pixel2,
geom::Angle  skyTmp[2] 
) const
privatevirtual

Reimplemented in lsst::afw::image::TanWcs.

Definition at line 857 of file Wcs.cc.

858 {
859  assert(_wcsInfo);
860 
861  // wcslib assumes 1-indexed coordinates
862  double pixTmp[2] = { pixel1 - lsst::afw::image::PixelZeroPos + lsstToFitsPixels,
863  pixel2 - lsst::afw::image::PixelZeroPos + lsstToFitsPixels};
864  double imgcrd[2];
865  double phi, theta;
866 
867  double sky[2];
868  int status = 0;
869  status = wcsp2s(_wcsInfo, 1, 2, pixTmp, imgcrd, &phi, &theta, sky, &status);
870  if (status > 0) {
871  throw LSST_EXCEPT(except::RuntimeError,
872  (boost::format("Error: wcslib returned a status code of %d at pixel %s, %s: %s") %
873  status % pixel1 % pixel2 % wcs_errmsg[status]).str());
874  }
875  // FIXME -- _wcsInfo.lat, _wcsInfo.lng ?
876  skyTmp[0] = sky[0] * afwGeom::degrees;
877  skyTmp[1] = sky[1] * afwGeom::degrees;
878 }
int status
const int lsstToFitsPixels
Definition: Wcs.cc:78
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
AngleUnit const degrees
Definition: Angle.h:92
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
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
void Wcs::rotateImageBy90 ( int  nQuarter,
lsst::afw::geom::Extent2I  dimensions 
) const
virtual

Definition at line 627 of file Wcs.cc.

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

Definition at line 283 of file Wcs.h.

283 {shiftReferencePixel(d.getX(), d.getY());}
void shiftReferencePixel(geom::Extent2D const &d)
Definition: Wcs.h:283
int d
Definition: KDTree.cc:89
void Wcs::shiftReferencePixel ( double  dx,
double  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.

Definition at line 1205 of file Wcs.cc.

1205  {
1206  assert(_wcsInfo);
1207  _wcsInfo->crpix[0] += dx;
1208  _wcsInfo->crpix[1] += dy;
1209 
1210  // tells libwcs to invalidate cached data, since transformation has been modified
1211  _wcsInfo->flag = 0;
1212 }
double dx
Definition: ImageUtils.cc:90
double dy
Definition: ImageUtils.cc:90
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
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 812 of file Wcs.cc.

812  {
813  assert(_wcsInfo);
814 
816  double skyTmp[2];
817  double imgcrd[2];
818  double phi, theta;
819  double pixTmp[2];
820 
821  /*
822  printf("skyToIWC: _coordSystem = %i\n", (int)_coordSystem);
823  printf("coord (%.3f, %.3f)\n", coord->getLongitude().asDegrees(), coord->getLatitude().asDegrees());
824  printf("->sky (%.3f, %.3f)\n", sky->getLongitude().asDegrees(), sky->getLatitude().asDegrees());
825  */
826 
827  skyTmp[_wcsInfo->lng] = sky->getLongitude().asDegrees();
828  skyTmp[_wcsInfo->lat] = sky->getLatitude() .asDegrees();
829 
830  //Estimate pixel coordinates
831  int stat[1];
832  int status = 0;
833  imgcrd[0] = imgcrd[1] = -1e6;
834  /*
835  printf(" skyTmp[] = (%.3f, %.3f)\n", skyTmp[0], skyTmp[1]);
836  printf(" _wcsInfo->lng,lat = %i, %i\n", _wcsInfo->lng, _wcsInfo->lat);
837  */
838  status = wcss2p(_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
839  if (status > 0) {
840  throw LSST_EXCEPT(except::RuntimeError,
841  (boost::format("Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
842  status % skyTmp[0] % skyTmp[1] % wcs_errmsg[status]).str());
843  }
844  /*
845  printf("->iwc (%.3f, %.3f)\n", imgcrd[0], imgcrd[1]);
846  printf("-> pix (%.2f, %.2f)\n", pixTmp[0], pixTmp[1]);
847  afwCoord::Coord::Ptr crval = getSkyOrigin();
848  printf("(crval is (%.3f, %.3f))\n", crval->getLongitude().asDegrees(), crval->getLatitude().asDegrees());
849  */
850  return GeomPoint(imgcrd[0], imgcrd[1]);
851 }
int status
boost::shared_ptr< Coord > Ptr
Definition: Coord.h:73
afw::coord::Coord::Ptr convertCoordToSky(coord::Coord const &coord) const
Definition: Wcs.cc:798
lsst::afw::geom::Point2D GeomPoint
Definition: Wcs.cc:60
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
GeomPoint Wcs::skyToPixel ( geom::Angle  sky1,
geom::Angle  sky2 
) const

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

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

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.

Definition at line 808 of file Wcs.cc.

808  {
809  return skyToPixelImpl(sky1, sky2);
810 }
virtual geom::Point2D skyToPixelImpl(geom::Angle sky1, geom::Angle sky2) const
Definition: Wcs.cc:752
GeomPoint Wcs::skyToPixel ( coord::Coord const &  coord) const

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

Definition at line 791 of file Wcs.cc.

791  {
793  return skyToPixelImpl(sky->getLongitude(), sky->getLatitude());
794 }
boost::shared_ptr< Coord > Ptr
Definition: Coord.h:73
afw::coord::Coord::Ptr convertCoordToSky(coord::Coord const &coord) const
Definition: Wcs.cc:798
virtual geom::Point2D skyToPixelImpl(geom::Angle sky1, geom::Angle sky2) const
Definition: Wcs.cc:752
GeomPoint Wcs::skyToPixelImpl ( geom::Angle  sky1,
geom::Angle  sky2 
) const
privatevirtual

Reimplemented in lsst::afw::image::TanWcs.

Definition at line 752 of file Wcs.cc.

754  {
755  assert(_wcsInfo);
756 
757  double skyTmp[2];
758  double imgcrd[2];
759  double phi, theta;
760  double pixTmp[2];
761  /*
762  printf("_skyCoordsReversed: %c\n", (_skyCoordsReversed ? 'T' : 'F'));
763  printf("wcsinfo.lat: %i, lng: %i\n", _wcsInfo->lat, _wcsInfo->lng);
764  */
765  // WCSLib is smart enough to notice and handle crazy SDSS CTYPE1 = DEC--TAN,
766  // by recording the indices of the long and lat coordinates.
767  skyTmp[_wcsInfo->lng] = sky1.asDegrees();
768  skyTmp[_wcsInfo->lat] = sky2.asDegrees();
769 
770  int stat[1];
771  int status = 0;
772  status = wcss2p(_wcsInfo, 1, 2, skyTmp, &phi, &theta, imgcrd, pixTmp, stat);
773  if (status == 9) {
774  throw LSST_EXCEPT(except::DomainError,
775  (boost::format("sky coordinates %s, %s degrees is not valid for this WCS")
776  % sky1.asDegrees() % sky2.asDegrees()
777  ).str()
778  );
779  }
780  if (status > 0) {
781  throw LSST_EXCEPT(except::RuntimeError,
782  (boost::format("Error: wcslib returned a status code of %d at sky %s, %s deg: %s") %
783  status % sky1.asDegrees() % sky2.asDegrees() % wcs_errmsg[status]).str());
784  }
785 
786  // wcslib assumes 1-indexed coords
789 }
int status
Point< double, 2 > Point2D
Definition: Point.h:277
double asDegrees() const
Definition: Angle.h:124
const int fitsToLsstPixels
Definition: Wcs.cc:79
#define LSST_EXCEPT(type,...)
Definition: Exception.h:46
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
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
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 1128 of file Wcs.cc.

1128  {
1129  WcsPersistenceHelper const & keys = WcsPersistenceHelper::get();
1130  afw::table::BaseCatalog catalog = handle.makeCatalog(keys.schema);
1131  PTR(afw::table::BaseRecord) record = catalog.addNew();
1132  record->set(keys.crval, getSkyOrigin()->getPosition(afw::geom::degrees));
1133  record->set(keys.crpix, getPixelOrigin());
1134  Eigen::Matrix2d cdIn = getCDMatrix();
1135  Eigen::Map<Eigen::Matrix2d> cdOut((*record)[keys.cd].getData());
1136  cdOut = cdIn;
1137  record->set(keys.ctype1, std::string(_wcsInfo[0].ctype[0]));
1138  record->set(keys.ctype2, std::string(_wcsInfo[0].ctype[1]));
1139  record->set(keys.equinox, _wcsInfo[0].equinox);
1140  record->set(keys.radesys, std::string(_wcsInfo[0].radesys));
1141  record->set(keys.cunit1, std::string(_wcsInfo[0].cunit[0]));
1142  record->set(keys.cunit2, std::string(_wcsInfo[0].cunit[1]));
1143  handle.saveCatalog(catalog);
1144 }
#define PTR(...)
Definition: base.h:41
table::Key< table::Array< double > > cd
Definition: Wcs.cc:1087
CatalogT< BaseRecord > BaseCatalog
Definition: fwd.h:61
table::Key< std::string > radesys
Definition: Wcs.cc:1091
table::Key< std::string > ctype2
Definition: Wcs.cc:1089
table::Key< table::Point< double > > crval
Definition: Wcs.cc:1085
table::Key< double > equinox
Definition: Wcs.cc:1090
Eigen::Matrix2d getCDMatrix() const
Returns CD matrix. You would never have guessed that from the name.
Definition: Wcs.cc:587
table::Key< table::Point< double > > crpix
Definition: Wcs.cc:1086
lsst::afw::geom::Point2D getPixelOrigin() const
Returns CRPIX (corrected to LSST convention).
Definition: Wcs.cc:577
lsst::afw::coord::Coord::Ptr getSkyOrigin() const
Returns CRVAL.
Definition: Wcs.cc:571
table::Key< std::string > cunit1
Definition: Wcs.cc:1092
AngleUnit const degrees
Definition: Angle.h:92
table::Key< std::string > ctype1
Definition: Wcs.cc:1088
struct wcsprm * _wcsInfo
Definition: Wcs.h:353
afw::table::SourceRecord * record
table::Key< std::string > cunit2
Definition: Wcs.cc:1093

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 305 of file Wcs.h.

Member Data Documentation

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

Definition at line 359 of file Wcs.h.

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

Definition at line 358 of file Wcs.h.

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

Definition at line 354 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 355 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 356 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 357 of file Wcs.h.

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

Definition at line 353 of file Wcs.h.


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