Esempio n. 1
0
def camera2asdf(camera_refname, author, description, useafter):
    try:
        model = pcf2model(camera_refname, name='camera')
    except:
        print("Camera file was not converted.")
        raise
    camera_model = CameraModel(model=model)
    camera_model.meta.author = author
    camera_model.meta.description = description
    camera_model.meta.pedigree = "GROUND"
    camera_model.meta.title = "NIRSPEC CAMERA file"
    camera_model.meta.useafter = useafter
    entry = HistoryEntry({
        'description':
        "New version created from CV3 with updated file structure",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'jwstreftools',
        'author': 'N.Dencheva',
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': "0.7.1"
    })
    entry['software'] = software
    camera_model.history.append(entry)

    return camera_model
Esempio n. 2
0
def create_reffile_header(model):

    model.meta.instrument.name = "MIRI"
    model.meta.instrument.detector = "MIRIMAGE"
    model.meta.instrument.band = "N/A"
    model.meta.instrument.channel = "N/A"
    model.meta.exposure.type = "MIR_IMAGE"
    model.meta.author = "Alistair Glasse, David R. Law"
    model.meta.pedigree = "GROUND"
    model.meta.useafter = "2000-01-01T00:00:00"
    model.meta.reftype = "filteroffset"

    if (model.meta.model_type is 'DistortionModel'):
        model.meta.exposure.p_exptype = "MIR_IMAGE|MIR_TACQ|MIR_LYOT|MIR_4QPM|MIR_CORONCAL|MIR_LRS-FIXEDSLIT|MIR_LRS-SLITLESS|MIR_TACONFIRM|"

    if (model.meta.model_type is 'FilteroffsetModel'):
        model.meta.exposure.p_exptype = "MIR_IMAGE|MIR_TACQ|MIR_LYOT|MIR_4QPM|MIR_CORONCAL|MIR_TACONFIRM|"

    entry = HistoryEntry({
        'description':
        "New version created from CDP-7 with updated filter offset format",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'miricoord',
        'author': 'D.Law',
        'homepage': 'https://github.com/STScI-MIRI/miricoord',
        'version': "master"
    })
    entry['software'] = software
    model.history = [entry]

    return model
Esempio n. 3
0
def create_msa_reference(msa_file,
                         output_name,
                         author=None,
                         description=None,
                         useafter=None):
    f = fits.open(msa_file)
    auth = f[0].header['AUTHOR']
    descrip = f[0].header['DESCR']
    date = f[0].header['DATE']
    f.close()
    if author is None:
        author = auth
    if description is None:
        description = descrip
    if useafter is None:
        useafter = date
    try:
        msa_model = msa2asdf(msa_file, author, description, useafter)
    except:
        raise Exception("MSA file was not converted")
    entry = HistoryEntry({
        'description':
        "New version created from CV3 with updated file structure",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'jwstreftools',
        'author': 'N.Dencheva',
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': "0.7.1"
    })
    entry['software'] = software
    msa_model.history.append(entry)
    msa_model.to_asdf(output_name)
    msa_model.validate()
Esempio n. 4
0
def create_reffile_header(model,
                          detector,
                          band,
                          channel,
                          author,
                          useafter,
                          description=""):
    model.meta.description = description
    model.meta.author = author
    model.meta.useafter = useafter
    model.meta.pedigree = 'GROUND'
    model.meta.instrument.name = "MIRI"
    model.meta.instrument.detector = detector
    model.meta.instrument.channel = channel
    model.meta.instrument.band = band
    model.meta.exposure.type = "MIR_MRS"

    entry = HistoryEntry({
        'description':
        "DOCUMENT: MIRI-TN-00001-ETH_Iss2-1_Calibrationproduct_MRS_d2c.  Updated regions file from CDP-8B.05.01",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'miricoord',
        'author': 'D.Law',
        'homepage': 'https://github.com/STScI-MIRI/miricoord',
        'version': "master"
    })
    entry['software'] = software
    model.history = [entry]

    return model
def create_reffile_header(model):

    model.meta.instrument.name = "MIRI"
    model.meta.instrument.detector = "MIRIMAGE"
    model.meta.instrument.band = "N/A"
    model.meta.instrument.channel = "N/A"
    model.meta.exposure.type = "MIR_IMAGE"
    model.meta.exposure.p_exptype = "MIR_IMAGE|MIR_LRS-FIXEDSLIT|MIR_LRS-SLITLESS|"
    model.meta.author = "Alistair Glasse, David R. Law"
    model.meta.pedigree = "GROUND"
    model.meta.useafter = "2000-01-01T00:00:00"

    entry = HistoryEntry({
        'description':
        "New version created from CDP-7b with updated file structure",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'coordinates',
        'author': 'D.Law',
        'homepage': 'https://github.com/STScI-MIRI/miricoord',
        'version': "master"
    })
    entry['software'] = software
    model.history = [entry]

    return model
Esempio n. 6
0
def create_ote_reference(ote_file, output_name, author=None, description=None,
                         useafter="2016-03-01T09:08:05"):
    f = open(ote_file)
    lines = [l.strip() for l in f.readlines()]
    f.close()
    for i, line in enumerate(lines):
        if 'AUTHOR' in line:
            auth = lines[i + 1]
            continue
        elif 'DESCRIPTION' in line:
            descrip = lines[i + 1]
            continue
        elif 'DATE' in line:
            date = lines[i + 1]
            continue

    if author is None:
        author = auth
    if description is None:
        description = descrip
    if useafter is None:
        useafter = date
    try:
        model = ote2asdf(ote_file, author, description, useafter)
    except:
        raise Exception("OTE file was not converted.")
    entry = HistoryEntry({'description': "New version created from CV3 with updated file structure", 'time': datetime.datetime.utcnow()})
    software = Software({'name': 'jwstreftools', 'author': 'N.Dencheva',
                         'homepage': 'https://github.com/spacetelescope/jwreftools', 'version': "0.7.1"})
    entry['software'] = software
    model.history.append(entry)
    model.to_asdf(output_name)
    model.validate()
Esempio n. 7
0
def create_fore_reference(refdir,
                          author=None,
                          description=None,
                          useafter=None):
    # fore reference file
    for i, filter in enumerate(
        ["CLEAR", "F070LP", "F100LP", "F110W", "F140X", "F170LP", "F290LP"]):
        filename = "Fore_{0}.pcf".format(filter)
        out_name = "fore_cv3_{0}.asdf".format(filter)
        fore_refname = os.path.join(refdir, "CoordTransform", filename)
        with open(fore_refname) as f:
            lines = f.readlines()
        lines = [l.strip() for l in lines]
        for i, line in enumerate(lines):
            if 'AUTHOR' in line:
                auth = lines[i + 1]
                continue
            elif 'DESCRIPTION' in line:
                descrip = lines[i + 1]
                continue
            elif 'DATE' in line:
                date = lines[i + 1]
                continue

        if author is None:
            author = auth
        if description is None:
            description = descrip
        if useafter is None:
            useafter = date

        try:
            model = fore2asdf(fore_refname, name='fore')
        except:
            raise Exception(
                ("FORE file was not created - filter {0}".format(filter)))
        fore_model = FOREModel()
        fore_model.model = model
        fore_model.meta.pedigree = 'GROUND'
        fore_model.meta.author = author
        fore_model.meta.description = description
        fore_model.meta.useafter = useafter
        fore_model.meta.instrument.filter = filter

        entry = HistoryEntry({
            'description':
            "New version created from CV3 with updated file structure",
            'time': datetime.datetime.utcnow()
        })
        software = Software({
            'name': 'jwstreftools',
            'author': 'N.Dencheva',
            'homepage': 'https://github.com/spacetelescope/jwreftools',
            'version': "0.7.1"
        })
        entry['software'] = software
        fore_model.history.append(entry)
        fore_model.to_asdf(out_name)
        fore_model.validate()
