Пример #1
0
def create_datamodel(hdul):
    im = ImageModel(hdul)
    ref = create_reference_files(im)

    pipeline = miri.create_pipeline(im, ref)
    wcsobj = wcs.WCS(pipeline)
    im.meta.wcs = wcsobj
    return im
Пример #2
0
def create_wfss_wcs(pupil, filtername='F444W'):
    """Help create WFSS GWCS object."""
    hdul = create_hdul(exptype='NRC_WFSS', filtername=filtername, pupil=pupil)
    im = ImageModel(hdul)
    ref = get_reference_files(im)
    pipeline = nircam.create_pipeline(im, ref)
    wcsobj = wcs.WCS(pipeline)
    return wcsobj
Пример #3
0
def test_create_wcs(tmpdir, version):
    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
    }

    write_options = dict(version=version)
    helpers.assert_roundtrip_tree(tree, tmpdir, write_options=write_options)
Пример #4
0
 def _create_image_model(grating='G395H', filter='F290LP', **kwargs):
     hdul = create_nirspec_ifu_file(grating=grating,
                                    filter=filter,
                                    **kwargs)
     im = datamodels.ImageModel(hdul)
     refs = create_reference_files(im)
     pipeline = nirspec.create_pipeline(im, refs, slit_y_range=[-0.5, 0.5])
     w = wcs.WCS(pipeline)
     im.meta.wcs = w
     return im, refs
Пример #5
0
def create_tso_wcs(filtername=tsgrism_filters[0], subarray="SUBGRISM256"):
    """Help create tsgrism GWCS object."""
    hdul = create_hdul(exptype='NRC_TSGRISM', pupil='GRISMR',
                       filtername=filtername, detector='NRCALONG',
                       subarray=subarray, wcskeys=wcs_tso_kw)
    im = CubeModel(hdul)
    ref = get_reference_files(im)
    pipeline = nircam.create_pipeline(im, ref)
    wcsobj = wcs.WCS(pipeline)
    return wcsobj
Пример #6
0
def test_reproject():
    hdr1 = fits.Header.fromfile(get_pkg_data_filename('data/simple_wcs.hdr'))
    hdr2 = fits.Header.fromfile(get_pkg_data_filename('data/simple_wcs2.hdr'))
    w1 = fitswcs.WCS(hdr1)
    w2 = fitswcs.WCS(hdr2)
    gw2 = wcs.WCS(output_frame='icrs',
                  forward_transform=gwutil.make_fitswcs_transform(hdr2))
    func1 = reproject(w1, w2)
    func2 = reproject(w1, gw2)
    x1, y1 = func1(1, 2)
    x2, y2 = func2(1, 2)
    utils.assert_allclose(x1, x2, atol=10**-7)
    utils.assert_allclose(y1, y2, atol=10**-7)
Пример #7
0
def create_slit(model, x0, y0, order):
    """ Create a SlitModel representing a grism slit."""
    ymin = 0
    xmin = 0
    # ymax = 58
    # xmax = 1323
    model = Mapping((0, 1, 0, 0, 0)) | (Shift(xmin) & Shift(ymin) & Const1D(x0)
                                        & Const1D(y0) & Const1D(order)) | model
    wcsobj = wcs.WCS([('det', model), ('world', None)])
    wcsobj.bounding_box = ((20, 25), (800, 805))
    slit = SlitModel()
    slit.meta.wcs = wcsobj
    slit.source_xpos = x0
    slit.source_ypos = y0
    return slit
Пример #8
0
def test_nirspec_imaging():
    """
    Test Nirspec Imaging mode using build 6 reference files.
    """
    #Test creating the WCS
    f = create_nirspec_imaging_file()
    im = datamodels.ImageModel(f)

    refs = create_reference_files(im)

    pipe = nirspec.create_pipeline(im, refs)
    w = wcs.WCS(pipe)
    im.meta.wcs = w
    # Test evaluating the WCS
    im.meta.wcs(1, 2)
Пример #9
0
def create_fitswcs(inp, input_frame=None):
    if isinstance(inp, DataModel):
        wcsinfo = wcsinfo_from_model(inp)
        transform = fitswcs_transform_from_model(wcsinfo)
        output_frame = frame_from_model(wcsinfo)
    #elif isinstance(inp, six.string_types):
        #transform = create_fitswcs_transform(inp)
        #output_frame = frame_from_fits(inp)
    else:
        raise TypeError("Input is expected to be a DataModel instance or a FITS file.")

    if input_frame is None:
        input_frame = "detector"
    pipeline = [(input_frame, transform),
               (output_frame, None)]

    wcsobj = wcs.WCS(pipeline)
    return wcsobj
Пример #10
0
def test_miri_mrs_1A():
    #ref = {}
    ref = {
        'distortion': '',
        'regions': '',
        'specwcs': '',
        'v2v3': '',
        'wavelengthrange': ''
    }
    im = ImageModel()
    im.meta.instrument.name = 'MIRI'
    im.meta.instrument.detector = 'MIRIFUSHORT'
    im.meta.instrument.channel = '12'
    im.meta.instrument.band = 'SHORT'
    im.meta.exposure.type = 'MIR_MRS'
    step = AssignWcsStep()
    for reftype in refs:
        ref[reftype] = step.get_reference_file(im, reftype)

    pipeline = miri.create_pipeline(im, ref)
    wcsobj = wcs.WCS(pipeline)

    for ch in im.meta.instrument.channel:
        ref_data = mrs_ref_data[ch + band_mapping[im.meta.instrument.band]]
        #ref_data = mrs_ref_data[im.meta.instrument.channel + band_mapping[im.meta.instrument.band]]
        #x = np.trunc(ref_data['x']).astype(np.int)
        #y = np.trunc(ref_data['y']).astype(np.int)
        for i, s in enumerate(ref_data['s']):
            sl = int(ch) * 100 + s
            detector_to_alpha_beta = wcsobj.get_transform(
                'detector', 'alpha_beta')
            alpha, beta, lam = detector_to_alpha_beta.set_input(sl)(
                ref_data['x'][i], ref_data['y'][i])
            ##xan, yan, lam = wcsobj.forward_transform.set_input(sl)(ref_data['x'][i], ref_data['y'][i])
            utils.assert_allclose(alpha, ref_data['alpha'][i], atol=10**-5)
            utils.assert_allclose(beta, ref_data['beta'][i], atol=10**-5)
            utils.assert_allclose(lam, ref_data['lam'][i], atol=10**-5)
            detector_to_xan_yan = wcsobj.get_transform('detector', 'Xan_Yan')
            xan, yan, lam = wcsobj(ref_data['x'], ref_data['y'])
            utils.assert_allclose(xan, ref_data['v2'][i], atol=10**-5)
            utils.assert_allclose(yan, ref_data['v3'][i], atol=10**-5)
            utils.assert_allclose(lam, ref_data['lam'][i], atol=10**-5)
