Esempio n. 1
0
def ifu_msa_to_oteip(reference_files):
    """
    Transform from the MSA frame to the OTEIP frame.

    Parameters
    ----------
    reference_files: dict
        Dictionary with reference files returned by CRDS.

    Returns
    -------
    model : `~astropy.modeling.core.Model` model.
        Transform from MSA to OTEIP.
    """
    with AsdfFile.open(reference_files['fore']) as f:
        fore = f.tree['model'].copy()
    with AsdfFile.open(reference_files['ifufore']) as f:
        ifufore = f.tree['model'].copy()

    msa2fore_mapping = Mapping((0, 1, 2, 2))
    msa2fore_mapping.inverse = Identity(3)
    ifu_fore_transform = ifufore & Identity(1)
    ifu_fore_transform.inverse = Mapping(
        (0, 1, 2, 2)) | ifufore.inverse & Identity(1)
    fore_transform = msa2fore_mapping | fore & Identity(1)
    return msa2fore_mapping | ifu_fore_transform | fore_transform
Esempio n. 2
0
def compute_spec_transform(fiducial, refwcs):
    """
    Compute a simple transform given a fidicial point in a spatial-spectral wcs.
    """
    cdelt1 = refwcs.wcsinfo.cdelt1 / 3600.
    cdelt2 = refwcs.wcsinfo.cdelt2 / 3600.
    cdelt3 = refwcs.wcsinfo.cdelt3
    roll_ref = refwcs.wcsinfo.roll_ref

    y, x = grid_from_spec_domain(refwcs)
    ra, dec, lam = refwcs(x, y)

    min_lam = np.nanmin(lam)

    offset = Shift(0.) & Shift(0.)
    rot = Rotation2D(roll_ref)
    scale = Scale(cdelt1) & Scale(cdelt2)
    tan = Pix2Sky_TAN()
    skyrot = RotateNative2Celestial(fiducial[0][0], fiducial[0][1], 180.0)
    spatial = offset | rot | scale | tan | skyrot
    spectral = Scale(cdelt3) | Shift(min_lam)
    mapping = Mapping((1, 1, 0), )
    mapping.inverse = Mapping((2, 1))
    transform = mapping | spatial & spectral
    transform.outputs = ('ra', 'dec', 'lamda')
    return transform
Esempio n. 3
0
    def setup_class(cls):
        cls.model1D = Identity(n_inputs=1)
        cls.model2D = Identity(n_inputs=2) | Mapping((0, ), n_inputs=2)
        cls.model3D = Identity(n_inputs=3) | Mapping((0, ), n_inputs=3)

        cls.data = cls.x = cls.y = cls.z = np.linspace(0, 10, num=100)
        cls.lsq_exp = 0
Esempio n. 4
0
def ifu(input_model, reference_files):
    """
    IFU pipeline
    """
    slits = np.arange(30)
    # Get the corrected disperser model
    disperser = get_disperser(input_model, reference_files['disperser'])

    # Get the default spectral order and wavelength range and record them in the model.
    sporder, wrange = get_spectral_order_wrange(
        input_model, reference_files['wavelengthrange'])
    input_model.meta.wcsinfo.waverange_start = wrange[0]
    input_model.meta.wcsinfo.waverange_end = wrange[1]
    input_model.meta.wcsinfo.spectral_order = sporder

    # DMS to SCA transform
    dms2detector = dms_to_sca(input_model)
    # DETECTOR to GWA transform
    det2gwa = Identity(2) & detector_to_gwa(
        reference_files, input_model.meta.instrument.detector, disperser)

    # GWA to SLIT
    gwa2slit = gwa_to_ifuslit(slits, disperser, wrange, sporder,
                              reference_files)

    # SLIT to MSA transform
    slit2msa = ifuslit_to_msa(slits, reference_files)

    det, sca, gwa, slit_frame, msa_frame, oteip, v2v3, world = create_frames()
    if input_model.meta.instrument.filter != 'OPAQUE':
        # MSA to OTEIP transform
        msa2oteip = ifu_msa_to_oteip(reference_files)

        # OTEIP to V2,V3 transform
        # This includes a wavelength unit conversion from meters to microns.
        oteip2v23 = oteip_to_v23(reference_files)

        # Create coordinate frames in the NIRSPEC WCS pipeline"
        #
        # The oteip2v2v3 transform converts the wavelength from meters (which is assumed
        # in the whole pipeline) to microns (which is the expected output)
        #
        # "detector", "gwa", "slit_frame", "msa_frame", "oteip", "v2v3", "world"

        pipeline = [(det, dms2detector), (sca, det2gwa.rename('detector2gwa')),
                    (gwa, gwa2slit.rename('gwa2slit')),
                    (slit_frame, (Mapping(
                        (0, 1, 2, 3, 4)) | slit2msa).rename('slit2msa')),
                    (msa_frame, msa2oteip.rename('msa2oteip')),
                    (oteip, oteip2v23.rename('oteip2v23')), (v2v3, None)]
    else:

        pipeline = [(det, dms2detector), (sca, det2gwa.rename('detector2gwa')),
                    (gwa, gwa2slit.rename('gwa2slit')),
                    (slit_frame, (Mapping(
                        (0, 1, 2, 3, 4)) | slit2msa).rename('slit2msa')),
                    (msa_frame, None)]

    return pipeline