Esempio n. 8
0
def create_history_entry(description, software=None):
    """
    Create a HistoryEntry object.

    Parameters
    ----------
    description : str
        Description of the change.
    software : dict or list of dict
        A description of the software used.  It should not include
        asdf itself, as that is automatically notated in the
        `asdf_library` entry.

        Each dict must have the following keys:

        ``name``: The name of the software
        ``author``: The author or institution that produced the software
        ``homepage``: A URI to the homepage of the software
        ``version``: The version of the software

    Examples
    --------
    >>> soft = {'name': 'jwreftools', 'author': 'STSCI',
                'homepage': 'https://github.com/spacetelescope/jwreftools', 'version': "0.7"}
    >>> entry = create_history_entry(description="HISTORY of this file", software=soft)

    """
    from asdf.tags.core import Software, HistoryEntry
    import datetime

    if isinstance(software, list):
        software = [Software(x) for x in software]
    elif software is not None:
        software = Software(software)

    entry = HistoryEntry({
        'description': description,
        'time': datetime.datetime.utcnow()
    })

    if software is not None:
        entry['software'] = software
    return entry
Esempio n. 9
0
def create_ifufore_reference(ifufore_refname,
                             out_name,
                             author=None,
                             description=None,
                             useafter=None):
    #filename = "IFU_FORE.pcf"
    with open(ifufore_refname) as f:
        lines = f.readlines()
    lines = [l.strip() for l in lines]
    for i, line in enumerate(lines):
        if 'AUTHOR' in line:
            auth = lines[i + 1]
            continue
        elif 'DESCRIPTION' in line:
            descrip = lines[i + 1]
            continue
        elif 'DATE' in line:
            date = lines[i + 1]
            continue

    if author is None:
        author = auth
    if description is None:
        description = descrip
    if useafter is None:
        useafter = date
    try:
        model = fore2asdf(ifufore_refname, name='ifufore')
    except:
        print("IFUFORE file was not created.")
        raise
    ifufore_model = IFUFOREModel()
    ifufore_model.model = model
    ifufore_model.meta.pedigree = 'GROUND'
    ifufore_model.meta.author = author
    ifufore_model.meta.description = description
    ifufore_model.meta.useafter = useafter

    entry = HistoryEntry({
        'description':
        "New version created from CV3 with updated file structure",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'jwstreftools',
        'author': 'N.Dencheva',
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': "0.7.1"
    })
    entry['software'] = software
    ifufore_model.history.append(entry)
    ifufore_model.to_asdf(out_name)
    ifufore_model.validate()
Esempio n. 10
0
def create_fpa_reference(fpa_refname,
                         out_name,
                         author=None,
                         description=None,
                         useafter=None):
    with open(fpa_refname) as f:
        lines = f.readlines()
        lines = [l.strip() for l in lines]
    for i, line in enumerate(lines):
        if 'AUTHOR' in line:
            auth = lines[i + 1]
            continue
        elif 'DESCRIPTION' in line:
            descrip = lines[i + 1]
            continue
        elif 'DATE' in line:
            date = lines[i + 1]
            continue

    if author is None:
        author = auth
    if description is None:
        description = descrip
    if useafter is None:
        useafter = date

    try:
        model = fpa2asdf(fpa_refname, author, description, useafter)
    except:
        raise
    entry = HistoryEntry({
        'description':
        "New version created from CV3 with updated file structure",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'jwstreftools',
        'author': 'N.Dencheva',
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': "0.7.1"
    })
    entry['software'] = software
    model.history.append(entry)
    model.to_asdf(out_name)
    model.validate()
Esempio n. 11
0
def create_wavelengthrange_reference(wave_range_file,
                                     output_name,
                                     author=None,
                                     description=None,
                                     useafter=None):
    f = open(wave_range_file)
    lines = [l.strip() for l in f.readlines()]
    f.close()
    for i, line in enumerate(lines):
        if 'AUTHOR' in line:
            auth = lines[i + 1]
            continue
        elif 'DESCRIPTION' in line:
            descrip = lines[i + 1]
            continue
        elif 'DATE' in line:
            date = lines[i + 1]
            continue

    if author is None:
        author = auth
    if description is None:
        description = descrip
    if useafter is None:
        useafter = date

    wr_model = wavelength_range(wave_range_file, author, description, useafter)
    entry = HistoryEntry({
        'description':
        "New version created from CV3 with updated file structure",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'jwstreftools',
        'author': 'N.Dencheva',
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': "0.7.1"
    })
    entry['software'] = software
    wr_model.history.append(entry)
    wr_model.to_asdf(output_name)
    wr_model.validate()
Esempio n. 12
0
    def software_history_entry(self, value: dict):
        """Set the software used for making history entries."""
        if value is None:
            from weldx import __version__ as version

            self._DEFAULT_SOFTWARE_ENTRY = {
                "name": "weldx",
                "author": "BAM",
                "homepage":
                "https://www.bam.de/Content/EN/Projects/WelDX/weldx.html",
                "version": version,
            }
        else:
            if not isinstance(value, Dict):
                raise ValueError("expected a dictionary type")
            try:
                test = AsdfFile(tree=dict(software=Software(value)))
                test.validate()
            except ValidationError as ve:
                raise ValueError(f"Given value has invalid format: {ve}")
            self._DEFAULT_SOFTWARE_ENTRY = value
Esempio n. 13
0
    current_data = msm.Data(name="Welding current", data=I)

    # voltage data
    U_ts = ut.sine(f=Q_(10, "1/s"),
                   amp=Q_(3, "V"),
                   bias=Q_(40, "V"),
                   phase=Q_(0.1, "rad"))
    U = U_ts.interp_time(time)
    U["time"] = U["time"]

    voltage_data = msm.Data(name="Welding voltage", data=U)

    HKS_sensor = msm.GenericEquipment(name="HKS P1000-S3")
    BH_ELM = msm.GenericEquipment(name="Beckhoff ELM3002-0000")
    twincat_scope = Software(name="Beckhoff TwinCAT ScopeView",
                             version="3.4.3143")

    src_current = msm.Source(
        name="Current Sensor",
        output_signal=msm.Signal(signal_type="analog", unit="V", data=None),
        error=msm.Error(Q_(0.1, "percent")),
    )

    HKS_sensor.sources = []
    HKS_sensor.sources.append(src_current)

    from weldx.core import MathematicalExpression

    [a, x, b] = sympy.symbols("a x b")
    current_AD_func = MathematicalExpression(a * x + b)
    current_AD_func.set_parameter("a", Q_(32768.0 / 10.0, "1/V"))