Пример #11
0
def test_nirspec_fs_esa():
    """
    Test Nirspec FS mode using build 6 reference files.
    """
    #Test creating the WCS
    filename = create_nirspec_fs_file(grating="G140M", filter="F100LP")
    im = datamodels.ImageModel(filename)
    im.meta.filename = "test_fs.fits"
    refs = create_reference_files(im)

    pipe = nirspec.create_pipeline(im, refs)
    w = wcs.WCS(pipe)
    im.meta.wcs = w
    # Test evaluating the WCS
    w1 = nirspec.nrs_wcs_set_input(im, "S200A1")

    ref = fits.open(
        get_file_path(
            'Trace_SLIT_A_200_1_V84600010001P0000000002101_39547_JLAB88.fits'))
    pyw = astwcs.WCS(ref[1].header)

    # get positions within the slit and the coresponding lambda
    slit1 = ref[5].data  # y offset on the slit
    lam = ref[4].data

    # filter out locations outside the slit
    cond = np.logical_and(slit1 < .5, slit1 > -.5)
    y, x = cond.nonzero()  # 0-based

    x, y = pyw.wcs_pix2world(x, y, 0)
    # The pipeline works with 0-based coordinates
    x -= 1
    y -= 1

    sca2world = w1.get_transform('sca', 'v2v3')
    ra, dec, lp = sca2world(x, y)
    # w1 now outputs in microns hence the 1e6 factor
    lp *= 1e-6
    lam = lam[cond]
    nan_cond = ~np.isnan(lp)
    assert_allclose(lp[nan_cond], lam[nan_cond], atol=10**-13)
    ref.close()
Пример #12
0
def niriss_soss_set_input(model, order_number):
    """
    Extract a WCS fr a specific spectral order.

    Parameters
    ----------
    model : `~jwst.datamodels.ImageModel`
        An instance of an ImageModel
    order_number : int
        the spectral order

    Returns
    -------
    WCS - the WCS corresponding to the spectral order.

    """

    # Make sure the spectral order is available.
    if order_number < 1 or order_number > 3:
        raise ValueError('Order must be between 1 and 3')

    # Return the correct transform based on the order_number
    obj = model.meta.wcs.forward_transform.get_model(order_number)

    # use the size of the input subarray
    detector = cf.Frame2D(name='detector',
                          axes_order=(0, 1),
                          unit=(u.pix, u.pix))
    spec = cf.SpectralFrame(name='spectral',
                            axes_order=(2, ),
                            unit=(u.micron, ),
                            axes_names=('wavelength', ))
    sky = cf.CelestialFrame(reference_frame=coord.ICRS(),
                            axes_names=('ra', 'dec'),
                            axes_order=(0, 1),
                            unit=(u.deg, u.deg),
                            name='sky')
    world = cf.CompositeFrame([sky, spec], name='world')
    pipeline = [(detector, obj), (world, None)]

    return wcs.WCS(pipeline)
Пример #13
0
def test_nirspec_ifu_against_esa():
    """
    Test Nirspec IFU mode using build 6 reference files.
    """
    # Test creating the WCS
    # hdu = create_nirspec_ifu_file('OPAQUE', 'G140H', 'REF')
    hdul = create_nirspec_ifu_file("F100LP", "G140H")
    im = datamodels.ImageModel(hdul)
    im.meta.filename = "test_ifu.fits"
    refs = create_reference_files(im)

    pipe = nirspec.create_pipeline(im, refs)
    w = wcs.WCS(pipe)
    im.meta.wcs = w
    # Test evaluating the WCS (slice 0)
    w0 = nirspec.nrs_wcs_set_input(im, 0)

    #ref = fits.open(get_file_path('Trace_IFU_Slice_00_MON-COMBO-IFU-06_8410_jlab85.fits.gz'))
    ref = fits.open(
        get_file_path(
            'Trace_IFU_Slice_00_MON-COMBO-IFU-06_8410_jlab85.fits.gz'))
    crpix = np.array([ref[1].header['crpix1'], ref[1].header['crpix2']])
    crval = np.array([ref[1].header['crval1'], ref[1].header['crval2']])

    # get positions within the slit and the coresponding lambda
    slit1 = ref[5].data  # y offset on the slit
    lam = ref[4].data
    # filter out locations outside the slit
    cond = np.logical_and(slit1 < .5, slit1 > -.5)
    y, x = cond.nonzero()
    cor = crval - np.array(crpix)
    y = y + cor[1]
    x = x + cor[0]
    sca2world = w0.get_transform('sca', 'msa_frame')
    _, slit_y, lp = sca2world(x, y)

    # Convert meters to microns for the second parameters as the
    # first parameter will be in microns.
    assert_allclose(lp, lam[cond] * 1e6, rtol=1e-4, atol=1e-4)
    ref.close()
Пример #14
0
def niriss_soss_set_input(model, order_number):
    """
    Get the right model given the order number.

    Parameters
    ----------
    model - Input model
    order_number - the, well, order number desired

    Returns
    -------
    WCS - the WCS corresponding to the order_number

    """

    # Make sure the order number is correct.
    if order_number < 1 or order_number > 3:
        raise ValueError('Order must be between 1 and 3')

    # Return the correct transform based on the order_number
    obj = model.meta.wcs.forward_transform.get_model(order_number)

    # use the size of the input subarray7
    detector = cf.Frame2D(name='detector',
                          axes_order=(0, 1),
                          unit=(u.pix, u.pix))
    spec = cf.SpectralFrame(name='spectral',
                            axes_order=(2, ),
                            unit=(u.micron, ),
                            axes_names=('wavelength', ))
    sky = cf.CelestialFrame(reference_frame=coord.ICRS(),
                            axes_names=('ra', 'dec'),
                            axes_order=(0, 1),
                            unit=(u.deg, u.deg),
                            name='sky')
    world = cf.CompositeFrame([sky, spec], name='world')
    pipeline = [(detector, obj), (world, None)]

    return wcs.WCS(pipeline)
Пример #15
0
def test_nirspec_fs_esa():
    """
    Test Nirspec FS mode using build 6 reference files.
    """
    #Test creating the WCS
    filename = create_nirspec_fs_file(grating="G140M", filter="F100LP")
    im = datamodels.ImageModel(filename)
    im.meta.filename = "test_fs.fits"
    refs = create_reference_files(im)
    #refs['disperser'] = get_file_path('jwst_nirspec_disperser_0001.asdf')
    pipe = nirspec.create_pipeline(im, refs)
    w = wcs.WCS(pipe)
    im.meta.wcs = w
    # Test evaluating the WCS
    w1 = nirspec.nrs_wcs_set_input(im, "S200A1")

    #ref = fits.open(get_file_path('Trace_SLIT_A_200_1_SLIT-COMBO-016_9791_jlab85_0001.fits.gz'))
    ref = fits.open(
        get_file_path(
            'Trace_SLIT_A_200_1_V84600010001P0000000002101_39547_JLAB88.fits'))
    crpix = np.array([ref[1].header['crpix1'], ref[1].header['crpix2']])
    crval = np.array([ref[1].header['crval1'], ref[1].header['crval2']])
    # get positions within the slit and the coresponding lambda
    slit1 = ref[5].data  # y offset on the slit
    lam = ref[4].data
    # filter out locations outside the slit
    cond = np.logical_and(slit1 < .5, slit1 > -.5)
    y, x = cond.nonzero()
    cor = crval - np.array(crpix)
    y = y + cor[1]
    x = x + cor[0]
    sca2world = w1.get_transform('sca', 'v2v3')
    ra, dec, lp = sca2world(x, y)
    # w1 now outputs in microns hence the 1e6 factor
    lp *= 1e-6
    lam = lam[cond]
    nan_cond = ~np.isnan(lp)
    assert_allclose(lp[nan_cond], lam[nan_cond], atol=10**-13)
    ref.close()
