def time_init_7_no_units(): m = (models.Shift(-10.5) & models.Shift(-13.2) | models.AffineTransformation2D(matrix=[[1, 0], [0, 1]], translation=[0, 0]) | models.Scale(.01) & models.Scale(.04) | models.Pix2Sky_TAN() | models.RotateNative2Celestial(5.6, -72.05, 180))
def miri_old_model(): d2c = fits.open('polyd2c_1A_01.00.00.fits') slices = d2c[1].data rids = np.unique(slices).tolist() rids.remove(0) shiftx = models.Shift(-d2c[0].header['CENTERX']) shifty = models.Shift(-d2c[0].header['CENTERY']) scalex = models.Scale(1. / d2c[0].header['NORMX']) scaley = models.Scale(1. / d2c[0].header['NORMY']) b1 = d2c[1].header['B_DEL'] b0 = d2c[1].header['B_MIN'] coeffs = d2c[2].data channel_selector = {} for i in rids: palpha = fits_column_to_model(coeffs.field("alpha_" + str(int(i))), 4, 4) plam = fits_column_to_model(coeffs.field("lambda_" + str(int(i))), 4, 4) malpha = (shiftx & shifty) | (scalex & scaley) | palpha mlam = (shiftx & shifty) | (scalex & scaley) | plam beta = models.Const1D(b0 + i * b1) channel_selector[i] = models.Mapping( (0, 1, 0, 0, 1)) | malpha & beta & mlam return channel_selector
def from_fits(cls, header): if not isinstance(header, fits.Header): raise TypeError("expected a FIST Header") fitswcs = util.read_wcs_from_header(header) wcsaxes = fitswcs['WCSAXES'] if fitswcs['has_cd']: pc = fitswcs['CD'] else: pc = fitswcs['PC'] # get the part of the PC matrix corresponding to the imaging axes sky_axes = None if pc.shape != (2, 2): sky_axes, _ = util.get_axes(fitswcs) i, j = sky_axes sky_pc = np.zeros((2,2)) sky_pc[0, 0] = pc[i, i] sky_pc[0, 1] = pc[i, j] sky_pc[1, 0] = pc[j, i] sky_pc[1, 1] = pc[j, j] pc = sky_pc.copy() if sky_axes is not None: crpix = [] cdelt = [] for i in sky_axes: crpix.append(fitswcs['CRPIX'][i]) cdelt.append(fitswcs['CDELT'][i]) else: cdelt = fitswcs['CDELT'] crpix = fitswcs['CRPIX'] translation = astmodels.Shift(-crpix[0], name='offset_x') & astmodels.Shift(-crpix[1], name='offset_y') rotation = astmodels.AffineTransformation2D(matrix=pc, name='orient') scale = astmodels.Scale(cdelt[0], name='scale_x') & astmodels.Scale(cdelt[1], name='scale_y') return cls(translation, rotation, scale)
def test_bounding_box(): trans3 = models.Shift(10) & models.Scale(2) & models.Shift(-1) pipeline = [('detector', trans3), ('sky', None)] w = wcs.WCS(pipeline) bb = ((-1, 10), (6, 15)) with pytest.raises(ValueError): w.bounding_box = bb trans2 = models.Shift(10) & models.Scale(2) pipeline = [('detector', trans2), ('sky', None)] w = wcs.WCS(pipeline) w.bounding_box = bb assert w.bounding_box == w.forward_transform.bounding_box[::-1] pipeline = [("detector", models.Shift(2)), ("sky", None)] w = wcs.WCS(pipeline) w.bounding_box = (1, 5) assert w.bounding_box == w.forward_transform.bounding_box with pytest.raises(ValueError): w.bounding_box = ((1, 5), (2, 6)) # Test that bounding_box with quantities can be assigned and evaluates bb = ((1 * u.pix, 5 * u.pix), (2 * u.pix, 6 * u.pix)) trans = models.Shift(10 * u.pix) & models.Shift(2 * u.pix) pipeline = [('detector', trans), ('sky', None)] w = wcs.WCS(pipeline) w.bounding_box = bb assert_allclose(w(-1 * u.pix, -1 * u.pix), (np.nan, np.nan))
def setup(self): aff = models.AffineTransformation2D(matrix=[[1, 0], [0, 1]], translation=[0, 0]) self.model = (models.Shift(-10.5) & models.Shift(-13.2) | aff | models.Scale(.01) & models.Scale(.04) | models.Pix2Sky_TAN() | models.RotateNative2Celestial(5.6, -72.05, 180))
def test_RegionsSelector(): labels = np.zeros((10, 10)) labels[1, 2] = 1 labels[2][2: 4] = 1 labels[3][1: 4] = 1 labels[4][: 4] = 1 labels[5][1: 4] = 1 labels[6][2: 7] = 1 labels[7][3: 6] = 1 labels[:, -2:] = 2 mapper = selector.LabelMapperArray(labels) sel = {1: models.Shift(1) & models.Scale(1), 2: models.Shift(2) & models.Scale(2) } with pytest.raises(ValueError): # 0 can't be a key in ``selector`` selector.RegionsSelector(inputs=('x', 'y'), outputs=('x', 'y'), label_mapper=mapper, selector={0: models.Shift(1) & models.Scale(1), 2: models.Shift(2) & models.Scale(2) } ) reg_selector = selector.RegionsSelector(inputs=('x', 'y'), outputs=('x', 'y'), label_mapper=mapper, selector=sel ) with pytest.raises(NotImplementedError): reg_selector.inverse mapper.inverse = mapper.copy() assert_allclose(reg_selector(2, 1), sel[1](2, 1)) assert_allclose(reg_selector(8, 2), sel[2](8, 2)) # test set_input with pytest.raises(gwutils.RegionError): reg_selector.set_input(3) transform = reg_selector.set_input(2) assert_equal(transform.parameters, [2, 2]) assert_allclose(transform(1, 1), sel[2](1, 1)) # test inverse rsinv = reg_selector.inverse # The label_mapper arays should be the same assert_equal(reg_selector.label_mapper.mapper, rsinv.label_mapper.mapper) # the transforms of the inverse ``RegionsSelector`` should be the inverse of the # transforms of the ``RegionsSelector`` model. x = np.linspace(-5, 5, 100) assert_allclose(reg_selector.selector[1].inverse(x, x), rsinv.selector[1](x, x)) assert_allclose(reg_selector.selector[2].inverse(x, x), rsinv.selector[2](x, x)) assert np.isnan(reg_selector(0, 0)).all() # Test setting ``undefined_transform_value`` to a non-default value. reg_selector.undefined_transform_value = -100 assert_equal(reg_selector(0, 0), [-100, -100])
def pcf_forward(pcffile, outname): """ Create the **IDT** forward transform from collimator to gwa. """ with open(pcffile) as f: lines = [l.strip() for l in f.readlines()] factors = lines[lines.index('*Factor 2') + 1].split() # factor==1/factor in backward msa2ote direction and factor==factor in sky2detector direction scale = models.Scale(float(factors[0]), name="x_scale") & \ models.Scale(float(factors[1]), name="y_scale") rotation_angle = lines[lines.index('*Rotation') + 1] # The minius sign here is because astropy.modeling has the opposite direction of rotation than the idl implementation rotation = models.Rotation2D(-float(rotation_angle), name='rotation') # Here the model is called "output_shift" but in the team version it is the "input_shift". input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split() input_rot_shift = models.Shift(-float(input_rot_center[0]), name='input_x_shift') & \ models.Shift(-float(input_rot_center[1]), name='input_y_shift') # Here the model is called "input_shift" but in the team version it is the "output_shift". output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split() output_rot_shift = models.Shift(float(output_rot_center[0]), name='output_x_shift') & \ models.Shift(float(output_rot_center[1]), name='output_y_shift') degree = int(lines[lines.index('*FitOrder') + 1]) xcoeff_index = lines.index('*xForwardCoefficients 21 2') xlines = lines[xcoeff_index + 1: xcoeff_index + 22] xcoeff_forward = coeffs_from_pcf(degree, xlines) x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_forward) ycoeff_index = lines.index('*yForwardCoefficients 21 2') ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_forward) xcoeff_index = lines.index('*xBackwardCoefficients 21 2') xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22]) x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_backward) ycoeff_index = lines.index('*yBackwardCoefficients 21 2') ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22]) y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_backward) x_poly_forward.inverse = x_poly_backward y_poly_forward.inverse = y_poly_backward poly_mapping1 = Mapping((0, 1, 0, 1)) poly_mapping1.inverse = Identity(2) poly_mapping2 = Identity(2) poly_mapping2.inverse = Mapping((0, 1, 0, 1)) model = input_rot_shift | rotation | scale | output_rot_shift | \ poly_mapping1 | x_poly_forward & y_poly_forward | poly_mapping2 f = AsdfFile() f.tree = {'model': model} f.write_to(outname)
def imaging_distortion(input_model, reference_files): """ Create pixe2sky and sky2pixel transformation for the MIRI imager. Parameters ---------- model : jwst.datamodels.ImagingModel input model reference_files : dict reference files from CRDS using CDP 3 Reference distortion file Old one: ~~MIRI_FM_MIRIMAGE_F1000W_PSF_03.01.00.fits~~ Current one: MIRI_FM_MIRIMAGE_DISTORTION_06.03.00.fits reference files/corrections needed (pixel to sky): 1. Filter dependent shift in (x,y) (!with an oposite sign to that delievred by the IT) 2. Apply MI 3. Apply Ai and BI matrices 4. Apply the TI matrix (this gives V2/V3 coordinates) 5. Apply V2/V3 to sky transformation ref_file: filter_offset.asdf - (1) ref_file: distortion.asdf -(2,3,4) """ # Load the distortion and filter from the reference files. # Load in the distortion file. distortion = AsdfFile.open(reference_files['distortion']).tree['model'] filter_offset = AsdfFile.open(reference_files['filteroffset']).tree[ input_model.meta.instrument.filter] # Now apply each of the models. The Scale(60) converts from arc-minutes to deg. full_distortion = models.Shift( filter_offset['column_offset']) & models.Shift( filter_offset['row_offset']) | distortion | models.Scale( 1 / 60) & models.Scale(1 / 60) # ToDo: This will likely have to change in the future, but the "filteroffset" file we have # ToDo: currently does not contain that key. filter_offset = None if input_model.meta.instrument.filter in AsdfFile.open( reference_files['filteroffset']).tree: filter_offset = AsdfFile.open(reference_files['filteroffset']).tree[ input_model.meta.instrument.filter] full_distortion = models.Shift( filter_offset['row_offset']) & models.Shift( filter_offset['column_offset']) | distortion else: full_distortion = distortion full_distortion = full_distortion.rename('distortion') return full_distortion
def ifu(input_model, reference_files): """ Create the WCS pipeline for a MIRI IFU observation. """ #reference_files = {'distortion': 'jwst_miri_distortion_00001.asdf', #files must hold 2 channels each #'specwcs': 'jwst_miri_specwcs_00001.asdf', #'regions': 'jwst_miri_regions_00001.asdf', #'v2v3': 'jwst_miri_v2v3_00001.asdf' #'wavelengthrange': 'jwst_miri_wavelengthrange_0001.asdf'} detector = cf.Frame2D(name='detector', axes_order=(0, 1), unit=(u.pix, u.pix)) alpha_beta = cf.Frame2D(name='alpha_beta_spatial', axes_order=(0, 1), unit=(u.arcsec, u.arcsec), axes_names=('alpha', 'beta')) spec_local = cf.SpectralFrame(name='alpha_beta_spectral', axes_order=(2, ), unit=(u.micron, ), axes_names=('lambda', )) miri_focal = cf.CompositeFrame([alpha_beta, spec_local], name='alpha_beta') xyan_spatial = cf.Frame2D(name='Xan_Yan_spatial', axes_order=(0, 1), unit=(u.arcmin, u.arcmin), axes_names=('v2', 'v3')) spec = cf.SpectralFrame(name='Xan_Yan_spectral', axes_order=(2, ), unit=(u.micron, ), axes_names=('lambda', )) xyan = cf.CompositeFrame([xyan_spatial, spec], name='Xan_Yan') v23_spatial = cf.Frame2D(name='V2_V3_spatial', axes_order=(0, 1), unit=(u.deg, u.deg), axes_names=('v2', 'v3')) spec = cf.SpectralFrame(name='spectral', axes_order=(2, ), unit=(u.micron, ), axes_names=('lambda', )) v2v3 = cf.CompositeFrame([v23_spatial, spec], name='v2v3') icrs = cf.CelestialFrame(name='icrs', reference_frame=coord.ICRS(), axes_order=(0, 1), unit=(u.deg, u.deg), axes_names=('RA', 'DEC')) world = cf.CompositeFrame([icrs, spec], name='world') det2alpha_beta = (detector_to_alpha_beta( input_model, reference_files)).rename("detector_to_alpha_beta") ab2xyan = (alpha_beta2XanYan( input_model, reference_files)).rename("alpha_beta_to_Xan_Yan") xyan2v23 = models.Identity(1) & (models.Shift(7.8) | models.Scale(-1)) & models.Identity(1) | \ models.Scale(1/60) & models.Scale(1/60) & models.Identity(1) tel2sky = pointing.v23tosky(input_model) & models.Identity(1) pipeline = [(detector, det2alpha_beta), (miri_focal, ab2xyan), (xyan, xyan2v23), (v2v3, tel2sky), (world, None)] return pipeline
def test_calculate_affine_matrices(angle, scale, xoffset, yoffset): m = ((models.Scale(scale) & models.Scale(scale)) | models.Rotation2D(angle) | (models.Shift(xoffset) & models.Shift(yoffset))) affine = adwcs.calculate_affine_matrices(m, (100, 100)) assert_allclose(affine.offset, (yoffset, xoffset), atol=1e-10) angle = math.radians(angle) assert_allclose(affine.matrix, ((scale * math.cos(angle), scale * math.sin(angle)), (-scale * math.sin(angle), scale * math.cos(angle))), atol=1e-10)
def setup(self): aff = models.AffineTransformation2D(matrix=[[1, 0], [0, 1]] * u.arcsec, translation=[0, 0] * u.arcsec) aff.input_units_equivalencies = {'x': u.pixel_scale(1 * u.arcsec/u.pix), 'y': u.pixel_scale(1 * u.arcsec/u.pix)} self.model = (models.Shift(-10.5 * u.pix) & models.Shift(-13.2 * u.pix) | aff | models.Scale(.01 * u.arcsec) & models.Scale(.04 * u.deg) | models.Pix2Sky_TAN() | models.RotateNative2Celestial(5.6 * u.deg, -72.05 * u.deg, 180 * u.deg))
def test_ScaleModel(): # Scale by a scalar m = models.Scale(42) assert m(0) == 0 assert_equal(m([1, 2]), [42, 84]) # Scale by a list m = models.Scale([42, 43], n_models=2) assert_equal(m(0), [0, 0]) assert_equal(m([1, 2], model_set_axis=False), [[42, 84], [43, 86]])
def fpa2asdf(fpafile, outname, ref_kw): """ Create an asdf reference file with the FPA description. The CDP2 delivery includes a fits file - "FPA.fpa" which is the input to this function. This file is converted to asdf and is a reference file of type "FPA". nirspec_fs_ref_tools.fpa2asdf('Ref_Files/CoordTransform/Description/FPA.fpa', 'fpa.asdf') Parameters ---------- fpafile : str A fits file with FPA description (FPA.fpa) outname : str Name of output ASDF file. """ with open(fpafile) as f: lines = [l.strip() for l in f.readlines()] # NRS1 ind = lines.index("*SCA491_PitchX") scalex_nrs1 = models.Scale(1 / float(lines[ind + 1]), name='fpa_scale_x') ind = lines.index("*SCA491_PitchY") scaley_nrs1 = models.Scale(1 / float(lines[ind + 1]), name='fpa_scale_y') ind = lines.index("*SCA491_RotAngle") rot_nrs1 = models.Rotation2D(np.rad2deg(-float(lines[ind + 1])), name='fpa_rotation') ind = lines.index("*SCA491_PosX") shiftx_nrs1 = models.Shift(-float(lines[ind + 1]), name='fpa_shift_x') ind = lines.index("*SCA491_PosY") shifty_nrs1 = models.Shift(-float(lines[ind + 1]), name='fpa_shift_y') # NRS2 ind = lines.index("*SCA492_PitchX") scalex_nrs2 = models.Scale(1 / float(lines[ind + 1]), name='fpa_scale_x') ind = lines.index("*SCA492_PitchY") scaley_nrs2 = models.Scale(1 / float(lines[ind + 1]), name='fpa_scale_y') ind = lines.index("*SCA492_RotAngle") rot_nrs2 = models.Rotation2D(np.rad2deg(float(lines[ind + 1])), name='fpa_rotation') ind = lines.index("*SCA492_PosX") shiftx_nrs2 = models.Shift(-float(lines[ind + 1]), name='fpa_shift_x') ind = lines.index("*SCA492_PosY") shifty_nrs2 = models.Shift(-float(lines[ind + 1]), name='fpa_shift_y') tree = ref_kw.copy() tree['NRS1'] = (shiftx_nrs1 & shifty_nrs1) | rot_nrs1 | (scalex_nrs1 & scaley_nrs1) tree['NRS2'] = (shiftx_nrs2 & shifty_nrs2) | rot_nrs2 | (scalex_nrs2 & scaley_nrs2) fasdf = AsdfFile() fasdf.tree = tree fasdf.write_to(outname) return fasdf
def test_domain(): trans3 = models.Shift(10) & models.Scale(2) & models.Shift(-1) pipeline = [('detector', trans3), ('sky', None)] w = wcs.WCS(pipeline) bb = ((-1, 10), (6, 15)) with pytest.raises(DimensionalityError): w.bounding_box = bb trans2 = models.Shift(10) & models.Scale(2) pipeline = [('detector', trans2), ('sky', None)] w = wcs.WCS(pipeline) w.bounding_box = bb assert w.bounding_box == w.forward_transform.bounding_box[::-1]
def test_coupled_compound_model_nested(): ccm = CoupledCompoundModel("&", m.Shift(5) & m.Scale(2), m.Scale(10) | m.Shift(3)) new = roundtrip_object(ccm) assert isinstance(new, CoupledCompoundModel) assert isinstance(new.left, CompoundModel) assert isinstance(new.left.left, m.Shift) assert isinstance(new.left.right, m.Scale) assert isinstance(new.right, CompoundModel) assert isinstance(new.right.left, m.Scale) assert isinstance(new.right.right, m.Shift) assert ccm.n_inputs == new.n_inputs assert ccm.inputs == new.inputs
def v23tosky(input_model): v2_ref = input_model.meta.wcsinfo.v2_ref / 3600 v3_ref = input_model.meta.wcsinfo.v3_ref / 3600 roll_ref = input_model.meta.wcsinfo.roll_ref ra_ref = input_model.meta.wcsinfo.ra_ref dec_ref = input_model.meta.wcsinfo.dec_ref angles = [-v2_ref, v3_ref, -roll_ref, -dec_ref, ra_ref] axes = "zyxyz" sky_rotation = V23ToSky(angles, axes_order=axes, name="v23tosky") # The sky rotation expects values in deg. # This should be removed when models work with quantities. return astmodels.Scale(1 / 3600) & astmodels.Scale(1 / 3600) | sky_rotation
def test_domain(): trans3 = models.Shift(10) & models.Scale(2) & models.Shift(-1) pipeline = [('detector', trans3), ('sky', None)] w = wcs.WCS(pipeline) domain = [{'lower': -1, 'upper': 10, 'include_lower': True, 'include_upper': False, 'step': .1}, {'lower': 6, 'upper': 15, 'include_lower': False, 'include_upper': True, 'step': .5}] with pytest.raises(ValueError): w.domain = domain trans2 = models.Shift(10) & models.Scale(2) pipeline = [('detector', trans2), ('sky', None)] w = wcs.WCS(pipeline) w.domain = domain assert w.domain == w.forward_transform.meta['domain']
def imaging_distortion(input_model, reference_files): distortion = AsdfFile.open(reference_files['distortion']).tree['model'] # Convert to deg transform = distortion | models.Scale(1 / 3600) & models.Scale(1 / 3600) try: bb = transform.bounding_box except NotImplementedError: shape = input_model.data.shape # Note: Since bounding_box is attached to the model here it's in reverse order. bb = ((-0.5, shape[0] - 0.5), (-0.5, shape[1] - 0.5)) transform.bounding_box = bb return transform
def test_create_wcs(tmpdir): m1 = models.Shift(12.4) & models.Shift(-2) m2 = models.Scale(2) & models.Scale(-2) icrs = cf.CelestialFrame(name='icrs', reference_frame=coord.ICRS()) det = cf.Frame2D(name='detector', axes_order=(0, 1)) gw1 = wcs.WCS(output_frame='icrs', input_frame='detector', forward_transform=m1) gw2 = wcs.WCS(output_frame='icrs', forward_transform=m1) gw3 = wcs.WCS(output_frame=icrs, input_frame=det, forward_transform=m1) tree = {'gw1': gw1, 'gw2': gw2, 'gw3': gw3} helpers.assert_roundtrip_tree(tree, tmpdir)
def test_backward_transform(): """ Test backward transform raises an error when an analytical inverse is not available. """ # Test that an error is raised when one of the models has not inverse. poly = models.Polynomial1D(1, c0=4) w = wcs.WCS(forward_transform=poly & models.Scale(2), output_frame='sky') with pytest.raises(NotImplementedError): w.backward_transform # test backward transform poly.inverse = models.Shift(-4) w = wcs.WCS(forward_transform=poly & models.Scale(2), output_frame='sky') assert_allclose(w.backward_transform(1, 2), (-3, 1))
def _generate_wcs_transform(dispaxis): """Create mock gwcs.WCS object for resampled s2d data""" detector = cf.Frame2D(name='detector', axes_order=(0, 1), unit=(u.pix, u.pix)) icrs = cf.CelestialFrame(name='icrs', reference_frame=coord.ICRS(), axes_order=(0, 1), unit=(u.deg, u.deg), axes_names=('RA', 'DEC')) spec = cf.SpectralFrame(name='spec', axes_order=(2, ), unit=(u.micron, ), axes_names=('lambda', )) world = cf.CompositeFrame(name="world", frames=[icrs, spec]) if dispaxis == 1: mapping = models.Mapping((0, 1, 0)) if dispaxis == 2: mapping = models.Mapping((0, 1, 1)) transform = mapping | (models.Const1D(42) & models.Const1D(42) & (models.Shift(30) | models.Scale(0.1))) pipeline = [(detector, transform), (world, None)] wcs = WCS(pipeline) return wcs
def test_footprint(): icrs = cf.CelestialFrame(name='icrs', reference_frame=coord.ICRS(), axes_order=(0, 1)) spec = cf.SpectralFrame(name='freq', unit=[ u.Hz, ], axes_order=(2, )) world = cf.CompositeFrame([icrs, spec]) transform = (models.Shift(10) & models.Shift(-1)) & models.Scale(2) pipe = [('det', transform), (world, None)] w = wcs.WCS(pipe) with pytest.raises(TypeError): w.footprint() w.bounding_box = ((1, 5), (1, 3), (1, 6)) assert_equal( w.footprint(), np.array([[11, 0, 2], [11, 0, 12], [11, 2, 2], [11, 2, 12], [15, 0, 2], [15, 0, 12], [15, 2, 2], [15, 2, 12]])) assert_equal(w.footprint(axis_type='spatial'), np.array([[11., 0.], [11., 2.], [15., 2.], [15., 0.]])) assert_equal(w.footprint(axis_type='spectral'), np.array([2, 12]))
def test_from_fiducial_composite(): sky = coord.SkyCoord(1.63 * u.radian, -72.4 * u.deg, frame='fk5') tan = models.Pix2Sky_TAN() spec = cf.SpectralFrame(unit=(u.micron, ), axes_order=(0, )) celestial = cf.CelestialFrame(reference_frame=sky.frame, unit=(sky.spherical.lon.unit, sky.spherical.lat.unit), axes_order=(1, 2)) coord_frame = cf.CompositeFrame([spec, celestial], name='cube_frame') w = wcs_from_fiducial([.5, sky], coord_frame, projection=tan) assert isinstance(w.cube_frame.frames[1].reference_frame, coord.FK5) assert_allclose(w(1, 1, 1), (1.5, 96.52373368309931, -71.37420187296995)) # test returning coordinate objects with composite output_frame res = w(1, 2, 2, with_units=True) assert_allclose(res[0], u.Quantity(1.5 * u.micron)) assert isinstance(res[1], coord.SkyCoord) assert_allclose(res[1].ra.value, 99.329496642319) assert_allclose(res[1].dec.value, -70.30322020351122) trans = models.Shift(10) & models.Scale(2) & models.Shift(-1) w = wcs_from_fiducial([.5, sky], coord_frame, projection=tan, transform=trans) assert_allclose(w(1, 1, 1), (11.5, 99.97738475762152, -72.29039139739766)) # test coordinate object output coord_result = w(1, 1, 1, with_units=True) assert_allclose(coord_result[0], u.Quantity(11.5 * u.micron))
def test_high_level_api(): """ Test WCS high level API. """ output_frame = cf.CompositeFrame(frames=[icrs, spec]) transform = m1 & models.Scale(1.5) det = cf.CoordinateFrame(naxes=3, unit=(u.pix, u.pix, u.pix), axes_order=(0, 1, 2), axes_type=('length', 'length', 'length')) w = wcs.WCS(forward_transform=transform, output_frame=output_frame, input_frame=det) r, d, lam = w(xv, yv, xv) world_coord = w.pixel_to_world(xv, yv, xv) assert isinstance(world_coord[0], coord.SkyCoord) assert isinstance(world_coord[1], u.Quantity) assert_allclose(world_coord[0].data.lon.value, r) assert_allclose(world_coord[0].data.lat.value, d) assert_allclose(world_coord[1].value, lam) x1, y1, z1 = w.world_to_pixel(*world_coord) assert_allclose(x1, xv) assert_allclose(y1, yv) assert_allclose(z1, xv)
def fitswcs_transform_from_model(wcsinfo, wavetable=None): """ Create a WCS object using from datamodel.meta.wcsinfo. Transforms assume 0-based coordinates. Parameters ---------- wcsinfo : dict-like ``~jwst.meta.wcsinfo`` structure. Return ------ transform : `~astropy.modeling.core.Model` WCS forward transform - from pixel to world coordinates. """ spatial_axes, spectral_axes, unknown = gwutils.get_axes(wcsinfo) transform = gwutils.make_fitswcs_transform(wcsinfo) if spectral_axes: sp_axis = spectral_axes[0] if wavetable is None: # Subtract one from CRPIX which is 1-based. spectral_transform = astmodels.Shift(-(wcsinfo['CRPIX'][sp_axis] - 1)) | \ astmodels.Scale(wcsinfo['CDELT'][sp_axis]) | \ astmodels.Shift(wcsinfo['CRVAL'][sp_axis]) else: # Wave dimension is an array that needs to be converted to a table waves = wavetable['wavelength'].flatten() spectral_transform = astmodels.Tabular1D(lookup_table=waves) transform = transform & spectral_transform return transform
def fitswcs_transform_from_model(wcsinfo): """ Create a WCS object using from datamodel.meta.wcsinfo. Transforms assume 0-based coordinates. Parameters ---------- wcsinfo : dict-like ``~jwst.meta.wcsinfo`` structure. Return ------ transform : `~astropy.modeling.core.Model` WCS forward transform - from pixel to world coordinates. """ spatial_axes, spectral_axes, unknown = gwutils.get_axes(wcsinfo) #sp_axis = spectral_axes[0] transform = gwutils.make_fitswcs_transform(wcsinfo) #if wcsinfo['WCSAXES'] == 3: if spectral_axes: sp_axis = spectral_axes[0] # Subtract one from CRPIX which is 1-based. spectral_transform = astmodels.Shift(-(wcsinfo['CRPIX'][sp_axis] - 1)) | \ astmodels.Scale(wcsinfo['CDELT'][sp_axis]) | \ astmodels.Shift(wcsinfo['CRVAL'][sp_axis]) transform = transform & spectral_transform return transform
def test_custom_inverse_reset(): """Test resetting a custom inverse to the model's default inverse.""" class TestModel(Model): inputs = () outputs = ('y', ) @property def inverse(self): return models.Shift() @staticmethod def evaluate(): return 0 # The above test model has no meaning, nor does its inverse--this just # tests that setting an inverse and resetting to the default inverse works m = TestModel() assert isinstance(m.inverse, models.Shift) m.inverse = models.Scale() assert isinstance(m.inverse, models.Scale) del m.inverse assert isinstance(m.inverse, models.Shift)
def from_tree_transform(self, node): factor = node['factor'] if not isinstance(factor, u.Quantity) and not np.isscalar(factor): raise NotImplementedError( "Asdf currently only supports scalar inputs to Scale transform." ) return models.Scale(factor)
def test_insert_transform(): """ Tests inserting a transform.""" m1 = models.Shift(12.4) m2 = models.Scale(3.1) gw = wcs.WCS(output_frame='icrs', forward_transform=m1) assert (gw.forward_transform(1.2) == m1(1.2)) gw.insert_transform(frame='icrs', transform=m2) assert (gw.forward_transform(1.2) == (m1 | m2)(1.2))
def test_Scale_inverse_bounding_box(): model = models.Scale(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