Esempio n. 14
0
def create_grism_waverange(outname="",
                           history="Ground NIRCAM Grismwavelengthrange",
                           author="STScI",
                           filter_range=None):
    """Create a wavelengthrange reference file.

    Supply a filter range dictionary keyed on order or use the default

    """
    ref_kw = common_reference_file_keywords(reftype="wavelengthrange",
                                            title="NIRCAM Grism wavelenghtrange",
                                            description="NIRCAM Grism+Filter Wavelength Ranges",
                                            exp_type="NRC_GRISM",
                                            author=author,
                                            model_type="WavelengthrangeModel",
                                            filename=outname,
                                            )

    if filter_range is None:
        # These numbers from Nor Pirzkal, in microns
        filter_range = {1: {'F250M': [2.500411072, 4.800260833],
                            'F277W': [2.500411072, 3.807062006],
                            'F300M': [2.684896869, 4.025318456],
                            'F322W2': [2.5011293930000003, 4.215842089],
                            'F335M': [3.01459734, 4.260432726],
                            'F356W': [3.001085025, 4.302320901],
                            'F360M': [3.178096344, 4.00099629],
                            'F410M': [3.6267051809999997, 4.5644598],
                            'F430M': [4.04828939, 4.511761774],
                            'F444W': [3.696969216, 4.899565197],
                            'F460M': [3.103778615, 4.881999188],
                            'F480M': [4.5158154679999996, 4.899565197]},
                        2: {'F250M': [2.500411072, 2.667345336],
                            'F277W': [2.500411072, 3.2642254050000004],
                            'F300M': [2.6659796289999997, 3.2997071729999994],
                            'F322W2': [2.5011293930000003, 4.136119434],
                            'F335M': [2.54572003, 3.6780519760000003],
                            'F356W': [2.529505253, 4.133416971],
                            'F360M': [2.557881113, 4.83740855],
                            'F410M': [2.5186954019999996, 4.759037127],
                            'F430M': [2.5362614100000003, 4.541488865],
                            'F444W': [2.5011293930000003, 4.899565197],
                            'F460M': [2.575447122, 4.883350419],
                            'F480M': [2.549773725, 4.899565197]}}

    # array of integers
    orders = list(filter_range.keys())
    orders.sort()

    # same filters for every order, array of strings
    wrange_selector = list(filter_range[orders[0]].keys())
    wrange_selector.sort()

    # The lists below need
    # to remain ordered to be correctly referenced
    wavelengthrange = []
    for order in orders:
        o = []
        for fname in wrange_selector:
            o.append(filter_range[order][fname])
        wavelengthrange.append(o)

    ref = wcs_ref_models.WavelengthrangeModel()
    ref.meta.update(ref_kw)
    ref.meta.exposure.p_exptype = "NRC_GRISM|NRC_TSGRISM"
    ref.meta.input_units = u.micron
    ref.meta.output_units = u.micron
    ref.wrange_selector = wrange_selector
    ref.wrange = wavelengthrange
    ref.order = orders

    entry = HistoryEntry({'description': history, 'time': datetime.datetime.utcnow()})
    sdict = Software({'name': 'nircam_reftools.py',
                      'author': author,
                      'homepage': 'https://github.com/spacetelescope/jwreftools',
                      'version': '0.7.1'})
    entry['sofware'] = sdict
    ref.history['entries'] = [entry]
    ref.to_asdf(outname)
    ref.validate()
Esempio n. 15
0
def create_ifupost_reference(model_dir,
                             out_name,
                             author=None,
                             description=None,
                             useafter=None):
    """
    Create the IFUPOST reference.

    Parameters
    ----------
    model_dir : str
        Directory with the model. it should contain a
        subdirectory ``CoordTransform``.
    out_name : str
        Name for the reference file.
    author : str
        Author field.
    description : str
        Consice description of the file.
    useafter : str
        A useafter date in ISO format.
    """
    model_dir = os.path.join(model_dir, "CoordTransform", "IFU")
    ifupost_list = glob.glob(model_dir + '/IFU-POST*')
    f = open(ifupost_list[0])
    lines = f.readlines()
    f.close()
    lines = [l.strip() for l in lines]
    for i, line in enumerate(lines):
        if 'AUTHOR' in line:
            auth = lines[i + 1]
            continue
        elif 'DESCRIPTION' in line:
            descrip = lines[i + 1]
            continue
        elif 'DATE' in line:
            date = lines[i + 1]
            continue

    if author is None:
        author = auth
    if description is None:
        description = descrip
    if useafter is None:
        useafter = date

    try:
        model = ifupost2asdf(ifupost_list, author, description, useafter)
    except:
        raise Exception("IFUPOST file was not created.")
    entry = HistoryEntry({
        'description':
        "New version created from CV3 with updated file structure",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'jwstreftools',
        'author': 'N.Dencheva',
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': "0.7.1"
    })
    entry['software'] = software
    model.history.append(entry)
    model.to_asdf(out_name)
    model.validate()
Esempio n. 16
0
def create_wavecorr_refs(wzpc_files,
                         outname=None,
                         author=None,
                         description=None,
                         useafter="2015-11-01"):
    """
    Create WAVECORR reference files (Nirspec wavelength zero-point correction).

    Parameters
    ----------
    wzpc_files : list or str
        A list of *slit-*wzprf.fits file names to create the Fixed Slits reference file.
        A file name to create the MSA reference file.
    author : str
        Author. If None it will be read from the first file.
    description : str
        Description of the file. If None will be read from the header.
    useafter : str
        Useafter date.

    """
    model = WaveCorrModel()
    aps = []
    if isinstance(wzpc_files, list):
        # Create a reference file for the Fixed Slits mode.
        model.meta.exposure.type = "NRS_FIXEDSLIT"
        model.meta.exposure.p_exptype = "NRS_FIXEDSLIT|NRS_BRIGHTOBJ|"
        for f in wzpc_files:
            aps.append(
                _wzpc2asdf(f,
                           author=author,
                           description=description,
                           useafter=useafter))
        if description is None:
            description = "Wavelength zero-point reference file for Nirspec fixed slits, computed using a simple toy model."
    elif isinstance(wzpc_files, str):
        model.meta.exposure.type = "NRS_MSASPEC"
        wzpc_files = [wzpc_files]
        aps.append(
            _wzpc2asdf(wzpc_files[0],
                       author=author,
                       description=description,
                       useafter=useafter))
    else:
        raise ValueError(
            "Invalid input - expected a string or a list of strings.")
    f0 = wzpc_files[0]
    model.apertures = aps
    if author is None:
        author = fits.getval(f0, 'AUTHOR')
    if description is None:
        description = fits.getval(f0, 'DESCRIP')
    pedigree = fits.getval(f0, 'PEDIGREE')

    model.meta.author = author
    model.meta.pedigree = pedigree
    model.meta.description = description
    model.meta.useafter = useafter
    model.meta.date = fits.getval(f0, 'date')
    model.meta.origin = fits.getval(f0, 'author')
    model.meta.instrument.p_detector = "NRS1|NRS2|"

    entry = HistoryEntry({
        'description': "NIRSPEC wavelength zero-point correction.",
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'jwstreftools',
        'author': 'N.Dencheva',
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': "0.7.1"
    })
    entry['software'] = software
    model.history.append(entry)
    if outname is None:
        outname = "nirspec_wavecorr.asdf"
    model.to_asdf(outname)