Esempio n. 5
0
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)
Esempio n. 6
0
def gwa_to_ifuslit(slits, disperser, wrange, order, reference_files):
    """
    GWA to SLIT transform.

    Parameters
    ----------
    slits : list
        A list of slit IDs for all IFU slits 0-29.
    disperser : dict
        A corrected disperser ASDF object.
    filter : str
        The filter used.
    grating : str
        The grating used in the observation.
    reference_files: dict
        Dictionary with reference files returned by CRDS.

    Returns
    -------
    model : `~jwst_lib.pipeline_models.Gwa2Slit` model.
        Transform from GWA frame to SLIT frame.
   """
    agreq = AngleFromGratingEquation(disperser['groove_density'],
                                     order,
                                     name='alpha_from_greq')
    lgreq = WavelengthFromGratingEquation(disperser['groove_density'],
                                          order,
                                          name='lambda_from_greq')
    collimator2gwa = collimator_to_gwa(reference_files, disperser)
    lam = (wrange[1] - wrange[0]) / 2 + wrange[0]

    ifuslicer = AsdfFile.open(reference_files['ifuslicer'])
    ifupost = AsdfFile.open(reference_files['ifupost'])
    slit_models = {}
    ifuslicer_model = ifuslicer.tree['model']
    for slit in slits:
        slitdata = ifuslicer.tree['data'][slit]
        slitdata_model = get_slit_location_model(slitdata)
        ifuslicer_transform = (slitdata_model | ifuslicer_model)
        ifupost_transform = ifupost.tree[slit]['model']
        msa2gwa = ifuslicer_transform | ifupost_transform | collimator2gwa
        gwa2msa = gwa_to_ymsa(msa2gwa)  # TODO: Use model sets here
        bgwa2msa = Mapping((0, 1, 0, 1), n_inputs=3) | \
                 Const1D(0) * Identity(1) & Const1D(-1) * Identity(1) & Identity(2) | \
                 Identity(1) & gwa2msa & Identity(2) | \
                 Mapping((0, 1, 0, 1, 2, 3)) | Identity(2) & msa2gwa & Identity(2) | \
                 Mapping((0, 1, 2, 5), n_inputs=7)| Identity(2) & lgreq

        # msa to before_gwa
        #msa2bgwa = Mapping((0, 1, 2, 2)) | msa2gwa & Identity(1) | Mapping((3, 0, 1, 2)) | agreq
        msa2bgwa = msa2gwa & Identity(1) | Mapping((3, 0, 1, 2)) | agreq
        bgwa2msa.inverse = msa2bgwa
        slit_models[slit] = bgwa2msa

    ifuslicer.close()
    ifupost.close()
    return Gwa2Slit(slit_models)