Пример #16
0
def create_fitswcs(inp, input_frame=None):
    if isinstance(inp, DataModel):
        wcsinfo = wcsinfo_from_model(inp)
        wavetable = None
        spatial_axes, spectral_axes, unknown = gwutils.get_axes(wcsinfo)
        sp_axis = spectral_axes[0]
        if wcsinfo['CTYPE'][sp_axis] == 'WAVE-TAB':
            wavetable = inp.wavetable
        transform = fitswcs_transform_from_model(wcsinfo, wavetable)
        output_frame = frame_from_model(wcsinfo)
    #elif isinstance(inp, str):
    #transform = create_fitswcs_transform(inp)
    #output_frame = frame_from_fits(inp)
    else:
        raise TypeError(
            "Input is expected to be a DataModel instance or a FITS file.")

    if input_frame is None:
        input_frame = "detector"
    pipeline = [(input_frame, transform), (output_frame, None)]

    wcsobj = wcs.WCS(pipeline)
    return wcsobj
Пример #17
0
def test_miri_mrs_1C():
    ref = {}

    im = ImageModel()
    im.meta.instrument.name = 'MIRI'
    im.meta.instrument.detector = 'MIRIFUSHORT'
    im.meta.instrument.channel = '12'
    im.meta.instrument.band = 'LONG'
    im.meta.exposure.type = 'MIR_MRS'
    step = AssignWcsStep()
    for reftype in refs:
        ref[reftype] = step.get_reference_file(im, reftype)

    pipeline = miri.create_pipeline(im, ref)
    wcsobj = wcs.WCS(pipeline)

    for ch in im.meta.instrument.channel:
        ref_data = mrs_ref_data[ch + band_mapping[im.meta.instrument.band]]
    for i, s in enumerate(ref_data['s']):
        sl = int(ch) * 100 + s
        xan, yan, lam = wcsobj.forward_transform.set_input(sl)(
            ref_data['x'][i], ref_data['y'][i])
        utils.assert_allclose(xan, ref_data['v2'][i], atol=10**-5)
        utils.assert_allclose(yan, ref_data['v3'][i], atol=10**-5)
        utils.assert_allclose(lam, ref_data['lam'][i], atol=10**-5)
    for i, s in enumerate(ref_data['s']):
        sl = int(ch) * 100 + s
        xan, yan, lam = wcsobj.forward_transform(ref_data['x'][i],
                                                 ref_data['y'][i])
        utils.assert_allclose(xan, ref_data['v2'][i], atol=10**-5)
        utils.assert_allclose(yan, ref_data['v3'][i], atol=10**-5)
        utils.assert_allclose(lam, ref_data['lam'][i], atol=10**-5)
        xin, yin = wcsobj.backward_transform(ref_data['v2'][i],
                                             ref_data['v3'][i],
                                             ref_data['lam'][i])
        utils.assert_allclose(xin, ref_data['x'][i], atol=10**-5)
        utils.assert_allclose(y, ref_data['y'][i], atol=10**-5)
Пример #18
0
def test_nirspec_ifu_against_esa():
    """
    Test Nirspec IFU mode using CV3 reference files.
    """
    ref = fits.open(
        get_file_path(
            'Trace_IFU_Slice_00_SMOS-MOD-G1M-17-5344175105_30192_JLAB88.fits'))

    # Test NRS1
    pyw = astwcs.WCS(ref['SLITY1'].header)
    hdul = create_nirspec_ifu_file("OPAQUE", "G140M")
    im = datamodels.ImageModel(hdul)
    im.meta.filename = "test_ifu.fits"
    refs = create_reference_files(im)

    pipe = nirspec.create_pipeline(im, refs)
    w = wcs.WCS(pipe)
    im.meta.wcs = w
    # Test evaluating the WCS (slice 0)
    w0 = nirspec.nrs_wcs_set_input(im, 0)

    # get positions within the slit and the coresponding lambda
    slit1 = ref['SLITY1'].data  # y offset on the slit
    lam = ref['LAMBDA1'].data
    # filter out locations outside the slit
    cond = np.logical_and(slit1 < .5, slit1 > -.5)
    y, x = cond.nonzero()  # 0-based

    x, y = pyw.wcs_pix2world(x, y, 0)
    # The pipeline accepts 0-based cooridnates
    x -= 1
    y -= 1
    sca2world = w0.get_transform('sca', 'msa_frame')
    _, slit_y, lp = sca2world(x, y)

    lp *= 10**-6
    assert_allclose(lp, lam[cond], atol=1e-13)
Пример #19
0
def test_ifu_bbox():
    bbox = {
        0: ((122.0908542999878, 1586.2584665188083), (773.5411133037417,
                                                      825.1150258966278)),
        1: ((140.3793485788431, 1606.8904629423566), (1190.353197027459,
                                                      1243.0853605832503)),
        2: ((120.0139534379125, 1583.9271768905855), (724.3249534782219,
                                                      775.8104288584977)),
        3: ((142.50252648927454, 1609.3106221382388), (1239.4122720740888,
                                                       1292.288713688988)),
        4: ((117.88884113088403, 1581.5517394150106), (674.9787657901347,
                                                       726.3752061973377)),
        5: ((144.57465414462143, 1611.688447569682), (1288.4808318659427,
                                                      1341.5035313084197)),
        6: ((115.8602297714846, 1579.27471654949), (625.7982466386104,
                                                    677.1147840452901)),
        7: ((146.7944728147906, 1614.2161842198498), (1337.531525654835,
                                                      1390.7050687363856)),
        8: ((113.86384530944383, 1577.0293086386203), (576.5344359685643,
                                                       627.777022204828)),
        9: ((149.0259581360621, 1616.7687282225652), (1386.5118806905086,
                                                      1439.843598490326)),
        10: ((111.91564190274217, 1574.8351095461135), (527.229828693075,
                                                        578.402894851317)),
        11: ((151.3053466801954, 1619.3720722471498), (1435.423685040875,
                                                       1488.917203728964)),
        12: ((109.8957204607345, 1572.570246400894), (477.9699083444277,
                                                      529.0782087498488)),
        13: ((153.5023503173659, 1621.9005029476564), (1484.38405923062,
                                                       1538.0443479389924)),
        14: ((107.98320121613297, 1570.411787034636), (428.6704834494425,
                                                       479.7217241891257)),
        15: ((155.77991404913857, 1624.5184927460925), (1533.169633314481,
                                                        1586.9984359105376)),
        16: ((106.10212081215678, 1568.286103827344), (379.3860245240618,
                                                       430.3780648366697)),
        17: ((158.23149941845386, 1627.305849064835), (1582.0496119714928,
                                                       1636.0513450787032)),
        18: ((104.09366374413436, 1566.030231370944), (330.0822744105267,
                                                       381.01974582564395)),
        19: ((160.4511021152353, 1629.888830991371), (1630.7797743277185,
                                                      1684.9592727079018)),
        20: ((102.25220592881234, 1563.9475099032868), (280.7233309522168,
                                                        331.6093009077988)),
        21: ((162.72784286205734, 1632.5257403739463), (1679.6815760587567,
                                                        1734.03692957156)),
        22: ((100.40115742738622, 1561.8476640376036), (231.35443588323855,
                                                        282.19575854747006)),
        23: ((165.05939163941662, 1635.2270773628682), (1728.511467615387,
                                                        1783.0485841263735)),
        24: ((98.45723949658425, 1559.6499479349648), (182.0417295679079,
                                                       232.83530870639865)),
        25: ((167.44628840053574, 1637.9923229870349), (1777.2512197664128,
                                                        1831.971115503598)),
        26: ((96.56508092457855, 1557.5079027818058), (132.5285162704088,
                                                       183.27350269292484)),
        27: ((169.8529496136358, 1640.778485168005), (1826.028691168028,
                                                      1880.9336718824313)),
        28: ((94.71390837793813, 1555.4048050512263), (82.94691422559131,
                                                       133.63901517357235)),
        29: ((172.3681094850081, 1643.685604697228), (1874.8184744639657,
                                                      1929.9072657798927))
    }

    hdul = create_nirspec_ifu_file("F290LP", "G140M")
    im = datamodels.IFUImageModel(hdul)
    im.meta.filename = "test_ifu.fits"
    refs = create_reference_files(im)

    pipe = nirspec.create_pipeline(im, refs, slit_y_range=[-.5, .5])
    w = wcs.WCS(pipe)
    im.meta.wcs = w

    _, wrange = nirspec.spectral_order_wrange_from_model(im)
    pipe = im.meta.wcs.pipeline

    g2s = pipe[2].transform
    transforms = [pipe[0].transform]
    transforms.append(pipe[1].transform[1:])
    transforms.append(astmodels.Identity(1))
    transforms.append(astmodels.Identity(1))
    transforms.extend([step.transform for step in pipe[4:-1]])

    for sl in range(30):
        transforms[2] = g2s.get_model(sl)
        m = functools.reduce(lambda x, y: x | y,
                             [tr.inverse for tr in transforms[:3][::-1]])
        bbox_sl = nirspec.compute_bounding_box(m, wrange)
        assert_allclose(bbox[sl], bbox_sl)