Esempio n. 17
0
def create_grism_config(conffile="",
                        fname="",
                        pupil="",
                        author="STScI",
                        history="NIRISS Grism Parameters",
                        outname=""):
    """
    pupil is the blocking filter
    filter is the grism

    Create an asdf reference file to hold Grism C (column) or Grism R (rows)
    configuration, no sensativity information is included

    Note: The orders are named alphabetically, i.e. Order A, Order B
    There are also sensativity fits files which are tables of wavelength,
    sensativity, and error. These are specified in the conffile but will
    not be read in and saved in the output reference file.

    direct_filter is not specified because it assumes that the wedge
    information (wx,wy) is included in the conf file in one of the key-value
    pairs, where the key includes the beam designation

    For each spectral order, the configuration file contains a pair of
    magnitude-cutoff values. Sources with magnitudes fainter than the
    extraction cutoff (MMAG_EXTRACT_X) are not extracted, but are accounted
    for when computing the spectral contamination and background estimates.
    Sources with magnitudes fainter than the second cutoff (MMAG_MARK_X) are
    completely ignored.  Here, X equals A, B, C, etc., with each letter
    referring to a spectral order, as specified in the configuration file.
     -- the initial conf file that nor gave me didn't have this keyword so
     this code adds a placeholder.

     this reference file also contains the polynomial model which is appropriate
     for the coefficients which are listed.

    Parameters
    ----------
    conffile : str
        The text file with configuration information
    pupil : str
        Name of the grism the conffile corresponds to
    filter : str
        Name of the filter the conffile corresponds to
    author : str
        The name of the author
    history : str
        A comment about the refrence file to be saved with the meta information
    outname : str
        Output name for the reference file


    Returns
    -------
    fasdf : asdf.AsdfFile(jwst.datamodels.NIRISSGrismModel)
    """

    if not history:
        history = "Created from {0:s}".format(conffile)

    # if pupil is none get from filename like NIRCAM_modB_R.conf
    if not fname:
        fname = conffile.split(".")[0]
    if not pupil:
        pupil = conffile.split(".")[1]

    ref_kw = common_reference_file_keywords(reftype="specwcs",
                description="{0:s} dispersion model parameters".format(pupil),
                exp_type="NIS_WFSS",
                model_type='NIRISSGrismModel',
                pupil=pupil,
                filtername=fname,
                history=history,
                author=author,
                filename=outname,
                )

    # get all the key-value pairs from the input file
    conf = dict_from_file(conffile)
    beamdict = split_order_info(conf)
    letter = re.compile("^[a-zA-Z0-9]{0,1}$")  # match one only
    etoken = re.compile("^BEAM_[A-Z,a-z]{1,1}")  # find beam key

    # add min and max mag info if not provided
    # also make beam coeff lists
    # wx are the wedge offsets for the filters
    # in niriss there's a different grism file for each filter

    # for k, bdict in beamdict.items():
    #     if isinstance(bdict, dict):
    #         keys = bdict.keys()
    #         minmag = "MMAG_EXTRACT"
            # maxmag = "MMAG_MARK"
            # if minmag not in keys:
            #     beamdict[k][minmag] = 99.
            # if maxmag not in keys:
            #    beamdict[k][maxmag] = 0.0
            # if "wx" not in keys:
            #    beamdict[k]['wx'] = 0.0
            # if "wy" not in keys:
            #    beamdict[k]['wy'] = 0.0

    # add to the big tree
    # tree['spectral_orders'] = beamdict

    # add the polynomial model for this file.
    # this structure allows there to be a different polynomial relationship
    # for each order if necessary. Either way, the coefficients should be
    # stored with the polynomials since they are directly dependent on
    # each other
    # for order in tree['spectral_orders']:
    #     print("order: {}".format(order))
    #     xc = tree['spectral_orders'][order]["DISPX"]
    #     yc = tree['spectral_orders'][order]["DISPY"]
    #     lc = tree['spectral_orders'][order]["DISPL"]
    #     print("{} {} {}".format(xc, yc, lc))
    #     model = models.PolyTraceDispersion(xc, yc, lc, w)
    #     tree['spectral_orders'][order]['model'] = model

    # The lists below need
    # to remain ordered and referenced by filter or order
    orders = sorted(beamdict.keys())

    # disp[] per sorted order
    displ = []
    dispx = []
    dispy = []
    invdispl = []

    for order in orders:
        # convert the displ wavelengths to microns
        l0 = beamdict[order]['DISPL'][0] / 10000.
        l1 = beamdict[order]['DISPL'][1] / 10000.
        # create polynomials for the coefficients of each order
        invdispl.append(Polynomial1D(1, c0=-l0/l1, c1=1./l1))
        displ.append(Polynomial1D(1, c0=l0, c1=l1))

        # the dispxy functions here are pulled into a 1D
        # such that the final poly is ans = x_model + t*y_model

        e0, e1 = beamdict[order]['DISPX']
        model_x = Polynomial2D(2, c0_0=e0[0], c1_0=e0[1], c2_0=e0[4],
                               c0_1=e0[2], c1_1=e0[5], c0_2=e0[3])
        model_y = Polynomial2D(2, c0_0=e1[0], c1_0=e1[1], c2_0=e1[4],
                               c0_1=e1[2], c1_1=e1[5], c0_2=e1[3])
        dispx.append((model_x, model_y))

        e0, e1 = beamdict[order]['DISPY']
        model_x = Polynomial2D(2, c0_0=e0[0], c1_0=e0[1], c2_0=e0[4],
                               c0_1=e0[2], c1_1=e0[5], c0_2=e0[3])
        model_y = Polynomial2D(2, c0_0=e1[0], c1_0=e1[1], c2_0=e1[4],
                               c0_1=e1[2], c1_1=e1[5], c0_2=e1[3])
        dispy.append((model_x, model_y))
        # disp is x_model + t*y_model
        # invdisp is (t - model_x) / model_y

    # change the orders into translatable integer strings
    # the conf file niriss is giving me are using letter designations
    beam_lookup = {"A": "+1", "B": "0", "C": "+2", "D": "+3", "E": "-1"}
    ordermap = [int(beam_lookup[order]) for order in orders]

    # save the reference file
    ref = NIRISSGrismModel()
    ref.meta.update(ref_kw)
    ref.meta.input_units = u.micron
    ref.meta.output_units = u.micron
    ref.dispx = dispx
    ref.dispy = dispy
    ref.displ = displ
    ref.invdispl = invdispl
    ref.fwcpos_ref = conf['FWCPOS_REF']
    ref.orders = ordermap
    entry = HistoryEntry({'description': history, 'time': datetime.datetime.utcnow()})
    sdict = Software({'name': 'niriss_reftools.py',
                      'author': author,
                      'homepage': 'https://github.com/spacetelescope/jwreftools',
                      'version': '0.7.1'})
    entry['sofware'] = sdict
    ref.history['entries'] = [entry]
    ref.to_asdf(outname)
    ref.validate()
Esempio n. 18
0
def create_grism_waverange(outname="",
                           history="NIRCAM Grism wavelengthrange",
                           author="STScI",
                           module="N/A",
                           pupil="N/A",
                           filter_range=None):
    """Create a wavelengthrange reference file. There is a different file for each filter

    Supply a filter range dictionary or use the default

    """
    ref_kw = common_reference_file_keywords(reftype="wavelengthrange",
                                            title="NIRISS WFSS waverange",
                                            exp_type="NIS_WFSS",
                                            description="NIRISS WFSS Filter Wavelength Ranges",
                                            useafter="2014-01-01T00:00:00",
                                            author=author,
                                            model_type="WavelengthrangeModel",
                                            module=module,
                                            pupil=None,
                                            filename=outname,
                                            filtername=None)

    if filter_range is None:
        # These numbers from Grabriel Brammer, in microns
        # There is only one set of ranges because they are
        # valid for all orders listed, the wavelengthrange
        # file requires a double array by order, so they
        # will be replicated for each order, this allows
        # allows adaptation for future updates per order
        filter_range = {'F090W': [0.79, 1.03],
                        'F115W': [0.97, 1.32],
                        'F140M': [1.29, 1.52],
                        'F150W': [1.29, 1.71],
                        'F158M': [1.41, 1.74],
                        'F200W': [1.70, 2.28]
                        }
        orders = [-1, 0, 1, 2, 3]
    else:
        # array of integers
        orders = list(filter_range.keys())
        orders.sort()

    # same filters for every order, array of strings
    wrange_selector = list(filter_range.keys())
    wrange_selector.sort()

    # The lists below need
    # to remain ordered to be correctly referenced
    wavelengthrange = []
    for order in orders:
        o = []
        for fname in wrange_selector:
            o.append(filter_range[fname])
        wavelengthrange.append(o)

    ref = wcs_ref_models.WavelengthrangeModel()
    ref.meta.update(ref_kw)
    ref.meta.input_units = u.micron
    ref.meta.output_units = u.micron
    ref.wrange_selector = wrange_selector
    ref.wrange = wavelengthrange
    ref.order = orders
    entry = HistoryEntry({'description': history, 'time': datetime.datetime.utcnow()})
    sdict = Software({'name': 'niriss_reftools.py',
                      'author': author,
                      'homepage': 'https://github.com/spacetelescope/jwreftools',
                      'version': '0.7.1'})
    entry['sofware'] = sdict
    ref.history['entries'] = [entry]
    ref.to_asdf(outname)
    ref.validate()