Esempio n. 7
0
def _make_reference_gwcs_wcs(fits_hdr):
    hdr = fits.Header.fromfile(get_pkg_data_filename(fits_hdr))
    fw = fitswcs.WCS(hdr)

    unit_conv = Scale(1.0 / 3600.0, name='arcsec_to_deg_1D')
    unit_conv = unit_conv & unit_conv
    unit_conv.name = 'arcsec_to_deg_2D'

    unit_conv_inv = Scale(3600.0, name='deg_to_arcsec_1D')
    unit_conv_inv = unit_conv_inv & unit_conv_inv
    unit_conv_inv.name = 'deg_to_arcsec_2D'

    c2s = CartesianToSpherical(name='c2s', wrap_lon_at=180)
    s2c = SphericalToCartesian(name='s2c', wrap_lon_at=180)
    c2tan = ((Mapping((0, 1, 2), name='xyz') / Mapping(
        (0, 0, 0), n_inputs=3, name='xxx')) | Mapping((1, 2), name='xtyt'))
    c2tan.name = 'Cartesian 3D to TAN'

    tan2c = (Mapping((0, 0, 1), n_inputs=2, name='xtyt2xyz') |
             (Const1D(1, name='one') & Identity(2, name='I(2D)')))
    tan2c.name = 'TAN to cartesian 3D'

    tan2c.inverse = c2tan
    c2tan.inverse = tan2c

    aff = AffineTransformation2D(matrix=fw.wcs.cd)

    offx = Shift(-fw.wcs.crpix[0])
    offy = Shift(-fw.wcs.crpix[1])

    s = 5e-6
    scale = Scale(s) & Scale(s)

    det2tan = (offx & offy) | scale | tan2c | c2s | unit_conv_inv

    taninv = s2c | c2tan
    tan = Pix2Sky_TAN()
    n2c = RotateNative2Celestial(fw.wcs.crval[0], fw.wcs.crval[1], 180)
    wcslin = unit_conv | taninv | scale.inverse | aff | tan | n2c

    sky_frm = cf.CelestialFrame(reference_frame=coord.ICRS())
    det_frm = cf.Frame2D(name='detector')
    v2v3_frm = cf.Frame2D(name="v2v3",
                          unit=(u.arcsec, u.arcsec),
                          axes_names=('x', 'y'),
                          axes_order=(0, 1))
    pipeline = [(det_frm, det2tan), (v2v3_frm, wcslin), (sky_frm, None)]

    gw = gwcs.WCS(input_frame=det_frm,
                  output_frame=sky_frm,
                  forward_transform=pipeline)
    gw.crpix = fw.wcs.crpix
    gw.crval = fw.wcs.crval
    gw.bounding_box = ((-0.5, fw.pixel_shape[0] - 0.5),
                       (-0.5, fw.pixel_shape[1] - 0.5))

    return gw
Esempio n. 8
0
def gwa_to_slit(slits_id, disperser, wrange, order, reference_files):
    """
    GWA to SLIT transform.

    Parameters
    ----------
    slits_id : list
        A list of slit IDs for all open shutters/slitlets.
    disperser : dict
        A corrected disperser ASDF object.
    filter : str
        The filter used.
    grating : str
        The grating used in the observation.
    reference_files: dict
        Dictionary with reference files returned by CRDS.

    Returns
    -------
    model : `~jwst_lib.pipeline_models.Gwa2Slit` model.
        Transform from GWA frame to SLIT frame.
    """
    agreq = AngleFromGratingEquation(disperser['groove_density'],
                                     order,
                                     name='alpha_from_greq')
    lgreq = WavelengthFromGratingEquation(disperser['groove_density'],
                                          order,
                                          name='lambda_from_greq')
    collimator2gwa = collimator_to_gwa(reference_files, disperser)

    msa = AsdfFile.open(reference_files['msa'])
    slit_models = {}
    for i in range(1, 6):
        slit_names = slits_id[slits_id[:, 0] == i]
        if slit_names.any():
            msa_model = msa.tree[i]['model']
            for slit in slit_names:
                index = slit[1] - 1
                slitdata = msa.tree[slit[0]]['data'][index]
                slitdata_model = get_slit_location_model(slitdata)
                msa_transform = slitdata_model | msa_model
                msa2gwa = (msa_transform | collimator2gwa)
                gwa2msa = gwa_to_ymsa(msa2gwa)  # TODO: Use model sets here
                bgwa2msa = Mapping((0, 1, 0, 1), n_inputs=3) | \
                    Const1D(0) * Identity(1) & Const1D(-1) * Identity(1) & Identity(2) | \
                    Identity(1) & gwa2msa & Identity(2) | \
                    Mapping((0, 1, 0, 1, 2, 3)) | Identity(2) & msa2gwa & Identity(2) | \
                    Mapping((0, 1, 2, 5), n_inputs=7)| Identity(2) & lgreq

                # msa to before_gwa
                msa2bgwa = msa2gwa & Identity(1) | Mapping(
                    (3, 0, 1, 2)) | agreq
                bgwa2msa.inverse = msa2bgwa
                s = slitid_to_slit(np.array([slit]))[0]
                slit_models[s] = bgwa2msa
    msa.close()
    return Gwa2Slit(slit_models)
