def identity_gwcs(): """ A simple 1-1 gwcs that converts from pixels to arcseconds Note this WCS does not have a correct axis correlation matrix. """ identity = m.Multiply(1 * u.arcsec / u.pixel) & m.Multiply( 1 * u.arcsec / u.pixel) sky_frame = cf.CelestialFrame( axes_order=(0, 1), name='helioprojective', reference_frame=Helioprojective(obstime="2018-01-01"), unit=(u.arcsec, u.arcsec), axis_physical_types=("custom:pos.helioprojective.lat", "custom:pos.helioprojective.lon")) detector_frame = cf.CoordinateFrame(name="detector", naxes=2, axes_order=(0, 1), axes_type=("pixel", "pixel"), axes_names=("x", "y"), unit=(u.pix, u.pix)) wcs = gwcs.wcs.WCS(forward_transform=identity, output_frame=sky_frame, input_frame=detector_frame) wcs.pixel_shape = (10, 20) wcs.array_shape = wcs.pixel_shape[::-1] return wcs
def identity_gwcs_4d(): """ A simple 1-1 gwcs that converts from pixels to arcseconds """ identity = (m.Multiply(1 * u.arcsec / u.pixel) & m.Multiply(1 * u.arcsec / u.pixel) & m.Multiply(1 * u.nm / u.pixel) & m.Multiply(1 * u.nm / u.pixel)) sky_frame = cf.CelestialFrame( axes_order=(0, 1), name='helioprojective', reference_frame=Helioprojective(obstime="2018-01-01")) wave_frame = cf.SpectralFrame(axes_order=(2, ), unit=u.nm) time_frame = cf.TemporalFrame(axes_order=(3, ), unit=u.s) frame = cf.CompositeFrame([sky_frame, wave_frame, time_frame]) detector_frame = cf.CoordinateFrame(name="detector", naxes=4, axes_order=(0, 1, 2, 3), axes_type=("pixel", "pixel", "pixel", "pixel"), axes_names=("x", "y", "z", "s"), unit=(u.pix, u.pix, u.pix, u.pix)) return gwcs.wcs.WCS(forward_transform=identity, output_frame=frame, input_frame=detector_frame)
def generate_s3d_wcs(): """ create a fake gwcs for a cube """ # create input /output frames detector = cf.CoordinateFrame(name='detector', axes_order=(0,1,2), axes_names=['x', 'y', 'z'], axes_type=['spatial', 'spatial', 'spatial'], naxes=3, unit=['pix', 'pix', 'pix']) sky = cf.CelestialFrame(reference_frame=coord.ICRS(), name='sky', axes_names=("RA", "DEC")) spec = cf.SpectralFrame(name='spectral', unit=['um'], axes_names=['wavelength'], axes_order=(2,)) world = cf.CompositeFrame(name="world", frames=[sky, spec]) # create fake transform to at least get a bounding box # for the s3d jwst loader # shape 30,10,10 (spec, y, x) crpix1, crpix2, crpix3 = 5, 5, 15 # (x, y, spec) crval1, crval2, crval3 = 1, 1, 1 cdelt1, cdelt2, cdelt3 = 0.01, 0.01, 0.05 shift = models.Shift(-crpix2) & models.Shift(-crpix1) scale = models.Multiply(cdelt2) & models.Multiply(cdelt1) proj = models.Pix2Sky_TAN() skyrot = models.RotateNative2Celestial(crval2, 90 + crval1, 180) celestial = shift | scale | proj | skyrot wave_model = models.Shift(-crpix3) | models.Multiply(cdelt3) | models.Shift(crval3) transform = models.Mapping((2, 0, 1)) | celestial & wave_model | models.Mapping((1, 2, 0)) # bounding box based on shape (30,10,10) in test transform.bounding_box = ((0, 29), (0, 9), (0, 9)) # create final wcs pipeline = [(detector, transform), (world, None)] return WCS(pipeline)
def gwcs_3d_identity_units(): """ A simple 1-1 gwcs that converts from pixels to arcseconds """ identity = (models.Multiply(1 * u.arcsec / u.pixel) & models.Multiply(1 * u.arcsec / u.pixel) & models.Multiply(1 * u.nm / u.pixel)) sky_frame = cf.CelestialFrame(axes_order=(0, 1), name='icrs', reference_frame=coord.ICRS(), axes_names=("longitude", "latitude")) wave_frame = cf.SpectralFrame(axes_order=(2, ), unit=u.nm, axes_names=("wavelength", )) frame = cf.CompositeFrame([sky_frame, wave_frame]) detector_frame = cf.CoordinateFrame(name="detector", naxes=3, axes_order=(0, 1, 2), axes_type=("pixel", "pixel", "pixel"), axes_names=("x", "y", "z"), unit=(u.pix, u.pix, u.pix)) return wcs.WCS(forward_transform=identity, output_frame=frame, input_frame=detector_frame)
def gwcs_4d_identity_units(): """ A simple 1-1 gwcs that converts from pixels to arcseconds """ identity = (models.Multiply(1 * u.arcsec / u.pixel) & models.Multiply(1 * u.arcsec / u.pixel) & models.Multiply(1 * u.nm / u.pixel) & models.Multiply(1 * u.s / u.pixel)) sky_frame = cf.CelestialFrame(axes_order=(0, 1), name='icrs', reference_frame=coord.ICRS()) wave_frame = cf.SpectralFrame(axes_order=(2, ), unit=u.nm) time_frame = cf.TemporalFrame(axes_order=(3, ), unit=u.s, reference_frame=Time("2000-01-01T00:00:00")) frame = cf.CompositeFrame([sky_frame, wave_frame, time_frame]) detector_frame = cf.CoordinateFrame(name="detector", naxes=4, axes_order=(0, 1, 2, 3), axes_type=("pixel", "pixel", "pixel", "pixel"), axes_names=("x", "y", "z", "s"), unit=(u.pix, u.pix, u.pix, u.pix)) return wcs.WCS(forward_transform=identity, output_frame=frame, input_frame=detector_frame)
def generate_celestial_transform(crpix: Union[Iterable[float], u.Quantity], cdelt: Union[Iterable[float], u.Quantity], pc: Union[ArrayLike, u.Quantity], crval: Union[Iterable[float], u.Quantity], lon_pole: Union[float, u.Quantity] = None, projection: Model = m.Pix2Sky_TAN()) -> CompoundModel: """ Create a simple celestial transform from FITS like parameters. Supports unitful or unitless parameters, but if any parameters have units all must have units, if parameters are unitless they are assumed to be in degrees. Parameters ---------- crpix The reference pixel (a length two array). crval The world coordinate at the reference pixel (a length two array). pc The rotation matrix for the affine transform. If specifying parameters with units this should have celestial (``u.deg``) units. lon_pole The longitude of the celestial pole, defaults to 180 degrees. projection The map projection to use, defaults to ``TAN``. Notes ----- This function has not been tested with more complex projections. Ensure that your lon_pole is correct for your projection. """ spatial_unit = None if hasattr(crval[0], "unit"): spatial_unit = crval[0].unit # TODO: Note this assumption is only valid for certain projections. if lon_pole is None: lon_pole = 180 if spatial_unit is not None: lon_pole = u.Quantity(lon_pole, unit=spatial_unit) # Make translation unitful if all parameters have units translation = (0, 0) if spatial_unit is not None: translation *= pc.unit # If we have units then we need to convert all things to Quantity # as they might be Parameter classes crpix = u.Quantity(crpix) cdelt = u.Quantity(cdelt) crval = u.Quantity(crval) lon_pole = u.Quantity(lon_pole) pc = u.Quantity(pc) shift = m.Shift(-crpix[0]) & m.Shift(-crpix[1]) scale = m.Multiply(cdelt[0]) & m.Multiply(cdelt[1]) rot = m.AffineTransformation2D(pc, translation=translation) skyrot = m.RotateNative2Celestial(crval[0], crval[1], lon_pole) return shift | scale | rot | projection | skyrot
def identity_gwcs_3d(): """ A simple 1-1 gwcs that converts from pixels to arcseconds """ identity = (TwoDScale(1 * u.arcsec / u.pixel) & m.Multiply(1 * u.nm / u.pixel)) sky_frame = cf.CelestialFrame( axes_order=(0, 1), name='helioprojective', reference_frame=Helioprojective(obstime="2018-01-01"), axes_names=("longitude", "latitude"), unit=(u.arcsec, u.arcsec), axis_physical_types=("custom:pos.helioprojective.lon", "custom:pos.helioprojective.lat")) wave_frame = cf.SpectralFrame(axes_order=(2, ), unit=u.nm, axes_names=("wavelength", )) frame = cf.CompositeFrame([sky_frame, wave_frame]) detector_frame = cf.CoordinateFrame(name="detector", naxes=3, axes_order=(0, 1, 2), axes_type=("pixel", "pixel", "pixel"), axes_names=("x", "y", "z"), unit=(u.pix, u.pix, u.pix)) wcs = gwcs.wcs.WCS(forward_transform=identity, output_frame=frame, input_frame=detector_frame) wcs.pixel_shape = (10, 20, 30) wcs.array_shape = wcs.pixel_shape[::-1] return wcs
def test_Multiply_inverse_bounding_box(): model = models.Multiply(2) model.bounding_box = (1, 5) assert model.bounding_box == (1, 5) inverse_model = model.inverse assert inverse_model.bounding_box == (2, 10) assert inverse_model(model(4, with_bounding_box=True), with_bounding_box=True) == 4.0
def gwcs_1d_freq_quantity(): detector_1d = cf.CoordinateFrame(name='detector', axes_order=(0, ), naxes=1, unit=u.pix, axes_type="detector") return wcs.WCS([(detector_1d, models.Multiply(1 * u.Hz / u.pix)), (freq_frame, None)])
def gwcs_3d_galactic_spectral(): """ This fixture has the axes ordered as lat, spectral, lon. """ # lat,wav,lon crpix1, crpix2, crpix3 = 29, 39, 44 crval1, crval2, crval3 = 10, 20, 25 cdelt1, cdelt2, cdelt3 = -0.01, 0.5, 0.01 shift = models.Shift(-crpix3) & models.Shift(-crpix1) scale = models.Multiply(cdelt3) & models.Multiply(cdelt1) proj = models.Pix2Sky_CAR() skyrot = models.RotateNative2Celestial(crval3, 90 + crval1, 180) celestial = shift | scale | proj | skyrot wave_model = models.Shift(-crpix2) | models.Multiply( cdelt2) | models.Shift(crval2) transform = models.Mapping( (2, 0, 1)) | celestial & wave_model | models.Mapping((1, 2, 0)) transform.bounding_box = ((5, 50), (-2, 45), (-1, 35)) sky_frame = cf.CelestialFrame(axes_order=(2, 0), reference_frame=coord.Galactic(), axes_names=("Longitude", "Latitude")) wave_frame = cf.SpectralFrame(axes_order=(1, ), unit=u.Hz, axes_names=("Frequency", )) frame = cf.CompositeFrame([sky_frame, wave_frame]) detector_frame = cf.CoordinateFrame(name="detector", naxes=3, axes_order=(0, 1, 2), axes_type=("pixel", "pixel", "pixel"), unit=(u.pix, u.pix, u.pix)) owcs = wcs.WCS(forward_transform=transform, output_frame=frame, input_frame=detector_frame) owcs.array_shape = (30, 20, 10) owcs.pixel_shape = (10, 20, 30) return owcs
def identity_gwcs(): """ A simple 1-1 gwcs that converts from pixels to arcseconds """ identity = m.Multiply(1 * u.arcsec / u.pixel) & m.Multiply( 1 * u.arcsec / u.pixel) sky_frame = cf.CelestialFrame( axes_order=(0, 1), name='helioprojective', reference_frame=Helioprojective(obstime="2018-01-01")) detector_frame = cf.CoordinateFrame(name="detector", naxes=2, axes_order=(0, 1), axes_type=("pixel", "pixel"), axes_names=("x", "y"), unit=(u.pix, u.pix)) return gwcs.wcs.WCS(forward_transform=identity, output_frame=sky_frame, input_frame=detector_frame)
def gwcs_spec_cel_time_4d(): """ A complex 4D mixed celestial + spectral + time WCS. """ # spectroscopic frame: wave_model = models.Shift(-5) | models.Multiply(3.7) | models.Shift(20) wave_model.bounding_box = (7, 50) wave_frame = cf.SpectralFrame(name='wave', unit=u.m, axes_order=(0, ), axes_names=('lambda', )) # time frame: time_model = models.Identity(1) # models.Linear1D(10, 0) time_frame = cf.TemporalFrame(Time("2010-01-01T00:00"), name='time', unit=u.s, axes_order=(3, )) # Values from data/acs.hdr: crpix = (12, 13) crval = (5.63, -72.05) cd = [[1.291E-05, 5.9532E-06], [5.02215E-06, -1.2645E-05]] aff = models.AffineTransformation2D(matrix=cd, name='rotation') offx = models.Shift(-crpix[0], name='x_translation') offy = models.Shift(-crpix[1], name='y_translation') wcslin = models.Mapping((1, 0)) | (offx & offy) | aff tan = models.Pix2Sky_TAN(name='tangent_projection') n2c = models.RotateNative2Celestial(*crval, 180, name='sky_rotation') cel_model = wcslin | tan | n2c icrs = cf.CelestialFrame(reference_frame=coord.ICRS(), name='sky', axes_order=(2, 1)) wcs_forward = wave_model & cel_model & time_model comp_frm = cf.CompositeFrame(frames=[wave_frame, icrs, time_frame], name='TEST 4D FRAME') detector_frame = cf.CoordinateFrame(name="detector", naxes=4, axes_order=(0, 1, 2, 3), axes_type=("pixel", "pixel", "pixel", "pixel"), unit=(u.pix, u.pix, u.pix, u.pix)) w = wcs.WCS(forward_transform=wcs_forward, output_frame=comp_frm, input_frame=detector_frame) w.bounding_box = ((0, 63), (0, 127), (0, 255), (0, 9)) w.array_shape = (10, 256, 128, 64) w.pixel_shape = (64, 128, 256, 10) return w
def identity_gwcs_4d(): """ A simple 1-1 gwcs that converts from pixels to arcseconds """ identity = (TwoDScale(1 * u.arcsec / u.pixel) & m.Multiply(1 * u.nm / u.pixel) & m.Multiply(1 * u.s / u.pixel)) sky_frame = cf.CelestialFrame( axes_order=(0, 1), name='helioprojective', reference_frame=Helioprojective(obstime="2018-01-01"), unit=(u.arcsec, u.arcsec), axis_physical_types=("custom:pos.helioprojective.lon", "custom:pos.helioprojective.lat")) wave_frame = cf.SpectralFrame(axes_order=(2, ), unit=u.nm) time_frame = cf.TemporalFrame(Time("2020-01-01T00:00", format="isot", scale="utc"), axes_order=(3, ), unit=u.s) frame = cf.CompositeFrame([sky_frame, wave_frame, time_frame]) detector_frame = cf.CoordinateFrame(name="detector", naxes=4, axes_order=(0, 1, 2, 3), axes_type=("pixel", "pixel", "pixel", "pixel"), axes_names=("x", "y", "z", "s"), unit=(u.pix, u.pix, u.pix, u.pix)) wcs = gwcs.wcs.WCS(forward_transform=identity, output_frame=frame, input_frame=detector_frame) wcs.pixel_shape = (10, 20, 30, 40) wcs.array_shape = wcs.pixel_shape[::-1] return wcs
def gwcs_1d_spectral(): """ A simple 1D spectral WCS. """ wave_model = models.Shift(-5) | models.Multiply(3.7) | models.Shift(20) wave_model.bounding_box = (7, 50) wave_frame = cf.SpectralFrame(axes_order=(0, ), unit=u.Hz, axes_names=("Frequency", )) detector_frame = cf.CoordinateFrame(name="detector", naxes=1, axes_order=(0, ), axes_type=("pixel", ), unit=(u.pix, )) owcs = wcs.WCS(forward_transform=wave_model, output_frame=wave_frame, input_frame=detector_frame) owcs.array_shape = (44, ) owcs.pixel_shape = (44, ) return owcs
test_models = [ astmodels.Identity(2), astmodels.Polynomial1D(2, c0=1, c1=2, c2=3), astmodels.Polynomial2D(1, c0_0=1, c0_1=2, c1_0=3), astmodels.Shift(2.), astmodels.Hermite1D(2, c0=2, c1=3, c2=0.5), astmodels.Legendre1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev1D(2, c0=2, c1=3, c2=0.5), astmodels.Chebyshev2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Legendre2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Hermite2D(1, 1, c0_0=1, c0_1=2, c1_0=3), astmodels.Scale(3.4), astmodels.RotateNative2Celestial(5.63, -72.5, 180), astmodels.Multiply(3), astmodels.Multiply(10 * u.m), astmodels.RotateCelestial2Native(5.63, -72.5, 180), astmodels.EulerAngleRotation(23, 14, 2.3, axes_order='xzx'), astmodels.Mapping((0, 1), n_inputs=3), astmodels.Shift(2. * u.deg), astmodels.Scale(3.4 * u.deg), astmodels.RotateNative2Celestial(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg), astmodels.RotateCelestial2Native(5.63 * u.deg, -72.5 * u.deg, 180 * u.deg), astmodels.RotationSequence3D([1.2, 2.3, 3.4, .3], 'xyzx'), astmodels.SphericalRotationSequence([1.2, 2.3, 3.4, .3], 'xyzy'), custom_and_analytical_inverse(), ] math_models = []
x_mean=5., y_mean=5., x_stddev=3., y_stddev=3.), astropy_models.KingProjectedAnalytic1D(amplitude=10., r_core=5., r_tide=2.), astropy_models.Linear1D(slope=2.0, intercept=1.5), astropy_models.Logarithmic1D(amplitude=10., tau=3.5), astropy_models.Lorentz1D(amplitude=10., x_0=0.5, fwhm=2.5), astropy_models.Moffat1D(amplitude=10., x_0=0.5, gamma=1.2, alpha=2.5), astropy_models.Moffat2D(amplitude=10., x_0=0.5, y_0=1.5, gamma=1.2, alpha=2.5), astropy_models.Multiply(3), astropy_models.Multiply(10 * u.m), astropy_models.Planar2D(slope_x=0.5, slope_y=1.2, intercept=2.5), astropy_models.RedshiftScaleFactor(z=2.5), astropy_models.RickerWavelet1D(amplitude=10., x_0=0.5, sigma=1.2), astropy_models.RickerWavelet2D(amplitude=10., x_0=0.5, y_0=1.5, sigma=1.2), astropy_models.Ring2D(amplitude=10., x_0=0.5, y_0=1.5, r_in=5., width=10.), astropy_models.Scale(3.4), astropy_models.Sersic1D(amplitude=10., r_eff=1., n=4.), astropy_models.Sersic2D(amplitude=10., r_eff=1., n=4., x_0=0.5, y_0=1.5, ellip=0.0, theta=0.0),
def test_Multiply_inverse(): m = models.Multiply(1.2345) assert_allclose(m.inverse(m(6.789)), 6.789)
def from_tree_transform(self, node): factor = node['factor'] return models.Multiply(factor)