Esempio n. 19
0
def single_pass_weld_example(
    out_file: Optional[Union[str, BytesIO]] = "single_pass_weld_example.asdf",
) -> Optional[tuple[BytesIO, dict]]:
    """Create ASDF file containing all required fields of the single_pass_weld schema.

    Parameters
    ----------
    out_file :
        destination file, if None returns a BytesIO buffer.

    Returns
    -------
    buff, tree
        When writing to memory, return the buffer and the tree (as dictionary).

    """
    # Imports
    import asdf
    import numpy as np
    import pandas as pd
    from asdf.tags.core import Software

    import weldx.geometry as geo
    import weldx.measurement as msm

    # importing the weldx package with prevalent default abbreviations
    import weldx.transformations as tf
    from weldx.asdf.util import get_schema_path, write_buffer, write_read_buffer
    from weldx.constants import META_ATTR, Q_
    from weldx.core import MathematicalExpression, TimeSeries
    from weldx.tags.aws.process.gas_component import GasComponent
    from weldx.tags.aws.process.shielding_gas_for_procedure import (
        ShieldingGasForProcedure, )
    from weldx.tags.aws.process.shielding_gas_type import ShieldingGasType
    from weldx.tags.processes.process import GmawProcess
    from weldx.transformations.local_cs import LocalCoordinateSystem as lcs
    from weldx.transformations.rotation import WXRotation
    from weldx.welding.groove.iso_9692_1 import get_groove
    from weldx.welding.util import sine

    # Timestamp
    reference_timestamp = pd.Timestamp("2020-11-09 12:00:00")

    # Geometry
    # groove + trace = geometry
    groove = get_groove(
        groove_type="VGroove",
        workpiece_thickness=Q_(5, "mm"),
        groove_angle=Q_(50, "deg"),
        root_face=Q_(1, "mm"),
        root_gap=Q_(1, "mm"),
    )

    # define the weld seam length in mm
    seam_length = Q_(300, "mm")

    # create a linear trace segment a the complete weld seam trace
    trace_segment = geo.LinearHorizontalTraceSegment(seam_length)
    trace = geo.Trace(trace_segment)

    geometry = dict(groove_shape=groove, seam_length=seam_length)

    base_metal = dict(common_name="S355J2+N", standard="DIN EN 10225-2:2011")

    workpiece = dict(base_metal=base_metal, geometry=geometry)

    # Setup the Coordinate System Manager (CSM)
    # crete a new coordinate system manager with default base coordinate system
    csm = tf.CoordinateSystemManager("base")

    # add the workpiece coordinate system
    csm.add_cs(
        coordinate_system_name="workpiece",
        reference_system_name="base",
        lcs=trace.coordinate_system,
    )

    tcp_start_point = Q_([5.0, 0.0, 2.0], "mm")
    tcp_end_point = Q_([-5.0, 0.0, 2.0], "mm") + np.append(
        seam_length, Q_([0, 0], "mm"))

    v_weld = Q_(10, "mm/s")
    s_weld = (tcp_end_point - tcp_start_point)[0]  # length of the weld
    t_weld = s_weld / v_weld

    t_start = pd.Timedelta("0s")
    t_end = pd.Timedelta(str(t_weld.to_base_units()))

    rot = WXRotation.from_euler(seq="x", angles=180, degrees=True)

    coords = [tcp_start_point.magnitude, tcp_end_point.magnitude]

    tcp_wire = lcs(coordinates=coords, orientation=rot, time=[t_start, t_end])

    # add the workpiece coordinate system
    csm.add_cs(
        coordinate_system_name="tcp_wire",
        reference_system_name="workpiece",
        lcs=tcp_wire,
    )

    tcp_contact = lcs(coordinates=[0, 0, -10])

    # add the workpiece coordinate system
    csm.add_cs(
        coordinate_system_name="tcp_contact",
        reference_system_name="tcp_wire",
        lcs=tcp_contact,
    )

    TCP_reference = csm.get_cs("tcp_contact", "workpiece")

    # Measurements
    # time
    time = pd.timedelta_range(start="0s", end="10s", freq="2s")

    # current data
    I_ts = sine(f=Q_(10, "1/s"), amp=Q_(20, "A"), bias=Q_(300, "A"))
    current_data = TimeSeries(I_ts.interp_time(time).data, time)

    # voltage data
    U_ts = sine(f=Q_(10, "1/s"),
                amp=Q_(3, "V"),
                bias=Q_(40, "V"),
                phase=Q_(0.1, "rad"))
    voltage_data = TimeSeries(U_ts.interp_time(time).data, time)

    # define current source and transformations

    src_current = msm.SignalSource(
        name="Current Sensor",
        output_signal=msm.Signal(signal_type="analog", units="V", data=None),
        error=msm.Error(Q_(0.1, "percent")),
    )

    current_AD_transform = msm.SignalTransformation(
        name="AD conversion current measurement",
        error=msm.Error(Q_(0.01, "percent")),
        func=MathematicalExpression(
            "a * x + b", dict(a=Q_(32768.0 / 10.0, "1/V"), b=Q_(0.0, ""))),
        type_transformation="AD",
    )

    current_calib_transform = msm.SignalTransformation(
        name="Calibration current measurement",
        error=msm.Error(0.0),
        func=MathematicalExpression(
            "a * x + b", dict(a=Q_(1000.0 / 32768.0, "A"), b=Q_(0.0, "A"))),
    )

    # define voltage source and transformations

    src_voltage = msm.SignalSource(
        name="Voltage Sensor",
        output_signal=msm.Signal("analog", "V", data=None),
        error=msm.Error(Q_(0.1, "percent")),
    )

    voltage_AD_transform = msm.SignalTransformation(
        name="AD conversion voltage measurement",
        error=msm.Error(Q_(0.01, "percent")),
        func=MathematicalExpression(
            "a * x + b", dict(a=Q_(32768.0 / 10.0, "1/V"), b=Q_(0.0, ""))),
        type_transformation="AD",
    )

    voltage_calib_transform = msm.SignalTransformation(
        name="Calibration voltage measurement",
        error=msm.Error(0.0),
        func=MathematicalExpression(
            "a * x + b", dict(a=Q_(100.0 / 32768.0, "V"), b=Q_(0.0, "V"))),
    )

    # Define lab equipment

    HKS_sensor = msm.MeasurementEquipment(
        name="HKS P1000-S3",
        sources=[src_current, src_voltage],
    )
    BH_ELM = msm.MeasurementEquipment(
        name="Beckhoff ELM3002-0000",
        transformations=[current_AD_transform, voltage_AD_transform],
    )

    twincat_scope = Software(name="Beckhoff TwinCAT ScopeView",
                             version="3.4.3143")
    setattr(current_calib_transform, META_ATTR, dict(software=twincat_scope))
    setattr(voltage_calib_transform, META_ATTR, dict(software=twincat_scope))

    # Define current measurement chain

    welding_current_chain = msm.MeasurementChain.from_equipment(
        name="welding current measurement chain",
        equipment=HKS_sensor,
        source_name="Current Sensor",
    )
    welding_current_chain.add_transformation_from_equipment(
        equipment=BH_ELM,
        transformation_name="AD conversion current measurement",
    )
    welding_current_chain.add_transformation(
        transformation=current_calib_transform,
        data=current_data,
    )

    # Define voltage measurement chain

    welding_voltage_chain = msm.MeasurementChain.from_equipment(
        name="welding voltage measurement chain",
        equipment=HKS_sensor,
        source_name="Voltage Sensor",
    )
    welding_voltage_chain.add_transformation_from_equipment(
        equipment=BH_ELM,
        transformation_name="AD conversion voltage measurement",
    )
    welding_voltage_chain.add_transformation(
        transformation=voltage_calib_transform,
        data=voltage_data,
    )

    # Define measurements

    welding_current = msm.Measurement(
        name="welding current measurement",
        data=[current_data],
        measurement_chain=welding_current_chain,
    )

    welding_voltage = msm.Measurement(
        name="welding voltage measurement",
        data=[voltage_data],
        measurement_chain=welding_voltage_chain,
    )

    # GMAW Process
    params_pulse = dict(
        wire_feedrate=Q_(10.0, "m/min"),
        pulse_voltage=Q_(40.0, "V"),
        pulse_duration=Q_(5.0, "ms"),
        pulse_frequency=Q_(100.0, "Hz"),
        base_current=Q_(60.0, "A"),
    )
    process_pulse = GmawProcess(
        "pulse",
        "CLOOS",
        "Quinto",
        params_pulse,
        tag="CLOOS/pulse",
        meta={"modulation": "UI"},
    )

    gas_comp = [
        GasComponent("argon", Q_(82, "percent")),
        GasComponent("carbon dioxide", Q_(18, "percent")),
    ]
    gas_type = ShieldingGasType(gas_component=gas_comp, common_name="SG")

    gas_for_procedure = ShieldingGasForProcedure(
        use_torch_shielding_gas=True,
        torch_shielding_gas=gas_type,
        torch_shielding_gas_flowrate=Q_(20, "l / min"),
    )

    process = dict(
        welding_process=process_pulse,
        shielding_gas=gas_for_procedure,
        weld_speed=TimeSeries(v_weld),
        welding_wire={"diameter": Q_(1.2, "mm")},
    )

    # ASDF file
    tree = dict(
        reference_timestamp=reference_timestamp,
        equipment=[HKS_sensor, BH_ELM],
        measurements=[welding_current, welding_voltage],
        welding_current=welding_current_chain.get_signal(
            "Calibration current measurement").data,
        welding_voltage=welding_voltage_chain.get_signal(
            "Calibration voltage measurement").data,
        coordinate_systems=csm,
        TCP=TCP_reference,
        workpiece=workpiece,
        process=process,
    )
    tree[META_ATTR] = {"welder": "A.W. Elder"}

    model_path = get_schema_path("single_pass_weld-0.1.0.yaml")

    # pre-validate?
    write_read_buffer(
        tree,
        asdffile_kwargs=dict(custom_schema=str(model_path)),
    )

    if out_file:
        with asdf.AsdfFile(
                tree,
                custom_schema=str(model_path),
        ) as ff:
            ff.write_to(out_file, all_array_storage="inline")
    else:
        return (
            write_buffer(
                tree,
                asdffile_kwargs=dict(custom_schema=str(model_path)),
                write_kwargs=dict(all_array_storage="inline"),
            ),
            tree,
        )
