Files
tenmon/3rdparty/include/pcl/AstrometricMetadata.h
T
2022-04-12 08:17:18 +02:00

1122 lines
38 KiB
C++

// ____ ______ __
// / __ \ / ____// /
// / /_/ // / / /
// / ____// /___ / /___ PixInsight Class Library
// /_/ \____//_____/ PCL 2.4.23
// ----------------------------------------------------------------------------
// pcl/AstrometricMetadata.h - Released 2022-03-12T18:59:29Z
// ----------------------------------------------------------------------------
// This file is part of the PixInsight Class Library (PCL).
// PCL is a multiplatform C++ framework for development of PixInsight modules.
//
// Copyright (c) 2003-2022 Pleiades Astrophoto S.L. All Rights Reserved.
//
// Redistribution and use in both source and binary forms, with or without
// modification, is permitted provided that the following conditions are met:
//
// 1. All redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. All redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. Neither the names "PixInsight" and "Pleiades Astrophoto", nor the names
// of their contributors, may be used to endorse or promote products derived
// from this software without specific prior written permission. For written
// permission, please contact info@pixinsight.com.
//
// 4. All products derived from this software, in any form whatsoever, must
// reproduce the following acknowledgment in the end-user documentation
// and/or other materials provided with the product:
//
// "This product is based on software from the PixInsight project, developed
// by Pleiades Astrophoto and its contributors (https://pixinsight.com/)."
//
// Alternatively, if that is where third-party acknowledgments normally
// appear, this acknowledgment must be reproduced in the product itself.
//
// THIS SOFTWARE IS PROVIDED BY PLEIADES ASTROPHOTO AND ITS CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PLEIADES ASTROPHOTO OR ITS
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, BUSINESS
// INTERRUPTION; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; AND LOSS OF USE,
// DATA OR PROFITS) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// ----------------------------------------------------------------------------
#ifndef __PCL_AstrometricMetadata_h
#define __PCL_AstrometricMetadata_h
/// \file pcl/AstrometricMetadata.h
#include <pcl/Defs.h>
#include <pcl/AutoPointer.h>
#include <pcl/Optional.h>
#include <pcl/Point.h>
#include <pcl/ProjectionBase.h>
#include <pcl/Property.h>
#include <pcl/SphericalRotation.h>
#include <pcl/TimePoint.h>
#include <pcl/WCSKeywords.h>
#include <pcl/WorldTransformation.h>
/*
* Based on original work contributed by Andrés del Pozo.
*/
#ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
namespace pi
{
class ImageWindow;
}
#endif
namespace pcl
{
// ----------------------------------------------------------------------------
/*!
* \defgroup astrometry_support Astrometry Support Classes
*
* This group of classes implement the core astrometry support on the
* PixInsight platform.
*
* The original implementation of these classes has been contributed by Spanish
* software developer and PTeam member Andrés del Pozo, who is also the author
* of all astrometry scripts available in the standard PixInsight distribution,
* including the ImageSolver and AnnotateImage scripts, among others.
*/
// ----------------------------------------------------------------------------
#ifndef __PCL_BUILDING_PIXINSIGHT_APPLICATION
class PCL_CLASS ImageWindow;
#endif
class PCL_CLASS XISFReader;
class PCL_CLASS XISFWriter;
/*!
* \class AstrometricMetadata
* \brief Astrometric metadata
*
* \ingroup astrometry_support
*/
class PCL_CLASS AstrometricMetadata
{
public:
/*!
* \struct pcl::AstrometricMetadata::DescriptionItems
* \brief A collection of strings describing the properties and parameters
* of an astrometric solution.
*/
struct DescriptionItems
{
String referenceMatrix;
String wcsTransformationType;
String controlPoints;
String splineLengths;
String projectionName;
String projectionOrigin;
String resolution;
String rotation;
String referenceSystem;
String observationStartTime;
String observationEndTime;
String observerLocation;
String focalDistance;
String pixelSize;
String fieldOfView;
String centerCoordinates;
String topLeftCoordinates;
String topRightCoordinates;
String bottomLeftCoordinates;
String bottomRightCoordinates;
};
/*!
* Default constructor. Constructs an uninitialized %AstrometricMetadata
* object.
*/
AstrometricMetadata() = default;
/*!
* Copy constructor.
*/
AstrometricMetadata( const AstrometricMetadata& x )
: m_projection( x.m_projection->Clone() )
, m_transformWI( x.m_transformWI->Clone() )
, m_refSys( x.m_refSys )
, m_width( x.m_width )
, m_height( x.m_height )
, m_pixelSize( x.m_pixelSize )
, m_obsStartTime( x.m_obsStartTime )
, m_obsEndTime( x.m_obsEndTime )
, m_geoLongitude( x.m_geoLongitude )
, m_geoLatitude( x.m_geoLatitude )
, m_geoHeight( x.m_geoHeight )
, m_resolution( x.m_resolution )
, m_focalLength( x.m_focalLength )
{
}
/*!
* Move constructor.
*/
AstrometricMetadata( AstrometricMetadata&& ) = default;
/*!
* Constructor from minimal data.
*
* \param projection Pointer to a dynamically allocated projection
* system.
*
* \param worldTransformation Pointer to a dynamically allocated world
* transformation.
*
* \param width Width in pixels of the image with which this
* astrometric solution is associated.
*
* \param height Height in pixels of the image with which this
* astrometric solution is associated.
*
* Ownership of the specified \a projection and \a worldTransformation
* objects will be transferred to this object, which will destroy and
* deallocate them when appropriate.
*/
AstrometricMetadata( ProjectionBase* projection, WorldTransformation* worldTransformation, int width, int height );
#ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
// Implemented in /core/Components/ImageWindow.cpp
AstrometricMetadata( const pi::ImageWindow* );
#else
/*!
* Constructs an %AstrometricMetadata object from the existing keywords and
* properties of an image \a window.
*/
AstrometricMetadata( const ImageWindow& window );
#endif
/*!
* Constructs an %AstrometricMetadata object from the existing keywords and
* properties of the currently selected image in an XISF \a reader.
*/
AstrometricMetadata( XISFReader& reader );
/*!
* Virtual destructor.
*/
virtual ~AstrometricMetadata()
{
}
/*!
* Copy constructor. Returns a reference to this object.
*/
AstrometricMetadata& operator =( const AstrometricMetadata& x )
{
m_projection = x.m_projection->Clone();
m_transformWI = x.m_transformWI->Clone();
m_refSys = x.m_refSys;
m_width = x.m_width;
m_height = x.m_height;
m_pixelSize = x.m_pixelSize;
m_obsStartTime = x.m_obsStartTime;
m_obsEndTime = x.m_obsEndTime;
m_geoLongitude = x.m_geoLongitude;
m_geoLatitude = x.m_geoLatitude;
m_geoHeight = x.m_geoHeight;
m_resolution = x.m_resolution;
m_focalLength = x.m_focalLength;
return *this;
}
/*!
* Move constructor. Returns a reference to this object.
*/
AstrometricMetadata& operator =( AstrometricMetadata&& ) = default;
/*!
* Returns true iff this object is valid. A valid %AstrometricMetadata
* instance defines a projection system and a world transformation.
*/
bool IsValid() const
{
return !m_projection.IsNull() && !m_transformWI.IsNull();
}
/*!
* Checks that this astrometric solution is valid and can perform coherent
* coordinate transformations, and returns the reprojection errors
* measured at the center and the four corners of the image.
*
* \param[out] centerErrors Reprojection errors at the geometric center
* of the image, or (Width()/2,Height()/2)
* image coordinates.
*
* \param[out] topLeftErrors Reprojection errors at (0,0) image
* coordinates.
*
* \param[out] topRightErrors Reprojection errors at (Width(),0) image
* coordinates.
*
* \param[out] bottomLeftErrors Reprojection errors at (0,Height()) image
* coordinates.
*
* \param[out] bottomRightErrors Reprojection errors at (Width(),Height())
* image coordinates.
*
* This routine performs five successive coordinate transformations, from
* image to celestial and from celestial to image coordinates, computed for
* the four corners and the geometric center of the image. The reported
* values in the specified point variables are the differences between the
* initial and final image coordinates, on the X and Y axes, in pixels.
*
* This function throws an Error exception if the solution has not been
* initialized, or if it cannot perform valid coordinate transformations.
*/
void Verify( DPoint& centerErrors,
DPoint& topLeftErrors, DPoint& topRightErrors,
DPoint& bottomLeftErrors, DPoint& bottomRightErrors ) const;
/*!
* Checks that this astrometric solution is valid and can perform coherent
* coordinate transformations.
*
* \param tolerance Maximum difference in pixels allowed for validation.
* The default value is 0.01 pixels.
*
* This routine performs two successive coordinate transformations, from
* image to celestial and from celestial to image coordinates, computed for
* the geometric center of the image. If the absolute value of the
* difference between the initial and final image coordinates is greater
* than the specified tolerance in pixels, for one or both axes, an Error
* exception is thrown.
*
* This function also throws an Error exception if the solution has not been
* initialized, or if it cannot perform valid coordinate transformations.
*/
void Validate( double tolerance = 0.01 ) const;
/*!
* Returns true if this object uses a world transformation based on 2-D
* surface splines (or <em>thin plates</em>), false if a WCS linear
* transformation is being used.
*/
bool HasSplineWorldTransformation() const
{
return dynamic_cast<const SplineWorldTransformation*>( m_transformWI.Pointer() ) != nullptr;
}
#ifdef __PCL_BUILDING_PIXINSIGHT_APPLICATION
// Implemented in /core/Components/ImageWindow/ImageWindow.cpp
void Write( pi::ImageWindow* window, bool notify = true ) const;
#else
/*!
* Updates the keywords and properties of an image \a window to represent
* this astrometric solution.
*
* The pixel dimensions of the image in the target \a window must be
* coherent with this astrometric solution. If that is not true, this member
* function will throw an Error exception. An Error exception will also be
* thrown if this object does not define a valid astrometric solution.
*
* See the UpdateBasicKeywords(), UpdateWCSKeywords() and UpdateProperties()
* member functions for information on the metadata items modified by this
* function.
*/
void Write( ImageWindow& window, bool notify = true ) const;
#endif
/*!
* Updates the keywords and properties of the current image in an XISF
* \a writer to store the astrometric solution represented by this object.
*
* The caller must ensure that the pixel dimensions of the current image in
* the target %XISF \a writer, that is, the width and height of the image
* being generated, are coherent with this astrometric solution. Currently
* this condition cannot be verified or enforced by this member function.
*
* This function will throw an Error exception if this object does not
* define a valid astrometric solution.
*
* See the UpdateBasicKeywords(), UpdateWCSKeywords() and UpdateProperties()
* member functions for information on the metadata items modified by this
* function.
*/
void Write( XISFWriter& writer ) const;
/*!
* Returns the name of the coordinate reference system to which this
* astrometric solution has been referred.
*
* This corresponds to the reference system of the coordinates of the
* reference point sources (usually stars with data acquired from
* astrometric catalogs) used to compute the astrometric solution. The
* current implementation supports the following reference systems:
*
* \b ICRS
*
* Reference point source positions are \e astrometric: they include
* corrections for space motion (proper motions, annual parallax and radial
* velocity, when available) and gravitational deflection of light, but
* \e not annual aberration. This is the default reference system that is
* assumed when none is specified or acquired from existing metadata.
*
* \b GCRS
*
* Reference point source positions are \e proper: they include corrections
* for space motion (proper motions, annual parallax and radial velocity,
* when available), gravitational deflection of light, and annual aberration
* (rigorous relativistic model).
*
* Other nonstandard values can be returned by this function, such as
* different values of the RADESYS FITS keyword. Such values will be
* preserved but won't be supported by standard platform implementations.
*/
IsoString ReferenceSystem() const
{
return m_refSys.IsEmpty() ? IsoString( "ICRS" ) : m_refSys;
}
/*!
* Sets the coordinate reference system. See ReferenceSystem() for more
* information and supported values.
*/
void SetReferenceSystem( const IsoString& refSys )
{
m_refSys = refSys.Trimmed();
}
/*!
* Returns the name of the reference system of celestial coordinates
* derived from the specified image metadata.
*
* \param properties A list of XISF image properties.
*
* \param keywords A list of FITS header keywords.
*
* The reference system will be inferred from the following metadata items:
*
* \li The standard XISF property 'Observation:CelestialReferenceSystem'
*
* \li The standard FITS keyword 'RADESYS'.
*
* In case of metadata duplicity, XISF properties always take precedence
* over FITS keywords.
*
* Typical returned values are "ICRS" and "GCRS". If no valid reference
* system can be deduced from the specified metadata, this function returns
* an empty string.
*/
static IsoString ReferenceSystemFromMetadata( const PropertyArray& properties, const FITSKeywordArray& keywords );
/*!
* Returns the width in pixels of the image associated with the astrometric
* solution represented by this object.
*/
int Width() const
{
return m_width;
}
/*!
* Returns the height in pixels of the image associated with the astrometric
* solution represented by this object.
*/
int Height() const
{
return m_height;
}
/*!
* Returns a pointer to the projection system of this astrometric solution.
* Returns \c nullptr if this object is not valid.
*/
const ProjectionBase* Projection() const
{
return m_projection.Pointer();
}
/*!
* Returns a pointer to the world coordinate transformation of this
* astrometric solution. Returns \c nullptr if this object is not valid.
*/
const WorldTransformation* WorldTransform() const
{
return m_transformWI.Pointer();
}
/*!
* Returns the image resolution in seconds of arc per pixel, calculated from
* the specified \a focal distance in millimeters.
*/
double ResolutionFromFocal( double focal ) const
{
return (focal > 0) ? m_pixelSize.OrElse( 0 )/focal * 0.18/Const<double>::pi() : 0.0;
}
/*!
* Returns the focal distance in millimeters, calculated from the specified
* image \a resolution expressed in seconds of arc per pixel.
*/
double FocalFromResolution( double resolution ) const
{
return ResolutionFromFocal( resolution );
}
/*!
* Returns the angle of rotation of the Y axis of the image with respect to
* the north direction, as represented on a flat projection of the celestial
* sphere. A rotation angle of zero aligns north along the positive Y axis.
* A positive rotation angle rotates the Y axis from north to east.
*
* The returned value is the rotation angle of the projection in degrees.
* The \a flipped variable will be true iff the projection is mirrored on
* the east-west direction.
*/
double Rotation( bool& flipped ) const;
/*!
* Returns the resolution of the image in degrees per pixel.
*
* This value usually is an approximation since it changes across the image.
* It should only be used for informative purposes.
*/
double Resolution() const
{
return m_resolution;
}
/*!
* Returns the observation start time, if available. When defined, the
* returned value should be represented in the UTC timescale.
*/
Optional<TimePoint> ObservationStartTime() const
{
return m_obsStartTime;
}
/*!
* Sets the observation start time. The specified \a startTime value should
* be represented in the UTC timescale.
*/
void SetObservationStartTime( TimePoint startTime )
{
m_obsStartTime = startTime;
}
/*!
* Returns the observation end time, if available. When defined, the
* returned value should be represented in the UTC timescale.
*/
Optional<TimePoint> ObservationEndTime() const
{
return m_obsEndTime;
}
/*!
* Sets the observation end time. The specified \a endTime value should be
* represented in the UTC timescale.
*/
void SetObservationEndTime( TimePoint endTime )
{
m_obsEndTime = endTime;
}
/*!
* Returns an estimate of the observation middle time. If both the start and
* end times are defined, returns the time point between them. If only the
* start time is defined, it is returned. Otherwise an undefined object is
* returned.
*/
Optional<TimePoint> ObservationMiddleTime() const
{
if ( !m_obsStartTime.IsDefined() )
return Optional<TimePoint>();
if ( !m_obsEndTime.IsDefined() )
return m_obsStartTime;
return m_obsStartTime() + (m_obsEndTime() - m_obsStartTime())/2;
}
/*!
* Returns the geodetic longitude of the observation location, if available.
* The returned value is expressed in degrees in the range (-180,+180],
* reckoned positive eastward of the reference meridian.
*/
Optional<double> LocationLongitude() const
{
return m_geoLongitude;
}
/*!
* Sets the geodetic longitude of the observation location. The specified
* \a longitude must be expressed in degrees and can be either in the range
* [0,360] or [-180,+180], reckoned positive eastward.
*
* If a value out of the valid range is specified, this function will throw
* an Error exception.
*/
void SetLocationLongitude( double longitude )
{
if ( longitude > 180 )
longitude -= 360;
else if ( longitude <= -180 )
longitude += 360;
if ( longitude < -180 || longitude > +180 )
throw Error( "AstrometricMetadata::SetLocationLongitude(): Geographic longitude out of range." );
m_geoLongitude = longitude;
}
/*!
* Returns the geodetic latitude of the observation location, if available.
* The returned value is expressed in degrees in the range [-90,+90],
* reckoned positive north of the equator.
*/
Optional<double> LocationLatitude() const
{
return m_geoLatitude;
}
/*!
* Sets the geodetic latitude of the observation location. The specified
* \a latitude must be expressed in degrees and must be in the range
* [-90,+90], reckoned positive north of the equator.
*
* If a value out of the valid range is specified, this function will throw
* an Error exception.
*/
void SetLocationLatitude( double latitude )
{
if ( latitude < -90 || latitude > +90 )
throw Error( "AstrometricMetadata::SetLocationLatitude(): Geographic latitude out of range." );
m_geoLatitude = latitude;
}
/*!
* Returns the geodetic height of the observation location in meters, if
* available.
*/
Optional<double> LocationHeight() const
{
return m_geoHeight;
}
/*!
* Sets the geodetic height of the observation location in meters.
*/
void SetLocationHeight( double height )
{
m_geoHeight = height;
}
/*!
* Returns the physical pixel size in micrometers, if available.
*/
Optional<double> PixelSize() const
{
return m_pixelSize;
}
/*!
* Redefines the physical pixel size in micrometers. Recalculates the focal
* distance as a function of the pixel size.
*/
void SetPixelSize( double pixelSize )
{
m_pixelSize = pixelSize;
m_focalLength = FocalFromResolution( m_resolution );
}
/*!
* Transformation from image coordinates to celestial coordinates.
*
* \param[out] pRD Reference to a point where the output equatorial
* spherical coordinates will be stored, expressed in
* degrees. \a pRD.x will be the right ascension and
* \a pRD.y the declination. Output right ascensions are
* constrained to the [0,360) range. Output declinations
* are in the range [-90,+90].
*
* \param pI Input image coordinates in pixels. The specified
* location can legally lie outside the image bounds
* defined by [0,0]-[Width(),Height()].
*
* Returns true iff the specified point \a pI can be projected on the
* celestial sphere using this astrometric solution.
*
* The output coordinates stored in \a pRD will be referred to the reference
* system of this astrometric solution, either ICRS or GCRS, as returned by
* the ReferenceSystem() member function.
*
* \sa RawImageToCelestial(), CelestialToImage()
*/
bool ImageToCelestial( DPoint& pRD, const DPoint& pI ) const
{
if ( !IsValid() )
throw Error( "Invalid call to AstrometricMetadata::ImageToCelestial(): No astrometric solution." );
if ( m_projection->Inverse( pRD, m_transformWI->Inverse( pI ) ) )
{
// Constrain right ascension to the [0,360) range.
if ( pRD.x < 0 )
pRD.x += 360;
else if ( pRD.x >= 360 )
pRD.x -= 360;
return true;
}
return false;
}
/*!
* Transformation from image coordinates to celestial coordinates, without
* enforcing a valid range of right ascensions.
*
* \param[out] pRD Reference to a point where the output equatorial
* spherical coordinates will be stored, expressed in
* degrees. \a pRD.x will be the right ascension and
* \a pRD.y the declination. Output right ascensions are
* \e not constrained to the [0,360) range. Output
* declinations are in the range [-90,+90].
*
* \param pI Input image coordinates in pixels. The specified
* location can legally lie outside the image bounds
* defined by [0,0]-[Width(),Height()].
*
* Returns true iff the specified point \a pI can be projected on the
* celestial sphere using this astrometric solution.
*
* The output coordinates stored in \a pRD will be referred to the reference
* system of this astrometric solution, either ICRS or GCRS, as returned by
* the ReferenceSystem() member function.
*
* This function is useful for interpolation schemes where discontinuities
* caused by zero crossings in right ascension, i.e. abrupt changes from 360
* to 0 degrees, are not admissible numerically. Right ascensions returned
* by this function can be larger than 360 degrees or less than zero,
* ensuring smooth transitions.
*
* \sa ImageToCelestial(), CelestialToImage()
*/
bool RawImageToCelestial( DPoint& pRD, const DPoint& pI ) const
{
if ( !IsValid() )
throw Error( "Invalid call to AstrometricMetadata::RawImageToCelestial(): No astrometric solution." );
return m_projection->Inverse( pRD, m_transformWI->Inverse( pI ) );
}
/*!
* Transformation from celestial coordinates to image coordinates.
*
* \param[out] pI Reference to a point where the output image coordinates
* will be stored.
*
* \param pRD Input equatorial spherical coordinates expressed in
* degrees. \a pRD.x is the right ascension and \a pRD.y
* is declination.
*
* Returns true iff the specified celestial coordinates can be reprojected
* on the image coordinate system. Note that the output image coordinates
* can lie outside of the image bounds defined by [0,0]-[Width(),Height()].
*
* The input coordinates specified in \a pRD are expected to be referred to
* the reference system of this astrometric solution, either ICRS or GCRS,
* as returned by the ReferenceSystem() member function.
*
* \sa ImageToCelestial(), RawImageToCelestial()
*/
bool CelestialToImage( DPoint& pI, const DPoint& pRD ) const
{
if ( !IsValid() )
throw Error( "Invalid call to AstrometricMetadata::CelestialToImage(): No astrometric solution." );
DPoint pW;
if ( m_projection->Direct( pW, pRD ) )
{
pI = m_transformWI->Direct( pW );
return true;
}
return false;
}
/*!
* Regenerates the astrometric solution from standardized metadata.
*
* \param properties A list of XISF image properties describing
* critical astrometry-related metadata items.
*
* \param keywords A list of FITS header keywords, which should
* contain at least a minimal set of standard WCS
* keywords to define a linear world transformation
* from celestial to image coordinates.
*
* \param controlPoints If not empty, this array must contain a list of
* spline control points and generation parameters
* serialized in raw binary format. See the
* SplineWorldTransformation class for more
* information.
*
* \param width Width in pixels of the image with which this
* astrometric solution is associated.
*
* \param height Height in pixels of the image with which this
* astrometric solution is associated.
*
* The following standard XISF properties will be extracted from the
* specified \a properties array, if available:
*
* <pre>
* Observation:CelestialReferenceSystem
* Observation:Center:RA
* Observation:Center:Dec
* Observation:Equinox
* Observation:Time:Start
* Observation:Time:End
* Observation:Location:Longitude
* Observation:Location:Latitude
* Observation:Location:Elevation
* Instrument:Telescope:FocalLength
* Instrument:Sensor:XPixelSize
* </pre>
*
* %XISF properties will take precedence over equivalent %FITS keywords.
*
* If the specified \a controlPoints array contains a valid serialization of
* spline control points, the astrometric solution will use a high-precision
* world transformation based on two-dimensional surface splines, also knwon
* as <em>thin plate splines</em>, which is capable of modeling local image
* distortions that are intractable with WCS linear transformations.
*
* If this object contains valid metadata before calling this function, it
* will be disposed as appropriate, and a completely new astrometric
* solution will be constructed.
*
* This member function can throw exceptions (of the Error class) if either
* the specified \a controlPoints array is not empty and does not contain a
* valid raw serialization of a spline-based transformation, or if the
* generated coordinate transformations are not invalid (in the numerical or
* geometric sense).
*/
void Build( const PropertyArray& properties, const FITSKeywordArray& keywords,
const ByteArray& controlPoints, int width, int height );
/*!
* Updates the specified \a keywords array with basic astrometric FITS
* header keywords. This includes a number of standard instrumental and
* observational keywords, as well as some customary nonstandard keywords,
* included for compatibility with third-party applications:
*
* <pre>
* RA
* OBJCTRA
* DEC
* OBJCTDEC
* DATE-OBS
* DATE-END
* OBSGEO-L
* LONG-OBS
* OBSGEO-B
* LAT-OBS
* OBSGEO-H
* ALT-OBS
* FOCALLEN
* XPIXSZ
* YPIXSZ
* PIXSIZE
* </pre>
*
* Keywords are updated when the corresponding metadata items are available.
*/
void UpdateBasicKeywords( FITSKeywordArray& keywords ) const;
/*!
* Updates the specified \a keywords array with the set of standard WCS FITS
* header keywords:
*
* <pre>
* RADESYS
* EQUINOX
* EPOCH
* CTYPE1
* CTYPE2
* CRVAL1
* CRVAL2
* CRPIX1
* CRPIX2
* CD1_1
* CD1_2
* CD2_1
* CD2_2
* PC1_1
* PC1_2
* PC2_1
* PC2_2
* CDELT1
* CDELT2
* CROTA1
* CROTA2
* PV1_1
* PV1_2
* PV1_3
* PV1_4
* LONPOLE
* LATPOLE
* </pre>
*
* In addition, a custom nonstandard keyword is also generated to signal the
* availability of a spline-based astrometric solution:
*
* <pre>
* REFSPLIN
* </pre>
*/
void UpdateWCSKeywords( FITSKeywordArray& keywords ) const;
/*!
* Updates the specified \a properties array with a restricted set of view
* properties to reflect the state of this astrometric solution.
*
* The following standard XISF properties will be created or redefined:
*
* <pre>
* Instrument:Telescope:FocalLength
* Instrument:Sensor:XPixelSize
* Instrument:Sensor:YPixelSize
* Observation:Center:RA
* Observation:Center:Dec
* Observation:CelestialReferenceSystem
* Observation:Equinox
* </pre>
*
* The following properties can be removed if the transformation is valid,
* since the default coordinate reference point is the geometric center of
* the image, which is used to calculate the values of the standard
* \c Observation:Center:RA and \c Observation:Center:Dec properties:
*
* <pre>
* Observation:Center:X
* Observation:Center:Y
* </pre>
*
* The following properties will be created or redefined if the
* corresponding metadata items are available, or removed otherwise:
*
* <pre>
* Observation:Time:Start
* Observation:Time:End
* Observation:Location:Longitude
* Observation:Location:Latitude
* Observation:Location:Elevation
* </pre>
*
* In addition, the following nonstandard property, used by platform image
* plate solving scripts, will be created, redefined, or removed:
*
* <pre>
* Transformation_ImageToProjection
* </pre>
*/
void UpdateProperties( PropertyArray& properties ) const;
/*!
* Removes astrometry-related FITS header keywords from the specified
* \a keywords array. This includes some basic instrumental and
* observational keywords, as well as the following keywords:
*
* <pre>
* RADESYS
* EQUINOX
* EPOCH
* CTYPE1
* CTYPE2
* CRVAL1
* CRVAL2
* CRPIX1
* CRPIX2
* CD1_1
* CD1_2
* CD2_1
* CD2_2
* PC1_1
* PC1_2
* PC2_1
* PC2_2
* CDELT1
* CDELT2
* CROTA1
* CROTA2
* PV1_1
* PV1_2
* PV1_3
* PV1_4
* LONPOLE
* LATPOLE
* REFSPLIN
* </pre>
*
* If \a removeCenterKeywords is true, the following keywords will also be
* removed:
*
* <pre>
* RA
* OBJCTRA
* DEC
* OBJCTDEC
* </pre>
*
* If \a removeScaleKeywords is true, the following keywords will also be
* removed:
*
* <pre>
* FOCALLEN
* XPIXSZ
* YPIXSZ
* PIXSIZE
* </pre>
*/
static void RemoveKeywords( FITSKeywordArray& keywords, bool removeCenterKeywords = true, bool removeScaleKeywords = true );
/*!
* Rescales the values of existing FITS header keywords defining physical
* pixel dimensions in the specified \a keywords array.
*
* This function multiplies the values of the following keywords by the
* specified \a scalingFactor:
*
* <pre>
* XPIXSZ
* YPIXSZ
* PIXSIZE
* </pre>
*
* This is useful in cases where a geometric transformation has to be
* applied to an image to modify its scale, such as a resampling operation.
*/
static void RescalePixelSizeKeywords( FITSKeywordArray& keywords, double scalingFactor );
/*!
* Removes astrometry-related XISF properties from the specified
* \a properties array.
*
* If \a removeCenterProperties is true, the following properties will also
* be removed:
*
* <pre>
* Observation:Center:RA
* Observation:Center:Dec
* Observation:Center:X
* Observation:Center:Y
* Observation:CelestialReferenceSystem
* Observation:Equinox
* </pre>
*
* If \a removeScaleProperties is true, the following properties will also
* be removed:
*
* <pre>
* Instrument:Telescope:FocalLength
* Instrument:Sensor:XPixelSize
* Instrument:Sensor:YPixelSize
* </pre>
*
* In addition, the following nonstandard property, used by platform image
* plate solving scripts, will be removed:
*
* <pre>
* Transformation_ImageToProjection
* </pre>
*/
static void RemoveProperties( PropertyArray& properties, bool removeCenterProperties = true, bool removeScaleProperties = true );
/*!
* Removes astrometry-related XISF properties from the specified \a window's
* main view.
*
* See RemoveProperties( PropertyArray&, bool, bool ) for detailed
* information.
*/
static void RemoveProperties( ImageWindow& window, bool removeCenterProperties = true, bool removeScaleProperties = true );
/*!
* Rescales the values of existing XISF properties defining physical pixel
* dimensions in the specified \a properties array.
*
* This function multiplies the values of the following properties by the
* specified \a scalingFactor:
*
* <pre>
* Instrument:Sensor:XPixelSize
* Instrument:Sensor:YPixelSize
* </pre>
*
* This is useful in cases where a geometric transformation has to be
* applied to an image to modify its scale, such as a resampling operation.
*/
static void RescalePixelSizeProperties( PropertyArray& properties, double scalingFactor );
/*!
* Rescales the values of existing XISF properties defining physical pixel
* dimensions for the specified \a window's main view.
*
* See RescalePixelSizeProperties( PropertyArray&, double ) for detailed
* information.
*/
static void RescalePixelSizeProperties( ImageWindow& window, double scalingFactor );
/*!
* Returns a printable textual representation of the metadata properties and
* parameters of the astrometric solution represented by this object.
*/
String Summary() const;
/*!
* Returns a collection of strings describing the metadata properties and
* parameters of this astrometric solution.
*
* The returned object is a copy of an internal structure that is generated
* automatically as necessary and cached between successive function calls.
* This allows for efficient real-time representations of astrometric
* metadata and parameters.
*/
DescriptionItems Description() const
{
UpdateDescription();
return m_description.IsNull() ? DescriptionItems() : *m_description;
}
private:
AutoPointer<ProjectionBase> m_projection;
AutoPointer<WorldTransformation> m_transformWI;
IsoString m_refSys; // ICRS(default) or GCRS
Optional<double> m_equinox; // years - deprecated
int m_width = 0; // px
int m_height = 0; // px
Optional<double> m_pixelSize; // um
Optional<TimePoint> m_obsStartTime; // UTC
Optional<TimePoint> m_obsEndTime; // UTC
Optional<double> m_geoLongitude; // deg
Optional<double> m_geoLatitude; // deg
Optional<double> m_geoHeight; // m
double m_resolution = 0; // deg/px
Optional<double> m_focalLength; // mm
mutable
AutoPointer<DescriptionItems> m_description;
WCSKeywords ComputeWCSKeywords() const;
void UpdateDescription() const;
};
} //pcl
#endif // __AstrometricMetadata_h
// ----------------------------------------------------------------------------
// EOF pcl/AstrometricMetadata.h - Released 2022-03-12T18:59:29Z