Esempio n. 9
0
def imaging(input_model, reference_files):
    """
    Imaging pipeline

    frames : detector, gwa, msa, sky
    """
    # Get the corrected disperser model
    disperser = get_disperser(input_model, reference_files['disperser'])

    # DETECTOR to GWA transform
    det2gwa = detector_to_gwa(reference_files,
                              input_model.meta.instrument.detector, disperser)

    gwa_through = Const1D(-1) * Identity(1) & Const1D(-1) * Identity(
        1) & Identity(1)

    angles = [
        disperser['theta_x'], disperser['theta_y'], disperser['theta_z'],
        disperser['tilt_y']
    ]
    rotation = Rotation3DToGWA(angles, axes_order="xyzy",
                               name='rotaton').inverse
    dircos2unitless = DirCos2Unitless(name='directional_cosines2unitless')

    col = AsdfFile.open(reference_files['collimator']).tree['model']

    # Get the default spectral order and wavelength range and record them in the model.
    sporder, wrange = get_spectral_order_wrange(
        input_model, reference_files['wavelengthrange'])
    input_model.meta.wcsinfo.waverange_start = wrange[0]
    input_model.meta.wcsinfo.waverange_end = wrange[1]
    input_model.meta.wcsinfo.spectral_order = sporder

    lam = wrange[0] + (wrange[1] - wrange[0]) * .5

    lam_model = Mapping((0, 1, 1)) | Identity(2) & Const1D(lam)

    gwa2msa = gwa_through | rotation | dircos2unitless | col | lam_model
    gwa2msa.inverse = col.inverse | dircos2unitless.inverse | rotation.inverse | gwa_through

    # MSA to OTEIP transform
    msa2ote = msa_to_oteip(reference_files)
    msa2oteip = msa2ote | Mapping((0, 1), n_inputs=3)
    msa2oteip.inverse = Mapping((0, 1, 0, 1)) | msa2ote.inverse | Mapping(
        (0, 1), n_inputs=3)
    # OTEIP to V2,V3 transform
    with AsdfFile.open(reference_files['ote']) as f:
        oteip2v23 = f.tree['model'].copy()

    # Create coordinate frames in the NIRSPEC WCS pipeline
    # "detector", "gwa", "msa", "oteip", "v2v3", "world"
    det, gwa, msa_frame, oteip, v2v3 = create_imaging_frames()

    imaging_pipeline = [(det, det2gwa), (gwa, gwa2msa), (msa_frame, msa2oteip),
                        (oteip, oteip2v23), (v2v3, None)]

    return imaging_pipeline
Esempio n. 10
0
def test_regions_selector(tmpdir):
    m1 = Mapping([0, 1, 1]) | Shift(1) & Shift(2) & Shift(3)
    m2 = Mapping([0, 1, 1]) | Scale(2) & Scale(3) & Scale(3)
    sel = {1: m1, 2: m2}
    a = np.zeros((5, 6), dtype=np.int32)
    a[:, 1:3] = 1
    a[:, 4:5] = 2
    mask = selector.LabelMapperArray(a)
    rs = selector.RegionsSelector(inputs=('x', 'y'), outputs=('ra', 'dec', 'lam'),
                                  selector=sel, label_mapper=mask)
    assert_selector_roundtrip(rs, tmpdir)
Esempio n. 11
0
def test_regions_selector(tmpdir):
    m1 = Mapping([0, 1, 1]) | Shift(1) & Shift(2) & Shift(3)
    m2 = Mapping([0, 1, 1]) | Scale(2) & Scale(3) & Scale(3)
    sel = {1:m1, 2:m2}
    a = np.zeros((5,6), dtype=np.int32)
    a[:, 1:3] = 1
    a[:, 4:5] = 2
    mask = selector.LabelMapperArray(a)
    rs = selector.RegionsSelector(inputs=('x', 'y'), outputs=('ra', 'dec', 'lam'),
                                  selector=sel, label_mapper=mask)
    tree = {'model': rs}
    helpers.assert_roundtrip_tree(tree, tmpdir, extensions=GWCSExtension())