def create_grism_specwcs(conffile="",
                         pupil=None,
                         direct_filter=None,
                         author="STScI",
                         history="",
                         outname=None):
    """
    Note: This code is shamelessly stolen from the jwreftools package
    (see https://github.com/spacetelescope/jwreftools/) and adapted for use
    on HST GRISMCONF files. The docstrings and comments have not yet been
    updated accordingly.

    Create an asdf reference file to hold grism configuration information. No
    sensitivity information is included

    Note: The orders are named alphabetically, i.e. Order A, Order B
    There are also sensativity fits files which are tables of wavelength,
    sensativity, and error. These are specified in the conffile but will
    not be read in and saved in the output reference file for now.
    It's possible they may be included in the future, either here or as
    a separate reference files. Their use here would be to help define the
    min and max wavelengths which set the extent of the dispersed trace on
    the grism image. Convolving the sensitiviy file with the filter throughput
    allows one to calculate the wavelength of minimum throughput which defines
    the edges of the trace.

    direct_filter is not specified because it assumes that the wedge
    information (wx,wy) is included in the conf file in one of the key-value
    pairs, where the key includes the beam designation

     this reference file also contains the polynomial model which is
     appropriate for the coefficients which are listed.
     wavelength = DISPL(order,x0,y0,t)
     dx = DISPX(order,x0,y0,t)
     dy = DISPY(order,x0,y0,t)

     t = INVDISPX(order,x0,y0,dx)
     t = INVDISPY(order,x0,y0,dy)
     t = INVDISL(order,x0,y0, wavelength)



    Parameters
    ----------
    conffile : str
        The text file with configuration information, formatted as aXe expects
    pupil : str
        Name of the grism the conffile corresponds to
        Taken from the conffile name if not specified
    module : str
        Name of the Nircam module
        Taken from the conffile name if not specified
    author : str
        The name of the author
    history : str
        A comment about the refrence file to be saved with the meta information
    outname : str
        Output name for the reference file

    Returns
    -------
    fasdf : asdf.AsdfFile(WFC3IRGrismModel)

    """
    if outname is None:
        outname = "wfc3_ir_specwcs.asdf"
    if not history:
        history = "Created from {0:s}".format(conffile)

    # if pupil is none get from filename like NIRCAM_modB_R.conf
    if pupil is None:
        pupil = "GRISM" + conffile.split(".")[0][-1]
    print("Pupil is {}".format(pupil))

    ref_kw = common_reference_file_keywords(
        reftype="specwcs",
        title="HST IR Grism Parameters",
        description="{0:s} dispersion models".format(pupil),
        exp_type="WFC3_IR",
        author=author,
        model_type="WFC3IRGrismModel",
        fname=direct_filter,
        pupil=pupil,
        filename=outname,
    )

    # get all the key-value pairs from the input file
    conf = dict_from_file(conffile)
    beamdict = split_order_info(conf)

    # Get x and y offsets from the filter, if necessary
    if direct_filter is not None:
        wx = beamdict["WEDGE"][direct_filter][0]
        wy = beamdict["WEDGE"][direct_filter][0]
    else:
        wx, wy = 0, 0

    beamdict.pop("WEDGE")

    # beam = re.compile('^(?:[+\-]){0,1}[a-zA-Z0-9]{0,1}$')  # match beam only
    # read in the sensitivity tables to save their content
    # they currently have names like this: NIRCam.A.1st.sensitivity.fits
    # translated as inst.beam/order.param
    temp = dict()
    etoken = re.compile("^[a-zA-Z]*_(?:[+\-]){1,1}[1,2]{1,1}")  # find beam key
    for b, bdict in beamdict.items():
        temp[b] = dict()

    # add the new beam information to beamdict and remove spurious beam info
    for k in temp:
        for kk in temp[k]:
            if etoken.match(kk):
                kk = kk.replace("_{}".format(k), "")
            beamdict[k][kk] = temp[k][kk]

    # for NIRCAM, the R and C grism coefficients contain zeros where
    # the dispersion is in the opposite direction. Meaning, the GRISMR,
    # which disperses along ROWS has coefficients of zero in the y models
    # and vice versa.
    #
    # There are separate reference files for each grism. Depending on the grism
    # dispersion direction you either want to use the dx from source center or
    # the dy from source center in the inverse dispersion relationship which is
    # used to calculate the t value needed to calculate the wavelength at that
    # pixel.
    # The model creation here takes all of this into account by looking at the
    # GRISM[R/C] the file is used for and creating a reference model with the
    # appropriate dispersion direction in use. This eliminates having to decide
    # which direction to calculatethe dispersion from given the input x,y
    # pixel in the dispersed image.
    orders = beamdict.keys()

    # dispersion models valid per order and direction saved to reference file
    # Forward
    invdispl = []
    invdispx = []
    invdispy = []
    # Backward
    displ = []
    dispx = []
    dispy = []

    for order in orders:
        # convert the displ wavelengths to microns if the input
        # file is still in angstroms
        l0 = beamdict[order]['DISPL'][0] / 10000.
        l1 = beamdict[order]['DISPL'][1] / 10000.

        # create polynomials using the coefficients of each order

        # This holds the wavelength lookup coeffs
        # This model is  INVDISPL for backward and returns t
        # This model should be DISPL for forward and returns wavelength
        if l1 == 0:
            lmodel = Polynomial1D(1, c0=0, c1=0)
        else:
            lmodel = Polynomial1D(1, c0=-l0 / l1, c1=1. / l1)
        invdispl.append(lmodel)
        lmodel = Polynomial1D(1, c0=l0, c1=l1)
        displ.append(lmodel)

        # This holds the x coefficients, for the R grism this model is the
        # the INVDISPX returning t, for the C grism this model is the DISPX
        e = beamdict[order]['DISPX']
        xmodel = DISPXY_Model(e, wx)
        dispx.append(xmodel)
        inv_xmodel = DISPXY_Model(e, wx, inv=True)
        invdispx.append(inv_xmodel)

        # This holds the y coefficients, for the C grism, this model is
        # the INVDISPY, returning t, for the R grism, this model is the DISPY
        e = beamdict[order]['DISPY']
        ymodel = DISPXY_Model(e, wy)
        dispy.append(ymodel)
        inv_ymodel = DISPXY_Model(e, wy, inv=True)
        invdispy.append(ymodel)

    # change the orders into translatable integers
    # so that we can look up the order with the proper index
    oo = [int(o) for o in beamdict]

    # We need to register the converter for the DISPXY_Model class with asdf
    asdf.get_config().add_extension(DISPXY_Extension())

    ref = WFC3IRGrismModel()
    ref.meta.update(ref_kw)
    # This reference file is good for NRC_WFSS and TSGRISM modes
    ref.meta.exposure.p_exptype = "NRC_WFSS|NRC_TSGRISM"
    ref.meta.input_units = u.micron
    ref.meta.output_units = u.micron
    ref.displ = displ
    ref.dispx = dispx
    print(ref.dispx)
    ref.dispy = dispy
    print(ref.dispy)
    ref.invdispx = invdispx
    ref.invdispy = invdispy
    ref.invdispl = invdispl
    ref.order = oo
    history = HistoryEntry({
        'description': history,
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'nircam_reftools.py',
        'author': author,
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': '0.7.1'
    })
    history['software'] = software
    ref.history = [history]
    ref.to_asdf(outname)
    ref.validate()