Пример #20
0
def test_functional_ifu_prism():
    """Compare Nirspec instrument model with IDT model for IFU prism."""
    # setup test
    model_file = 'ifu_prism_functional_ESA_v1_20180619.txt'
    hdu1 = create_nirspec_ifu_file(grating='PRISM',
                                   filter='CLEAR',
                                   gwa_xtil=0.35986012,
                                   gwa_ytil=0.13448857,
                                   gwa_tilt=37.1)
    im = datamodels.ImageModel(hdu1)
    refs = create_reference_files(im)
    pipeline = nirspec.create_pipeline(im, refs, slit_y_range=[-0.55, 0.55])
    w = wcs.WCS(pipeline)
    im.meta.wcs = w
    slit_wcs = nirspec.nrs_wcs_set_input(im, 0)  # use slice 0
    ins_file = get_file_path(model_file)
    ins_tab = table.Table.read(ins_file, format='ascii')
    slitx = [0] * 5
    slity = [-.5, -.25, 0, .25, .5]
    lam = np.array([.7e-7, 1e-6, 2e-6, 3e-6, 5e-6])
    order, wrange = nirspec.get_spectral_order_wrange(im,
                                                      refs['wavelengthrange'])
    im.meta.wcsinfo.sporder = order
    im.meta.wcsinfo.waverange_start = wrange[0]
    im.meta.wcsinfo.waverange_end = wrange[1]

    # Slit to MSA entrance
    # This includes the Slicer transform and the IFUFORE transform
    slit2msa = slit_wcs.get_transform('slit_frame', 'msa_frame')
    msax, msay, _ = slit2msa(slitx, slity, lam)
    assert_allclose(slitx, ins_tab['xslitpos'])
    assert_allclose(slity, ins_tab['yslitpos'])
    assert_allclose(msax + 0.0073, ins_tab['xmsapos'],
                    rtol=1e-2)  # expected offset
    assert_allclose(msay + 0.0085, ins_tab['ymaspos'],
                    rtol=1e-2)  # expected offset

    # Slicer
    slit2slicer = slit_wcs.get_transform('slit_frame', 'slicer')
    x_slicer, y_slicer, _ = slit2slicer(slitx, slity, lam)

    # MSA exit
    # Applies the IFUPOST transform to coordinates at the Slicer
    with datamodels.IFUPostModel(refs['ifupost']) as ifupost:
        ifupost_transform = nirspec._create_ifupost_transform(ifupost.slice_0)
    x_msa_exit, y_msa_exit = ifupost_transform(x_slicer, y_slicer, lam)
    assert_allclose(x_msa_exit, ins_tab['xmsapos'])
    assert_allclose(y_msa_exit, ins_tab['ymaspos'])

    # Coordinates at Collimator exit
    # Applies the Collimator forward transform to coordinates at the MSA exit
    with datamodels.open(refs['collimator']) as col:
        colx, coly = col.model.inverse(x_msa_exit, y_msa_exit)
    assert_allclose(colx, ins_tab['xcoll'])
    assert_allclose(coly, ins_tab['ycoll'])

    # After applying direcitonal cosines
    dircos = trmodels.Unitless2DirCos()
    xcolDircosi, ycolDircosi, z = dircos(colx, coly)
    assert_allclose(xcolDircosi, ins_tab['xcolDirCosi'])
    assert_allclose(ycolDircosi, ins_tab['ycolDirCosi'])

    # Slit to GWA entrance
    # applies the Collimator forward, Unitless to Directional and 3D Rotation to MSA exit coordinates
    with datamodels.DisperserModel(refs['disperser']) as disp:
        disperser = nirspec.correct_tilt(disp, im.meta.instrument.gwa_xtilt,
                                         im.meta.instrument.gwa_ytilt)
    collimator2gwa = nirspec.collimator_to_gwa(refs, disperser)
    x_gwa_in, y_gwa_in, z_gwa_in = collimator2gwa(x_msa_exit, y_msa_exit)
    assert_allclose(x_gwa_in, ins_tab['xdispIn'])

    # Slit to GWA out
    # Runs slit--> slicer --> msa_exit --> collimator --> dircos --> rotation --> angle_from_grating equation
    slit2gwa = slit_wcs.get_transform('slit_frame', 'gwa')
    x_gwa_out, y_gwa_out, z_gwa_out = slit2gwa(slitx, slity, lam)
    assert_allclose(x_gwa_out, ins_tab['xdispLaw'])
    assert_allclose(y_gwa_out, ins_tab['ydispLaw'])

    # CAMERA entrance (assuming direction is from sky to detector)
    angles = [
        disperser['theta_x'], disperser['theta_y'], disperser['theta_z'],
        disperser['tilt_y']
    ]
    rotation = trmodels.Rotation3DToGWA(angles,
                                        axes_order="xyzy",
                                        name='rotation')
    dircos2unitless = trmodels.DirCos2Unitless()
    gwa2cam = rotation.inverse | dircos2unitless
    x_camera_entrance, y_camera_entrance = gwa2cam(x_gwa_out, y_gwa_out,
                                                   z_gwa_out)
    assert_allclose(x_camera_entrance, ins_tab['xcamCosi'])
    assert_allclose(y_camera_entrance, ins_tab['ycamCosi'])

    # at FPA
    with datamodels.CameraModel(refs['camera']) as camera:
        x_fpa, y_fpa = camera.model.inverse(x_camera_entrance,
                                            y_camera_entrance)
    assert_allclose(x_fpa, ins_tab['xfpapos'])
    assert_allclose(y_fpa, ins_tab['yfpapos'])

    # at SCA
    slit2sca = slit_wcs.get_transform('slit_frame', 'sca')
    x_sca_nrs1, y_sca_nrs1 = slit2sca(slitx, slity, lam)

    # At NRS2
    with datamodels.FPAModel(refs['fpa']) as fpa:
        x_sca_nrs2, y_sca_nrs2 = fpa.nrs2_model.inverse(x_fpa, y_fpa)
    assert_allclose(x_sca_nrs1 + 1, ins_tab['i'])
    assert_allclose(y_sca_nrs1 + 1, ins_tab['j'])

    # at oteip
    # Goes through slicer, ifufore, and fore transforms
    slit2oteip = slit_wcs.get_transform('slit_frame', 'oteip')
    x_oteip, y_oteip, _ = slit2oteip(slitx, slity, lam)
    assert_allclose(x_oteip, ins_tab['xOTEIP'])
    assert_allclose(y_oteip, ins_tab['yOTEIP'])

    # at v2, v3 [in arcsec]
    slit2v23 = slit_wcs.get_transform('slit_frame', 'v2v3')
    v2, v3, _ = slit2v23(slitx, slity, lam)
    v2 /= 3600
    v3 /= 3600
    assert_allclose(v2, ins_tab['xV2V3'])
    assert_allclose(v3, ins_tab['yV2V3'])