Esempio n. 12
0
    def _v2v3_to_tpcorr_from_full(tpcorr):
        s2c = tpcorr['s2c']
        c2s = tpcorr['c2s']

        # unit_conv = _get_submodel(tpcorr, 'arcsec_to_deg_2D')
        # unit_conv_inv = _get_submodel(tpcorr, 'deg_to_arcsec_2D')
        #
        # The code below is a work-around to the code above not working.
        # TODO: understand why _get_submodel is unable to retrieve
        #       some submodels in a compound model.
        #
        unit_conv = _get_submodel(tpcorr, 'arcsec_to_deg_1D')
        unit_conv = unit_conv & unit_conv
        unit_conv.name = 'arcsec_to_deg_2D'
        unit_conv_inv = _get_submodel(tpcorr, 'deg_to_arcsec_1D')
        unit_conv_inv = unit_conv_inv & unit_conv_inv
        unit_conv_inv.name = 'deg_to_arcsec_2D'

        affine = tpcorr['tp_affine']
        affine_inv = affine.inverse
        affine_inv.name = 'tp_affine_inv'

        rot = tpcorr['det_to_optic_axis']
        rot_inv = rot.inverse
        rot_inv.name = 'optic_axis_to_det'

        # c2tan = _get_submodel(tpcorr, 'Cartesian 3D to TAN')
        # tan2c = _get_submodel(tpcorr, 'TAN to cartesian 3D')
        #
        # The code below is a work-around to the code above not working.
        # TODO: understand why _get_submodel is unable to retrieve
        #       some submodels in a compound model.
        #
        c2tan = ((Mapping((0, 1, 2), name='xyz') / Mapping(
            (0, 0, 0), n_inputs=3, name='xxx')) | Mapping((1, 2), name='xtyt'))
        c2tan.name = 'Cartesian 3D to TAN'
        tan2c = (Mapping((0, 0, 1), n_inputs=2, name='xtyt2xyz') |
                 (Const1D(1, name='one') & Identity(2, name='I(2D)')))
        tan2c.name = 'TAN to cartesian 3D'

        v2v3_to_tpcorr = unit_conv | s2c | rot | c2tan | affine
        v2v3_to_tpcorr.name = 'jwst_v2v3_to_tpcorr'

        tpcorr_to_v2v3 = affine_inv | tan2c | rot_inv | c2s | unit_conv_inv
        tpcorr_to_v2v3.name = 'jwst_tpcorr_to_v2v3'

        v2v3_to_tpcorr.inverse = tpcorr_to_v2v3
        tpcorr_to_v2v3.inverse = v2v3_to_tpcorr

        return v2v3_to_tpcorr
Esempio n. 13
0
def test_slicing_on_instance_with_parameterless_model():
    """
    Regression test to fix an issue where the indices attached to parameter
    names on a compound model were not handled properly when one or more
    submodels have no parameters.  This was especially evident in slicing.
    """

    p2 = Polynomial2D(1, c0_0=1, c1_0=2, c0_1=3)
    p1 = Polynomial2D(1, c0_0=1, c1_0=2, c0_1=3)
    mapping = Mapping((0, 1, 0, 1))
    offx = Shift(-2, name='x_translation')
    offy = Shift(-1, name='y_translation')
    aff = AffineTransformation2D(matrix=[[1, 2], [3, 4]], name='rotation')
    model = mapping | (p1 & p2) | (offx & offy) | aff

    assert model.param_names == ('c0_0_1', 'c1_0_1', 'c0_1_1',
                                 'c0_0_2', 'c1_0_2', 'c0_1_2',
                                 'offset_3', 'offset_4',
                                 'matrix_5', 'translation_5')
    assert model(1, 2) == (23.0, 53.0)

    m = model[3:]
    assert m.param_names == ('offset_3', 'offset_4', 'matrix_5',
                             'translation_5')
    assert m(1, 2) == (1.0, 1.0)
Esempio n. 14
0
def oteip_to_v23(reference_files):
    """
    Transform from the OTEIP frame to the V2V3 frame.

    Parameters
    ----------
    reference_files: dict
        Dictionary with reference files returned by CRDS.

    Returns
    -------
    model : `~astropy.modeling.core.Model` model.
        Transform from OTEIP to V2V3.

    """
    with AsdfFile.open(reference_files['ote']) as f:
        ote = f.tree['model'].copy()
    fore2ote_mapping = Identity(3, name='fore2ote_mapping')
    fore2ote_mapping.inverse = Mapping((0, 1, 2, 2))
    # Create the transform to v2/v3/lambda.  The wavelength units up to this point are
    # meters as required by the pipeline but the desired output wavelength units is microns.
    # So we are going to Scale the spectral units by 1e6 (meters -> microns)
    # The spatial units are currently in deg. Convertin to arcsec.
    oteip_to_xyan = fore2ote_mapping | (ote & Scale(1e6))
    # Add a shift for the aperture.
    oteip2v23 = oteip_to_xyan | Identity(1) & (Shift(468 / 3600) | Scale(-1)) & Identity(1)

    return oteip2v23
Esempio n. 15
0
def test_LabelMapperDict(tmpdir):
    dmapper = create_scalar_mapper()
    sel = selector.LabelMapperDict(('x', 'y'),
                                   dmapper,
                                   inputs_mapping=Mapping((0, ), n_inputs=2),
                                   atol=1e-3)
    tree = {'model': sel}
    helpers.assert_roundtrip_tree(tree, tmpdir, extensions=GWCSExtension())
