示例#1
0
def ifu_slicer2asdf(ifuslicer, outname):
    """
    Create an asdf reference file with the MSA description.

    ifu_slicer2asdf("IFU_slicer.sgd", "ifu_slicer.asdf")

    Parameters
    ----------
    ifuslicer : str
        A fits file with the IFU slicer description
    outname : str
        Name of output ASDF file.
    """
    ref_kw = common_reference_file_keywords("IFUSLICER", "NIRSPEC IFU SLICER description - CDP4")
    f = fits.open(ifuslicer)
    tree = ref_kw.copy()
    data = f[1].data
    header = f[1].header
    shiftx = models.Shift(header['XREF'], name='ifu_slicer_xref')
    shifty = models.Shift(header['YREF'], name='ifu_slicer_yref')
    rot = models.Rotation2D(header['ROT'], name='ifu_slicer_rot')
    model = rot | shiftx & shifty
    tree['model'] = model
    tree['data'] = f[1].data
    f.close()
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.write_to(outname)
    return fasdf
示例#2
0
def wavelength_range(spectral_conf, outname, ref_kw):
    """
    Parameters
    ----------
    spectral_conf : str
        reference file: spectralconfigurations.txt
    outname : str
        output file name
    """
    with open(spectral_conf) as f:
        lines = f.readlines()
    lines = [l.strip() for l in lines][13:]
    lines = [l.split() for l in lines]
    tree = ref_kw.copy()
    filter_grating = {}
    for l in lines:
        f_g = l[0] + '_' + l[1]
        filter_grating[f_g] = {
            'order': int(l[2]),
            'range': [float(l[3]), float(l[4])]
        }
    tree['filter_grating'] = filter_grating
    fasdf = AsdfFile()

    fasdf.tree = tree
    fasdf.write_to(outname)
    return fasdf
def ifu_slicer2asdf(ifuslicer, outname, ref_kw):
    """
    Create an asdf reference file with the MSA description.

    ifu_slicer2asdf("IFU_slicer.sgd", "ifu_slicer.asdf")

    Parameters
    ----------
    ifuslicer : str
        A fits file with the IFU slicer description
    outname : str
        Name of output ASDF file.
    """
    f = fits.open(ifuslicer)
    tree = ref_kw.copy()
    data = f[1].data
    header = f[1].header
    shiftx = models.Shift(header['XREF'], name='ifu_slicer_xref')
    shifty = models.Shift(header['YREF'], name='ifu_slicer_yref')
    rot = models.Rotation2D(header['ROT'], name='ifu_slicer_rot')
    model = rot | shiftx & shifty
    tree['model'] = model
    tree['data'] = f[1].data
    f.close()
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#4
0
def prism2asdf(prifile, tiltyfile, tiltxfile, outname):
    """Create a NIRSPEC prism disperser reference file in ASDF format.

    Combine information stored in disperser_G?.dis and disperser_G?_TiltY.gtp
    files delievred by the IDT.


    Parameters
    ----------
    prifile : list or str
        File with primary information for the PRSIM
    tiltyfile : str
        File with tilt_Y data, e.g. disperser_PRISM_TiltY.gtp.
    tiltxfile: str
        File with tilt_x data, e.g. disperser_PRISM_TiltX.gtp.
    outname : str
        Name of output ASDF file.

    Returns
    -------
    fasdf : asdf.AsdfFile

    """

    params = common_reference_file_keywords("PRISM", "NIRSPEC PRISM Model")
    flist = [prifile, tiltyfile, tiltxfile]

    # translate the files
    for fname in flist:
        try:
            refparams = dict_from_file(fname)
        except:
            print("Disperser file was not converted.")
            raise

        pdict = {}
        coeffs = {}
        parts = fname.lower().split(".")[0]
        ref = str("_".join(parts.split("_")[1:]))

        if "pri" not in fname:
            try:
                for i, c in enumerate(refparams['CoeffsTemperature00']):
                    coeffs['c' + str(i)] = c
                pdict['tilt_model'] = models.Polynomial1D(len(coeffs)-1, **coeffs)
                del refparams['CoeffsTemperature00']
            except KeyError:
                print("Missing CoeffsTemperature in {0}".format(fname))
                raise

        # store the rest of the keys
        for k, v in refparams.items():
            pdict[k] = v
        print(pdict)
        params[ref] = pdict

    fasdf = AsdfFile()
    fasdf.tree = params
    fasdf.write_to(outname)
    return fasdf
def ifu_slicer2asdf(ifuslicer, outname, ref_kw):
    """
    Create an asdf reference file with the MSA description.

    ifu_slicer2asdf("IFU_slicer.sgd", "ifu_slicer.asdf")

    Parameters
    ----------
    ifuslicer : str
        A fits file with the IFU slicer description
    outname : str
        Name of output ASDF file.
    """
    f = fits.open(ifuslicer)
    tree = ref_kw.copy()
    data = f[1].data
    header = f[1].header
    shiftx = models.Shift(header['XREF'], name='ifu_slicer_xref')
    shifty = models.Shift(header['YREF'], name='ifu_slicer_yref')
    rot = models.Rotation2D(header['ROT'], name='ifu_slicer_rot')
    model = rot | shiftx & shifty
    tree['model'] = model
    tree['data'] = f[1].data
    f.close()
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#6
0
def ifupost2asdf(ifupost_files, outname):
    """
    Create a reference file of type ``ifupost`` .

    Combines all IDT ``IFU-POST`` reference files in one ASDF file.

    forward direction : MSA to Collimator
    backward_direction: Collimator to MSA

    Parameters
    ----------
    ifupost_files : list
        Names of all ``IFU-POST`` IDT reference files
    outname : str
        Name of output ``ASDF`` file
    """
    ref_kw = common_reference_file_keywords("IFUPOST", "NIRSPEC IFU-POST transforms - CDP4")
    fa = AsdfFile()
    fa.tree = ref_kw
    for fifu in ifupost_files:
        n = int((fifu.split('IFU-POST_')[1]).split('.pcf')[0])
        fa.tree[n] = {}
        with open(fifu) as f:
            lines = [l.strip() for l in f.readlines()]
        factors = lines[lines.index('*Factor 2') + 1].split()
        rotation_angle = float(lines[lines.index('*Rotation') + 1])
        input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split()
        output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split()
        linear_sky2det = homothetic_sky2det(input_rot_center, rotation_angle, factors, output_rot_center)

        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)

        output2poly_mapping = Identity(2, name='output_mapping')
        output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
        input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
        input2poly_mapping.inverse = Identity(2)

        model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping

        model = linear_sky2det | model_poly
        fa.tree[n]['model'] = model
    asdffile = fa.write_to(outname)
    return asdffile
示例#7
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)
示例#8
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)
def ote2asdf(otepcf, outname, ref_kw):
    """
    ref_kw = common_reference_file_keywords('OTE', 'NIRSPEC OTE transform - CDP4')

    ote2asdf('Model/Ref_Files/CoordTransform/OTE.pcf', 'jwst_nirspec_ote_0001.asdf', ref_kw)
    """
    with open(otepcf) as f:
        lines = [l.strip() for l in f.readlines()]

    factors = lines[lines.index('*Factor 2 1') + 1].split()
    # this corresponds to modeling Rotation direction as is
    rotation_angle = float(lines[lines.index('*Rotation') + 1])
    input_rot_center = lines[lines.index('*InputRotationCentre 2 1') + 1].split()
    output_rot_center = lines[lines.index('*OutputRotationCentre 2 1') + 1].split()

    mlinear = homothetic_det2sky(input_rot_center, rotation_angle, factors, output_rot_center)

    degree = int(lines[lines.index('*FitOrder') + 1])

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_backward = coeffs_from_pcf(degree, xlines)
    x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward)

    xcoeff_index = lines.index('*xForwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_forward = coeffs_from_pcf(degree, xlines)
    x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_backward = coeffs_from_pcf(degree, ylines)
    y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_forward = coeffs_from_pcf(degree, ylines)
    y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping

    model = model_poly | mlinear


    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    f.add_history_entry("Build 6")
    f.write_to(outname)
    return model_poly, mlinear
示例#10
0
def create_regions_file(slices, detector, band, channel, name, author,
                        useafter, description, outformat):
    tree = create_reffile_header("REGIONS", detector, band, channel, author,
                                 useafter, description)
    tree['filename'] = name
    f = AsdfFile()
    tree['regions'] = slices
    f.tree = tree
    #    f.add_history_entry("DOCUMENT: MIRI-TN-00001-ETH; SOFTWARE: polyd2c_CDP5.pro; DATA USED: Data set of: - FM Test Campaign relevant to MRS-OPT-01, MRS-OPT-02, MRS-OPT-04, MRS-OPT-08; - CV1 Test Campaign relevant to MRS-OPT-02; - CV2 Test Campaign relevant to MRS-OPT-02; - Laboratory measurement of SPO; ============ DIFFERENCES: - New file structure: Change of Extention names and Table Column Headers.; - Replaced V2/V3 with XAN/YAN;")
    f.write_to(name)  #,all_array_storage=outformat)
示例#11
0
def create_v23(reftype, detector, band, channels, data, name):
    """
    Create the transform from MIRI Local to telescope V2/V3 system for all channels.
    """
    channel = "".join([ch[0] for ch in channels])
    tree = {"detector": detector,
            "instrument" : "MIRI",
            "band": band,
            "channel": channel,
            "exp_type": "MIR_MRS",
            "pedigree": "GROUND",
            "title": "MIRI IFU model - based on CDP-4",
            "reftype": reftype,
            "author": "N. Dencheva"
            }
    ab_v23 = data[0]
    v23_ab = data[1]
    m = {}
    c0_0, c0_1, c1_0, c1_1 = ab_v23[0][1:]
    ch1_v2 = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[0][1:]
    ch1_a = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                name="v23_ab")

    c0_0, c0_1, c1_0, c1_1 = ab_v23[1][1:]
    ch1_v3 = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[1][1:]
    ch1_b = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                name="v23_ab")
    c0_0, c0_1, c1_0, c1_1 = ab_v23[2][1:]
    ch2_v2 = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[2][1:]
    ch2_a = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                name="v23_ab")

    c0_0, c0_1, c1_0, c1_1 = ab_v23[3][1:]
    ch2_v3 = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[3][1:]
    ch2_b = models.Polynomial2D(2, c0_0=c0_0, c1_0=c1_0, c0_1=c0_1, c1_1=c1_1,
                                name="v23_ab")
    ch1_for =  ch1_v2 & ch1_v3
    ch2_for = ch2_v2 & ch2_v3
    ch1_for.inverse =  ch1_a & ch1_b
    ch2_for.inverse =  ch2_a & ch2_b
    m[channels[0]] = ch1_for
    m[channels[1]] = ch2_for
    tree['model'] = m

    f = AsdfFile()
    f.tree = tree
    f.write_to(name)
示例#12
0
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
示例#13
0
def create_specwcs_file(reftype, detector, band, channel, lmodel, name, author,
                        useafter, description):
    tree = create_reffile_header(reftype, detector, band, channel, author,
                                 useafter, description)
    tree['subarray'] = "N/A"
    tree['filename'] = name
    tree['model'] = lmodel
    f = AsdfFile()
    f.tree = tree
    f.add_history_entry(
        "DOCUMENT: MIRI-TN-00001-ETH; SOFTWARE: polyd2c_CDP5.pro; DATA USED: Data set of: - FM Test Campaign relevant to MRS-OPT-01, MRS-OPT-02, MRS-OPT-04, MRS-OPT-08; - CV1 Test Campaign relevant to MRS-OPT-02; - CV2 Test Campaign relevant to MRS-OPT-02; - Laboratory measurement of SPO; ============ DIFFERENCES: - New file structure: Change of Extention names and Table Column Headers.; - Replaced V2/V3 with XAN/YAN;"
    )
    f.write_to(name)
示例#14
0
def create_distortion_file(reftype, detector,  band, channel, data, name):

    tree = create_reffile_header(reftype, detector, band, channel)

    adata, bdata, xdata, ydata, sdata1, sdata2 = data
    tree['alpha_model'] = adata
    tree['beta_model'] = bdata
    tree['x_model'] = xdata
    tree['y_model'] = ydata
    tree['slice_model'] = {str(channel[0])+band: sdata1, str(channel[1])+band: sdata2}
    f = AsdfFile()
    f.tree = tree
    f.write_to(name)
示例#15
0
def create_wavelengthrange_file(name):
    f = AsdfFile()
    #wavelengthrange = {'1SHORT': (4.88, 5.77),
    #'1MEDIUM': (5.64, 6.67),
    #'1LONG': (6.50, 7.70),
    #'2SHORT': (7.47, 8.83),
    #'2MEDIUM': (8.63, 10.19),
    #'2LONG': (9.96, 11.77),
    #'3SHORT': (11.49, 13.55),
    #'3MEDIUM': (13.28, 15.66),
    #'3LONG': (15.34, 18.09),
    #'4SHORT': (17.60, 21.00),
    #'4MEDIUM': (20.51, 24.48),
    #'4LONG': (23.92, 28.55)
    #}
    # Relaxing the range to match the distortion. The table above
    # comes from the report and is "as designed".
    wavelengthrange = {
        '1SHORT': (4.68, 5.97),
        '1MEDIUM': (5.24, 6.87),
        '1LONG': (6.2, 7.90),
        '2SHORT': (7.27, 9.03),
        '2MEDIUM': (8.43, 10.39),
        '2LONG': (9.76, 11.97),
        '3SHORT': (11.29, 13.75),
        '3MEDIUM': (13.08, 15.86),
        '3LONG': (15.14, 18.29),
        '4SHORT': (17.40, 21.20),
        '4MEDIUM': (20.31, 24.68),
        '4LONG': (23.72, 28.75)
    }
    channels = [
        '1SHORT', '1MEDIUM', '1LONG', '2SHORT', '2MEDIUM', '2LONG', '3SHORT',
        '3MEDIUM', '3LONG', '4SHORT', '4MEDIUM', '4LONG'
    ]
    tree = {
        "instrument": "MIRI",
        "exp_type": "MIR_MRS",
        "pedigree": "GROUND",
        "title": "MIRI IFU model - based on CDP-4",
        "reftype": "WAVELENGTHRANGE",
        "author": "N. Dencheva"
    }
    tree['channels'] = channels
    f.tree = tree
    vr = np.empty((12, 2), dtype=np.float)
    for i, ch in enumerate(channels):
        vr[i] = wavelengthrange[ch]
    f.tree['wavelengthrange'] = vr
    f.write_to(name)