Пример #21
0
def test_functional_ifu_grating():
    """Compare Nirspec instrument model with IDT model for IFU grating."""

    # setup test
    model_file = 'ifu_grating_functional_ESA_v1_20180619.txt'
    hdul = create_nirspec_ifu_file(grating='G395H',
                                   filter='F290LP',
                                   gwa_xtil=0.35986012,
                                   gwa_ytil=0.13448857)
    im = datamodels.ImageModel(hdul)
    refs = create_reference_files(im)
    pipeline = nirspec.create_pipeline(im, refs, slit_y_range=[-0.55, 0.55])
    w = wcs.WCS(pipeline)
    im.meta.wcs = w
    slit_wcs = nirspec.nrs_wcs_set_input(im, 0)  # use slice 0
    ins_file = get_file_path(model_file)
    ins_tab = table.Table.read(ins_file, format='ascii')
    slitx = [0] * 5
    slity = [-.5, -.25, 0, .25, .5]
    lam = np.array([2.9, 3.39, 3.88, 4.37, 5]) * 10**-6
    order, wrange = nirspec.get_spectral_order_wrange(im,
                                                      refs['wavelengthrange'])
    im.meta.wcsinfo.sporder = order
    im.meta.wcsinfo.waverange_start = wrange[0]
    im.meta.wcsinfo.waverange_end = wrange[1]

    # Slit to MSA entrance
    # This includes the Slicer transform and the IFUFORE transform
    slit2msa = slit_wcs.get_transform('slit_frame', 'msa_frame')
    msax, msay, _ = slit2msa(slitx, slity, lam)
    assert_allclose(slitx, ins_tab['xslitpos'])
    assert_allclose(slity, ins_tab['yslitpos'])
    assert_allclose(msax + 0.0073, ins_tab['xmsapos'],
                    rtol=1e-2)  # expected offset
    assert_allclose(msay + 0.0085, ins_tab['ymaspos'],
                    rtol=1e-2)  # expected offset

    # Slicer
    slit2slicer = slit_wcs.get_transform('slit_frame', 'slicer')
    x_slicer, y_slicer, _ = slit2slicer(slitx, slity, lam)

    # MSA exit
    # Applies the IFUPOST transform to coordinates at the Slicer
    with datamodels.IFUPostModel(refs['ifupost']) as ifupost:
        ifupost_transform = nirspec._create_ifupost_transform(ifupost.slice_0)
    x_msa_exit, y_msa_exit = ifupost_transform(x_slicer, y_slicer, lam)
    assert_allclose(x_msa_exit, ins_tab['xmsapos'])
    assert_allclose(y_msa_exit, ins_tab['ymaspos'])

    # Computations are done using the eact form of the equations in the reports
    # Part I of the Forward IFU-POST transform - the linear transform
    xc_out = 0.0487158154447
    yc_out = 0.00856211956976
    xc_in = 0.000355277216
    yc_in = -3.0089012e-05
    theta = np.deg2rad(-0.129043957046)
    factor_x = 0.100989874454
    factor_y = 0.100405184145

    # Slicer coordinates
    xS = 0.000399999989895
    yS = -0.00600000005215

    x = xc_out + factor_x * (+cos(theta) * (xS - xc_in) + sin(theta) *
                             (yS - yc_in))
    y = yc_out + factor_y * (-sin(theta) * (xS - xc_in) + cos(theta) *
                             (yS - yc_in))

    # Forward IFU-POST II part - non-linear transform
    lam = 2.9e-6
    coef_names = [
        f'c{x}_{y}' for x in range(6) for y in range(6) if x + y <= 5
    ]
    y_forw = [
        -82.3492267824, 29234.6982762, -540260.780853, 771881.305018,
        -2563462.26848, 29914272.1164, 4513.04082605, -2212869.44311,
        32875633.0303, -29923698.5288, 27293902.5636, -39820.4434726,
        62431493.9962, -667197265.033, 297253538.182, -1838860.86305,
        -777169857.2, 4514693865.7, 42790637.764, 3596423850.94, -260274017.448
    ]
    y_forw_dist = [
        188531839.97, -43453434864.0, 70807756765.8, -308272809909.0,
        159768473071.0, 9712633344590.0, -11762923852.9, 3545938873190.0,
        -4198643655420.0, 12545642983100.0, -11707051591600.0, 173091230285.0,
        -108534069056000.0, 82893348097600.0, -124708740989000.0,
        2774389757990.0, 1476779720300000.0, -545358301961000.0,
        -93101557994100.0, -7536890639430000.0, 646310545048000.0
    ]
    y_coeff = {}
    for i, coef in enumerate(coef_names):
        y_coeff[coef] = y_forw[i] + lam * y_forw_dist[i]
    poly2d = astmodels.Polynomial2D(5, **y_coeff)
    ifupost_y = poly2d(x, y)
    assert_allclose(ifupost_y, ins_tab['ymaspos'][0])
    assert_allclose(ifupost_y, y_msa_exit[0])

    # reset 'lam'
    lam = np.array([2.9, 3.39, 3.88, 4.37, 5]) * 10**-6

    # Coordinates at Collimator exit
    # Applies the Collimator forward transform to coordinates at the MSA exit
    with datamodels.open(refs['collimator']) as col:
        colx, coly = col.model.inverse(x_msa_exit, y_msa_exit)
    assert_allclose(colx, ins_tab['xcoll'])
    assert_allclose(coly, ins_tab['ycoll'])

    # After applying direcitonal cosines
    dircos = trmodels.Unitless2DirCos()
    xcolDircosi, ycolDircosi, z = dircos(colx, coly)
    assert_allclose(xcolDircosi, ins_tab['xcolDirCosi'])
    assert_allclose(ycolDircosi, ins_tab['ycolDirCosi'])

    # Slit to GWA entrance
    # applies the Collimator forward, Unitless to Directional and 3D Rotation to MSA exit coordinates
    with datamodels.DisperserModel(refs['disperser']) as disp:
        disperser = nirspec.correct_tilt(disp, im.meta.instrument.gwa_xtilt,
                                         im.meta.instrument.gwa_ytilt)
    collimator2gwa = nirspec.collimator_to_gwa(refs, disperser)
    x_gwa_in, y_gwa_in, z_gwa_in = collimator2gwa(x_msa_exit, y_msa_exit)
    assert_allclose(x_gwa_in, ins_tab['xdispIn'])

    # Slit to GWA out
    # Runs slit--> slicer --> msa_exit --> collimator --> dircos --> rotation --> angle_from_grating equation
    slit2gwa = slit_wcs.get_transform('slit_frame', 'gwa')
    x_gwa_out, y_gwa_out, z_gwa_out = slit2gwa(slitx, slity, lam)
    assert_allclose(x_gwa_out, ins_tab['xdispLaw'])
    assert_allclose(y_gwa_out, ins_tab['ydispLaw'])

    # CAMERA entrance (assuming direction is from sky to detector)
    angles = [
        disperser['theta_x'], disperser['theta_y'], disperser['theta_z'],
        disperser['tilt_y']
    ]
    rotation = trmodels.Rotation3DToGWA(angles,
                                        axes_order="xyzy",
                                        name='rotation')
    dircos2unitless = trmodels.DirCos2Unitless()
    gwa2cam = rotation.inverse | dircos2unitless
    x_camera_entrance, y_camera_entrance = gwa2cam(x_gwa_out, y_gwa_out,
                                                   z_gwa_out)
    assert_allclose(x_camera_entrance, ins_tab['xcamCosi'])
    assert_allclose(y_camera_entrance, ins_tab['ycamCosi'])

    # at FPA
    with datamodels.CameraModel(refs['camera']) as camera:
        x_fpa, y_fpa = camera.model.inverse(x_camera_entrance,
                                            y_camera_entrance)
    assert_allclose(x_fpa, ins_tab['xfpapos'])
    assert_allclose(y_fpa, ins_tab['yfpapos'])

    # at SCA
    slit2sca = slit_wcs.get_transform('slit_frame', 'sca')
    x_sca_nrs1, y_sca_nrs1 = slit2sca(slitx, slity, lam)

    # At NRS2
    with datamodels.FPAModel(refs['fpa']) as fpa:
        x_sca_nrs2, y_sca_nrs2 = fpa.nrs2_model.inverse(x_fpa, y_fpa)
    assert_allclose(x_sca_nrs1[:3] + 1, ins_tab['i'][:3])
    assert_allclose(y_sca_nrs1[:3] + 1, ins_tab['j'][:3])
    assert_allclose(x_sca_nrs2[3:] + 1, ins_tab['i'][3:])
    assert_allclose(y_sca_nrs2[3:] + 1, ins_tab['j'][3:])

    # at oteip
    # Goes through slicer, ifufore, and fore transforms
    slit2oteip = slit_wcs.get_transform('slit_frame', 'oteip')
    x_oteip, y_oteip, _ = slit2oteip(slitx, slity, lam)
    assert_allclose(x_oteip, ins_tab['xOTEIP'])
    assert_allclose(y_oteip, ins_tab['yOTEIP'])

    # at v2, v3 [in arcsec]
    slit2v23 = slit_wcs.get_transform('slit_frame', 'v2v3')
    v2, v3, _ = slit2v23(slitx, slity, lam)
    v2 /= 3600
    v3 /= 3600
    assert_allclose(v2, ins_tab['xV2V3'])
    assert_allclose(v3, ins_tab['yV2V3'])