Esempio n. 16
0
File: niriss.py Progetto: sosey/jwst
def niriss_soss(input_model, reference_files):
    """
    The NIRISS SOSS pipeline includes 3 coordinate frames -
    detector, focal plane and sky

    reference_files={'specwcs': 'soss_wavelengths_configuration.asdf'}
    """

    # Get the target RA and DEC, they will be used for setting the WCS RA and DEC based on a conversation
    # with Kevin Volk.
    try:
        target_ra = float(input_model['meta.target.ra'])
        target_dec = float(input_model['meta.target.dec'])
    except:
        # There was an error getting the target RA and DEC, so we are not going to continue.
        raise ValueError('Problem getting the TARG_RA or TARG_DEC from input model {}'.format(input_model))

    # Define the frames
    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')
    try:
        with AsdfFile.open(reference_files['specwcs']) as wl:
            wl1 = wl.tree[1].copy()
            wl2 = wl.tree[2].copy()
            wl3 = wl.tree[3].copy()
    except Exception as e:
        raise IOError('Error reading wavelength correction from {}'.format(reference_files['specwcs']))

    cm_order1 = (Mapping((0, 1, 0, 1)) | (Const1D(target_ra) & Const1D(target_dec) & wl1)).rename('Order1')
    cm_order2 = (Mapping((0, 1, 0, 1)) | (Const1D(target_ra) & Const1D(target_dec) & wl2)).rename('Order2')
    cm_order3 = (Mapping((0, 1, 0, 1)) | (Const1D(target_ra) & Const1D(target_dec) & wl3)).rename('Order3')

    # Define the transforms, they should accept (x,y) and return (ra, dec, lambda)
    soss_model = NirissSOSSModel([1, 2, 3], [cm_order1, cm_order2, cm_order3]).rename('3-order SOSS Model')

    # Define the pipeline based on the frames and models above.
    pipeline = [(detector, soss_model),
                (world, None)
                ]

    return pipeline
Esempio n. 17
0
    def _tpcorr_init(v2_ref, v3_ref, roll_ref):
        s2c = SphericalToCartesian(name='s2c', wrap_lon_at=180)
        c2s = CartesianToSpherical(name='c2s', wrap_lon_at=180)

        unit_conv = Scale(1.0 / 3600.0, name='arcsec_to_deg_1D')
        unit_conv = unit_conv & unit_conv
        unit_conv.name = 'arcsec_to_deg_2D'

        unit_conv_inv = Scale(3600.0, name='deg_to_arcsec_1D')
        unit_conv_inv = unit_conv_inv & unit_conv_inv
        unit_conv_inv.name = 'deg_to_arcsec_2D'

        affine = AffineTransformation2D(name='tp_affine')
        affine_inv = AffineTransformation2D(name='tp_affine_inv')

        rot = RotationSequence3D([v2_ref, -v3_ref, roll_ref],
                                 'zyx',
                                 name='det_to_optic_axis')
        rot_inv = rot.inverse
        rot_inv.name = 'optic_axis_to_det'

        # projection submodels:
        c2tan = ((Mapping((0, 1, 2), name='xyz') / Mapping(
            (0, 0, 0), n_inputs=3, name='xxx')) | Mapping((1, 2), name='xtyt'))
        c2tan.name = 'Cartesian 3D to TAN'
        tan2c = (Mapping((0, 0, 1), n_inputs=2, name='xtyt2xyz') |
                 (Const1D(1, name='one') & Identity(2, name='I(2D)')))
        tan2c.name = 'TAN to cartesian 3D'

        total_corr = (unit_conv | s2c | rot | c2tan | affine | tan2c | rot_inv
                      | c2s | unit_conv_inv)
        total_corr.name = 'JWST tangent-plane linear correction. v1'

        inv_total_corr = (unit_conv | s2c | rot | c2tan | affine_inv | tan2c
                          | rot_inv | c2s | unit_conv_inv)
        inv_total_corr.name = 'Inverse JWST tangent-plane linear correction. v1'

        # TODO
        # re-enable circular inverse definitions once
        # https://github.com/spacetelescope/asdf/issues/744 or
        # https://github.com/spacetelescope/asdf/issues/745 are resolved.
        #
        # inv_total_corr.inverse = total_corr
        total_corr.inverse = inv_total_corr

        return total_corr
Esempio n. 18
0
def test_swap_axes():
    x = np.zeros((2, 3))
    y = np.ones((2, 3))

    mapping = Mapping((1, 0))
    assert mapping(1, 2) == (2.0, 1.0)
    assert mapping.inverse(2, 1) == (1, 2)
    assert_array_equal(mapping(x, y), (y, x))
    assert_array_equal(mapping.inverse(y, x), (x, y))