示例#16
0
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 wavelength_range(spectral_conf, outname, ref_kw):
    """
    Parameters
    ----------
    spectral_conf : str
        reference file: spectralconfigurations.txt
    outname : str
        output file name
    """
    with open(spectral_conf) as f:
        lines = f.readlines()
    lines = [l.strip() for l in lines][13:]
    lines = [l.split() for l in lines]
    tree = ref_kw.copy()
    filter_grating = {}
    for l in lines:
        f_g = l[0] + '_' + l[1]
        filter_grating[f_g] = {
            'order': int(l[2]),
            'range': [float(l[3]), float(l[4])]
        }
    tree['filter_grating'] = filter_grating
    # values in lamp_grating come from private communication with the INS team
    #lamp_grating = {}
    filter_grating['FLAT1_G140M'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['LINE1_G140M'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['FLAT1_G140H'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['LINE1_G140H'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['FLAT2_G235M'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['LINE2_G235M'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['FLAT2_G235H'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['LINE2_G235H'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['FLAT3_G395M'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['LINE3_G395M'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['FLAT3_G395H'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['LINE3_G395H'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['REF_G140M'] = {'order': -1, 'range': [1.3e-6, 1.7e-6]}
    filter_grating['REF_G140H'] = {'order': -1, 'range': [1.3e-6, 1.7e-6]}
    filter_grating['TEST_MIRROR'] = {'order': -1, 'range': [0.6e-6, 5.3e-6]}
    #for grating in ["G140H", "G140M", "G235H", "G235M", "G395H", "G395M", "MIRROR"]:
    #lamp_grating['FLAT4_{0}'.format(grating)] = {'order': -1, 'range': [0.7e-6, 1.2e-6]}
    #for grating in ["G140H", "G140M", "G235H", "G235M", "G395H", "G395M", "MIRROR"]:
    #lamp_grating['LINE4_{0}'.format(grating)] = {'order': -1, 'range': [0.6e-6, 5.3e-6]}
    #tree['lamp_grating'] = lamp_grating
    fasdf = AsdfFile()

    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#18
0
def create_distortion_file(reftype, detector, band, channel, data, name):

    tree = create_reffile_header(reftype, detector, band, channel)

    adata, bdata, xdata, ydata, sdata1, sdata2 = data
    tree['alpha_model'] = adata
    tree['beta_model'] = bdata
    tree['x_model'] = xdata
    tree['y_model'] = ydata
    tree['slice_model'] = {
        str(channel[0]) + band: sdata1,
        str(channel[1]) + band: sdata2
    }
    f = AsdfFile()
    f.tree = tree
    f.write_to(name)
def wavelength_range(spectral_conf, outname, ref_kw):
    """
    Parameters
    ----------
    spectral_conf : str
        reference file: spectralconfigurations.txt
    outname : str
        output file name
    """
    with open(spectral_conf) as f:
        lines = f.readlines()
    lines = [l.strip() for l in lines][13 :]
    lines = [l.split() for l in lines]
    tree = ref_kw.copy()
    filter_grating = {}
    for l in lines:
        f_g = l[0] + '_' + l[1]
        filter_grating[f_g] = {'order': int(l[2]), 'range': [float(l[3]), float(l[4])]}
    tree['filter_grating'] = filter_grating
    # values in lamp_grating come from private communication with the INS team
    #lamp_grating = {}
    filter_grating['FLAT1_G140M'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['LINE1_G140M'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['FLAT1_G140H'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['LINE1_G140H'] = {'order': -1, 'range': [1e-6, 1.8e-6]}
    filter_grating['FLAT2_G235M'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['LINE2_G235M'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['FLAT2_G235H'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['LINE2_G235H'] = {'order': -1, 'range': [1.7e-6, 3.1e-6]}
    filter_grating['FLAT3_G395M'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['LINE3_G395M'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['FLAT3_G395H'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['LINE3_G395H'] = {'order': -1, 'range': [2.9e-6, 5.3e-6]}
    filter_grating['REF_G140M'] = {'order': -1, 'range': [1.3e-6, 1.7e-6]}
    filter_grating['REF_G140H'] = {'order': -1, 'range': [1.3e-6, 1.7e-6]}
    filter_grating['TEST_MIRROR'] = {'order': -1, 'range': [0.6e-6, 5.3e-6]}
    #for grating in ["G140H", "G140M", "G235H", "G235M", "G395H", "G395M", "MIRROR"]:
        #lamp_grating['FLAT4_{0}'.format(grating)] = {'order': -1, 'range': [0.7e-6, 1.2e-6]}
    #for grating in ["G140H", "G140M", "G235H", "G235M", "G395H", "G395M", "MIRROR"]:
        #lamp_grating['LINE4_{0}'.format(grating)] = {'order': -1, 'range': [0.6e-6, 5.3e-6]}
    #tree['lamp_grating'] = lamp_grating
    fasdf = AsdfFile()

    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#20
0
def create_wavelengthrange_file(name):
    f = AsdfFile()
    #wavelengthrange = {'1SHORT': (4.88, 5.77),
                        #'1MEDIUM': (5.64, 6.67),
                        #'1LONG': (6.50, 7.70),
                        #'2SHORT': (7.47, 8.83),
                        #'2MEDIUM': (8.63, 10.19),
                        #'2LONG': (9.96, 11.77),
                        #'3SHORT': (11.49, 13.55),
                        #'3MEDIUM': (13.28, 15.66),
                        #'3LONG': (15.34, 18.09),
                        #'4SHORT': (17.60, 21.00),
                        #'4MEDIUM': (20.51, 24.48),
                        #'4LONG': (23.92, 28.55)
                        #}
    # Relaxing the range to match the distortion. The table above
    # comes from the report and is "as designed".
    wavelengthrange = {'1SHORT': (4.68, 5.97),
                        '1MEDIUM': (5.24, 6.87),
                        '1LONG': (6.2, 7.90),
                        '2SHORT': (7.27, 9.03),
                        '2MEDIUM': (8.43, 10.39),
                        '2LONG': (9.76, 11.97),
                        '3SHORT': (11.29, 13.75),
                        '3MEDIUM': (13.08, 15.86),
                        '3LONG': (15.14, 18.29),
                        '4SHORT': (17.40, 21.20),
                        '4MEDIUM': (20.31, 24.68),
                        '4LONG': (23.72, 28.75)
                        }
    channels = ['1SHORT', '1MEDIUM', '1LONG', '2SHORT', '2MEDIUM', '2LONG',
                '3SHORT', '3MEDIUM', '3LONG', '4SHORT', '4MEDIUM', '4LONG']
    tree = {
            "instrument": "MIRI",
            "exp_type": "MIR_MRS",
            "pedigree": "GROUND",
            "title": "MIRI IFU model - based on CDP-4",
            "reftype": "WAVELENGTHRANGE",
            "author": "N. Dencheva"
            }
    tree['channels'] = channels
    f.tree = tree
    vr = np.empty((12, 2), dtype=np.float)
    for i, ch in enumerate(channels):
        vr[i] = wavelengthrange[ch]
    f.tree['wavelengthrange'] = vr
    f.write_to(name)
def create_miri_imager_filter_offset(distfile, outname):
    """
    Create an asdf reference file with the filter offsets for the MIRI imager.

    Note: The IDT supplied distortion file lists sky to pixel as the
    forward transform. Since "forward" in the JWST pipeline is from
    pixel to sky, the offsets are taken with the opposite sign.

    Parameters
    ----------
    distfile : str
        MIRI imager DISTORTION file provided by the IDT team.
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    -------
    >>> create_miri_imager_filer_offset('MIRI_FM_MIRIMAGE_DISTORTION_03.02.00.fits',
                                        'jwst_miri_filter_offset_0001.asdf')
    """

    with fits.open(distfile) as f:
        data = f[9].data

    d = dict.fromkeys(data.field('FILTER'))
    for i in data:
        d[i[0]] = {'column_offset': -i[1], 'row_offset': -i[2]}
    tree = {
        "title": "MIRI imager filter offset - CDP4",
        "reftype": "FILTEROFFSET",
        "instrument": "MIRI",
        "detector": "MIRIMAGE",
        "pedigree": "GROUND",
        "author": "N. Dencheva",
        "exp_type": "MIR_IMAGE"
    }
    tree.update(d)
    f = AsdfFile()
    f.tree = tree
    f.write_to(outname)
示例#22
0
def create_wavelengthrange_file(name, detector, author, useafter, description):
    f = AsdfFile()

    # Relaxing the range to match the distortion. The table above
    # comes from the report and is "as designed".
    wavelengthrange = {
        '1SHORT': (4.68, 5.97),
        '1MEDIUM': (5.24, 6.87),
        '1LONG': (6.2, 7.90),
        '2SHORT': (7.27, 9.03),
        '2MEDIUM': (8.43, 10.39),
        '2LONG': (9.76, 11.97),
        '3SHORT': (11.29, 13.75),
        '3MEDIUM': (13.08, 15.86),
        '3LONG': (15.14, 18.29),
        '4SHORT': (17.40, 21.20),
        '4MEDIUM': (20.31, 24.68),
        '4LONG': (23.72, 28.75)
    }
    channels = [
        '1SHORT', '1MEDIUM', '1LONG', '2SHORT', '2MEDIUM', '2LONG', '3SHORT',
        '3MEDIUM', '3LONG', '4SHORT', '4MEDIUM', '4LONG'
    ]

    tree = create_reffile_header("WAVELENGTHRANGE",
                                 detector,
                                 band="N/A",
                                 channel="N/A",
                                 author=author,
                                 useafter=useafter,
                                 description=description)
    tree['filename'] = name
    tree['author'] = 'Nadia Dencheva'
    tree['detector'] = "N/A"
    tree['channels'] = channels

    f.tree = tree
    vr = np.empty((12, 2), dtype=np.float)
    for i, ch in enumerate(channels):
        vr[i] = wavelengthrange[ch]
    f.tree['wavelengthrange'] = vr
    f.add_history_entry(
        "DOCUMENT: MIRI-TN-00001-ETH; SOFTWARE: polyd2c_CDP5.pro; DATA USED: Data set of: - FM Test Campaign relevant to MRS-OPT-01, MRS-OPT-02, MRS-OPT-04, MRS-OPT-08; - CV1 Test Campaign relevant to MRS-OPT-02; - CV2 Test Campaign relevant to MRS-OPT-02; - Laboratory measurement of SPO; ============ DIFFERENCES: - New file structure: Change of Extention names and Table Column Headers.; - Replaced V2/V3 with XAN/YAN;"
    )
    f.write_to(name)
示例#23
0
def create_miri_imager_filter_offset(distfile, outname):
    """
    Create an asdf reference file with the filter offsets for the MIRI imager.

    Note: The IDT supplied distortion file lists sky to pixel as the
    forward transform. Since "forward" in the JWST pipeline is from
    pixel to sky, the offsets are taken with the opposite sign.

    Parameters
    ----------
    distfile : str
        MIRI imager DISTORTION file provided by the IDT team.
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    -------
    >>> create_miri_imager_filer_offset('MIRI_FM_MIRIMAGE_DISTORTION_03.02.00.fits',
                                        'jwst_miri_filter_offset_0001.asdf')
    """

    with fits.open(distfile) as f:
        data = f[9].data

    d = dict.fromkeys(data.field('FILTER'))
    for i in data:
        d[i[0]] = {'column_offset': -i[1], 'row_offset': -i[2]}
    tree = {"title": "MIRI imager filter offset - CDP4",
            "reftype": "FILTEROFFSET",
            "instrument": "MIRI",
            "detector": "MIRIMAGE",
            "pedigree": "GROUND",
            "author": "N. Dencheva",
            "exp_type": "MIR_IMAGE"
            }
    tree.update(d)
    f = AsdfFile()
    f.tree = tree
    f.write_to(outname)
示例#24
0
def create_distortion_file(reftype, detector, band, channel, data, name,
                           author, useafter, description):

    description = 'MIRI MRS Distortion Maps'
    tree = create_reffile_header(reftype, detector, band, channel, author,
                                 useafter, description)
    tree['filename'] = name
    adata, bdata, xdata, ydata, bzero, bdel = data
    tree['alpha_model'] = adata
    tree['beta_model'] = bdata
    tree['x_model'] = xdata
    tree['y_model'] = ydata
    tree['bzero'] = bzero
    tree['bdel'] = bdel

    f = AsdfFile()
    f.tree = tree
    f.add_history_entry(
        "DOCUMENT: MIRI-TN-00001-ETH; SOFTWARE: polyd2c_CDP5.pro; DATA USED: Data set of: - FM Test Campaign relevant to MRS-OPT-01, MRS-OPT-02, MRS-OPT-04, MRS-OPT-08; - CV1 Test Campaign relevant to MRS-OPT-02; - CV2 Test Campaign relevant to MRS-OPT-02; - Laboratory measurement of SPO; ============ DIFFERENCES: - New file structure: Change of Extention names and Table Column Headers.; - Replaced V2/V3 with XAN/YAN;"
    )
    f.write_to(name)
示例#25
0
def msa2asdf(msafile, outname, ref_kw):
    """
    Create an asdf reference file with the MSA description.

    The CDP2 delivery includes a fits file - "MSA.msa".
    This file is converted to asdf and serves as a reference file of type "REGIONS".

    mas2asfdf("MSA.msa", "msa.asdf") --> creates an 85MB file

    Parameters
    ----------
    msafile : str
        A fits file with MSA description (MSA.msa)
    outname : str
        Name of output ASDF file.
    """
    f = fits.open(msafile)
    tree = ref_kw.copy()
    data = f[5].data  # SLITS and IFU
    header = f[5].header
    shiftx = models.Shift(header['SLITXREF'], name='slit_xref')
    shifty = models.Shift(header['SLITYREF'], name='slit_yref')
    slitrot = models.Rotation2D(header['SLITROT'], name='slit_rot')
    for j, slit in enumerate(
        ['S200A1', 'S200A2', 'S400A1', 'S1600A1', 'S200B1', 'IFU']):
        slitdata = data[j]
        t = {}
        for i, s in enumerate(['xcenter', 'ycenter', 'xsize', 'ysize']):
            t[s] = slitdata[i + 1]
        model = models.Scale(t['xsize']) & models.Scale(t['ysize']) | \
              models.Shift(t['xcenter']) & models.Shift(t['ycenter']) | \
              slitrot | shiftx & shifty
        t['model'] = model
        tree[slit] = t

    f.close()
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.write_to(outname)
    return fasdf
示例#26
0
def msa2asdf(msafile, outname, ref_kw):
    """
    Create an asdf reference file with the MSA description.

    The CDP2 delivery includes a fits file - "MSA.msa".
    This file is converted to asdf and serves as a reference file of type "REGIONS".

    mas2asfdf("MSA.msa", "msa.asdf") --> creates an 85MB file

    Parameters
    ----------
    msafile : str
        A fits file with MSA description (MSA.msa)
    outname : str
        Name of output ASDF file.
    """
    f = fits.open(msafile)
    tree = ref_kw.copy()
    data = f[5].data # SLITS and IFU
    header = f[5].header
    shiftx = models.Shift(header['SLITXREF'], name='slit_xref')
    shifty = models.Shift(header['SLITYREF'], name='slit_yref')
    slitrot = models.Rotation2D(header['SLITROT'], name='slit_rot')
    for j, slit in enumerate(['S200A1', 'S200A2', 'S400A1', 'S1600A1', 'S200B1', 'IFU']):
        slitdata = data[j]
        t = {}
        for i, s in enumerate(['xcenter', 'ycenter', 'xsize', 'ysize']):
            t[s] = slitdata[i+1]
        model = models.Scale(t['xsize']) & models.Scale(t['ysize']) | \
              models.Shift(t['xcenter']) & models.Shift(t['ycenter']) | \
              slitrot | shiftx & shifty
        t['model'] = model
        tree[slit] = t

    f.close()
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.write_to(outname)
    return fasdf
def msa2asdf(msafile, outname, ref_kw):
    """
    Create an asdf reference file with the MSA description.

    mas2asfdf("MSA.msa", "msa.asdf")

    Parameters
    ----------
    msafile : str
        A fits file with MSA description (MSA.msa)
    outname : str
        Name of output ASDF file.
    """
    f = fits.open(msafile)
    tree = ref_kw.copy()
    data = f[5].data  # SLITS and IFU
    header = f[5].header
    shiftx = models.Shift(header['SLITXREF'], name='slit_xref')
    shifty = models.Shift(header['SLITYREF'], name='slit_yref')
    slitrot = models.Rotation2D(header['SLITROT'], name='slit_rot')

    tree[5] = {}
    tree[5]['model'] = slitrot | shiftx & shifty
    tree[5]['data'] = f[5].data
    for i in range(1, 5):
        header = f[i].header
        shiftx = models.Shift(header['QUADXREF'], name='msa_xref')
        shifty = models.Shift(header['QUADYREF'], name='msa_yref')
        slitrot = models.Rotation2D(header['QUADROT'], name='msa_rot')
        tree[i] = {}
        tree[i]['model'] = slitrot | shiftx & shifty
        tree[i]['data'] = f[i].data

    f.close()
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
def msa2asdf(msafile, outname, ref_kw):
    """
    Create an asdf reference file with the MSA description.

    mas2asfdf("MSA.msa", "msa.asdf")

    Parameters
    ----------
    msafile : str
        A fits file with MSA description (MSA.msa)
    outname : str
        Name of output ASDF file.
    """
    f = fits.open(msafile)
    tree = ref_kw.copy()
    data = f[5].data # SLITS and IFU
    header = f[5].header
    shiftx = models.Shift(header['SLITXREF'], name='slit_xref')
    shifty = models.Shift(header['SLITYREF'], name='slit_yref')
    slitrot = models.Rotation2D(header['SLITROT'], name='slit_rot')

    tree[5] = {}
    tree[5]['model'] = slitrot | shiftx & shifty
    tree[5]['data'] = f[5].data
    for i in range(1, 5):
        header = f[i].header
        shiftx = models.Shift(header['QUADXREF'], name='msa_xref')
        shifty = models.Shift(header['QUADYREF'], name='msa_yref')
        slitrot = models.Rotation2D(header['QUADROT'], name='msa_rot')
        tree[i] = {}
        tree[i]['model'] = slitrot | shiftx & shifty
        tree[i]['data'] = f[i].data

    f.close()
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#29
0
def wavelength_range(spectral_conf, outname, ref_kw):
    """
    Parameters
    ----------
    spectral_conf : str
        reference file: spectralconfigurations.txt
    outname : str
        output file name
    """
    with open(spectral_conf) as f:
        lines = f.readlines()
    lines = [l.strip() for l in lines][13 :]
    lines = [l.split() for l in lines]
    tree = ref_kw.copy()
    filter_grating = {}
    for l in lines:
        f_g = l[0] + '_' + l[1]
        filter_grating[f_g] = {'order': int(l[2]), 'range': [float(l[3]), float(l[4])]}
    tree['filter_grating'] = filter_grating
    fasdf = AsdfFile()

    fasdf.tree = tree
    fasdf.write_to(outname)
    return fasdf
示例#30
0
def create_distortion_file(reftype, detector, band, channel, channels, data,
                           name, author, useafter, description, outformat):

    description = 'MIRI MRS Distortion Maps'
    tree = create_reffile_header(reftype, detector, band, channel, author,
                                 useafter, description)
    """
    tree = {"detector": detector,
            "instrument" : "MIRI",
            "band": band,
            "channel": channel,
            "exp_type": "MIR_MRS",
            "pedigree": "GROUND",
            "title": "MIRI IFU model - based on CDP-6",
            "reftype": reftype,
            "author": author,
            "useafter": useafter,
            "description": description
            }
    """
    tree['filename'] = name

    # Split the provided data vector into its pieces
    adata, bdata, xdata, ydata, bzero, bdel, ab_v23, v23_ab = data
    """
    Construct the xy -> alpha,beta model
    """

    tree['alpha_model'] = adata
    tree['beta_model'] = bdata
    tree['x_model'] = xdata
    tree['y_model'] = ydata
    tree['bzero'] = bzero
    tree['bdel'] = bdel
    """
    Create the transform from MIRI Local to telescope V2/V3 system for all channels.
    """
    channel = "".join([ch[0] for ch in channels])

    m = {}
    # Read in coefficients from the tables.  Note that we'll flip the coefficient
    # ordering since they were set up for column-major indexing (IDL) but we're working in
    # python (row-major)
    # ab -> v2 transform for first channel
    c0_0, c1_0, c0_1, c1_1 = ab_v23[0][1:]
    ch1_v2 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    # v2,v3 -> a transform for first channel
    c0_0, c1_0, c0_1, c1_1 = v23_ab[0][1:]
    ch1_a = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")
    # ab -> v3 transform for first channel
    c0_0, c1_0, c0_1, c1_1 = ab_v23[1][1:]
    ch1_v3 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    # v2,v3 -> b transform for first channel
    c0_0, c1_0, c0_1, c1_1 = v23_ab[1][1:]
    ch1_b = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")
    # ab -> v2 transform for second channel
    c0_0, c1_0, c0_1, c1_1 = ab_v23[2][1:]
    ch2_v2 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    # v2,v3 -> a transform for second channel
    c0_0, c1_0, c0_1, c1_1 = v23_ab[2][1:]
    ch2_a = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")
    # ab -> v3 transform for second channel
    c0_0, c1_0, c0_1, c1_1 = ab_v23[3][1:]
    ch2_v3 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    # v2,v3 -> b transform for second channel
    c0_0, c1_0, c0_1, c1_1 = v23_ab[3][1:]
    ch2_b = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")

    # Transforms from the CDP only went to XAN,YAN, now need a transform to V2,V3
    # Mapping to transform from XAN,YAN in arcmin to V2,V3 in arcsec
    xanyan_to_v2v3 = models.Identity(1) & (models.Scale(-1) | models.Shift(
        -7.8)) | models.Scale(60.) & models.Scale(60.)

    # Since the matrix transforms need a 4-element input we need a mapping
    # to go from (0,1) to (0,1,0,1)
    map = models.Mapping((0, 1, 0, 1), n_inputs=2)

    # Put the mappings all together
    ch1 = map | ch1_v2 & ch1_v3 | xanyan_to_v2v3
    ch2 = map | ch2_v2 & ch2_v3 | xanyan_to_v2v3

    # And make the inverse mapping
    ch1.inverse = xanyan_to_v2v3.inverse | map | ch1_a & ch1_b
    ch2.inverse = xanyan_to_v2v3.inverse | map | ch2_a & ch2_b

    #pdb.set_trace()

    m[channels[0]] = ch1
    m[channels[1]] = ch2

    tree['abv2v3_model'] = m

    f = AsdfFile()
    f.tree = tree

    #    f.add_history_entry("DOCUMENT: MIRI-TN-00001-ETH; SOFTWARE: polyd2c_CDP5.pro; DATA USED: Data set of: - FM Test Campaign relevant to MRS-OPT-01, MRS-OPT-02, MRS-OPT-04, MRS-OPT-08; - CV1 Test Campaign relevant to MRS-OPT-02; - CV2 Test Campaign relevant to MRS-OPT-02; - Laboratory measurement of SPO; ============ DIFFERENCES: - New file structure: Change of Extention names and Table Column Headers.; - Replaced V2/V3 with XAN/YAN;")
    f.write_to(name)  #,all_array_storage=outformat)
示例#31
0
def create_nircam_distortion(channel, module, detector, outname):
    """
    Create an asdf reference file with all distortion components for the MIRI imager.

    NOTE: The IDT has not provided any distortion information. The files are constructed
    using ISIM transformations provided/(computed?) by the TEL team which they use to
    create the SIAF file.
    These reference files should be replaced when/if the IDT provides us with distortion.

    Parameters
    ----------
    channel : str
        header['channel'] or ImageModel.meta.imstrument.channel
        ("SHORT" or "LONG")
    module : str
        header['module'] or ImageModel.meta.imstrument.module
        ("A" or "B")
    detector : str
        NRCB1, NRCB2, NRCB3, NRCB4, NRCB5, NRCA1, NRCA2, NRCA3, NRCA4, NRCA5
        (NRCA5 and NRCB5 are the LW detectors? or simply NRCA and NRCB)
    outname : str
        Name of output file.

    Examples
    --------

    """
    if channel == "SHORT":
        ch = "SW"
    elif channel == "LONG":
        ch = "LW"
    else:
        raise ValueError("Channel {0} not found".format(ch))
    numdet = detector[-1]
    det = detector[-2]
    if numdet == '5':
        numdet = "1"
    from_system = "NIRCAM" + det + ch + "_" + numdet
    to_system = "NIRCAM" + det + ch
    amodel, bmodel, startunit, endunit = read_siaf_table.get_siaf_transform(
        from_system, to_system, 1, 1)
    to_otesky_x, to_otesky_y, startunit, endunit = read_siaf_table.get_siaf_transform(
        to_system, "OTESKY", 5, 5)
    ote2nrcx, ote2nrcy, startunit, endunit = read_siaf_table.get_siaf_transform(
        "OTESKY", to_system, 5, 5)
    nrc2detx,  nrc2dety, startunit, endunit = read_siaf_table.get_siaf_transform(
        to_system, from_system, 1, 1)
    model = Mapping([0, 1, 0, 1]) | amodel & bmodel | Mapping([0, 1, 0, 1]) | \
          to_otesky_x & to_otesky_y
    model_inv = Mapping([0, 1, 0, 1]) | ote2nrcx & ote2nrcy | Mapping((0, 1, 0, 1)) | \
              nrc2detx & nrc2dety
    model.inverse = model_inv

    tree = {"title": "NIRCAM Distortion",
            "instrument": "NIRCAM",
            "pedigree": "GROUND",
            "reftype" : "DISTORTION",
            "author": "N. Dencheva",
            "detector": detector,
            "module": module,
            "channel": channel,
            "exp_type": "NRC_IMAGE",
            "model": model
            }

    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.write_to(outname)
示例#32
0
def create_specwcs_file(reftype, detector, band, channel, lmodel, name):
    tree = create_reffile_header(reftype, detector, band, channel)
    tree['model'] = lmodel
    f = AsdfFile()
    f.tree = tree
    f.write_to(name)
def ote2asdf(otepcf, outname, ref_kw):
    """
    ref_kw = common_reference_file_keywords('OTE', 'NIRSPEC OTE transform - CDP4')

    ote2asdf('Model/Ref_Files/CoordTransform/OTE.pcf', 'jwst_nirspec_ote_0001.asdf', ref_kw)
    """
    with open(otepcf) as f:
        lines = [l.strip() for l in f.readlines()]

    factors = lines[lines.index('*Factor 2 1') + 1].split()
    # this corresponds to modeling Rotation direction as is
    rotation_angle = float(lines[lines.index('*Rotation') + 1])
    input_rot_center = lines[lines.index('*InputRotationCentre 2 1') +
                             1].split()
    output_rot_center = lines[lines.index('*OutputRotationCentre 2 1') +
                              1].split()

    mlinear = homothetic_det2sky(input_rot_center, rotation_angle, factors,
                                 output_rot_center)

    degree = int(lines[lines.index('*FitOrder') + 1])

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_backward = coeffs_from_pcf(degree, xlines)
    x_poly_forward = models.Polynomial2D(degree,
                                         name='x_poly_forward',
                                         **xcoeff_backward)

    xcoeff_index = lines.index('*xForwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_forward = coeffs_from_pcf(degree, xlines)
    x_poly_backward = models.Polynomial2D(degree,
                                          name='x_poly_backward',
                                          **xcoeff_forward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_backward = coeffs_from_pcf(degree, ylines)
    y_poly_forward = models.Polynomial2D(degree,
                                         name='y_poly_forward',
                                         **ycoeff_backward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_forward = coeffs_from_pcf(degree, ylines)
    y_poly_backward = models.Polynomial2D(degree,
                                          name='y_poly_backward',
                                          **ycoeff_forward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward
                                       & y_poly_forward) | output2poly_mapping

    model = model_poly | mlinear

    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    f.add_history_entry("Build 6")
    f.write_to(outname)
    return model_poly, mlinear
示例#34
0
def pcf2asdf(pcffile, outname, ref_file_kw):
    """
    Create an asdf reference file with the transformation coded in a NIRSPEC
    Camera.pcf or Collimator*.pcf file.

    - forward (team): sky to detector
      - Shift inputs to input_rotation_center
      - Rotate inputs
      - Scale  inputs
      - Shift inputs to output_rot_center
      - Apply polynomial distortion
    - backward_team (team definition) detector to sky
      - Apply polynomial distortion
      - Shift inputs to output_rot_center
      - Scale  inputs
      - Rotate inputs
      - Shift inputs to input_rotation_center

    WCS implementation
    - forward: detector to sky
      - equivalent to backward_team
    - backward: sky to detector
      - equivalent to forward_team

    Parameters
    ----------
    pcffile : str
        one of the NIRSPEC ".pcf" reference files provided by the IDT team.
        "pcf" stands for "polynomial coefficients fit"
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    --------
    >>> pcf2asdf("Camera.pcf", "camera.asdf")

    """
    linear_det2sky = linear_from_pcf_det2sky(pcffile)

    with open(pcffile) as f:
        lines = [l.strip() for l in f.readlines()]

    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_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward)

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping

    model = model_poly | linear_det2sky

    f = AsdfFile()
    f.tree = ref_file_kw.copy()
    f.tree['model'] = model
    f.write_to(outname)
def disperser2asdf(disfile, tiltyfile, tiltxfile, outname, ref_kw):
    """
    Create a NIRSPEC disperser reference file in ASDF format.

    Combine information stored in disperser_G?.dis and disperser_G?_TiltY.gtp
    files delievred by the IDT.

    disperser2asdf("disperser_G140H.dis", "disperser_G140H_TiltY.gtp", "disperserG140H.asdf")

    Parameters
    ----------
    disfile : list or str
        A list of .dis files or a wild card string (*.dis).
    tiltyfile : str
        File with tilt_Y data, e.g. disperser_G395H_TiltY.gtp.
    outname : str
        Name of output ASDF file.

    Returns
    -------
    fasdf : asdf.AsdfFile

    """

    disperser = disfile.split('.dis')[0].split('_')[1]
    with open(disfile) as f:
        lines = [l.strip() for l in f.readlines()]

    try:
        ind = lines.index('*TYPE')
        disperser_type = (lines[ind + 1]).lower()
    except ValueError:
        raise ValueError("Unknown disperser type in {0}".format(disfile))

    if disperser_type == 'gratingdata':
        d = dict.fromkeys(
            ['groove_density', 'theta_z', 'theta_y', 'theta_x', 'tilt_y'])
    elif disperser_type == 'prismdata':
        d = dict.fromkeys([
            'tref', 'pref', 'angle', 'coefformula', 'thermalcoef', 'wbound'
            'theta_z', 'theta_y', 'theta_x', 'tilt_y'
        ])

    d.update(ref_kw)
    try:
        ind = lines.index('*GRATINGNAME')
        grating_name = lines[ind + 1]
    except ValueError:
        grating_name = 'PRISM'

    #for line in lines:
    ind = lines.index('*THETAZ')
    d['theta_z'] = float(lines[ind + 1]) / 3600.  # in degrees
    ind = lines.index('*THETAX')
    d['theta_x'] = float(lines[ind + 1]) / 3600.  # in degrees
    ind = lines.index('*THETAY')
    d['theta_y'] = float(lines[ind + 1]) / 3600.  # in degrees
    ind = lines.index('*TILTY')
    d['tilt_y'] = float(lines[ind + 1])  # in degrees
    try:
        ind = lines.index('*TILTX')
        d['tilt_x'] = float(lines[ind + 1])  # in degrees
    except ValueError:
        d['tilt_x'] = 0.0

    if disperser_type == 'gratingdata':
        ind = lines.index('*GROOVEDENSITY')
        d['groove_density'] = float(lines[ind + 1])
    elif disperser_type == 'prismdata':
        ind = lines.index('*ANGLE')
        d['angle'] = float(lines[ind + 1])  # in degrees

        ind = lines.index('*TREF')
        d['tref'] = float(lines[ind + 1])  # Temperature in K

        ind = lines.index('*PREF')
        d['pref'] = float(lines[ind + 1])  # Pressure in ATM

        ind = lines.index('*COEFFORMULA')
        coefs = np.array(lines[ind:ind + int(l[-1])], dtype=np.float)
        kcoef = coefs[::2]
        lcoef = coefs[1::2]
        d['lcoef'] = lcoef
        d['kcoef'] = kcoef

        # 6 coeffs - D0, D1, D2, E0, E1, lambdak
        ind = lines.index('*THERMALCOEF')
        coefs = lines[ind:ind + int(l[-1])]
        d['tcoef'] = [float(c) for c in coefs]

        ind = lines.index('*WBOUND')
        coefs = lines[ind:ind + 2]
        d['wbound'] = [float(c) for c in coefs]

    assert grating_name in tiltyfile
    assert grating_name in tiltxfile
    tiltyd = disperser_tilt(tiltyfile)
    tiltxd = disperser_tilt(tiltxfile)

    d['gwa_tiltx'] = tiltyd
    d['gwa_tilty'] = tiltxd
    fasdf = AsdfFile()
    fasdf.tree = d
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#36
0
def disperser2asdf(disfile, tiltyfile, tiltxfile, outname, ref_kw):
    """
    Create a NIRSPEC disperser reference file in ASDF format.

    Combine information stored in disperser_G?.dis and disperser_G?_TiltY.gtp
    files delievred by the IDT.

    disperser2asdf("disperser_G140H.dis", "disperser_G140H_TiltY.gtp", "disperserG140H.asdf")

    Parameters
    ----------
    disfile : list or str
        A list of .dis files or a wild card string (*.dis).
    tiltyfile : str
        File with tilt_Y data, e.g. disperser_G395H_TiltY.gtp.
    outname : str
        Name of output ASDF file.

    Returns
    -------
    fasdf : asdf.AsdfFile

    """
    disperser = disfile.split('.dis')[0].split('_')[1]
    with open(disfile) as f:
        lines=[l.strip() for l in f.readlines()]
    d = dict.fromkeys(['groove_density', 'theta_z', 'theta_y', 'theta_x', 'tilt_y'])
    d.update(ref_kw)
    for line in lines:
        ind = lines.index('*GRATINGNAME')
        grating_name = lines[ind + 1]
        ind = lines.index('*GROOVEDENSITY')
        d['groove_density'] = float(lines[ind + 1])
        ind = lines.index('*THETAZ')
        d['theta_z'] = float(lines[ind + 1]) / 3600. # in degrees
        ind = lines.index('*THETAX')
        d['theta_x'] = float(lines[ind + 1]) / 3600. # in degrees
        ind = lines.index('*THETAY')
        d['theta_y'] = float(lines[ind + 1]) / 3600. # in degrees
        ind = lines.index('*TILTY')
        d['tilt_y'] = float(lines[ind + 1]) # in degrees
        try:
            ind = lines.index('*TILTX')
            d['tilt_x'] = float(lines[ind + 1]) # in degrees
        except ValueError:
            d['tilt_x'] = 0.0


    assert grating_name in tiltyfile
    assert grating_name in tiltxfile

    with open(tiltyfile) as f:
        s = f.read()
    tiltyd = {}
    vals = s.split('*')
    for line in vals[::-1]:
        if line.startswith("CoeffsTemperature00"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = {}
            for i , c in enumerate([float(c) for c in l[1:1+n]]):
                coeffs['c' + str(i)] = c
            tiltyd['tilt_model'] = models.Polynomial1D(n-1, **coeffs)
        elif line.startswith("Temperatures"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1+n]
            tiltyd['temperatures'] = [float(c) for c in coeffs]
        elif line.startswith("Zeroreadings"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1+n]
            tiltyd['zeroreadings'] = [float(c) for c in coeffs]
        elif line.startswith("Unit"):
            tiltyd['unit'] = line.split('\n')[1]

    with open(tiltxfile) as f:
        s = f.read()
    tiltxd = {}
    vals = s.split('*')
    for line in vals[::-1]:
        if line.startswith("CoeffsTemperature00"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = {}
            for i , c in enumerate([float(c) for c in l[1:1+n]]):
                coeffs['c' + str(i)] = c
            tiltxd['tilt_model'] = models.Polynomial1D(n-1, **coeffs)
        elif line.startswith("Temperatures"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1+n]
            tiltxd['temperatures'] = [float(c) for c in coeffs]
        elif line.startswith("Zeroreadings"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1+n]
            tiltxd['zeroreadings'] = [float(c) for c in coeffs]
        elif line.startswith("Unit"):
            tiltxd['unit'] = line.split('\n')[1]


    d['gwa_tiltx'] = tiltyd
    d['gwa_tilty'] = tiltxd
    fasdf = AsdfFile()
    fasdf.tree = d
    fasdf.write_to(outname)
    return fasdf
def create_miri_imager_distortion(distfile, outname):
    """
    Create an asdf reference file with all distortion components for the MIRI imager.
    The filter offsets are stored in a sepaate file.

    Note: The IDT supplied distortion file lists sky to pixel as the
    forward transform. Since "forward" in the JWST pipeline is from
    pixel to sky, the meaning of forward and inverse matrices and the order
    in which they are applied is switched.

    The order of operation from pixel to sky is:
    - Apply MI matrix
    - Apply Ai and BI matrices
    - Apply the TI matrix (this gives V2/V3 coordinates)

    Parameters
    ----------
    distfile : str
        MIRI imager DISTORTION file provided by the IDT team.
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    --------
    >>> create_miri_imager_distortion("MIRI_FM_MIRIMAGE_DISTORTION_03.02.00.fits", 'test.asdf')
    """
    fdist = fits.open(distfile)
    mi_matrix = fdist[8].data
    mi_col = models.Polynomial1D(1,
                                 c0=mi_matrix[0, 2],
                                 c1=mi_matrix[0, 0],
                                 name="M_column_correction")
    mi_row = models.Polynomial1D(1,
                                 c0=mi_matrix[1, 2],
                                 c1=mi_matrix[1, 1],
                                 name="M_row_correction")
    m_matrix = fdist[4].data
    m_col = models.Polynomial1D(1, c0=m_matrix[0, 2], c1=m_matrix[0, 0])
    m_row = models.Polynomial1D(1, c0=m_matrix[1, 2], c1=m_matrix[1, 1])
    mi_col.inverse = m_col
    mi_row.inverse = m_row
    m_transform = mi_col & mi_row  #mi_row & mi_col

    ai_matrix = fdist[6].data
    a_matrix = fdist[2].data
    col_poly = polynomial_from_coeffs_matrix(ai_matrix, name="A_correction")
    col_poly.inverse = polynomial_from_coeffs_matrix(a_matrix)
    bi_matrix = fdist[5].data
    b_matrix = fdist[1].data
    row_poly = polynomial_from_coeffs_matrix(bi_matrix, name="B_correction")
    row_poly.inverse = polynomial_from_coeffs_matrix(b_matrix)
    poly = col_poly & row_poly

    ti_matrix = fdist[7].data
    t_matrix = fdist[3].data
    ti_col = models.Polynomial2D(1, name='TI_column_correction')
    ti_col.parameters = ti_matrix[0][::-1]
    ti_row = models.Polynomial2D(1, name='TI_row_correction')
    ti_row.parameters = ti_matrix[1][::-1]

    t_col = models.Polynomial2D(1, name='T_column_correction')
    t_col.parameters = t_matrix[0][::-1]
    t_row = models.Polynomial2D(1, name='T_row_correction')
    t_row.parameters = t_matrix[1][::-1]
    ti_col.inverse = t_col
    ti_row.inverse = t_row
    t_transform = ti_row & ti_col

    mapping = models.Mapping([0, 1, 0, 1])
    mapping.inverse = models.Identity(2)

    # ident is created here so that mapping can be assigned as inverse
    ident = models.Identity(2)
    ident.inverse = models.Mapping([0, 1, 0, 1])

    poly2t_mapping = models.Mapping([0, 1, 0, 1])
    poly2t_mapping.inverse = models.Mapping([0, 1, 0, 1])

    distortion_transform = m_transform | mapping | poly | poly2t_mapping | t_transform | ident | models.Mapping(
        [1, 0])

    fdist.close()
    f = AsdfFile()
    tree = {
        "title": "MIRI imager distortion - CDP4",
        "reftype": "DISTORTION",
        "instrument": "MIRI",
        "detector": "MIRIMAGE",
        "exp_type": "MIR_IMAGE",
        "pedigree": "GROUND",
        "author": "N. Dencheva",
        "model": distortion_transform
    }
    f.tree = tree
    fasdf = f.write_to(outname)
def ifupost2asdf(ifupost_files, outname, ref_kw):
    """
    Create a reference file of type ``ifupost`` .

    Combines all IDT ``IFU-POST`` reference files in one ASDF file.

    forward direction : MSA to Collimator
    backward_direction: Collimator to MSA

    Parameters
    ----------
    ifupost_files : list
        Names of all ``IFU-POST`` IDT reference files
    outname : str
        Name of output ``ASDF`` file
    """
    fa = AsdfFile()
    fa.tree = ref_kw
    for fifu in ifupost_files:
        n = int((fifu.split('IFU-POST_')[1]).split('.pcf')[0])
        fa.tree[n] = {}
        with open(fifu) as f:
            lines = [l.strip() for l in f.readlines()]
        factors = lines[lines.index('*Factor 2') + 1].split()
        rotation_angle = float(lines[lines.index('*Rotation') + 1])
        input_rot_center = lines[lines.index('*InputRotationCentre 2') +
                                 1].split()
        output_rot_center = lines[lines.index('*OutputRotationCentre 2') +
                                  1].split()
        linear_sky2det = homothetic_sky2det(input_rot_center, rotation_angle,
                                            factors, output_rot_center)

        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)

        output2poly_mapping = Identity(2, name='output_mapping')
        output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
        input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
        input2poly_mapping.inverse = Identity(2)

        model_poly = input2poly_mapping | (
            x_poly_forward & y_poly_forward) | output2poly_mapping

        model = linear_sky2det | model_poly
        fa.tree[n]['model'] = model
    fa.add_history_entry("Build 6")
    asdffile = fa.write_to(outname)
    return asdffile
示例#39
0
def fore2asdf(pcffore, outname, ref_kw):
    """
    forward direction : msa 2 ote
    backward_direction: msa 2 fpa
    """
    with open(pcffore) 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 in ote2msa direction
    scale = models.Scale(1. / float(factors[0]), name='scale_x') & \
          models.Scale(1 / float(factors[1]), name='scale_y')

    rotation_angle = lines[lines.index('*Rotation') + 1]
    rotation = models.Rotation2D(float(rotation_angle), name='rotation')

    input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split()
    output_offset = models.Shift(float(input_rot_center[0]), name="output_x_shift") & \
                 models.Shift(float(input_rot_center[1]), name="output_y_shift")

    output_rot_center = lines[lines.index('*OutputRotationCentre 2') +
                              1].split()
    input_offset = models.Shift(-float(output_rot_center[0]), name="input_x_shift") & \
                  models.Shift(-float(output_rot_center[1]), name="input_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)
    # Polynomial Correction in x
    x_poly_backward = models.Polynomial2D(degree,
                                          name="x_poly_backward",
                                          **xcoeff_forward)
    xlines_distortion = lines[xcoeff_index + 22:xcoeff_index + 43]
    xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion)
    x_poly_backward_distortion = models.Polynomial2D(
        degree, name="x_backward_distortion", **xcoeff_forward_distortion)
    # do chromatic correction
    # the input is Xote, Yote, lam
    model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \
                     ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * Mapping((2,)))

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree,
                                     lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree,
                                          name="y_poly_backward",
                                          **ycoeff_forward)

    ylines_distortion = lines[ycoeff_index + 22:ycoeff_index + 43]
    ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion)
    y_poly_backward_distortion = models.Polynomial2D(
        degree, name="y_backward_distortion", **ycoeff_forward_distortion)

    # do chromatic correction
    # the input is Xote, Yote, lam
    model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \
                     ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * Mapping((2,)))

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(
        degree, lines[xcoeff_index + 1:xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree,
                                         name="x_poly_forward",
                                         **xcoeff_backward)

    xcoeff_backward_distortion = coeffs_from_pcf(
        degree, lines[xcoeff_index + 22:xcoeff_index + 43])
    x_poly_forward_distortion = models.Polynomial2D(
        degree, name="x_forward_distortion", **xcoeff_backward_distortion)

    # the chromatic correction is done here
    # the input is Xmsa, Ymsa, lam
    model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * Mapping((2,)))

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(
        degree, lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree,
                                         name="y_poly_forward",
                                         **ycoeff_backward)

    ycoeff_backward_distortion = coeffs_from_pcf(
        degree, lines[ycoeff_index + 22:ycoeff_index + 43])
    y_poly_forward_distortion = models.Polynomial2D(
        degree, name="y_forward_distortion", **ycoeff_backward_distortion)

    # do chromatic correction
    # the input is Xmsa, Ymsa, lam
    model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * Mapping((2,)))

    #assign inverse transforms
    model_x = model_x_forward.copy()
    model_y = model_y_forward.copy()

    model_x.inverse = model_x_backward
    model_y.inverse = model_y_backward

    output2poly_mapping = Identity(2, name="output_mapping")
    output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2])
    input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping")
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (model_x & model_y) | output2poly_mapping
    fore_linear = (input_offset | rotation | scale | output_offset)
    fore_linear_inverse = fore_linear.inverse
    fore_linear.inverse = fore_linear_inverse & Identity(1)
    model = model_poly | fore_linear

    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    asdffile = f.write_to(outname)
    return asdffile
示例#40
0
def disperser2asdf(disfile, tiltyfile, tiltxfile, outname, ref_kw):
    """
    Create a NIRSPEC disperser reference file in ASDF format.

    Combine information stored in disperser_G?.dis and disperser_G?_TiltY.gtp
    files delievred by the IDT.

    disperser2asdf("disperser_G140H.dis", "disperser_G140H_TiltY.gtp", "disperserG140H.asdf")

    Parameters
    ----------
    disfile : list or str
        A list of .dis files or a wild card string (*.dis).
    tiltyfile : str
        File with tilt_Y data, e.g. disperser_G395H_TiltY.gtp.
    outname : str
        Name of output ASDF file.

    Returns
    -------
    fasdf : asdf.AsdfFile

    """

    #t = {}
    disperser = disfile.split('.dis')[0].split('_')[1]
    with open(disfile) as f:
        lines = [l.strip() for l in f.readlines()]
    d = dict.fromkeys(
        ['groove_density', 'theta_z', 'theta_y', 'theta_x', 'tilt_y'])
    d.update(ref_kw)
    for line in lines:
        ind = lines.index('*GRATINGNAME')
        grating_name = lines[ind + 1]
        ind = lines.index('*GROOVEDENSITY')
        d['groove_density'] = float(lines[ind + 1])
        ind = lines.index('*THETAZ')
        d['theta_z'] = float(lines[ind + 1]) / 3600.  # in degrees
        ind = lines.index('*THETAX')
        d['theta_x'] = float(lines[ind + 1]) / 3600.  # in degrees
        ind = lines.index('*THETAY')
        d['theta_y'] = float(lines[ind + 1]) / 3600.  # in degrees
        ind = lines.index('*TILTY')
        d['tilt_y'] = float(lines[ind + 1])  # in degrees
        try:
            ind = lines.index('*TILTX')
            d['tilt_x'] = float(lines[ind + 1])  # in degrees
        except ValueError:
            d['tilt_x'] = 0.0

    assert grating_name in tiltyfile
    assert grating_name in tiltxfile

    with open(tiltyfile) as f:
        s = f.read()
    tiltyd = {}
    vals = s.split('*')
    for line in vals[::-1]:
        if line.startswith("CoeffsTemperature00"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = {}
            for i, c in enumerate([float(c) for c in l[1:1 + n]]):
                coeffs['c' + str(i)] = c
            tiltyd['tilt_model'] = models.Polynomial1D(n - 1, **coeffs)
        elif line.startswith("Temperatures"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1 + n]
            tiltyd['temperatures'] = [float(c) for c in coeffs]
        elif line.startswith("Zeroreadings"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1 + n]
            tiltyd['zeroreadings'] = [float(c) for c in coeffs]
        elif line.startswith("Unit"):
            tiltyd['unit'] = line.split('\n')[1]

    with open(tiltxfile) as f:
        s = f.read()
    tiltxd = {}
    vals = s.split('*')
    for line in vals[::-1]:
        if line.startswith("CoeffsTemperature00"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = {}
            for i, c in enumerate([float(c) for c in l[1:1 + n]]):
                coeffs['c' + str(i)] = c
            tiltxd['tilt_model'] = models.Polynomial1D(n - 1, **coeffs)
        elif line.startswith("Temperatures"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1 + n]
            tiltxd['temperatures'] = [float(c) for c in coeffs]
        elif line.startswith("Zeroreadings"):
            l = line.split('\n')
            n = int(l[0].split()[1])
            coeffs = l[1:1 + n]
            tiltxd['zeroreadings'] = [float(c) for c in coeffs]
        elif line.startswith("Unit"):
            tiltxd['unit'] = line.split('\n')[1]
        """
        TODO: add prism specific coefficients, get_disperser_info.pro
        """

    d['gwa_tiltx'] = tiltyd
    d['gwa_tilty'] = tiltxd
    fasdf = AsdfFile()
    fasdf.tree = d
    fasdf.write_to(outname)
    return fasdf
示例#41
0
def pcf2asdf(pcffile, outname, ref_file_kw):
    """
    Create an asdf reference file with the transformation coded in a NIRSPEC
    Camera.pcf or Collimator*.pcf file.

    - forward (team): sky to detector
      - Shift inputs to input_rotation_center
      - Rotate inputs
      - Scale  inputs
      - Shift inputs to output_rot_center
      - Apply polynomial distortion
    - backward_team (team definition) detector to sky
      - Apply polynomial distortion
      - Shift inputs to output_rot_center
      - Scale  inputs
      - Rotate inputs
      - Shift inputs to input_rotation_center

    WCS implementation
    - forward: detector to sky
      - equivalent to backward_team
    - backward: sky to detector
      - equivalent to forward_team

    Parameters
    ----------
    pcffile : str
        one of the NIRSPEC ".pcf" reference files provided by the IDT team.
        "pcf" stands for "polynomial coefficients fit"
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    --------
    >>> pcf2asdf("Camera.pcf", "camera.asdf")

    """
    with open(pcffile) as f:
        lines = [l.strip() for l in f.readlines()]

    factors = lines[lines.index('*Factor 2') + 1].split()
    scale = models.Scale(1 / float(factors[0]), name="x_scale") & \
          models.Scale(1 / float(factors[1]), name="y_scale")

    rotation_angle = lines[lines.index('*Rotation') + 1]
    # Backward rotation is in the counter-clockwise direction as in modeling
    # Forward is clockwise
    backward_rotation = models.Rotation2D(float(rotation_angle),
                                          name='rotation')
    rotation = backward_rotation.copy()

    # 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()
    output_offset = models.Shift(float(input_rot_center[0]), name='output_x_shift') & \
                 models.Shift(float(input_rot_center[1]), name='output_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()
    input_offset = models.Shift(-float(output_rot_center[0]), name='input_x_shift') & \
                  models.Shift(-float(output_rot_center[1]), name='input_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_backward = models.Polynomial2D(degree,
                                          name='x_poly_backward',
                                          **xcoeff_forward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree,
                                     lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree,
                                          name='y_poly_backward',
                                          **ycoeff_forward)

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(
        degree, lines[xcoeff_index + 1:xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree,
                                         name='x_poly_forward',
                                         **xcoeff_backward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(
        degree, lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree,
                                         name='y_poly_forward',
                                         **ycoeff_backward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward
                                       & y_poly_forward) | output2poly_mapping

    model = model_poly | input_offset | scale | rotation | output_offset

    f = AsdfFile()
    f.tree = ref_file_kw.copy()
    f.tree['model'] = model
    f.write_to(outname)
示例#42
0
def ote2asdf(otepcf, outname, ref_kw):
    """
    ref_kw = common_reference_file_keywords('OTE', 'NIRSPEC OTE transform - CDP4')

    ote2asdf('Model/Ref_Files/CoordTransform/OTE.pcf', 'jwst_nirspec_ote_0001.asdf', ref_kw)
    """
    with open(otepcf) as f:
        lines = [l.strip() for l in f.readlines()]

    factors = lines[lines.index('*Factor 2 1') + 1].split()

    scale = models.Scale(1 / float(factors[0]), name="x_scale") & \
          models.Scale(1 / float(factors[1]), name="y_scale")

    # this corresponds to modeling Rotation direction as is
    rotation_angle = lines[lines.index('*Rotation') + 1]
    rotation = models.Rotation2D(float(rotation_angle), name='rotation')

    input_rot_center = lines[lines.index('*InputRotationCentre 2 1') + 1].split()
    output_offset = models.Shift(float(input_rot_center[0]), name='output_x_shift') & \
                 models.Shift(float(input_rot_center[1]), name='output_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') + 1].split()
    input_offset = models.Shift(-float(output_rot_center[0]), name='input_x_shift') & \
                  models.Shift(-float(output_rot_center[1]), name='input_y_shift')

    degree = int(lines[lines.index('*FitOrder') + 1])

    xcoeff_index = lines.index('*xForwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_forward = coeffs_from_pcf(degree, xlines)
    x_poly_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_forward = coeffs_from_pcf(degree, ylines)
    y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward)

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_backward = coeffs_from_pcf(degree, xlines)
    x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_backward = coeffs_from_pcf(degree, ylines)
    y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    mlinear = input_offset | rotation | scale | output_offset

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping

    model = model_poly | mlinear


    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    f.write_to(outname)
示例#43
0
def create_specwcs_file(reftype, detector, band, channel, lmodel, name):
    tree = create_reffile_header(reftype, detector, band, channel)
    tree['model'] = lmodel
    f = AsdfFile()
    f.tree = tree
    f.write_to(name)
def pcf2asdf(pcffile, outname, ref_file_kw):
    """
    Create an asdf reference file with the transformation coded in a NIRSPEC
    Camera.pcf or Collimator*.pcf file.

    - forward (team): sky to detector
      - Shift inputs to input_rotation_center
      - Rotate inputs
      - Scale  inputs
      - Shift inputs to output_rot_center
      - Apply polynomial distortion
    - backward_team (team definition) detector to sky
      - Apply polynomial distortion
      - Shift inputs to output_rot_center
      - Scale  inputs
      - Rotate inputs
      - Shift inputs to input_rotation_center

    WCS implementation
    - forward: detector to sky
      - equivalent to backward_team
    - backward: sky to detector
      - equivalent to forward_team

    Parameters
    ----------
    pcffile : str
        one of the NIRSPEC ".pcf" reference files provided by the IDT team.
        "pcf" stands for "polynomial coefficients fit"
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    --------
    >>> pcf2asdf("Camera.pcf", "camera.asdf")

    """
    linear_det2sky = linear_from_pcf_det2sky(pcffile)

    with open(pcffile) as f:
        lines = [l.strip() for l in f.readlines()]

    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_backward = models.Polynomial2D(degree,
                                          name='x_poly_backward',
                                          **xcoeff_forward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree,
                                     lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree,
                                          name='y_poly_backward',
                                          **ycoeff_forward)

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(
        degree, lines[xcoeff_index + 1:xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree,
                                         name='x_poly_forward',
                                         **xcoeff_backward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(
        degree, lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree,
                                         name='y_poly_forward',
                                         **ycoeff_backward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward
                                       & y_poly_forward) | output2poly_mapping

    model = model_poly | linear_det2sky

    f = AsdfFile()
    f.tree = ref_file_kw.copy()
    f.add_history_entry("Build 6")
    f.tree['model'] = model
    f.write_to(outname)
示例#45
0
def create_miri_imager_distortion(distfile, outname):
    """
    Create an asdf reference file with all distortion components for the MIRI imager.
    The filter offsets are stored in a sepaate file.

    Note: The IDT supplied distortion file lists sky to pixel as the
    forward transform. Since "forward" in the JWST pipeline is from
    pixel to sky, the meaning of forward and inverse matrices and the order
    in which they are applied is switched.

    The order of operation from pixel to sky is:
    - Apply MI matrix
    - Apply Ai and BI matrices
    - Apply the TI matrix (this gives V2/V3 coordinates)

    Parameters
    ----------
    distfile : str
        MIRI imager DISTORTION file provided by the IDT team.
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    --------
    >>> create_miri_imager_distortion("MIRI_FM_MIRIMAGE_DISTORTION_03.02.00.fits", 'test.asdf')
    """
    fdist = fits.open(distfile)
    mi_matrix = fdist[8].data
    mi_col = models.Polynomial1D(1, c0=mi_matrix[0, 2], c1=mi_matrix[0,0], name="M_column_correction")
    mi_row = models.Polynomial1D(1, c0=mi_matrix[1, 2], c1=mi_matrix[1,1], name="M_row_correction")
    m_matrix = fdist[4].data
    m_col = models.Polynomial1D(1, c0=m_matrix[0, 2], c1=m_matrix[0,0])
    m_row = models.Polynomial1D(1, c0=m_matrix[1, 2], c1=m_matrix[1,1])
    mi_col.inverse = m_col
    mi_row.inverse = m_row
    m_transform = mi_col & mi_row #mi_row & mi_col

    ai_matrix = fdist[6].data
    a_matrix = fdist[2].data
    col_poly = polynomial_from_coeffs_matrix(ai_matrix, name="A_correction")
    col_poly.inverse = polynomial_from_coeffs_matrix(a_matrix)
    bi_matrix = fdist[5].data
    b_matrix = fdist[1].data
    row_poly = polynomial_from_coeffs_matrix(bi_matrix, name="B_correction")
    row_poly.inverse = polynomial_from_coeffs_matrix(b_matrix)
    poly = col_poly & row_poly

    ti_matrix = fdist[7].data
    t_matrix = fdist[3].data
    ti_col = models.Polynomial2D(1, name='TI_column_correction')
    ti_col.parameters = ti_matrix[0][::-1]
    ti_row = models.Polynomial2D(1, name='TI_row_correction')
    ti_row.parameters = ti_matrix[1][::-1]

    t_col = models.Polynomial2D(1, name='T_column_correction')
    t_col.parameters = t_matrix[0][::-1]
    t_row = models.Polynomial2D(1, name='T_row_correction')
    t_row.parameters = t_matrix[1][::-1]
    ti_col.inverse = t_col
    ti_row.inverse = t_row
    t_transform = ti_row & ti_col

    mapping = models.Mapping([0, 1, 0, 1])
    mapping.inverse = models.Identity(2)

    # ident is created here so that mapping can be assigned as inverse
    ident = models.Identity(2)
    ident.inverse = models.Mapping([0,1,0,1])

    poly2t_mapping = models.Mapping([0, 1, 0, 1])
    poly2t_mapping.inverse = models.Mapping([0, 1, 0, 1])

    distortion_transform = m_transform | mapping | poly | poly2t_mapping | t_transform | ident

    fdist.close()
    f = AsdfFile()
    tree = {"title": "MIRI imager distortion - CDP4",
            "reftype": "DISTORTION",
            "instrument": "MIRI",
            "detector": "MIRIMAGE",
            "exp_type": "MIR_IMAGE",
            "pedigree": "GROUND",
            "author": "N. Dencheva",
            "model": distortion_transform
            }
    f.tree = tree
    fasdf = f.write_to(outname)
def fore2asdf(pcffore, outname, ref_kw):
    """
    forward direction : msa 2 ote
    backward_direction: msa 2 fpa

    """
    with open(pcffore) as f:
        lines = [l.strip() for l in f.readlines()]

    fore_det2sky = linear_from_pcf_det2sky(pcffore)
    fore_linear = fore_det2sky
    fore_linear.inverse = fore_det2sky.inverse & Identity(1)

    # compute the polynomial
    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)
    # Polynomial Correction in x
    x_poly_backward = models.Polynomial2D(degree,
                                          name="x_poly_backward",
                                          **xcoeff_forward)
    xlines_distortion = lines[xcoeff_index + 22:xcoeff_index + 43]
    xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion)
    x_poly_backward_distortion = models.Polynomial2D(
        degree, name="x_backward_distortion", **xcoeff_forward_distortion)
    # do chromatic correction
    # the input is Xote, Yote, lam
    model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \
                     ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * \
                     (Mapping((2,)) | Identity(1)))

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree,
                                     lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree,
                                          name="y_poly_backward",
                                          **ycoeff_forward)

    ylines_distortion = lines[ycoeff_index + 22:ycoeff_index + 43]
    ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion)
    y_poly_backward_distortion = models.Polynomial2D(
        degree, name="y_backward_distortion", **ycoeff_forward_distortion)

    # do chromatic correction
    # the input is Xote, Yote, lam
    model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \
                     ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * \
                     (Mapping((2,)) | Identity(1) ))

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(
        degree, lines[xcoeff_index + 1:xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree,
                                         name="x_poly_forward",
                                         **xcoeff_backward)

    xcoeff_backward_distortion = coeffs_from_pcf(
        degree, lines[xcoeff_index + 22:xcoeff_index + 43])
    x_poly_forward_distortion = models.Polynomial2D(
        degree, name="x_forward_distortion", **xcoeff_backward_distortion)

    # the chromatic correction is done here
    # the input is Xmsa, Ymsa, lam
    model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * \
                    (Mapping((2,)) | Identity(1)))

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(
        degree, lines[ycoeff_index + 1:ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree,
                                         name="y_poly_forward",
                                         **ycoeff_backward)

    ycoeff_backward_distortion = coeffs_from_pcf(
        degree, lines[ycoeff_index + 22:ycoeff_index + 43])
    y_poly_forward_distortion = models.Polynomial2D(
        degree, name="y_forward_distortion", **ycoeff_backward_distortion)

    # do chromatic correction
    # the input is Xmsa, Ymsa, lam
    model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * \
                    (Mapping((2,)) | Identity(1)))

    #assign inverse transforms
    model_x = model_x_forward.copy()
    model_y = model_y_forward.copy()

    model_x.inverse = model_x_backward
    model_y.inverse = model_y_backward

    output2poly_mapping = Identity(2, name="output_mapping")
    output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2])
    input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping")
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (model_x & model_y) | output2poly_mapping

    model = model_poly | fore_linear

    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    f.add_history_entry("Build 6")
    asdffile = f.write_to(outname)
    return asdffile
示例#47
0
def fore2asdf(pcffore, outname, ref_kw):
    """
    forward direction : msa 2 ote
    backward_direction: msa 2 fpa

    """
    with open(pcffore) as f:
        lines = [l.strip() for l in f.readlines()]

    fore_det2sky = linear_from_pcf_det2sky(pcffore)
    fore_linear = fore_det2sky
    fore_linear.inverse = fore_det2sky.inverse & Identity(1)

    # compute the polynomial
    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)
    # Polynomial Correction in x
    x_poly_backward = models.Polynomial2D(degree, name="x_poly_backward", **xcoeff_forward)
    xlines_distortion = lines[xcoeff_index + 22: xcoeff_index + 43]
    xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion)
    x_poly_backward_distortion = models.Polynomial2D(degree, name="x_backward_distortion",
                                                     **xcoeff_forward_distortion)
    # do chromatic correction
    # the input is Xote, Yote, lam
    model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \
                     ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * \
                     (Mapping((2,)) | Identity(1)))

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree, name="y_poly_backward",  **ycoeff_forward)

    ylines_distortion = lines[ycoeff_index + 22: ycoeff_index + 43]
    ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion)
    y_poly_backward_distortion = models.Polynomial2D(degree, name="y_backward_distortion",
                                                     **ycoeff_forward_distortion)

    # do chromatic correction
    # the input is Xote, Yote, lam
    model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \
                     ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * \
                     (Mapping((2,)) | Identity(1) ))

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree,name="x_poly_forward", **xcoeff_backward)

    xcoeff_backward_distortion = coeffs_from_pcf(degree, lines[xcoeff_index + 22: xcoeff_index + 43])
    x_poly_forward_distortion = models.Polynomial2D(degree, name="x_forward_distortion", **xcoeff_backward_distortion)

    # the chromatic correction is done here
    # the input is Xmsa, Ymsa, lam
    model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * \
                    (Mapping((2,)) | Identity(1)))

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree, name="y_poly_forward",**ycoeff_backward)

    ycoeff_backward_distortion = coeffs_from_pcf(degree, lines[ycoeff_index + 22: ycoeff_index + 43])
    y_poly_forward_distortion = models.Polynomial2D(degree, name="y_forward_distortion",
                                                    **ycoeff_backward_distortion)

    # do chromatic correction
    # the input is Xmsa, Ymsa, lam
    model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * \
                    (Mapping((2,)) | Identity(1)))

    #assign inverse transforms
    model_x = model_x_forward.copy()
    model_y = model_y_forward.copy()

    model_x.inverse = model_x_backward
    model_y.inverse = model_y_backward

    output2poly_mapping = Identity(2, name="output_mapping")
    output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2])
    input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping")
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping  | (model_x & model_y) | output2poly_mapping


    model = model_poly | fore_linear

    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    asdffile = f.write_to(outname)
    return asdffile
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")
    nrs1_pitchx = float(lines[ind+1])
    ind = lines.index("*SCA491_PitchY")
    nrs1_pitchy = float(lines[ind+1])
    ind = lines.index("*SCA491_RotAngle")
    nrs1_angle = float(lines[ind+1])
    ind = lines.index("*SCA491_PosX")
    nrs1_posx = float(lines[ind+1])
    ind = lines.index("*SCA491_PosY")
    nrs1_posy = float(lines[ind+1])

    # NRS2
    ind = lines.index("*SCA492_PitchX")
    nrs2_pitchx = float(lines[ind+1])
    ind = lines.index("*SCA492_PitchY")
    nrs2_pitchy = float(lines[ind+1])
    ind = lines.index("*SCA492_RotAngle")
    nrs2_angle = float(lines[ind+1])
    ind = lines.index("*SCA492_PosX")
    nrs2_posx = float(lines[ind+1])
    ind = lines.index("*SCA492_PosY")
    nrs2_posy = float(lines[ind+1])

    tree = ref_kw.copy()

    # NRS1 Sky to Detector
    scaling = np.array([[1/nrs1_pitchx, 0], [0, 1/nrs1_pitchy]])
    rotmat = models.Rotation2D._compute_matrix(-nrs1_angle)
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_sky2detector')
    nrs1_sky2det = models.Shift(-nrs1_posx, name='fpa_shift_x') & \
                 models.Shift(-nrs1_posy, name='fpa_shift_y') | aff

    # NRS1 Detector to Sky
    rotmat = models.Rotation2D._compute_matrix(-nrs1_angle)
    scaling = np.array([[nrs1_pitchx, 0], [0, nrs1_pitchy]])
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_detector2sky')
    nrs1_det2sky = aff | models.Shift(nrs1_posx, name='fpa_shift_x_det2sky') & \
                 models.Shift(nrs1_posy, name='fpa_shift_y_det2sky')

    nrs1_det2sky.inverse = nrs1_sky2det

    # NRS2 Sky to Detector
    scaling = np.array([[-1/nrs2_pitchx, 0], [0, -1/nrs2_pitchy]])
    rotmat = models.Rotation2D._compute_matrix(-nrs2_angle)
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_sky2detector')
    nrs2_sky2det = models.Shift(-nrs2_posx, name='fpa_shixft_x') & \
                 models.Shift(-nrs2_posy, name='fpa_shift_y') | aff

    # NRS2 Detector to Sky
    rotmat = models.Rotation2D._compute_matrix(nrs2_angle)
    scaling = np.array([[-nrs2_pitchx, 0], [0, -nrs2_pitchy]])
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_detector2sky')
    nrs2_det2sky = aff | models.Shift(nrs2_posx, name='fpa_shift_x_det2sky') & \
                 models.Shift(nrs2_posy, name='fpa_shift_y_det2sky')

    nrs2_det2sky.inverse = nrs2_sky2det

    tree['NRS1'] = nrs1_det2sky
    tree['NRS2'] = nrs2_det2sky
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#49
0
def create_regions_file(slices, detector, band, channel, name):
    tree = create_reffile_header("REGIONS", detector, band, channel)
    f = AsdfFile()
    tree['regions'] = slices
    f.tree = tree
    f.write_to(name)
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")
    nrs1_pitchx = float(lines[ind + 1])
    ind = lines.index("*SCA491_PitchY")
    nrs1_pitchy = float(lines[ind + 1])
    ind = lines.index("*SCA491_RotAngle")
    nrs1_angle = float(lines[ind + 1])
    ind = lines.index("*SCA491_PosX")
    nrs1_posx = float(lines[ind + 1])
    ind = lines.index("*SCA491_PosY")
    nrs1_posy = float(lines[ind + 1])

    # NRS2
    ind = lines.index("*SCA492_PitchX")
    nrs2_pitchx = float(lines[ind + 1])
    ind = lines.index("*SCA492_PitchY")
    nrs2_pitchy = float(lines[ind + 1])
    ind = lines.index("*SCA492_RotAngle")
    nrs2_angle = float(lines[ind + 1])
    ind = lines.index("*SCA492_PosX")
    nrs2_posx = float(lines[ind + 1])
    ind = lines.index("*SCA492_PosY")
    nrs2_posy = float(lines[ind + 1])

    tree = ref_kw.copy()

    # NRS1 Sky to Detector
    scaling = np.array([[1 / nrs1_pitchx, 0], [0, 1 / nrs1_pitchy]])
    rotmat = models.Rotation2D._compute_matrix(-nrs1_angle)
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_sky2detector')
    nrs1_sky2det = models.Shift(-nrs1_posx, name='fpa_shift_x') & \
                 models.Shift(-nrs1_posy, name='fpa_shift_y') | aff

    # NRS1 Detector to Sky
    rotmat = models.Rotation2D._compute_matrix(-nrs1_angle)
    scaling = np.array([[nrs1_pitchx, 0], [0, nrs1_pitchy]])
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_detector2sky')
    nrs1_det2sky = aff | models.Shift(nrs1_posx, name='fpa_shift_x_det2sky') & \
                 models.Shift(nrs1_posy, name='fpa_shift_y_det2sky')

    nrs1_det2sky.inverse = nrs1_sky2det

    # NRS2 Sky to Detector
    scaling = np.array([[-1 / nrs2_pitchx, 0], [0, -1 / nrs2_pitchy]])
    rotmat = models.Rotation2D._compute_matrix(-nrs2_angle)
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_sky2detector')
    nrs2_sky2det = models.Shift(-nrs2_posx, name='fpa_shixft_x') & \
                 models.Shift(-nrs2_posy, name='fpa_shift_y') | aff

    # NRS2 Detector to Sky
    rotmat = models.Rotation2D._compute_matrix(nrs2_angle)
    scaling = np.array([[-nrs2_pitchx, 0], [0, -nrs2_pitchy]])
    matrix = np.dot(rotmat, scaling)
    aff = models.AffineTransformation2D(matrix, name='fpa_affine_detector2sky')
    nrs2_det2sky = aff | models.Shift(nrs2_posx, name='fpa_shift_x_det2sky') & \
                 models.Shift(nrs2_posy, name='fpa_shift_y_det2sky')

    nrs2_det2sky.inverse = nrs2_sky2det

    tree['NRS1'] = nrs1_det2sky
    tree['NRS2'] = nrs2_det2sky
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#51
0
def pcf2asdf(pcffile, outname, ref_file_kw):
    """
    Create an asdf reference file with the transformation coded in a NIRSPEC
    Camera.pcf or Collimator*.pcf file.

    - forward (team): sky to detector
      - Shift inputs to input_rotation_center
      - Rotate inputs
      - Scale  inputs
      - Shift inputs to output_rot_center
      - Apply polynomial distortion
    - backward_team (team definition) detector to sky
      - Apply polynomial distortion
      - Shift inputs to output_rot_center
      - Scale  inputs
      - Rotate inputs
      - Shift inputs to input_rotation_center

    WCS implementation
    - forward: detector to sky
      - equivalent to backward_team
    - backward: sky to detector
      - equivalent to forward_team

    Parameters
    ----------
    pcffile : str
        one of the NIRSPEC ".pcf" reference files provided by the IDT team.
        "pcf" stands for "polynomial coefficients fit"
    outname : str
        Name of reference file to be wriiten to disk.

    Returns
    -------
    fasdf : AsdfFile
        AsdfFile object

    Examples
    --------
    >>> pcf2asdf("Camera.pcf", "camera.asdf")

    """
    with open(pcffile) as f:
        lines = [l.strip() for l in f.readlines()]

    factors = lines[lines.index('*Factor 2') + 1].split()
    scale = models.Scale(1 / float(factors[0]), name="x_scale") & \
          models.Scale(1 / float(factors[1]), name="y_scale")

    rotation_angle = lines[lines.index('*Rotation') + 1]
    # Backward rotation is in the counter-clockwise direction as in modeling
    # Forward is clockwise
    backward_rotation = models.Rotation2D(float(rotation_angle), name='rotation')
    rotation = backward_rotation.copy()

    # 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()
    output_offset = models.Shift(float(input_rot_center[0]), name='output_x_shift') & \
                 models.Shift(float(input_rot_center[1]), name='output_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()
    input_offset = models.Shift(-float(output_rot_center[0]), name='input_x_shift') & \
                  models.Shift(-float(output_rot_center[1]), name='input_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_backward = models.Polynomial2D(degree, name='x_poly_backward', **xcoeff_forward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree, name='y_poly_backward', **ycoeff_forward)

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree, name='x_poly_forward', **xcoeff_backward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree, name='y_poly_forward', **ycoeff_backward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward & y_poly_forward) | output2poly_mapping

    model = model_poly | input_offset |scale |rotation |output_offset

    f = AsdfFile()
    f.tree = ref_file_kw.copy()
    f.tree['model'] = model
    f.write_to(outname)
示例#52
0
def create_v23(reftype, detector, band, channels, data, name, author, useafter,
               description):
    """
    Create the transform from MIRI Local to telescope V2/V3 system for all channels.
    """
    channel = "".join([ch[0] for ch in channels])
    tree = create_reffile_header(reftype, detector, band, channel, author,
                                 useafter, description)
    """
    tree = {"detector": detector,
            "instrument" : "MIRI",
            "band": band,
            "channel": channel,
            "exp_type": "MIR_MRS",
            "pedigree": "GROUND",
            "title": "MIRI IFU model - based on CDP-4",
            "reftype": reftype,
            "author": author,
            "useafter": useafter,
            "description": description
            }
    """
    tree['filename'] = name
    ab_v23 = data[0]
    v23_ab = data[1]
    m = {}
    c0_0, c0_1, c1_0, c1_1 = ab_v23[0][1:]
    ch1_v2 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[0][1:]
    ch1_a = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")

    c0_0, c0_1, c1_0, c1_1 = ab_v23[1][1:]
    ch1_v3 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[1][1:]
    ch1_b = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")
    c0_0, c0_1, c1_0, c1_1 = ab_v23[2][1:]
    ch2_v2 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[2][1:]
    ch2_a = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")

    c0_0, c0_1, c1_0, c1_1 = ab_v23[3][1:]
    ch2_v3 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[3][1:]
    ch2_b = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")
    ch1_for = ch1_v2 & ch1_v3
    ch2_for = ch2_v2 & ch2_v3
    ch1_for.inverse = ch1_a & ch1_b
    ch2_for.inverse = ch2_a & ch2_b
    m[channels[0]] = ch1_for
    m[channels[1]] = ch2_for
    tree['model'] = m

    f = AsdfFile()
    f.tree = tree
    f.add_history_entry(
        "DOCUMENT: MIRI-TN-00001-ETH; SOFTWARE: polyd2c_CDP5.pro; DATA USED: Data set of: - FM Test Campaign relevant to MRS-OPT-01, MRS-OPT-02, MRS-OPT-04, MRS-OPT-08; - CV1 Test Campaign relevant to MRS-OPT-02; - CV2 Test Campaign relevant to MRS-OPT-02; - Laboratory measurement of SPO; ============ DIFFERENCES: - New file structure: Change of Extention names and Table Column Headers.; - Replaced V2/V3 with XAN/YAN;"
    )
    f.write_to(name)
def disperser2asdf(disfile, tiltyfile, tiltxfile, outname, ref_kw):
    """
    Create a NIRSPEC disperser reference file in ASDF format.

    Combine information stored in disperser_G?.dis and disperser_G?_TiltY.gtp
    files delievred by the IDT.

    disperser2asdf("disperser_G140H.dis", "disperser_G140H_TiltY.gtp", "disperserG140H.asdf")

    Parameters
    ----------
    disfile : list or str
        A list of .dis files or a wild card string (*.dis).
    tiltyfile : str
        File with tilt_Y data, e.g. disperser_G395H_TiltY.gtp.
    outname : str
        Name of output ASDF file.

    Returns
    -------
    fasdf : asdf.AsdfFile

    """

    disperser = disfile.split('.dis')[0].split('_')[1]
    with open(disfile) as f:
        lines=[l.strip() for l in f.readlines()]

    try:
        ind = lines.index('*TYPE')
        disperser_type = (lines[ind + 1]).lower()
    except ValueError:
        raise ValueError("Unknown disperser type in {0}".format(disfile))

    if disperser_type == 'gratingdata':
        d = dict.fromkeys(['groove_density', 'theta_z', 'theta_y', 'theta_x', 'tilt_y'])
    elif disperser_type == 'prismdata':
        d = dict.fromkeys(['tref', 'pref', 'angle', 'coefformula', 'thermalcoef', 'wbound'
                           'theta_z', 'theta_y', 'theta_x', 'tilt_y'])

    d.update(ref_kw)
    try:
        ind = lines.index('*GRATINGNAME')
        grating_name = lines[ind + 1]
    except ValueError:
        grating_name = 'PRISM'

    #for line in lines:
    ind = lines.index('*THETAZ')
    d['theta_z'] = float(lines[ind + 1]) / 3600. # in degrees
    ind = lines.index('*THETAX')
    d['theta_x'] = float(lines[ind + 1]) / 3600. # in degrees
    ind = lines.index('*THETAY')
    d['theta_y'] = float(lines[ind + 1]) / 3600. # in degrees
    ind = lines.index('*TILTY')
    d['tilt_y'] = float(lines[ind + 1]) # in degrees
    try:
        ind = lines.index('*TILTX')
        d['tilt_x'] = float(lines[ind + 1]) # in degrees
    except ValueError:
        d['tilt_x'] = 0.0

    if disperser_type == 'gratingdata':
        ind = lines.index('*GROOVEDENSITY')
        d['groove_density'] = float(lines[ind + 1])
    elif disperser_type == 'prismdata':
        ind = lines.index('*ANGLE')
        d['angle'] = float(lines[ind + 1]) # in degrees

        ind = lines.index('*TREF')
        d['tref'] = float(lines[ind + 1]) # Temperature in K

        ind = lines.index('*PREF')
        d['pref'] = float(lines[ind + 1]) # Pressure in ATM

        ind = lines.index('*COEFFORMULA')
        coefs = np.array(lines[ind : ind+int(l[-1])], dtype=np.float)
        kcoef = coefs[::2]
        lcoef = coefs[1::2]
        d['lcoef'] = lcoef
        d['kcoef'] = kcoef

        # 6 coeffs - D0, D1, D2, E0, E1, lambdak
        ind = lines.index('*THERMALCOEF')
        coefs = lines[ind : ind+int(l[-1])]
        d['tcoef'] = [float(c) for c in coefs]

        ind = lines.index('*WBOUND')
        coefs = lines[ind : ind + 2]
        d['wbound'] = [float(c) for c in coefs]

    assert grating_name in tiltyfile
    assert grating_name in tiltxfile
    tiltyd = disperser_tilt(tiltyfile)
    tiltxd = disperser_tilt(tiltxfile)

    d['gwa_tiltx'] = tiltyd
    d['gwa_tilty'] = tiltxd
    fasdf = AsdfFile()
    fasdf.tree = d
    fasdf.add_history_entry("Build 6")
    fasdf.write_to(outname)
    return fasdf
示例#54
0
def fore2asdf(pcffore, outname, ref_kw):
    """
    forward direction : msa 2 ote
    backward_direction: msa 2 fpa
    """
    with open(pcffore) 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 in ote2msa direction
    scale = models.Scale(1. / float(factors[0]), name='scale_x') & \
          models.Scale(1 / float(factors[1]), name='scale_y')

    rotation_angle = lines[lines.index('*Rotation') + 1]
    rotation = models.Rotation2D(float(rotation_angle), name='rotation')

    input_rot_center = lines[lines.index('*InputRotationCentre 2') + 1].split()
    output_offset = models.Shift(float(input_rot_center[0]), name="output_x_shift") & \
                 models.Shift(float(input_rot_center[1]), name="output_y_shift")

    output_rot_center = lines[lines.index('*OutputRotationCentre 2') + 1].split()
    input_offset = models.Shift(-float(output_rot_center[0]), name="input_x_shift") & \
                  models.Shift(-float(output_rot_center[1]), name="input_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)
    # Polynomial Correction in x
    x_poly_backward = models.Polynomial2D(degree, name="x_poly_backward", **xcoeff_forward)
    xlines_distortion = lines[xcoeff_index + 22: xcoeff_index + 43]
    xcoeff_forward_distortion = coeffs_from_pcf(degree, xlines_distortion)
    x_poly_backward_distortion = models.Polynomial2D(degree, name="x_backward_distortion",
                                                     **xcoeff_forward_distortion)
    # do chromatic correction
    # the input is Xote, Yote, lam
    model_x_backward = (Mapping((0, 1), n_inputs=3) | x_poly_backward) + \
                     ((Mapping((0,1), n_inputs=3) | x_poly_backward_distortion) * Mapping((2,)))

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ycoeff_forward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_backward = models.Polynomial2D(degree, name="y_poly_backward",  **ycoeff_forward)

    ylines_distortion = lines[ycoeff_index + 22: ycoeff_index + 43]
    ycoeff_forward_distortion = coeffs_from_pcf(degree, ylines_distortion)
    y_poly_backward_distortion = models.Polynomial2D(degree, name="y_backward_distortion",
                                                     **ycoeff_forward_distortion)

    # do chromatic correction
    # the input is Xote, Yote, lam
    model_y_backward = (Mapping((0,1), n_inputs=3) | y_poly_backward) + \
                     ((Mapping((0, 1), n_inputs=3) | y_poly_backward_distortion) * Mapping((2,)))

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xcoeff_backward = coeffs_from_pcf(degree, lines[xcoeff_index + 1: xcoeff_index + 22])
    x_poly_forward = models.Polynomial2D(degree,name="x_poly_forward", **xcoeff_backward)

    xcoeff_backward_distortion = coeffs_from_pcf(degree, lines[xcoeff_index + 22: xcoeff_index + 43])
    x_poly_forward_distortion = models.Polynomial2D(degree, name="x_forward_distortion", **xcoeff_backward_distortion)

    # the chromatic correction is done here
    # the input is Xmsa, Ymsa, lam
    model_x_forward = (Mapping((0,1), n_inputs=3) | x_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | x_poly_forward_distortion) * Mapping((2,)))

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ycoeff_backward = coeffs_from_pcf(degree, lines[ycoeff_index + 1: ycoeff_index + 22])
    y_poly_forward = models.Polynomial2D(degree, name="y_poly_forward",**ycoeff_backward)

    ycoeff_backward_distortion = coeffs_from_pcf(degree, lines[ycoeff_index + 22: ycoeff_index + 43])
    y_poly_forward_distortion = models.Polynomial2D(degree, name="y_forward_distortion",
                                                    **ycoeff_backward_distortion)

    # do chromatic correction
    # the input is Xmsa, Ymsa, lam
    model_y_forward = (Mapping((0,1), n_inputs=3) | y_poly_forward) + \
                    ((Mapping((0,1), n_inputs=3) | y_poly_forward_distortion) * Mapping((2,)))

    #assign inverse transforms
    model_x = model_x_forward.copy()
    model_y = model_y_forward.copy()

    model_x.inverse = model_x_backward
    model_y.inverse = model_y_backward

    output2poly_mapping = Identity(2, name="output_mapping")
    output2poly_mapping.inverse = Mapping([0, 1, 2, 0, 1, 2])
    input2poly_mapping = Mapping([0, 1, 2, 0, 1, 2], name="input_mapping")
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping  | (model_x & model_y) | output2poly_mapping
    fore_linear = (input_offset | rotation | scale | output_offset)
    fore_linear_inverse  = fore_linear.inverse
    fore_linear.inverse = fore_linear_inverse & Identity(1)
    model = model_poly | fore_linear

    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    asdffile = f.write_to(outname)
    return asdffile
示例#55
0
def ote2asdf(otepcf, outname, ref_kw):
    """
    ref_kw = common_reference_file_keywords('OTE', 'NIRSPEC OTE transform - CDP4')

    ote2asdf('Model/Ref_Files/CoordTransform/OTE.pcf', 'jwst_nirspec_ote_0001.asdf', ref_kw)
    """
    with open(otepcf) as f:
        lines = [l.strip() for l in f.readlines()]

    factors = lines[lines.index('*Factor 2 1') + 1].split()

    scale = models.Scale(1 / float(factors[0]), name="x_scale") & \
          models.Scale(1 / float(factors[1]), name="y_scale")

    # this corresponds to modeling Rotation direction as is
    rotation_angle = lines[lines.index('*Rotation') + 1]
    rotation = models.Rotation2D(float(rotation_angle), name='rotation')

    input_rot_center = lines[lines.index('*InputRotationCentre 2 1') +
                             1].split()
    output_offset = models.Shift(float(input_rot_center[0]), name='output_x_shift') & \
                 models.Shift(float(input_rot_center[1]), name='output_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') +
                              1].split()
    input_offset = models.Shift(-float(output_rot_center[0]), name='input_x_shift') & \
                  models.Shift(-float(output_rot_center[1]), name='input_y_shift')

    degree = int(lines[lines.index('*FitOrder') + 1])

    xcoeff_index = lines.index('*xForwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_forward = coeffs_from_pcf(degree, xlines)
    x_poly_backward = models.Polynomial2D(degree,
                                          name='x_poly_backward',
                                          **xcoeff_forward)

    ycoeff_index = lines.index('*yForwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_forward = coeffs_from_pcf(degree, ylines)
    y_poly_backward = models.Polynomial2D(degree,
                                          name='y_poly_backward',
                                          **ycoeff_forward)

    xcoeff_index = lines.index('*xBackwardCoefficients 21 2')
    xlines = lines[xcoeff_index + 1].split('\t')
    xcoeff_backward = coeffs_from_pcf(degree, xlines)
    x_poly_forward = models.Polynomial2D(degree,
                                         name='x_poly_forward',
                                         **xcoeff_backward)

    ycoeff_index = lines.index('*yBackwardCoefficients 21 2')
    ylines = lines[ycoeff_index + 1].split('\t')
    ycoeff_backward = coeffs_from_pcf(degree, ylines)
    y_poly_forward = models.Polynomial2D(degree,
                                         name='y_poly_forward',
                                         **ycoeff_backward)

    x_poly_forward.inverse = x_poly_backward
    y_poly_forward.inverse = y_poly_backward

    mlinear = input_offset | rotation | scale | output_offset

    output2poly_mapping = Identity(2, name='output_mapping')
    output2poly_mapping.inverse = Mapping([0, 1, 0, 1])
    input2poly_mapping = Mapping([0, 1, 0, 1], name='input_mapping')
    input2poly_mapping.inverse = Identity(2)

    model_poly = input2poly_mapping | (x_poly_forward
                                       & y_poly_forward) | output2poly_mapping

    model = model_poly | mlinear

    f = AsdfFile()
    f.tree = ref_kw.copy()
    f.tree['model'] = model
    f.write_to(outname)
示例#56
0
def create_regions_file(slices, detector, band, channel, name):
    tree = create_reffile_header("REGIONS", detector, band, channel)
    f = AsdfFile()
    tree['regions'] = slices
    f.tree = tree
    f.write_to(name)
示例#57
0
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")
    nrs1_pitchx = float(lines[ind+1])
    ind = lines.index("*SCA491_PitchY")
    nrs1_pitchy = float(lines[ind+1])
    ind = lines.index("*SCA491_RotAngle")
    nrs1_angle = np.rad2deg(float(lines[ind+1]))
    ind = lines.index("*SCA491_PosX")
    nrs1_posx = float(lines[ind+1])
    ind = lines.index("*SCA491_PosY")
    nrs1_posy = float(lines[ind+1])

    # NRS2
    ind = lines.index("*SCA492_PitchX")
    nrs2_pitchx = float(lines[ind+1])
    ind = lines.index("*SCA492_PitchY")
    nrs2_pitchy = float(lines[ind+1])
    ind = lines.index("*SCA492_RotAngle")
    nrs2_angle = np.rad2deg(float(lines[ind+1]))
    ind = lines.index("*SCA492_PosX")
    nrs2_posx = float(lines[ind+1])
    ind = lines.index("*SCA492_PosY")
    nrs2_posy = float(lines[ind+1])

    tree = ref_kw.copy()
    nrs1_sky2det = models.Shift(-nrs1_posx) & models.Shift(-nrs1_posy) | \
                 models.Rotation2D(-nrs1_angle) | \
                 models.Scale(1/nrs1_pitchx) & models.Scale(1/nrs1_pitchy)
    nrs1_det2sky = models.Rotation2D(nrs1_angle) | \
                 models.Scale(nrs1_pitchx) & models.Scale(nrs1_pitchy) | \
                 models.Shift(nrs1_posx) & models.Shift(nrs1_posy)
    nrs1_det2sky.inverse = nrs1_sky2det

    nrs2_sky2det = models.Shift(-nrs2_posx) & models.Shift(-nrs2_posy) | \
                 models.Rotation2D(-nrs2_angle) | \
                 models.Scale(1/nrs2_pitchx) & models.Scale(1/nrs2_pitchy)
    nrs2_det2sky = models.Rotation2D(nrs2_angle) | \
                 models.Scale(nrs2_pitchx) & models.Scale(nrs2_pitchy) | \
                 models.Shift(nrs2_posx) & models.Shift(nrs2_posy)
    nrs2_det2sky.inverse = nrs1_sky2det

    tree['NRS1'] = nrs1_det2sky
    tree['NRS2'] = nrs2_sky2det
    fasdf = AsdfFile()
    fasdf.tree = tree
    fasdf.write_to(outname)
    return fasdf
def create_nircam_distortion(coefffile, detector, aperture, opgsname, outname):
    """
    Create an asdf reference file with all distortion components for the NIRCam imager.

    NOTE: The IDT has not provided any distortion information. The files are constructed
    using ISIM transformations provided/(computed?) by the TEL team which they use to
    create the SIAF file.
    These reference files should be replaced when/if the IDT provides us with distortion.

    Parameters
    ----------
    detector : str
        NRCB1, NRCB2, NRCB3, NRCB4, NRCB5, NRCA1, NRCA2, NRCA3, NRCA4, NRCA5
    aperture : str
        Name of the aperture/subarray. (e.g. FULL, SUB160, SUB320, SUB640, GRISM_F322W2)
    outname : str
        Name of output file.

    Examples
    --------

    """
    numdet = detector[-1]
    module = detector[-2]
    channel = 'SHORT'
    if numdet == '5':
        channel = 'LONG'
        
    full_aperture = detector + '_' + aperture

    #"Forward' transformations. science --> ideal --> V2V3
    sci2idlx, sci2idly, sciunit, idlunit = read_siaf_table.get_siaf_transform(coefffile,full_aperture,'science','ideal', 5)
    idl2v2v3x, idl2v2v3y = read_siaf_table.get_siaf_v2v3_transform(coefffile,full_aperture,from_system='ideal')

    #'Reverse' transformations. V2V3 --> ideal --> science
    v2v32idlx, v2v32idly = read_siaf_table.get_siaf_v2v3_transform(coefffile,full_aperture,to_system='ideal')
    idl2scix, idl2sciy, idlunit, sciunit = read_siaf_table.get_siaf_transform(coefffile,full_aperture,'ideal','science', 5)
    
 
    #Map the models together to make a single transformation
    model =  Mapping([0, 1, 0, 1]) | sci2idlx & sci2idly | Mapping([0, 1, 0, 1]) | idl2v2v3x & idl2v2v3y
    model_inv =  Mapping([0, 1, 0, 1]) | v2v32idlx & v2v32idly | Mapping([0, 1, 0, 1]) | idl2scix & idl2sciy
    model.inverse = model_inv


    #In the reference file headers, we need to switch NRCA5 to NRCALONG, and same
    #for module B.
    if detector[-1] == '5':
        detector = detector[0:4] + 'LONG'
    

    tree = {"TITLE": "NIRCAM Distortion",
            "TELESCOP": "JWST",
            "INSTRUMENT": "NIRCAM",
            "PEDIGREE": "GROUND",
            "REFTYPE" : "DISTORTION",
            "AUTHOR": "B. Hilbert",
            "DETECTOR": detector,
            "MODULE": module,
            "CHANNEL": channel,
            "SUBARRAY": opgsname,
            "DESCRIP": "Distortion model function created from SIAF coefficients",
            "EXP_TYPE": "NRC_IMAGE",
            "USEAFTER": "2014-01-01T00:00:00",
            "model": model
            }

    fasdf = AsdfFile()
    fasdf.tree = tree

    sdict = {'name':'nircam_reftools.py','author':'B.Hilbert','homepage':'https://github.com/spacetelescope/jwreftools','version':'0.7'}
    
    fasdf.add_history_entry("File created from a file of distortion coefficients, NIRCam_SIAF_2016-09-29.csv, provided by Colin Cox in October 2016. Software used: https://github.com/spacetelescope/jwreftools",software=sdict)

    fasdf.write_to(outname)
示例#59
0
def create_v23(reftype, detector, band, channels, data, name):
    """
    Create the transform from MIRI Local to telescope V2/V3 system for all channels.
    """
    channel = "".join([ch[0] for ch in channels])
    tree = {
        "detector": detector,
        "instrument": "MIRI",
        "band": band,
        "channel": channel,
        "exp_type": "MIR_MRS",
        "pedigree": "GROUND",
        "title": "MIRI IFU model - based on CDP-4",
        "reftype": reftype,
        "author": "N. Dencheva"
    }
    ab_v23 = data[0]
    v23_ab = data[1]
    m = {}
    c0_0, c0_1, c1_0, c1_1 = ab_v23[0][1:]
    ch1_v2 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[0][1:]
    ch1_a = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")

    c0_0, c0_1, c1_0, c1_1 = ab_v23[1][1:]
    ch1_v3 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[1][1:]
    ch1_b = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")
    c0_0, c0_1, c1_0, c1_1 = ab_v23[2][1:]
    ch2_v2 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[2][1:]
    ch2_a = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")

    c0_0, c0_1, c1_0, c1_1 = ab_v23[3][1:]
    ch2_v3 = models.Polynomial2D(2,
                                 c0_0=c0_0,
                                 c1_0=c1_0,
                                 c0_1=c0_1,
                                 c1_1=c1_1,
                                 name="ab_v23")
    c0_0, c0_1, c1_0, c1_1 = v23_ab[3][1:]
    ch2_b = models.Polynomial2D(2,
                                c0_0=c0_0,
                                c1_0=c1_0,
                                c0_1=c0_1,
                                c1_1=c1_1,
                                name="v23_ab")
    ch1_for = ch1_v2 & ch1_v3
    ch2_for = ch2_v2 & ch2_v3
    ch1_for.inverse = ch1_a & ch1_b
    ch2_for.inverse = ch2_a & ch2_b
    m[channels[0]] = ch1_for
    m[channels[1]] = ch2_for
    tree['model'] = m

    f = AsdfFile()
    f.tree = tree
    f.write_to(name)