def create_wfss_wavelengthrange(outname="nircam_wfss_wavelengthrange.asdf",
                                history="Ground NIRCAM Grism wavelengthrange",
                                author="STScI",
                                wavelengthrange=None,
                                extract_orders=None):
    """Create a wavelengthrange reference file for NIRCAM.

    Parameters
    ----------
    outname: str
        The output name of the file
    history: str
        History information about it's creation
    author: str
        Person or entity making the file
    wavelengthrange: list(tuples)
        A list of tuples that set the order, filter, and
        wavelength range min and max
    extract_orders: list[list]
        A list of lists that specify

    """
    ref_kw = common_reference_file_keywords(
        reftype="wavelengthrange",
        title="NIRCAM WFSS reference file",
        description="NIRCAM Grism-Filter Wavelength Ranges",
        exp_type="NRC_WFSS",
        author=author,
        pupil="ANY",
        model_type="WavelengthrangeModel",
        filename=outname,
    )

    if wavelengthrange is None:
        # This is a list of tuples that specify the
        # order, filter, wave min, wave max
        wavelengthrange = [
            (1, 'F250M', 2.500411072, 4.800260833),
            (1, 'F277W', 2.500411072, 3.807062006),
            (1, 'F300M', 2.684896869, 4.025318456),
            (1, 'F322W2', 2.5011293930000003, 4.215842089),
            (1, 'F335M', 3.01459734, 4.260432726),
            (1, 'F356W', 3.001085025, 4.302320901),
            (1, 'F360M', 3.178096344, 4.00099629),
            (1, 'F410M', 3.6267051809999997, 4.5644598),
            (1, 'F430M', 4.04828939, 4.511761774),
            (1, 'F444W', 3.696969216, 4.899565197),
            (1, 'F460M', 3.103778615, 4.881999188),
            (1, 'F480M', 4.5158154679999996, 4.899565197),
            (2, 'F250M', 2.500411072, 2.667345336),
            (2, 'F277W', 2.500411072, 3.2642254050000004),
            (2, 'F300M', 2.6659796289999997, 3.2997071729999994),
            (2, 'F322W2', 2.5011293930000003, 4.136119434),
            (2, 'F335M', 2.54572003, 3.6780519760000003),
            (2, 'F356W', 2.529505253, 4.133416971),
            (2, 'F360M', 2.557881113, 4.83740855),
            (2, 'F410M', 2.5186954019999996, 4.759037127),
            (2, 'F430M', 2.5362614100000003, 4.541488865),
            (2, 'F444W', 2.5011293930000003, 4.899565197),
            (2, 'F460M', 2.575447122, 4.883350419),
            (2, 'F480M', 2.549773725, 4.899565197),
        ]
    # array of integers of unique orders
    orders = sorted(set((x[0] for x in wavelengthrange)))
    filters = sorted(set((x[1] for x in wavelengthrange)))

    # Nircam has not specified any limitation on the orders
    # that should be extracted by default yet so all are
    # included.
    if extract_orders is None:
        extract_orders = []
        for f in filters:
            extract_orders.append([f, orders])

    ref = wcs_ref_models.WavelengthrangeModel()
    ref.meta.update(ref_kw)
    ref.meta.exposure.p_exptype = "NRC_WFSS"
    ref.meta.input_units = u.micron
    ref.meta.output_units = u.micron
    ref.wavelengthrange = wavelengthrange
    ref.extract_orders = extract_orders
    ref.order = orders
    ref.waverange_selector = filters

    history = HistoryEntry({
        'description': history,
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'nircam_reftools.py',
        'author': author,
        'homepage': 'https://github.com/spacetelescope/jwreftools',
        'version': '0.7.1'
    })
    history['software'] = software
    ref.history = [history]
    ref.validate()
    ref.to_asdf(outname)
def create_tsgrism_wavelengthrange(outname="wfc3_tsgrism_wavelengthrange.asdf",
                                   history="WFC3 TSGrism wavelengthrange",
                                   author="STScI",
                                   wavelengthrange=None,
                                   extract_orders=None):
    """Create a wavelengthrange reference file for WFC3 TSGRISM mode.

    Parameters
    ----------
    outname: str
        The output name of the file
    history: str
        History information about it's creation
    author: str
        Person or entity making the file
    wavelengthrange: list(tuples)
        A list of tuples that set the order, filter, and
        wavelength range min and max
    extract_orders: list[list]
        A list of lists that specify

    """
    ref_kw = common_reference_file_keywords(
        reftype="wavelengthrange",
        title="WFC3 TSGRISM reference file",
        description="WFC3 Grism-Filter Wavelength Ranges",
        exp_type="WFC3_TSGRISM",
        author=author,
        pupil="ANY",
        model_type="WavelengthrangeModel",
        filename=outname,
    )

    if wavelengthrange is None:
        # This is a list of tuples that specify the
        # order, filter, wave min, wave max
        wavelengthrange = [
            (-1, 'G102', 0.7488958984375, 1.1496958984375),
            (0, 'G102', 0.7401, 1.2297),
            (1, 'G102', 0.7496, 1.1979),
            (2, 'G102', 0.7401, 1.1897),
            (3, 'G102', 0.7571, 0.9878),
            (-1, 'G141', 1.031, 1.7845),
            (0, 'G141', 1.0402, 1.6998),
            (1, 'G141', 0.9953, 1.7697),
            (2, 'G141', 0.9702, 1.5903),
            (3, 'G141', 1.0068, 1.3875),
            (4, 'G141', 1.031, 1.7845),
        ]

    # array of integers of unique orders
    orders = sorted(set((x[0] for x in wavelengthrange)))
    filters = sorted(set((x[1] for x in wavelengthrange)))

    # Nircam has not specified any limitation on the orders
    # that should be extracted by default yet so all are
    # included.
    if extract_orders is None:
        extract_orders = [
            ('G102', [1]),
            ('G141', [1]),
        ]

    ref = wcs_ref_models.WavelengthrangeModel()
    ref.meta.update(ref_kw)
    ref.meta.exposure.p_exptype = "WFC3_TSGRISM"
    ref.meta.input_units = u.micron
    ref.meta.output_units = u.micron
    ref.wavelengthrange = wavelengthrange
    ref.extract_orders = extract_orders
    ref.order = orders
    ref.waverange_selector = filters

    history = HistoryEntry({
        'description': history,
        'time': datetime.datetime.utcnow()
    })
    software = Software({
        'name': 'wfc3_reftools.py',
        'author': author,
        'homepage': 'https://github.com/spacetelescope/astrogrism_sandbox',
        'version': '0.0.0'
    })
    history['software'] = software
    ref.history = [history]
    ref.validate()
    ref.to_asdf(outname)