Пример #22
0
def test_functional_fs_msa(mode):
    #     """
    #     Compare Nirspec instrument model with IDT model for FS and MSA.
    #     """
    if mode == 'fs':
        model_file = 'fixed_slits_functional_ESA_v4_20180618.txt'
        hdul = create_nirspec_fs_file(grating='G395H', filter='F290LP')
        im = datamodels.ImageModel(hdul)
        refs = create_reference_files(im)
        pipeline = nirspec.create_pipeline(im,
                                           refs,
                                           slit_y_range=[-0.55, 0.55])
        w = wcs.WCS(pipeline)
        im.meta.wcs = w
        # Use slit S200A1
        slit_wcs = nirspec.nrs_wcs_set_input(im, 'S200A1')

    if mode == 'msa':
        model_file = 'msa_functional_ESA_v2_20180620.txt'
        hdul = create_nirspec_mos_file(grating='G395H', filt='F290LP')
        im = datamodels.ImageModel(hdul)
        refs = create_reference_files(im)
        slit = trmodels.Slit(name=1,
                             shutter_id=4699,
                             xcen=319,
                             ycen=13,
                             ymin=-0.55000000000000004,
                             ymax=0.55000000000000004,
                             quadrant=3,
                             source_id=1,
                             shutter_state='x',
                             source_name='lamp',
                             source_alias='foo',
                             stellarity=100.0,
                             source_xpos=-0.5,
                             source_ypos=0.5)
        open_slits = [slit]
        pipeline = nirspec.slitlets_wcs(im, refs, open_slits)
        w = wcs.WCS(pipeline)
        im.meta.wcs = w
        slit_wcs = nirspec.nrs_wcs_set_input(im, 1)

    ins_file = get_file_path(model_file)
    ins_tab = table.Table.read(ins_file, format='ascii')

    # Setup the test
    slitx = [0] * 5
    slity = [-.5, -.25, 0, .25, .5]
    lam = np.array([2.9, 3.39, 3.88, 4.37, 5]) * 10**-6

    # Slit to MSA absolute
    slit2msa = slit_wcs.get_transform('slit_frame', 'msa_frame')
    msax, msay, _ = slit2msa(slitx, slity, lam)

    assert_allclose(slitx, ins_tab['xslitpos'])
    assert_allclose(slity, ins_tab['yslitpos'])
    assert_allclose(msax, ins_tab['xmsapos'])
    assert_allclose(msay, ins_tab['ymaspos'])

    # Coordinates at Collimator exit
    # Applies the Collimator forward transform to MSa absolute coordinates
    with datamodels.open(refs['collimator']) as col:
        colx, coly = col.model.inverse(msax, msay)
    assert_allclose(colx, ins_tab['xcoll'])
    assert_allclose(coly, ins_tab['ycoll'])

    # After applying direcitonal cosines
    dircos = trmodels.Unitless2DirCos()
    xcolDircosi, ycolDircosi, z = dircos(colx, coly)
    assert_allclose(xcolDircosi, ins_tab['xcolDirCosi'])
    assert_allclose(ycolDircosi, ins_tab['ycolDirCosi'])

    # MSA to GWA entrance
    # This runs the Collimator forward, Unitless to Directional cosine, and
    # 3D Rotation. It uses the corrected GWA tilt value
    with datamodels.DisperserModel(refs['disperser']) as disp:
        disperser = nirspec.correct_tilt(disp, im.meta.instrument.gwa_xtilt,
                                         im.meta.instrument.gwa_ytilt)
    collimator2gwa = nirspec.collimator_to_gwa(refs, disperser)
    x_gwa_in, y_gwa_in, z_gwa_in = collimator2gwa(msax, msay)
    assert_allclose(x_gwa_in, ins_tab['xdispIn'])
    assert_allclose(y_gwa_in, ins_tab['ydispIn'])

    # Slit to GWA out
    slit2gwa = slit_wcs.get_transform('slit_frame', 'gwa')
    x_gwa_out, y_gwa_out, z_gwa_out = slit2gwa(slitx, slity, lam)
    assert_allclose(x_gwa_out, ins_tab['xdispLaw'])
    assert_allclose(y_gwa_out, ins_tab['ydispLaw'])

    # CAMERA entrance (assuming direction is from sky to detector)
    angles = [
        disperser['theta_x'], disperser['theta_y'], disperser['theta_z'],
        disperser['tilt_y']
    ]
    rotation = trmodels.Rotation3DToGWA(angles,
                                        axes_order="xyzy",
                                        name='rotation')
    dircos2unitless = trmodels.DirCos2Unitless()
    gwa2cam = rotation.inverse | dircos2unitless
    x_camera_entrance, y_camera_entrance = gwa2cam(x_gwa_out, y_gwa_out,
                                                   z_gwa_out)
    assert_allclose(x_camera_entrance, ins_tab['xcamCosi'])
    assert_allclose(y_camera_entrance, ins_tab['ycamCosi'])

    # at FPA
    with datamodels.CameraModel(refs['camera']) as camera:
        x_fpa, y_fpa = camera.model.inverse(x_camera_entrance,
                                            y_camera_entrance)
    assert_allclose(x_fpa, ins_tab['xfpapos'])
    assert_allclose(y_fpa, ins_tab['yfpapos'])

    # at SCA These are 0-based , the IDT results are 1-based
    slit2sca = slit_wcs.get_transform('slit_frame', 'sca')
    x_sca_nrs1, y_sca_nrs1 = slit2sca(slitx, slity, lam)
    # At NRS2
    with datamodels.FPAModel(refs['fpa']) as fpa:
        x_sca_nrs2, y_sca_nrs2 = fpa.nrs2_model.inverse(x_fpa, y_fpa)
    # expect 1 pix difference
    wvlns_on_nrs1 = slice(2)
    wvlns_on_nrs2 = slice(2, 4)
    assert_allclose(x_sca_nrs1[wvlns_on_nrs1] + 1, ins_tab['i'][wvlns_on_nrs1])
    assert_allclose(y_sca_nrs1[wvlns_on_nrs1] + 1, ins_tab['j'][wvlns_on_nrs1])
    assert_allclose(x_sca_nrs2[wvlns_on_nrs2] + 1, ins_tab['i'][wvlns_on_nrs2])
    assert_allclose(y_sca_nrs2[wvlns_on_nrs2] + 1, ins_tab['j'][wvlns_on_nrs2])

    # at oteip
    slit2oteip = slit_wcs.get_transform('slit_frame', 'oteip')
    x_oteip, y_oteip, _ = slit2oteip(slitx, slity, lam)
    assert_allclose(x_oteip, ins_tab['xOTEIP'])
    assert_allclose(y_oteip, ins_tab['yOTEIP'])

    # at v2, v3 [in arcsec]
    slit2v23 = slit_wcs.get_transform('slit_frame', 'v2v3')
    v2, v3, _ = slit2v23(slitx, slity, lam)
    v2 /= 3600
    v3 /= 3600
    assert_allclose(v2, ins_tab['xV2V3'])
    assert_allclose(v3, ins_tab['yV2V3'])