Esempio n. 19
0
def test_mapping_basic_permutations():
    """
    Tests a couple basic examples of the Mapping model--specifically examples
    that merely permute the outputs.
    """

    x, y = Rotation2D(90)(1, 2)

    rs = Rotation2D(90) | Mapping((1, 0))
    x_prime, y_prime = rs(1, 2)
    assert_allclose((x, y), (y_prime, x_prime))

    # A more complicated permutation
    m = Rotation2D(90) & Scale(2)
    x, y, z = m(1, 2, 3)

    ms = m | Mapping((2, 0, 1))
    x_prime, y_prime, z_prime = ms(1, 2, 3)
    assert_allclose((x, y, z), (y_prime, z_prime, x_prime))
Esempio n. 20
0
    def from_tree_transform(cls, node, ctx):
        mapping = node['mapping']
        n_inputs = node.get('n_inputs')
        if all([isinstance(x, int) for x in mapping]):
            return Mapping(tuple(mapping), n_inputs)

        if n_inputs is None:
            n_inputs = max([x for x in mapping if isinstance(x, int)]) + 1

        transform = Identity(n_inputs)
        new_mapping = []
        i = n_inputs
        for entry in mapping:
            if isinstance(entry, int):
                new_mapping.append(entry)
            else:
                new_mapping.append(i)
                transform = transform & Const1D(entry.value)
                i += 1
        return transform | Mapping(new_mapping)
Esempio n. 21
0
def test_cdot():
    result = _cdot(sh1, scl1)
    assert_allclose(result, np.array([[1]]))

    result = _cdot(rot, p2)
    assert_allclose(result, np.array([[2, 2]]))

    result = _cdot(rot, rot)
    assert_allclose(result, np.array([[2, 2], [2, 2]]))

    result = _cdot(Mapping((0, 0)), rot)
    assert_allclose(result, np.array([[2], [2]]))
Esempio n. 22
0
def test_fittable_compound():
    m = Identity(1) | Mapping((0, )) | Gaussian1D(1, 5, 4)
    x = np.arange(10)
    y_real = m(x)
    dy = 0.005
    with NumpyRNGContext(1234567):
        n = np.random.normal(0., dy, x.shape)
    y_noisy = y_real + n
    pfit = LevMarLSQFitter()
    new_model = pfit(m, x, y_noisy)
    y_fit = new_model(x)
    assert_allclose(y_fit, y_real, atol=dy)
Esempio n. 23
0
def test_mapping_inverse():
    """Tests inverting a compound model that includes a `Mapping`."""

    rs1 = Rotation2D(12.1) & Scale(13.2)
    rs2 = Rotation2D(14.3) & Scale(15.4)

    # Rotates 2 of the coordinates and scales the third--then rotates on a
    # different axis and scales on the axis of rotation.  No physical meaning
    # here just a simple test
    m = rs1 | Mapping([2, 0, 1]) | rs2

    assert_allclose((0, 1, 2), m.inverse(*m(0, 1, 2)), atol=1e-08)
Esempio n. 24
0
def mask_slit(ymin=-.5, ymax=.5):
    """
    Returns a model which masks out pixels in a NIRSpec cutout outside the slit.

    Uses ymin, ymax for the slit and the wavelength range to define the location of the slit.

    Parameters
    ----------
    ymin, ymax : float
        ymin and ymax relative boundary of a slit.

    Returns
    -------
    model : `~astropy.modeling.core.Model`
        A model which takes x_slit, y_slit, lam inputs and substitutes the
        values outside the slit with NaN.

    """
    greater_than_ymax = Logical(condition='GT', compareto=ymax, value=np.nan)
    less_than_ymin = Logical(condition='LT', compareto=ymin, value=np.nan)

    model = Mapping((0, 1, 2, 1)) | Identity(3) & (greater_than_ymax | less_than_ymin | models.Scale(0)) | \
          Mapping((0, 1, 3, 2, 3)) | Identity(1) & Mapping((0,), n_inputs=2) + Mapping((1,)) & \
          Mapping((0,), n_inputs=2) + Mapping((1,))
    model.inverse = Identity(3)
    return model