Esempio n. 23
0
def create_grism_config(conffile="",
                        pupil=None,
                        module=None,
                        author="STScI",
                        history="",
                        outname=""):
    """
    Create an asdf reference file to hold Grism C (column) or Grism R (rows)
    configuration, no sensativity information is included

    Note: The orders are named alphabetically, i.e. Order A, Order B
    There are also sensativity fits files which are tables of wavelength,
    sensativity, and error. These are specified in the conffile but will
    not be read in and saved in the output reference file for now.
    It's possible they may be included in the future, either here or as
    a separate reference files. Their use here would be to help define the
    min and max wavelengths which set the extent of the dispersed trace on
    the grism image. Convolving the sensitiviy file with the filter throughput
    allows one to calculate the wavelength of minimum throughput which defines
    the edges of the trace.

    direct_filter is not specified because it assumes that the wedge
    information (wx,wy) is included in the conf file in one of the key-value
    pairs, where the key includes the beam designation

     this reference file also contains the polynomial model which is appropriate
     for the coefficients which are listed.
     wavelength = DISPL(order,x0,y0,t)
     dx = DISPX(order,x0,y0,t)
     dy = DISPY(order,x0,y0,t)

     t = INVDISPX(order,x0,y0,dx)
     t = INVDISPY(order,x0,y0,dy)
     t = INVDISL(order,x0,y0, wavelength)



    Parameters
    ----------
    conffile : str
        The text file with configuration information, formatted as aXe expects
    pupil : str
        Name of the grism the conffile corresponds to
        Taken from the conffile name if not specified
    module : str
        Name of the Nircam module
        Taken from the conffile name if not specified
    author : str
        The name of the author
    history : str
        A comment about the refrence file to be saved with the meta information
    outname : str
        Output name for the reference file

    Returns
    -------
    fasdf : asdf.AsdfFile(jwst.datamodels.NIRCAMGrismModel)

    """
    if not history:
        history = "Created from {0:s}".format(conffile)

    # if pupil is none get from filename like NIRCAM_modB_R.conf
    if pupil is None:
        pupil = "GRISM" + conffile.split(".")[0][-1]
    # if module is none get from filename
    if module is None:
        module = conffile.split(".")[0][-3]
    print("Pupil is {}".format(pupil))

    ref_kw = common_reference_file_keywords(reftype="specwcs",
                                            title="NIRCAM Grism Parameters",
                                            description="{0:s} dispersion models".format(pupil),
                                            exp_type="NRC_GRISM",
                                            author=author,
                                            model_type="NIRCAMGrismModel",
                                            module=module,
                                            pupil=pupil,
                                            filename=outname,
                                            )


    # get all the key-value pairs from the input file
    conf = dict_from_file(conffile)
    beamdict = split_order_info(conf)
    # beam = re.compile('^(?:[+\-]){0,1}[a-zA-Z0-9]{0,1}$')  # match beam only
    # read in the sensitivity tables to save their content
    # they currently have names like this: NIRCam.A.1st.sensitivity.fits
    # translated as inst.beam/order.param
    temp = dict()
    etoken = re.compile("^[a-zA-Z]*_(?:[+\-]){1,1}[1,2]{1,1}")  # find beam key
    for b, bdict in beamdict.items():
            temp[b] = dict()
            # for key in bdict:
                # if 'SENSITIVITY' in key:
                #     print("Reading sensitivity from: {0:s}".format(bdict[key]))
                #     sdata = read_sensitivity_file(bdict[key])
                #     skeys = sdata.keys()
                #     for k in skeys:
                #         temp[b][key+"_"+k] = sdata[k]

    # add the new beam information to beamdict and remove spurious beam info
    for k in temp:
        for kk in temp[k]:
            if etoken.match(kk):
                kk = kk.replace("_{}".format(k), "")
            beamdict[k][kk] = temp[k][kk]

    # add min and max mag info if not provided
    # also make beam coeff lists
    # wx are the wedge offsets for the filters

    # for k, bdict in beamdict.items():
    #     if isinstance(bdict, dict):
    #         keys = bdict.keys()
    #         if "MMAG_EXTRACT" not in keys:
    #             beamdict[k]["MMAG_EXTRACT"] = 99.0
            # if maxmag not in keys:
            #    beamdict[k][maxmag] = 0.0
            # if "wx" not in keys:
            #    beamdict[k]['wx'] = 0.0
            # if "wy" not in keys:
            #    beamdict[k]['wy'] = 0.0
            # add the model for transforms



    # for NIRCAM, the R and C grism coefficients contain zeros where
    # the dispersion is in the opposite direction. Meaning, the GRISMR,
    # which disperses along ROWS has coefficients of zero in the y models
    # and vice versa.
    #
    # There are separate reference files for each grism. Depending on the grism
    # dispersion direction you either want to use the dx from source center or
    # the dy from source center in the inverse dispersion relationship which is
    # used to calculate the t value needed to calculate the wavelength at that pixel.
    #
    # The model creation here takes all of this into account by looking at the GRISM[R/C]
    # the file is used for and creating a reference model with the appropriate dispersion
    # direction in use. This eliminates having to decide which direction to calculate
    # the dispersion from given the input x,y pixel in the dispersed image.
    orders = beamdict.keys()

    # dispersion models valid per order and direction saved to reference file
    # Forward
    invdispl = []
    invdispx = []
    invdispy = []
    # Backward
    displ = []
    dispx = []
    dispy = []

    for order in orders:
        # convert the displ wavelengths to microns if the input file is still in angstroms
        l0 = beamdict[order]['DISPL'][0] / 10000.
        l1 = beamdict[order]['DISPL'][1] / 10000.

        # create polynomials using the coefficients of each order

        # This holds the wavelength lookup coeffs
        # This model is  INVDISPL for backward and returns t
        # This model should be DISPL for forward and returns wavelength
        if l1 == 0:
            lmodel = Polynomial1D(1, c0=0, c1=0)
        else:
            lmodel = Polynomial1D(1, c0=-l0/l1, c1=1./l1)
        invdispl.append(lmodel)
        lmodel = Polynomial1D(1, c0=l0, c1=l1)
        displ.append(lmodel)

        # This holds the x coefficients, for the R grism this model is the
        # the INVDISPX returning t, for the C grism this model is the DISPX
        x0, x1 = beamdict[order]['DISPX']
        xmodel = Polynomial1D(1, c0=x0, c1=x1)
        dispx.append(xmodel)
        if x1 == 0:
            xmodel = Polynomial1D(1, c0=0, c1=0)
        else:
            xmodel = Polynomial1D(1, c0=-x0/x1, c1=1./x1)
        invdispx.append(xmodel)

        # This holds the y coefficients, for the C grism, this model is
        # the INVDISPY, returning t, for the R grism, this model is the DISPY
        y0, y1 = beamdict[order]['DISPY']
        ymodel = Polynomial1D(1, c0=y0, c1=y1)
        dispy.append(ymodel)
        if y1 == 0:
            ymodel = Polynomial1D(1, c0=0, c1=0)
        else:
            ymodel = Polynomial1D(1, c0=-y0/y1, c1=1./y1)
        invdispy.append(ymodel)

    # change the orders into translatable integers
    # so that we can look up the order with the proper index
    oo = [int(o) for o in beamdict]

    ref = NIRCAMGrismModel()
    ref.meta.update(ref_kw)
    # This reference file is good for NRC_GRISM and TSGRISM modes
    ref.meta.exposure.p_exptype = "NRC_GRISM|NRC_TSGRISM"
    ref.meta.input_units = u.micron
    ref.meta.output_units = u.micron
    ref.displ = displ
    ref.dispx = dispx
    ref.dispy = dispy
    ref.invdispx = invdispx
    ref.invdispy = invdispy
    ref.invdispl = invdispl
    ref.orders = oo
    entry = HistoryEntry({'description': history, 'time': datetime.datetime.utcnow()})
    sdict = Software({'name': 'nircam_reftools.py',
             'author': author,
             'homepage': 'https://github.com/spacetelescope/jwreftools',
             'version': '0.7.1'})
    entry['sofware'] = sdict
    ref.history['entries'] = [entry]
    ref.to_asdf(outname)
    ref.validate()