Пример #23
0
    def __init__(self, spectrum=None, spectral_axis=None, wcs=None, **kwargs):
        # This handles cases where arithmetic is being performed, and an
        # object is created that's just a number
        if not isinstance(spectrum, (AstroData, NDData)):
            super().__init__(spectrum,
                             spectral_axis=spectral_axis,
                             wcs=wcs,
                             **kwargs)
            return

        if isinstance(spectrum, AstroData) and not spectrum.is_single:
            raise TypeError("Input spectrum must be a single AstroData slice")

        # Unit handling
        try:  # for NDData-like
            flux_unit = spectrum.unit
        except AttributeError:
            try:  # for AstroData
                flux_unit = u.Unit(spectrum.hdr.get('BUNIT'))
            except (TypeError, ValueError):  # unknown/missing
                flux_unit = None
        if flux_unit is None:
            flux_unit = u.dimensionless_unscaled
        try:
            kwargs['mask'] = spectrum.mask
        except AttributeError:
            flux = spectrum
        else:
            flux = spectrum.data
            kwargs['uncertainty'] = spectrum.uncertainty

        # If spectrum was a Quantity, it already has units so we'd better
        # not multiply them in again!
        if not isinstance(flux, u.Quantity):
            flux *= flux_unit

        # If no wavelength information is included, get it from the input
        if spectral_axis is None and wcs is None:
            if isinstance(spectrum, AstroData):
                if spectrum.wcs is not None:
                    wcs = spectrum.wcs
                else:
                    spec_unit = u.Unit(spectrum.hdr.get('CUNIT1', 'nm'))
                    try:
                        wavecal = dict(
                            zip(spectrum.WAVECAL["name"],
                                spectrum.WAVECAL["coefficients"]))
                    except (AttributeError,
                            KeyError):  # make a Model from the FITS WCS info
                        det2wave = (models.Shift(1 - spectrum.hdr['CRPIX1'])
                                    | models.Scale(spectrum.hdr['CD1_1'])
                                    | models.Shift(spectrum.hdr['CRVAL1']))
                    else:
                        det2wave = am.dict_to_chebyshev(wavecal)
                        det2wave.inverse = am.make_inverse_chebyshev1d(
                            det2wave, sampling=1)
                        spec_unit = u.nm
                    detector_frame = cf.CoordinateFrame(1,
                                                        axes_type='SPATIAL',
                                                        axes_order=(0, ),
                                                        unit=u.pix,
                                                        axes_names='x')
                    spec_frame = cf.SpectralFrame(unit=spec_unit,
                                                  name='lambda')
                    wcs = gWCS.WCS([(detector_frame, det2wave),
                                    (spec_frame, None)])
            else:
                wcs = spectrum.wcs  # from an NDData-like object

        super().__init__(flux=flux,
                         spectral_axis=spectral_axis,
                         wcs=wcs,
                         **kwargs)
        self.filename = getattr(spectrum, 'filename', None)
Пример #24
0
def make_gwcs(shape, galactic=False):
    """
    Create a simple celestial gWCS object in the ICRS coordinate frame.

    This function requires the `gwcs
    <https://github.com/spacetelescope/gwcs>`_ package.

    Parameters
    ----------
    shape : 2-tuple of int
        The shape of the 2D array to be used with the output
        `~gwcs.wcs.WCS` object.

    galactic : bool, optional
        If `True`, then the output WCS will be in the Galactic
        coordinate frame.  If `False` (default), then the output WCS
        will be in the ICRS coordinate frame.

    Returns
    -------
    wcs : `gwcs.wcs.WCS` object
        The generalized world coordinate system (WCS) transformation.

    See Also
    --------
    make_wcs, make_imagehdu

    Notes
    -----
    The `make_wcs` function returns an equivalent WCS transformation to
    this one, but as an `astropy.wcs.WCS` object.

    Examples
    --------
    >>> from photutils.datasets import make_gwcs
    >>> shape = (100, 100)
    >>> gwcs = make_gwcs(shape)
    >>> print(gwcs)
      From      Transform
    -------- ----------------
    detector linear_transform
        icrs             None
    """

    from gwcs import wcs as gwcs_wcs
    from gwcs import coordinate_frames as cf

    rho = np.pi / 3.
    scale = 0.1 / 3600.  # 0.1 arcsec/pixel in deg/pix

    shift_by_crpix = (models.Shift((-shape[1] / 2) + 1)
                      & models.Shift((-shape[0] / 2) + 1))

    cd_matrix = np.array([[-scale * np.cos(rho), scale * np.sin(rho)],
                          [scale * np.sin(rho), scale * np.cos(rho)]])

    rotation = models.AffineTransformation2D(cd_matrix, translation=[0, 0])
    rotation.inverse = models.AffineTransformation2D(np.linalg.inv(cd_matrix),
                                                     translation=[0, 0])

    tan = models.Pix2Sky_TAN()
    celestial_rotation = models.RotateNative2Celestial(197.8925, -1.36555556,
                                                       180.0)

    det2sky = shift_by_crpix | rotation | tan | celestial_rotation
    det2sky.name = 'linear_transform'

    detector_frame = cf.Frame2D(name='detector',
                                axes_names=('x', 'y'),
                                unit=(u.pix, u.pix))

    if galactic:
        sky_frame = cf.CelestialFrame(reference_frame=coord.Galactic(),
                                      name='galactic',
                                      unit=(u.deg, u.deg))
    else:
        sky_frame = cf.CelestialFrame(reference_frame=coord.ICRS(),
                                      name='icrs',
                                      unit=(u.deg, u.deg))

    pipeline = [(detector_frame, det2sky), (sky_frame, None)]

    return gwcs_wcs.WCS(pipeline)
