LSSTApplications
19.0.0-14-gb0260a2+72efe9b372,20.0.0+7927753e06,20.0.0+8829bf0056,20.0.0+995114c5d2,20.0.0+b6f4b2abd1,20.0.0+bddc4f4cbe,20.0.0-1-g253301a+8829bf0056,20.0.0-1-g2b7511a+0d71a2d77f,20.0.0-1-g5b95a8c+7461dd0434,20.0.0-12-g321c96ea+23efe4bbff,20.0.0-16-gfab17e72e+fdf35455f6,20.0.0-2-g0070d88+ba3ffc8f0b,20.0.0-2-g4dae9ad+ee58a624b3,20.0.0-2-g61b8584+5d3db074ba,20.0.0-2-gb780d76+d529cf1a41,20.0.0-2-ged6426c+226a441f5f,20.0.0-2-gf072044+8829bf0056,20.0.0-2-gf1f7952+ee58a624b3,20.0.0-20-geae50cf+e37fec0aee,20.0.0-25-g3dcad98+544a109665,20.0.0-25-g5eafb0f+ee58a624b3,20.0.0-27-g64178ef+f1f297b00a,20.0.0-3-g4cc78c6+e0676b0dc8,20.0.0-3-g8f21e14+4fd2c12c9a,20.0.0-3-gbd60e8c+187b78b4b8,20.0.0-3-gbecbe05+48431fa087,20.0.0-38-ge4adf513+a12e1f8e37,20.0.0-4-g97dc21a+544a109665,20.0.0-4-gb4befbc+087873070b,20.0.0-4-gf910f65+5d3db074ba,20.0.0-5-gdfe0fee+199202a608,20.0.0-5-gfbfe500+d529cf1a41,20.0.0-6-g64f541c+d529cf1a41,20.0.0-6-g9a5b7a1+a1cd37312e,20.0.0-68-ga3f3dda+5fca18c6a4,20.0.0-9-g4aef684+e18322736b,w.2020.45
LSSTDataManagementBasePackage
|
Go to the documentation of this file.
58 int const SERIALIZATION_VERSION = 1;
66 double const TIGHT_FITS_TOL = 0.0001;
68 class SkyWcsPersistenceHelper {
71 table::Key<table::Array<std::uint8_t>>
wcs;
73 static SkyWcsPersistenceHelper
const& get() {
74 static SkyWcsPersistenceHelper instance;
79 SkyWcsPersistenceHelper(
const SkyWcsPersistenceHelper&) =
delete;
80 SkyWcsPersistenceHelper& operator=(
const SkyWcsPersistenceHelper&) =
delete;
83 SkyWcsPersistenceHelper(SkyWcsPersistenceHelper&&) =
delete;
84 SkyWcsPersistenceHelper& operator=(SkyWcsPersistenceHelper&&) =
delete;
87 SkyWcsPersistenceHelper()
89 wcs(
schema.addField<table::Array<
std::uint8_t>>(
"wcs",
"wcs string representation",
"")) {}
92 class SkyWcsFactory :
public table::io::PersistableFactory {
97 CatalogVector
const& catalogs)
const override {
98 SkyWcsPersistenceHelper
const&
keys = SkyWcsPersistenceHelper::get();
102 table::BaseRecord
const& record = catalogs.front().front();
104 return SkyWcs::readString(stringRep);
108 std::string getSkyWcsPersistenceName() {
return "SkyWcs"; }
110 SkyWcsFactory registration(getSkyWcsPersistenceName());
117 auto const initialWcs =
119 auto const initialFrameDict = initialWcs->getFrameDict();
120 auto const iwcToSkyMap = initialFrameDict->getMapping(
"IWC",
"SKY");
121 auto const pixelFrame = initialFrameDict->getFrame(
"PIXELS");
122 auto const iwcFrame = initialFrameDict->getFrame(
"IWC");
123 auto const skyFrame = initialFrameDict->getFrame(
"SKY");
126 ndarray::Array<double, 2, 2> fieldAngleToIwcNdArray = ndarray::allocate(2, 2);
127 asEigenMatrix(fieldAngleToIwcNdArray) = orientationAndFlipXMatrix * 180.0 /
lsst::geom::PI;
128 auto const pixelsToFieldAngleMap = pixelsToFieldAngle.getMapping();
129 auto const fieldAngleToIwcMap =
ast::MatrixMap(fieldAngleToIwcNdArray);
130 auto const pixelsToIwcMap = pixelsToFieldAngleMap->then(fieldAngleToIwcMap);
131 auto finalFrameDict =
ast::FrameDict(*pixelFrame, pixelsToIwcMap, *iwcFrame);
132 finalFrameDict.addFrame(
"IWC", *iwcToSkyMap, *skyFrame);
133 return finalFrameDict;
140 Eigen::Matrix2d cdMatrix;
142 double scaleDeg =
scale.asDegrees();
143 double xmult = flipX ? 1.0 : -1.0;
144 cdMatrix(0, 0) =
std::cos(orientRad) * scaleDeg * xmult;
145 cdMatrix(0, 1) =
std::sin(orientRad) * scaleDeg;
146 cdMatrix(1, 0) = -
std::sin(orientRad) * scaleDeg * xmult;
147 cdMatrix(1, 1) =
std::cos(orientRad) * scaleDeg;
153 return src.getTransform()->then(*dstInverse);
166 double const side = 1.0;
176 auto skyLL = skyVec[0].getVector();
177 auto skyDx = skyVec[1].getVector() - skyLL;
178 auto skyDy = skyVec[2].getVector() - skyLL;
183 double skyAreaSq = skyDx.cross(skyDy).getSquaredNorm();
189 auto skyFrame = std::dynamic_pointer_cast<ast::SkyFrame>(
194 auto const crvalRad = skyFrame->getSkyRef();
201 return pixelToIwcTransform.getJacobian(
pixel);
210 return std::make_shared<SkyWcs>(*metadata);
223 auto const iwcToSky = thisDict->getMapping(
"IWC",
"SKY");
224 auto const gridToSky = gridToPixel.
then(*pixelToIwc).
then(*iwcToSky);
229 os <<
"Encoding=FITS-WCS, CDMatrix=1, FitsAxisOrder=<copy>, FitsTol=" << TIGHT_FITS_TOL;
234 if (nObjectsWritten == 0) {
237 "Could not represent this SkyWcs using FITS-WCS metadata");
242 header = tanWcs->getFitsMetadata(
true);
249 header->remove(
"DATE-OBS");
250 header->remove(
"MJD-OBS");
253 bool const hasCd11 = header->exists(
"CD1_1");
254 bool const hasCd12 = header->exists(
"CD1_2");
255 bool const hasCd21 = header->exists(
"CD2_1");
256 bool const hasCd22 = header->exists(
"CD2_2");
257 if (hasCd11 || hasCd12 || hasCd21 || hasCd22) {
258 if (!hasCd11) header->set(
"CD1_1", 0.0,
"Transformation matrix element");
259 if (!hasCd12) header->set(
"CD1_2", 0.0,
"Transformation matrix element");
260 if (!hasCd21) header->set(
"CD2_1", 0.0,
"Transformation matrix element");
261 if (!hasCd22) header->set(
"CD2_2", 0.0,
"Transformation matrix element");
282 return _linearizePixelToSky(
skyToPixel(coord), coord, skyUnit);
286 return _linearizePixelToSky(pix,
pixelToSky(pix), skyUnit);
291 return _linearizeSkyToPixel(
skyToPixel(coord), coord, skyUnit);
296 return _linearizeSkyToPixel(pix,
pixelToSky(pix), skyUnit);
316 is >> shortClassName;
326 auto frameSet = std::dynamic_pointer_cast<ast::FrameSet>(astObjectPtr);
329 os <<
"The AST serialization was read as a " << astObjectPtr->getClassName()
330 <<
" instead of a FrameSet";
334 return std::make_shared<SkyWcs>(frameDict);
354 return std::make_unique<SkyWcs>(*
this);
360 os <<
"FITS standard SkyWcs:";
362 os <<
"Non-standard SkyWcs (Frames: ";
379 return singleClassEquals(*
this,
other);
387 SkyWcsPersistenceHelper
const&
keys = SkyWcsPersistenceHelper::get();
395 : _frameDict(frameDict), _transform(), _pixelOrigin(), _pixelScaleAtOrigin(0 *
lsst::
geom::
radians) {
402 for (
auto const& domainName : domainNames) {
404 auto const frame = frameDict.
getFrame(domainName,
false);
405 if (frame->getNAxes() != 2) {
407 "Frame " + domainName +
" has " +
std::to_string(frame->getNAxes()) +
408 " axes instead of 2");
410 auto desiredClassName = domainName ==
"SKY" ?
"SkyFrame" :
"Frame";
411 if (frame->getClassName() != desiredClassName) {
413 "Frame " + domainName +
" is of type " + frame->getClassName() +
414 " instead of " + desiredClassName);
416 }
else if (domainName !=
"ACTUAL_PIXELS") {
419 "No frame with domain " + domainName +
" found");
425 if (baseDomain !=
"ACTUAL_PIXELS" && baseDomain !=
"PIXELS") {
427 "Base frame has domain " + baseDomain +
" instead of PIXELS or ACTUAL_PIXELS");
432 if (currentDomain !=
"SKY") {
434 "Current frame has domain " + currentDomain +
" instead of SKY");
437 return frameDict.
copy();
446 const double side = 1.0;
452 m(0, 0) = dsky10.first.asAngularUnits(skyUnit) / side;
453 m(0, 1) = dsky01.first.asAngularUnits(skyUnit) / side;
454 m(1, 0) = dsky10.second.asAngularUnits(skyUnit) / side;
455 m(1, 1) = dsky01.second.asAngularUnits(skyUnit) / side;
457 Eigen::Vector2d sky00v;
458 sky00v << sky00.getX(), sky00.getY();
459 Eigen::Vector2d pix00v;
460 pix00v << pix00.getX(), pix00.getY();
474 double const dx = 1000;
492 bool modifyActualPixels) {
493 auto const pixelMapping = pixelTransform.
getMapping();
494 auto oldFrameDict =
wcs.getFrameDict();
495 bool const hasActualPixels = oldFrameDict->hasDomain(
"ACTUAL_PIXELS");
496 auto const pixelFrame = oldFrameDict->getFrame(
"PIXELS",
false);
497 auto const iwcFrame = oldFrameDict->getFrame(
"IWC",
false);
498 auto const skyFrame = oldFrameDict->getFrame(
"SKY",
false);
499 auto const oldPixelToIwc = oldFrameDict->getMapping(
"PIXELS",
"IWC");
500 auto const iwcToSky = oldFrameDict->getMapping(
"IWC",
"SKY");
504 if (hasActualPixels) {
505 auto const actualPixelFrame = oldFrameDict->getFrame(
"ACTUAL_PIXELS",
false);
506 auto const oldActualPixelToPixels = oldFrameDict->getMapping(
"ACTUAL_PIXELS",
"PIXELS");
508 if (modifyActualPixels) {
509 newActualPixelsToPixels = pixelMapping->
then(*oldActualPixelToPixels).
simplified();
510 newPixelToIwc = oldPixelToIwc;
512 newActualPixelsToPixels = oldActualPixelToPixels;
516 std::make_shared<ast::FrameDict>(*actualPixelFrame, *newActualPixelsToPixels, *pixelFrame);
517 newFrameDict->
addFrame(
"PIXELS", *newPixelToIwc, *iwcFrame);
520 newFrameDict = std::make_shared<ast::FrameDict>(*pixelFrame, *newPixelToIwc, *iwcFrame);
522 newFrameDict->
addFrame(
"IWC", *iwcToSky, *skyFrame);
523 return std::make_shared<SkyWcs>(*newFrameDict);
527 return std::make_shared<SkyWcs>(metadata,
strip);
531 Eigen::Matrix2d
const& cdMatrix,
std::string const& projection) {
533 return std::make_shared<SkyWcs>(*metadata);
539 auto frameDict = makeSkyWcsFrameDict(pixelsToFieldAngle,
orientation, flipX, boresight, projection);
540 return std::make_shared<SkyWcs>(frameDict);
544 Eigen::Matrix2d
const& cdMatrix, Eigen::MatrixXd
const& sipA,
545 Eigen::MatrixXd
const& sipB) {
547 return std::make_shared<SkyWcs>(*metadata);
551 Eigen::Matrix2d
const& cdMatrix, Eigen::MatrixXd
const& sipA,
552 Eigen::MatrixXd
const& sipB, Eigen::MatrixXd
const& sipAp,
553 Eigen::MatrixXd
const& sipBp) {
555 return std::make_shared<SkyWcs>(*metadata);
560 auto iwcToSky =
wcs.getFrameDict()->getMapping(
"IWC",
"SKY");
561 return std::make_shared<TransformPoint2ToSpherePoint>(*iwcToSky, simplify);
566 return std::make_shared<TransformPoint2ToPoint2>(*pixelToIwc, simplify);
570 os <<
wcs.toString();
constexpr AngleUnit degrees
constant with units of degrees
std::shared_ptr< Mapping > getMapping(int from, std::string const &to) const
Variant of FrameSet::getMapping with the second frame specified by domain.
lsst::geom::AffineTransform linearizeSkyToPixel(lsst::geom::SpherePoint const &coord, lsst::geom::AngleUnit const &skyUnit) const
Return the local linear approximation to skyToPixel at a point given in sky coordinates.
bool isFits() const
Return true getFitsMetadata(true) will succeed, false if not.
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
bool isFlipped() const
Does the WCS follow the convention of North=Up, East=Left?
constexpr double PI
The ratio of a circle's circumference to diameter.
static std::shared_ptr< SkyWcs > readString(std::string &str)
Deserialize a SkyWcs from a string, using the same format as readStream.
A FrameSet consists of a set of one or more Frames (which describe coordinate systems),...
Point2D getPosition(AngleUnit unit) const noexcept
Return longitude, latitude as a Point2D object.
std::shared_ptr< Mapping > simplified() const
Return a simplied version of the mapping (which may be a compound Mapping such as a CmpMap).
std::shared_ptr< FrameDict > copy() const
Return a deep copy of this object.
lsst::geom::SpherePoint SpherePoint
table::Key< int > version
table::Key< table::Array< std::uint8_t > > wcs
An object passed to Persistable::write to allow it to persist itself.
int orientation(UnitVector3d const &a, UnitVector3d const &b, UnitVector3d const &c)
orientation computes and returns the orientations of 3 unit vectors a, b and c.
SeriesMap then(Mapping const &next) const
Return a series compound mapping this(first(input)) containing shallow copies of the original.
void saveCatalog(BaseCatalog const &catalog)
Save a catalog in the archive.
std::string toString() const override
Create a string representation of this object.
std::shared_ptr< SkyWcs > copyAtShiftedPixelOrigin(lsst::geom::Extent2D const &shift) const
Return a copy of this SkyWcs with the pixel origin shifted by the specified amount.
std::shared_ptr< daf::base::PropertyList > getPropertyListFromFitsChan(ast::FitsChan &fitsChan)
Copy values from an AST FitsChan into a PropertyList.
A specialized form of Channel which reads and writes FITS header cards.
A FrameSet whose frames can be referenced by domain name.
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
int write(Object const &object)
Write an object to a channel.
void addFrame(int iframe, Mapping const &map, Frame const &frame) override
Add a new Frame and an associated Mapping to this FrameSet so as to define a new coordinate system,...
std::shared_ptr< SkyWcs > makeModifiedWcs(TransformPoint2ToPoint2 const &pixelTransform, SkyWcs const &wcs, bool modifyActualPixels)
Create a new SkyWcs whose pixels are transformed by pixelTransform, as described below.
std::pair< Angle, Angle > getTangentPlaneOffset(SpherePoint const &other) const
Get the offset from a tangent plane centered at this point to another point.
A 2-dimensional celestial WCS that transform pixels to ICRS RA/Dec, using the LSST standard for pixel...
Interface supporting iteration over heterogenous containers.
table::PointKey< double > crval
MatrixMap is a form of Mapping which performs a general linear transformation.
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
std::shared_ptr< RecordT > src
std::shared_ptr< typehandling::Storable > cloneStorable() const override
Create a new SkyWcs that is a copy of this one.
std::shared_ptr< Frame > getFrame(std::string const &domain, bool copy=true) const
Variant of getFrame(int, bool) where the frame is specified by domain name.
A WinMap is a linear Mapping which transforms a rectangular window in one coordinate system into a si...
BaseCatalog makeCatalog(Schema const &schema)
Return a new, empty catalog with the given schema.
Channel provides input/output of AST objects.
SkyWcs(SkyWcs const &)=default
std::ostream & operator<<(std::ostream &os, GenericEndpoint const &endpoint)
Print "GenericEndpoint(_n_)" to the ostream where _n_ is the number of axes, e.g. "GenericAxes(4)".
A stream for ast::Channel.
std::shared_ptr< ast::FrameDict > readLsstSkyWcs(daf::base::PropertySet &metadata, bool strip=true)
Read an LSST celestial WCS FrameDict from a FITS header.
std::shared_ptr< TransformPoint2ToPoint2 > getPixelToIntermediateWorldCoords(SkyWcs const &wcs, bool simplify=true)
Return a transform from pixel coordinates to intermediate world coordinates.
static std::string getShortClassName()
Frame is used to represent a coordinate system.
static constexpr int CURRENT
index of current frame
lsst::geom::Point2D skyToPixel(lsst::geom::SpherePoint const &sky) const
Compute pixel position(s) from sky position(s)
bool operator==(SkyWcs const &other) const
Equality is based on the string representations being equal.
std::shared_ptr< SkyWcs > makeTanSipWcs(lsst::geom::Point2D const &crpix, lsst::geom::SpherePoint const &crval, Eigen::Matrix2d const &cdMatrix, Eigen::MatrixXd const &sipA, Eigen::MatrixXd const &sipB)
Construct a TAN-SIP SkyWcs with forward SIP distortion terms and an iterative inverse.
table::PointKey< double > crpix
ShiftMap is a linear Mapping which shifts each axis by a specified constant value.
Eigen::Matrix2d getCdMatrix() const
Get the 2x2 CD matrix at the pixel origin.
ItemVariant const * other
void show(std::ostream &os, bool showComments=true) const
Print a textual description the object to an ostream.
bool equals(typehandling::Storable const &other) const noexcept override
Compare this object to another Storable.
Reports errors in the logical structure of the program.
std::shared_ptr< SkyWcs > makeFlippedWcs(SkyWcs const &wcs, bool flipLR, bool flipTB, lsst::geom::Point2D const ¢er)
Return a copy of a FITS-WCS with pixel positions flipped around a specified center.
Transform< Point2Endpoint, Point2Endpoint > TransformPoint2ToPoint2
table::PointKey< int > pixel
lsst::geom::SpherePoint pixelToSky(lsst::geom::Point2D const &pixel) const
Compute sky position(s) from pixel position(s)
A base class for image defects.
String-based source and sink for channels.
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
std::shared_ptr< TransformPoint2ToSpherePoint > getIntermediateWorldCoordsToSky(SkyWcs const &wcs, bool simplify=true)
Return a transform from intermediate world coordinates to sky.
std::shared_ptr< Object > read()
Read an object from a channel.
lsst::geom::AffineTransform linearizePixelToSky(lsst::geom::SpherePoint const &coord, lsst::geom::AngleUnit const &skyUnit) const
Return the local linear approximation to pixelToSky at a point given in sky coordinates.
std::shared_ptr< SkyWcs > getTanWcs(lsst::geom::Point2D const &pixel) const
Get a local TAN WCS approximation to this WCS at the specified pixel position.
std::shared_ptr< const ast::FrameDict > getFrameDict() const
Get the contained FrameDict.
Eigen::Matrix2d makeCdMatrix(lsst::geom::Angle const &scale, lsst::geom::Angle const &orientation=0 *lsst::geom::degrees, bool flipX=false)
Make a WCS CD matrix.
static std::shared_ptr< T > dynamicCast(std::shared_ptr< Persistable > const &ptr)
Dynamically cast a shared_ptr.
std::shared_ptr< TransformPoint2ToPoint2 > makeWcsPairTransform(SkyWcs const &src, SkyWcs const &dst)
A Transform obtained by putting two SkyWcs objects "back to back".
static constexpr int BASE
index of base frame
#define LSST_ARCHIVE_ASSERT(EXPR)
An assertion macro used to validate the structure of an InputArchive.
std::shared_ptr< daf::base::PropertyList > getFitsMetadata(bool precise=false) const
Return the WCS as FITS WCS metadata.
A class used to convert scalar POD types such as double to Angle.
lsst::geom::Angle getPixelScale() const
Get the pixel scale at the pixel origin.
bool hasFitsApproximation() const
Does this SkyWcs have an approximate SkyWcs that can be represented as standard FITS WCS?
A class representing an angle.
Class for storing generic metadata.
std::shared_ptr< daf::base::PropertyList > makeTanSipMetadata(lsst::geom::Point2D const &crpix, lsst::geom::SpherePoint const &crval, Eigen::Matrix2d const &cdMatrix, Eigen::MatrixXd const &sipA, Eigen::MatrixXd const &sipB)
Make metadata for a TAN-SIP WCS without inverse matrices.
def scale(algorithm, min, max=None, frame=None)
constexpr AngleUnit radians
constant with units of radians
std::shared_ptr< SkyWcs > makeSkyWcs(daf::base::PropertySet &metadata, bool strip=false)
Construct a SkyWcs from FITS keywords.
Extent< double, 2 > Extent2D
lsst::geom::Point2D getPixelOrigin() const
Get the pixel origin, in pixels, using the LSST convention.
std::shared_ptr< daf::base::PropertyList > makeSimpleWcsMetadata(lsst::geom::Point2D const &crpix, lsst::geom::SpherePoint const &crval, Eigen::Matrix2d const &cdMatrix, std::string const &projection="TAN")
Make FITS metadata for a simple FITS WCS (one with no distortion).
Reports errors from accepting an object of an unexpected or inappropriate type.
Point in an unspecified spherical coordinate system.
std::string writeString() const
Serialize this SkyWcs to a string, using the same format as writeStream.
std::shared_ptr< RecordT > addNew()
Create a new record, add it to the end of the catalog, and return a pointer to it.
static std::shared_ptr< SkyWcs > readStream(std::istream &is)
Deserialize a SkyWcs from an input stream.
std::shared_ptr< const TransformPoint2ToSpherePoint > getTransform() const
Get a TransformPoint2ToSpherePoint that transforms pixels to sky in the forward direction and sky to ...
constexpr double asArcseconds() const noexcept
Return an Angle's value in arcseconds.
lsst::geom::SpherePoint getSkyOrigin() const
Get the sky origin, the celestial fiducial point.
void writeStream(std::ostream &os) const
Serialize this SkyWcs to an output stream.
std::set< std::string > getAllDomains() const
Get the domain names for all contained Frames (excluding frames with empty or defaulted domain names)...
Reports errors that are due to events beyond the control of the program.
bool hasDomain(std::string const &domain) const
Return True if a frame in this FrameDict has the specified domain.