Esempio n. 25
0
def slits_wcs(input_model, reference_files):
    """
    Create the WCS pipeline for observations using the MSA shutter array or fixed slits.

    Parameters
    ----------
    input_model : `~jwst_lib.models.ImageModel`
        The input data model.
    reference_files : dict
        Dictionary with reference files supplied by CRDS.

    """
    open_slits_id = get_open_slits(input_model)
    n_slits = len(open_slits_id)
    log.info("Computing WCS for {0} open slitlets".format(n_slits))
    # Get the corrected disperser model
    disperser = get_disperser(input_model, reference_files['disperser'])

    # Get the default spectral order and wavelength range and record them in the model.
    sporder, wrange = get_spectral_order_wrange(
        input_model, reference_files['wavelengthrange'])
    input_model.meta.wcsinfo.waverange_start = wrange[0]
    input_model.meta.wcsinfo.waverange_end = wrange[1]
    input_model.meta.wcsinfo.spectral_order = sporder

    # DETECTOR to GWA transform
    #det2gwa = Identity(2) & detector_to_gwa(reference_files, input_model.meta.instrument.detector, disperser)
    det2gwa = detector_to_gwa(reference_files,
                              input_model.meta.instrument.detector, disperser)

    # GWA to SLIT
    gwa2slit = gwa_to_slit(open_slits_id, disperser, wrange, sporder,
                           reference_files)

    # SLIT to MSA transform
    slit2msa = slit_to_msa(open_slits_id, reference_files['msa'])

    # MSA to OTEIP transform
    msa2oteip = msa_to_oteip(reference_files)

    # OTEIP to V2,V3 transform
    oteip2v23 = oteip_to_v23(reference_files)

    # Create coordinate frames in the NIRSPEC WCS pipeline"
    # "detector", "gwa", "slit_frame", "msa_frame", "oteip", "v2v3", "world"
    det, gwa, slit_frame, msa_frame, oteip, v2v3 = create_frames()

    msa_pipeline = [(det, det2gwa), (gwa, gwa2slit),
                    (slit_frame, Mapping((0, 1, 2, 3, 4)) | slit2msa),
                    (msa_frame, msa2oteip), (oteip, oteip2v23), (v2v3, None)]

    return msa_pipeline
Esempio n. 26
0
def test_mapping_inverse():
    """Tests inverting a compound model that includes a `Mapping`."""

    RS = Rotation2D & Scale

    # Rotates 2 of the coordinates and scales the third--then rotates on a
    # different axis and scales on the axis of rotation.  No physical meaning
    # here just a simple test
    M = RS | Mapping([2, 0, 1]) | RS

    m = M(12.1, 13.2, 14.3, 15.4)

    assert_allclose((0, 1, 2), m.inverse(*m(0, 1, 2)), atol=1e-08)
Esempio n. 27
0
def test_bad_inputs(name):
    mapping = Mapping((1, 0), name=name)

    if name is None:
        name = "Mapping"

    x = [np.ones((2, 3)) * idx for idx in range(5)]
    for idx in range(1, 6):
        if idx == 2:
            continue

        with pytest.raises(TypeError) as err:
            mapping.evaluate(*x[:idx])
        assert str(err.value) == f"{name} expects 2 inputs; got {idx}"
Esempio n. 28
0
    def from_tree_transform(cls, node, ctx):
        from astropy.modeling.models import Identity, Mapping

        mapping = node['mapping']
        n_inputs = node.get('n_inputs')
        if all([isinstance(x, six.integer_types) for x in mapping]):
            return Mapping(tuple(mapping), n_inputs)

        if n_inputs is None:
            n_inputs = max([x for x in mapping
                            if isinstance(x, six.integer_types)]) + 1

        transform = Identity(n_inputs)
        new_mapping = []
        i = n_inputs
        for entry in mapping:
            if isinstance(entry, six.integer_types):
                new_mapping.append(entry)
            else:
                new_mapping.append(i)
                transform = transform & ConstantType.from_tree(
                    {'value': int(entry.value)}, ctx)
                i += 1
        return transform | Mapping(new_mapping)
Esempio n. 29
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
Esempio n. 30
0
def test_LabelMapperRange(tmpdir):
    m = []
    for i in np.arange(9) * .1:
        c0_0, c1_0, c0_1, c1_1 = np.ones((4, )) * i
        m.append(Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1))
    keys = np.array([[4.88, 5.64], [5.75, 6.5], [6.67, 7.47], [7.7, 8.63],
                     [8.83, 9.96], [10.19, 11.49], [11.77, 13.28],
                     [13.33, 15.34], [15.56, 18.09]])
    rmapper = {}
    for k, v in zip(keys, m):
        rmapper[tuple(k)] = v
    sel = selector.LabelMapperRange(('x', 'y'),
                                    rmapper,
                                    inputs_mapping=Mapping((0, ), n_inputs=2))
    tree = {'model': sel}
    helpers.assert_roundtrip_tree(tree, tmpdir, extensions=GWCSExtension())