Пример #25
0
def convert_wcs(fitswcs):
    '''
    Accepts an astropy.wcs wcs object (based on the FITS standard).

    Returns the GWCS equivalent WCS object.
    '''
    # this first version only handles non distorted ra,dec tangent projections
    # check that it is that case
    radesys_dict = {
        'ICRS': coord.ICRS,
        'FK5': coord.FK5,
        'FK4': coord.FK4,
    }
    projection_dict = {
        'TAN': projections.Pix2Sky_TAN(),
        'SIN': projections.Pix2Sky_SIN()
    }
    fctypes = fitswcs.wcs.ctype
    fcrval = fitswcs.wcs.crval
    fcrpix = fitswcs.wcs.crpix
    if fitswcs.naxis != 2:
        raise ValueError("currently only handles 2d images")
    print(fctypes)
    ptypes = [ct[5:8] for ct in fctypes]
    for ptype in ptypes:
        print(ptype)
        if ptype not in ['TAN', 'SIN']:
            raise ValueError("currently only supports TAN and SIN projections")
        tptype = ptype  # temporary since this part is only for celestial coordinates
    if fitswcs.cpdis1 or fitswcs.cpdis2:  ### error here
        raise ValueError("currently doesn't support distortion")

    # Check for SIP correction
    fsip = fitswcs.sip
    if fsip:
        sipa = Polynomial2D(fsip.a_order)
        sipb = Polynomial2D(fsip.b_order)
        assign_coefficients(sipa, fsip.a)
        assign_coefficients(sipb, fsip.b)
        # now the inverse, if it exists
        if fsip.ap_order and fsip.bp_order:
            sipap = Polynomial2D(fsip.ap_order)
            sipbp = Polynomial2D(fsip.bp_order)
            assign_coefficients(sipap, fsip.ap)
            assign_coefficients(sipbp, fsip.bp)
        else:
            sipap = None
        siptrans = Identity(2) + (Mapping((0, 1, 0, 1)) | (sipa & sipb))
        if sipap:
            siptrans.inverse = Identity(2) + (Mapping(
                (0, 1, 0, 1)) | (sipap & sipbp))
    # construct transformation
    if fitswcs.wcs.has_cd():
        trans1 = (Shift(-fcrpix[0]) & Shift(-fcrpix[1]))
        trans2 = (projections.AffineTransformation2D(fitswcs.wcs.cd)
                  | projection_dict[tptype] | rotations.RotateNative2Celestial(
                      fcrval[0], fcrval[1], 180.))
    elif fitswcs.wcs.has_pc():
        trans1 = (Shift(-fcrpix[0]) & Shift(-fcrpix[1]))
        pcmatrix = np.array(fitswcs.wcs.cdelt) * fitswcs.wcs.pc
        trans2 = (projections.AffineTransformation2D(pcmatrix)
                  | projection_dict[tptype] | rotations.RotateNative2Celestial(
                      fcrval[0], fcrval[1], 180.))
    else:
        cdelt = fitswcs.wcs.cdelt
        crota2 = fitswcs.wcs.crota[1] * np.pi / 180  # unware of any crota1 case
        pscale_ratio = cdelt[1] / cdelt[0]
        pcmatrix = np.array(
            [[np.cos(crota2) * cdelt[0], -np.sin(crota2) * cdelt[1]],
             [np.sin(crota2) * cdelt[0],
              np.cos(crota2) * cdelt[1]]])
        trans1 = (Shift(-fcrpix[0]) & Shift(-fcrpix[1]))
        trans2 = (projections.AffineTransformation2D(pcmatrix)
                  | projection_dict[tptype] | rotations.RotateNative2Celestial(
                      fcrval[0], fcrval[1], 180.))
    if fsip:
        trans = trans1 | siptrans | trans2
    else:
        trans = trans1 | trans2
    detector_frame = cf.Frame2D(name="detector",
                                axes_names=('x', 'y'),
                                unit=(u.pix, u.pix))
    # Now see if a standard frame is referenced.
    if fitswcs.wcs.radesys:
        if fitswcs.wcs.radesys in radesys_dict:
            reference_frame = radesys_dict[fitswcs.wcs.radesys]()
            sky_frame = cf.CelestialFrame(reference_frame=reference_frame,
                                          name=fitswcs.wcs.radesys.lower())
    else:
        sky_frame = ''  # or None?

    wcsobj = ggwcs.WCS(forward_transform=trans,
                       input_frame=detector_frame,
                       output_frame=sky_frame)
    return wcsobj
Пример #26
0
def create_wcsobj(hdul):
    im = ImageModel(hdul)
    ref = get_reference_files(im)
    pipeline = niriss.create_pipeline(im, ref)
    wcsobj = wcs.WCS(pipeline)
    return wcsobj
Пример #27
0
def wcs_append(wcs_obj, forward_transform, output_frame):
    pipeline = [(getattr(wcs_obj, f) or f, m) for f, m in wcs_obj.pipeline]
    pipeline[-1] = (pipeline[-1][0], forward_transform)
    pipeline.append((output_frame, None))
    return wcs.WCS(pipeline)
Пример #28
0
shift = models.Shift(-1. * u.pix) & models.Shift(-2. * u.pix)

#shift = models.Chebyshev2D(2, 2)

#shift = models.Polynomial2D(2, 2)

detector_frame = cf.Frame2D(name="detector",
                            axes_names=("x", "y"),
                            unit=(u.pix, u.pix))
sky_frame = cf.CelestialFrame(reference_frame=coord.ICRS(),
                              name='icrs',
                              unit=(u.deg, u.deg))

pipeline = [(detector_frame, shift), (sky_frame, None)]
wcsobj = wcs.WCS(pipeline)

tree = {"wcs": wcsobj}

#fa = fits_embed.AsdfInFits(hdul, tree)
#fa = fits_embed.AsdfInFits(fits.HDUList(), tree)
#fa.write_to('test.fits')
af = AsdfFile(tree)

fd = io.BytesIO()

#af._write_tree(tree, fd, pad_blocks=False)
af.write_to(fd)
fd.seek(0)
wcsbytes = fd.read()
fd.close()