Пример #1
0
    def from_fits(cls, filename, chk_version=True):
        """

        Args:
            filename (str):
            chk_version (bool, optional):
                If True, demand the on-disk datamodel equals the current
                Passed to from_hdu() of DataContainer

        Returns:
            :class:`AllSpec2DObj`:

        """
        # Instantiate
        slf = cls()
        # Open
        hdul = io.fits_open(filename)
        # Meta
        hkeys = list(hdul[0].header.keys())
        for key in hkeys:
            if slf.hdr_prefix in key:
                slf['meta'][key.split(slf.hdr_prefix)[-1]] = hdul[0].header[key]
        # Detectors included
        detectors = hdul[0].header[slf.hdr_prefix+'DETS']
        for det in [int(item) for item in detectors.split(',')]:
            obj = Spec2DObj.from_hdu(hdul, hdu_prefix=spec2d_hdu_prefix(det), chk_version=chk_version)
            slf[det] = obj
        # Header
        slf['meta']['head0'] = hdul[0].header
        return slf
Пример #2
0
def append_NIRCam():
    # Load
    hdulist = io.fits_open('filtercurves.fits')
    curr_filters = [hdu.name for hdu in hdulist]
    #
    nircam = Table.read(
        'nircam_filter/nircam_modABmean_plus_ote_filter_properties.txt',
        format='ascii.basic')
    filters = nircam['Filter']
    for filt in filters:
        flt_name = 'NIRCAM-{}'.format(filt)
        if flt_name in curr_filters:
            print("Filter {} already there, skipping".format(flt_name))
            continue
        # load in the transmission
        filt_table = Table.read(
            'nircam_filter/{:}_NRC_and_OTE_ModAB_mean.txt'.format(filt),
            format='ascii.basic')
        wave = filt_table['microns'] * 1e4
        trans = filt_table['throughput']
        # Add it
        hdu = tohdu(wave, trans, flt_name)
        hdulist.append(hdu)
    # Write
    hdulist.writeto('filtercurves.fits', overwrite=True)
Пример #3
0
    def bpm(self, filename, det, shape=None, msbias=None):
        """
        Override parent bpm function with BPM specific to P200 DBSPr.

        Parameters
        ----------
        det : int, REQUIRED
        msbias : numpy.ndarray, required if the user wishes to generate a BPM based on a master bias

        Returns
        -------
        bpix : ndarray
          0 = ok; 1 = Mask

        """
        msgs.info("Custom bad pixel mask for DBSPr")
        bpm_img = self.empty_bpm(filename, det, shape=shape)

        # Fill in bad pixels if a master bias frame is provided
        if msbias is not None:
            return self.bpm_frombias(msbias, bpm_img)

        # Red CCD detector defect is present in data taken 2020-05-22
        # and absent in data taken 2020-04-21
        DEFECT_DATE = Time('2020-05-21')
        # TODO: Model the growth of the detector defect with time.
        # TODO: Get more precise date range for detector.
        with io.fits_open(filename) as hdul:
            if Time(hdul[0].header['UTSHUT']) > DEFECT_DATE:
                spec_binning = int(self.get_meta_value([hdul[0].header], 'binning').split(',')[0])
                bpm_img[464 // spec_binning : 723 // spec_binning, :] = 1

        return bpm_img
Пример #4
0
def test_coadd1d_1():
    """
    Test basic coadd using shane_kast_blue
    """
    # NOTE: flux_value is False
    parfile = 'coadd1d.par'
    if os.path.isfile(parfile):
        os.remove(parfile)
    coadd_ofile = data_path('J1217p3905_coadd.fits')
    if os.path.isfile(coadd_ofile):
        os.remove(coadd_ofile)

    coadd_ifile = data_path('shane_kast_blue.coadd1d')
    coadd_1dspec.main(
        coadd_1dspec.parse_args(
            [coadd_ifile, '--test_spec_path',
             data_path('')]))

    hdu = io.fits_open(coadd_ofile)
    assert hdu[1].header['EXT_MODE'] == 'OPT'
    assert hdu[1].header['FLUXED'] is False

    # Clean up
    hdu.close()
    os.remove(parfile)
    os.remove(coadd_ofile)
Пример #5
0
def load_multiext_fits(filename, ext):
    """
    Load data and primary header from a multi-extension FITS file

    Args:
        filename (:obj:`str`):
            Name of the file.
        ext (:obj:`str`, :obj:`int`, :obj:`list`):
            One or more file extensions with data to return.  The
            extension can be designated by its 0-indexed integer
            number or its name.

    Returns:
        tuple: Returns the image data from each provided extension.
        If return_header is true, the primary header is also
        returned.
    """
    # Format the input and set the tuple for an empty return
    _ext = ext if isinstance(ext, list) else [ext]
    n_ext = len(_ext)
    # Open the file
    hdu = io.fits_open(filename)
    head0 = hdu[0].header
    # Only one extension
    if n_ext == 1:
        data = hdu[_ext[0]].data.astype(np.float)
        return data, head0
    # Multiple extensions
    data = tuple([
        None if hdu[k].data is None else hdu[k].data.astype(np.float)
        for k in _ext
    ])
    # Return
    return data + (head0, )
Пример #6
0
def test_case():
    # Remove file if it exists
    ofile = 'test.fits.gz'
    if os.path.isfile(ofile):
        os.remove(ofile)

    # Instantiate
    data = MixedCaseContainer(np.arange(10), 5, 8.2)

    # Attributes and items are case-sensitive
    with pytest.raises(AttributeError):
        data.uppercase = 3
    with pytest.raises(KeyError):
        data['LOWERCASE'] = 3
    with pytest.raises(AttributeError):
        data.cAMELcASE = 3

    # HDU items are not
    data.to_file(ofile)
    with fits_open(ofile) as hdu:
        assert hdu['mixedcase'].header['UpPeRcAsE'] == 5, 'Bad header access'
        assert hdu['mixedcase'].header['CaMeLcAsE'] == 8.2, 'Bad header access'

    # And everything is as it should be when you read it back in
    _data = MixedCaseContainer.from_file(ofile)
    assert _data.UPPERCASE == 5, 'Bad file read'

    # Clean up
    os.remove(ofile)
Пример #7
0
def test_coadd1d_2():
    """
    Test combining Echelle
    """
    # NOTE: flux_value is False
    parfile = 'coadd1d.par'
    if os.path.isfile(parfile):
        os.remove(parfile)
    coadd_ofile = data_path('pisco_coadd.fits')
    if os.path.isfile(coadd_ofile):
        os.remove(coadd_ofile)

    coadd_ifile = data_path('gemini_gnirs_32_sb_sxd.coadd1d')
    coadd_1dspec.main(
        coadd_1dspec.parse_args(
            [coadd_ifile, '--test_spec_path',
             data_path('')]))

    hdu = io.fits_open(coadd_ofile)
    assert hdu[1].header['EXT_MODE'] == 'OPT'
    assert hdu[1].header['FLUXED'] is False

    # Clean up
    hdu.close()
    os.remove(parfile)
    os.remove(coadd_ofile)
Пример #8
0
    def from_fits(cls, filename, chk_version=True):
        """

        Args:
            filename (:obj:`str`):
                Name of the file to read.
            chk_version (:obj:`bool`, optional):
                If True, demand the on-disk datamodel equals the current one.
                Passed to from_hdu() of DataContainer.

        Returns:
            :class:`~pypeit.spec2dobj.AllSpec2DObj`: The constructed object.
        """
        # Instantiate
        self = cls()
        # Open
        hdul = io.fits_open(filename)
        # Meta
        for key in hdul[0].header.keys():
            if key == self.hdr_prefix + 'DETS':
                continue
            if self.hdr_prefix in key:
                meta_key = key.split(self.hdr_prefix)[-1].lower()
                self['meta'][meta_key] = hdul[0].header[key]
        # Detectors included
        detectors = hdul[0].header[self.hdr_prefix + 'DETS']
        for detname in detectors.split(','):
            self[detname] = Spec2DObj.from_hdu(hdul,
                                               hdu_prefix=f'{detname}-',
                                               chk_version=chk_version)
        return self
Пример #9
0
    def from_file(cls, file, detname, chk_version=True):
        """
        Overload :func:`pypeit.datamodel.DataContainer.from_file` to allow det
        input and to slurp the header

        Args:
            file (:obj:`str`):
                File name to read.
            detname (:obj:`str`):
                The string identifier for the detector or mosaic used to select
                the data that is read.
            chk_version (:obj:`bool`, optional):
                If False, allow a mismatch in datamodel to proceed

        Returns:
            :class:`~pypeit.spec2dobj.Spec2DObj`: 2D spectra object.

        """
        hdul = io.fits_open(file)
        # Quick check on det
        if not np.any([detname in hdu.name for hdu in hdul]):
            msgs.error(f'{detname} not available in any extension of {file}')
        slf = super().from_hdu(hdul,
                               hdu_prefix=f'{detname}-',
                               chk_version=chk_version)
        slf.head0 = hdul[0].header
        slf.chk_version = chk_version
        return slf
Пример #10
0
def load_telluric_grid(filename):
    """Load a telluric atmospheric grid

    NOTE: This is where the path to the data directory is added!

    Args:
        filename (str):
          The filename (NO PATH) of the telluric atmospheric grid to use.

    Returns:
        (:obj:`astropy.io.fits.HDUList`): Telluric Grid FITS HDU list
    """
    # Check for existance of file parameter
    if not filename:
        msgs.error("No file specified for telluric correction.  "
                   "See https://pypeit.readthedocs.io/en/latest/telluric.html")

    # Get the data path for the filename, whether in the package directory or cache
    file_with_path = get_telgrid_filepath(filename)

    # Check for existance of file
    # NOTE: With the use of `get_telgrid_filepath()`, this should never run
    if not os.path.isfile(file_with_path):
        msgs.error(f"File {file_with_path} is not on your disk.  "
                   "You likely need to download the Telluric files.  "
                   "See https://pypeit.readthedocs.io/en/release/installing.html"
                   "#atmospheric-model-grids")

    return io.fits_open(file_with_path)
Пример #11
0
def test_coadd1d_2():
    """
    Test combining Echelle
    """
    # NOTE: flux_value is False
    parfile = 'coadd1d.par'
    if os.path.isfile(parfile):
        os.remove(parfile)
    coadd_ofile = data_path('pisco_coadd.fits')
    if os.path.isfile(coadd_ofile):
        os.remove(coadd_ofile)

    coadd_ifile = data_path('gemini_gnirs_32_sb_sxd.coadd1d')
    scripts.coadd_1dspec.CoAdd1DSpec.main(
        scripts.coadd_1dspec.CoAdd1DSpec.parse_args(
            [coadd_ifile, '--test_spec_path',
             data_path('')]))

    hdu = io.fits_open(coadd_ofile)
    assert hdu[1].header['EXT_MODE'] == 'OPT'
    assert hdu[1].header['FLUXED'] is False

    # Test that the output file is kosher and contains the right quantities
    spec = onespec.OneSpec.from_file(coadd_ofile)
    assert spec.wave.shape == spec.wave_grid_mid.shape

    # Clean up
    hdu.close()
    os.remove(parfile)
    os.remove(coadd_ofile)
Пример #12
0
def test_coadd1d_1(monkeypatch):
    """
    Test basic coadd using shane_kast_blue
    """
    dp = data_path('')
    # Change to the parent directory of the data path, so we can test that
    # coadding without a coadd output file specified places the output next
    # to the spec1ds. Using monkeypatch means the current working directory
    # will be restored after the test.
    monkeypatch.chdir(Path(dp).parent)

    # NOTE: flux_value is False
    parfile = 'files/coadd1d.par'
    if os.path.isfile(parfile):
        os.remove(parfile)
    coadd_ofile = data_path('coadd1d_J1217p3905_KASTb_20150520_20150520.fits')
    if os.path.isfile(coadd_ofile):
        os.remove(coadd_ofile)

    coadd_ifile = data_path('shane_kast_blue.coadd1d')
    scripts.coadd_1dspec.CoAdd1DSpec.main(
        scripts.coadd_1dspec.CoAdd1DSpec.parse_args(
            [coadd_ifile, "--par_outfile", parfile]))
    hdu = io.fits_open(coadd_ofile)
    assert hdu[1].header['EXT_MODE'] == 'OPT'
    assert hdu[1].header['FLUXED'] is False
    # Test that the output file is kosher and contains the right quantities
    spec = onespec.OneSpec.from_file(coadd_ofile)
    assert spec.wave.shape == spec.wave_grid_mid.shape

    # Clean up
    hdu.close()
    os.remove(parfile)
    os.remove(coadd_ofile)
Пример #13
0
    def get_headarr(self, inp, strict=True):
        """
        Read the header data from all the extensions in the file.

        Args:
            inp (:obj:`str`, `astropy.io.fits.HDUList`_):
                Name of the file to read or the previously opened HDU list.
            strict (:obj:`bool`, optional):
                Function will fault if :func:`fits.getheader` fails to read
                any of the headers. Set to False to report a warning and
                continue.

        Returns:
            :obj:`list`: A list of `astropy.io.fits.Header`_ objects with the
            extension headers.
        """
        # Faster to open the whole file and then assign the headers,
        # particularly for gzipped files (e.g., DEIMOS)
        if isinstance(inp, str):
            try:
                hdu = io.fits_open(inp)
            except:
                if strict:
                    msgs.error('Problem opening {0}.'.format(inp))
                else:
                    msgs.warn(
                        'Problem opening {0}.'.format(inp) + msgs.newline() +
                        'Proceeding, but should consider removing this file!')
                    return ['None'] * 999  # self.numhead
        else:
            hdu = inp
        return [hdu[k].header for k in range(len(hdu))]
Пример #14
0
def gemini_read_amp(inp, ext):
    """
    Read one amplifier of an Gemini GMOS multi-extension FITS image

    Parameters
    ----------
    inp: :obj:`tuple`
        A two-tuple with either the filename and extension ``(str,int)`` with
        the data to read or the already opened `astropy.io.fits.HDUList`_
        object and extension ``(hdu,int)``.

    Returns
    -------
    data : `numpy.ndarray`_
        2D array with the science region of the raw image.
    overscan : `numpy.ndarray`_
        2D array with the overscan region of the raw image.
    datasec : :obj:`str`
        String representation of the section in the raw image with the
        science data.
    baissec : :obj:`str`
        String representation of the section in the raw image with the
        overscan.
    x1 : :obj:`int`
        Starting pixel along the first axis with the science data in the raw
        image.
    y1 : :obj:`int`
        Starting pixel along the second axis with the science data in the raw
        image.
    """
    # Parse input
    hdu = io.fits_open(inp) if isinstance(inp, str) else inp

    # get entire extension...
    temp = hdu[ext].data.transpose()
    tsize = temp.shape
    nxt = tsize[0]

    # parse the DETSEC keyword to determine the size of the array.
    header = hdu[ext].header
    detsec = header['DETSEC']
    x1, x2, y1, y2 = np.array(parse.load_sections(detsec, fmt_iraf=False)).flatten()

    # parse the DATASEC keyword to determine the size of the science region (unbinned)
    datasec = header['DATASEC']
    xdata1, xdata2, ydata1, ydata2 \
            = np.array(parse.load_sections(datasec, fmt_iraf=False)).flatten()

    # grab the components...
    data = temp[xdata1-1:xdata2,:]

    # Overscan
    biassec = header['BIASSEC']
    xdata1, xdata2, ydata1, ydata2 \
            = np.array(parse.load_sections(biassec, fmt_iraf=False)).flatten()
    overscan = temp[xdata1-1:xdata2,:]

    # Return
    return data, overscan, datasec, biassec, x1, x2
Пример #15
0
def write_filter_list():
    # Write the filter list
    hdulist = io.fits_open('filtercurves.fits')
    all_filters = [hdu.name for hdu in hdulist]
    tbl = Table()
    tbl['filter'] = all_filters
    # Write
    tbl.write('filter_list.ascii', format='ascii', overwrite=True)
Пример #16
0
def append_FORS():
    # Load
    hdulist = io.fits_open('filtercurves.fits')
    curr_filters = [hdu.name for hdu in hdulist]
    #
    filters = [
        'BESS_B', 'BESS_I', 'BESS_R', 'BESS_U', 'BESS_V', 'u_HIGH', 'b_HIGH',
        'v_HIGH', 'g_HIGH', 'GUNN_G', 'GUNN_R', 'GUNN_U', 'GUNN_V', 'GUNN_Z',
        'SPECIAL_R', 'SPECIAL_U'
    ]
    for filt in filters:
        vlt_name = 'VLT-{}'.format(filt)
        if vlt_name in curr_filters:
            print("Filter {} already there, skipping".format(vlt_name))
            continue
        if 'HIGH' in filt:
            url = 'http://www.eso.org/sci/facilities/paranal/instruments/fors/inst/Filters/{}.txt'.format(
                filt)
        else:
            url = 'http://www.eso.org/sci/facilities/paranal/instruments/fors/inst/Filters/M_{}.txt'.format(
                filt)
        r = requests.get(url)
        # Parse me
        ss = r.text.split('\n')
        lam, T = [], []
        for row in ss:
            if 'fors' in row.lower():
                continue
            elif len(row) == 0:
                continue
            elif 'Wavelen' in row:
                continue
            items = row.split(' ')
            if len(items[0]) == 0:  # Special
                items = items[1:]
                items[1] = items[-1]
            try:
                lam.append(float(items[0]) * 10)
            except ValueError:
                items = row.split('\t')  # HIGH
                try:
                    lam.append(float(items[0]) * 10)
                except:
                    embed(header='196')
                T.append(float(items[1]) / 10)
            else:
                try:
                    T.append(float(items[1]))
                except:
                    embed(header='205')
        # Recast
        wave = np.array(lam)
        trans = np.array(T)
        # Add it
        hdu = tohdu(wave, trans, vlt_name)
        hdulist.append(hdu)
    # Write
    hdulist.writeto('filtercurves.fits', overwrite=True)
Пример #17
0
    def bpm(self, filename, det, shape=None, msbias=None):
        """
        Generate a default bad-pixel mask.

        Even though they are both optional, either the precise shape for
        the image (``shape``) or an example file that can be read to get
        the shape (``filename`` using :func:`get_image_shape`) *must* be
        provided.

        Args:
            filename (:obj:`str` or None):
                An example file to use to get the image shape.
            det (:obj:`int`):
                1-indexed detector number to use when getting the image
                shape from the example file.
            shape (tuple, optional):
                Processed image shape
                Required if filename is None
                Ignored if filename is not None
            msbias (`numpy.ndarray`_, optional):
                Master bias frame used to identify bad pixels

        Returns:
            `numpy.ndarray`_: An integer array with a masked value set
            to 1 and an unmasked value set to 0.  All values are set to
            0.
        """
        # Call the base-class method to generate the empty bpm
        bpm_img = super().bpm(filename, det, shape=shape, msbias=msbias)
        msgs.info("Using hard-coded BPM for  MODS2B")

        # Get the binning
        hdu = io.fits_open(filename)
        header = hdu[0].header
        xbin, ybin = header['CCDXBIN'], header['CCDYBIN']
        hdu.close()

        # Apply the mask
        bpm_img[5176 // xbin:5179 // xbin, 549 // ybin:1544 // ybin] = 1
        bpm_img[5176 // xbin:5179 // xbin, 1544 // ybin:1628 // ybin] = 1
        bpm_img[4408 // xbin:4410 // xbin, 1544 // ybin:2661 // ybin] = 1
        bpm_img[4408 // xbin:4411 // xbin, 2660 // ybin:2663 // ybin] = 1
        bpm_img[2495 // xbin:2499 // xbin, 1326 // ybin:1544 // ybin] = 1
        bpm_img[2391 // xbin:2394 // xbin, 1048 // ybin:1051 // ybin] = 1
        bpm_img[1974 // xbin:1980 // xbin, 806 // ybin:1544 // ybin] = 1
        bpm_img[1975 // xbin:1980 // xbin, 1544 // ybin:1607 // ybin] = 1
        bpm_img[1972 // xbin:1974 // xbin, 1587 // ybin:1589 // ybin] = 1
        bpm_img[274 // xbin:278 // xbin, 1341 // ybin:1544 // ybin] = 1
        bpm_img[275 // xbin:278 // xbin, 1251 // ybin:1341 // ybin] = 1
        bpm_img[276 // xbin:278 // xbin, 1242 // ybin:1251 // ybin] = 1
        bpm_img[274 // xbin:277 // xbin, 1544 // ybin:3066 // ybin] = 1

        bpm_img[2392 // xbin, 1051 // ybin:1544 // ybin] = 1
        bpm_img[275 // xbin, 1220 // ybin:1242 // ybin] = 1

        return bpm_img
Пример #18
0
def fix_SDSS():

    par = io.fits_open('filter_curves_sdss.fits')
    pri_hdu = fits.PrimaryHDU()
    hdulist = fits.HDUList(pri_hdu)

    for i in ['SDSS-U', 'SDSS-G', 'SDSS-R', 'SDSS-I', 'SDSS-Z']:
        wave, trans = par[i[-1]].data['wavelength'], par[i[-1]].data['respt']
        hdu = tohdu(wave, trans, i)
        hdulist.append(hdu)

    # Load
    hdulist_orig = io.fits_open('filtercurves.fits')
    for i in range(len(hdulist_orig[6:])):
        hdulist.append(hdulist_orig[6 + i])

    curr_filters = [hdu.name for hdu in hdulist]
    # Write
    hdulist.writeto('filtercurves.fits', overwrite=True)
Пример #19
0
def load_filter_file(filter):
    """
    Load a system response curve for a given filter

    Args:
        filter (str): Name of filter

    Returns:
        ndarray, ndarray: wavelength, instrument throughput

    """
    '''
    # Optical filters
    BASS_MZLS_filters = ['BASS-MZLS-{}'.format(i) for i in ['G', 'R','Z']]
    CFHT_filters = ['CFHT-{}'.format(i) for i in ['U', 'G', 'R', 'I', 'Z']]
    DECAM_filters = ['DECAM-{}'.format(i) for i in ['U', 'G', 'R', 'I', 'Z', 'Y']]
    HSC_filters = ['HSC-{}'.format(i) for i in ['G', 'R', 'I', 'Z', 'Y']]
    LSST_filters = ['LSST-{}'.format(i) for i in ['U', 'G', 'R', 'I', 'Z', 'Y']]
    PS1_filters = ['PS1-{}'.format(i) for i in ['G', 'R', 'I', 'Z', 'Y']]
    SDSS_filters = ['SDSS-{}'.format(i) for i in ['U', 'G', 'R', 'I', 'Z']]

    # NIR filters
    UKIDSS_filters = ['UKIRT-{}'.format(i) for i in ['Y', 'J', 'H', 'K']]
    VISTA_filters = ['VISTA-{}'.format(i) for i in ['Z', 'Y', 'J', 'H', 'K']]
    TMASS_filters = ['TMASS-{}'.format(i) for i in ['J', 'H', 'K']]

    # Other filters
    GAIA_filters = ['GAIA-{}'.format(i) for i in ['G', 'B', 'R']]
    GALEX_filters = ['GALEX-{}'.format(i) for i in ['F', 'N']]
    WISE_filters = ['WISE-{}'.format(i) for i in ['W1', 'W2', 'W3', 'W4']]

    allowed_options = BASS_MZLS_filters + CFHT_filters + DECAM_filters + HSC_filters \
                      + LSST_filters + PS1_filters + SDSS_filters + UKIDSS_filters\
                      + VISTA_filters + TMASS_filters + GAIA_filters + GALEX_filters + WISE_filters
    '''
    filter_file = resource_filename('pypeit', os.path.join('data', 'filters', 'filter_list.ascii'))
    tbl = table.Table.read(filter_file, format='ascii')

    allowed_options = tbl['filter'].data

    # Check
    if filter not in allowed_options:
        msgs.error("PypeIt is not ready for filter = {}".format(filter))

    trans_file = resource_filename('pypeit', os.path.join('data', 'filters', 'filtercurves.fits'))
    trans = io.fits_open(trans_file)
    wave = trans[filter].data['lam']  # Angstroms
    instr = trans[filter].data['Rlam']  # Am keeping in atmospheric terms
    keep = instr > 0.
    # Parse
    wave = wave[keep]
    instr = instr[keep]

    # Return
    return wave, instr
Пример #20
0
 def load(cls, sensfile):
     # Write to outfile
     msgs.info(
         'Reading sensitivity function from file: {:}'.format(sensfile))
     hdulist = io.fits_open(sensfile)
     header = hdulist[0].header
     wave = hdulist['WAVE'].data
     sensfunc = hdulist['SENSFUNC'].data
     meta_table = table.Table(hdulist['METADATA'].data)
     out_table = table.Table(hdulist['OUT_TABLE'].data)
     return wave, sensfunc, meta_table, out_table, header
Пример #21
0
def waveids(fname):
    infile = io.fits_open(fname)
    pixels = []
    msgs.info("Loading fitted arc lines")
    try:
        o = 1
        while True:
            pixels.append(infile[o].data.astype(np.float))
            o += 1
    except:
        pass
    return pixels
Пример #22
0
def load_thar_spec():
    """Load the archived ThAr spectrum

    NOTE: This is where the path to the data directory is added!

    Args:
        filename (str):
          The filename (NO PATH) of the telluric atmospheric grid to use.

    Returns:
        (:obj:`astropy.io.fits.HDUList`): ThAr Spectrum FITS HDU list
    """
    return io.fits_open(os.path.join(Paths.arclines, 'thar_spec_MM201006.fits'))
Пример #23
0
def test_io(sobj1, sobj2, sobj3, sobj4):
    sobjs = specobjs.SpecObjs([sobj1, sobj2, sobj3, sobj4])
    sobjs[0]['BOX_WAVE'] = np.arange(1000).astype(float)
    sobjs[1]['BOX_WAVE'] = np.arange(1000).astype(float)
    sobjs[2]['BOX_WAVE'] = np.arange(1000).astype(float)
    #sobjs[0]['BOX_COUNTS'] = np.ones_like(sobjs[0].BOX_WAVE)  # This tests single array
    sobjs[1]['BOX_COUNTS'] = np.ones_like(sobjs[0].BOX_WAVE)
    sobjs[2]['BOX_COUNTS'] = np.ones_like(sobjs[0].BOX_WAVE)
    # Detector
    sobjs[0]['DETECTOR'] = tstutils.get_kastb_detector()
    tmp = tstutils.get_kastb_detector()

    tmp['det'] = 2
    sobjs[1]['DETECTOR'] = tmp
    # Write
    header = fits.PrimaryHDU().header
    header['TST'] = 'TEST'
    ofile = tstutils.data_path('tst_specobjs.fits')
    if os.path.isfile(ofile):
        os.remove(ofile)
    sobjs.write_to_fits(header, ofile, overwrite=False)
    # Read
    hdul = io.fits_open(ofile)
    assert len(hdul) == 7  # Primary + 4 Obj + 2 Detectors
    assert hdul[0].header['NSPEC'] == 4
    hdul.close()
    #
    _sobjs = specobjs.SpecObjs.from_fitsfile(ofile)
    assert _sobjs.nobj == 4
    assert np.array_equal(sobjs[0].BOX_WAVE, _sobjs[0].BOX_WAVE)
    assert np.array_equal(sobjs[1].BOX_WAVE, _sobjs[1].BOX_WAVE)
    _sobjs.write_to_fits(header, ofile, overwrite=True)

    # Detector
    assert _sobjs[0].DETECTOR is not None, '1st object started with Detector'
    assert _sobjs[
        1].DETECTOR is not None, '2nd object has DET=1 so should get decorated'
    assert _sobjs[2].DETECTOR is None

    # Now try updates!
    sobjs1 = specobjs.SpecObjs([sobj1])
    sobjs[0]['BOX_WAVE'] = np.arange(2000).astype(float)
    sobjs1[0]['DETECTOR'] = tstutils.get_kastb_detector()
    header1 = fits.PrimaryHDU().header
    sobjs1.write_to_fits(header1, ofile, overwrite=True, update_det='DET01')

    # Test
    _sobjs1 = specobjs.SpecObjs.from_fitsfile(ofile)
    assert _sobjs1.nobj == 3
    assert _sobjs1[2].BOX_WAVE.size == 2000
    os.remove(ofile)
Пример #24
0
    def bpm(self, filename, det, shape=None, msbias=None):
        """
        Generate a default bad-pixel mask.

        Even though they are both optional, either the precise shape for
        the image (``shape``) or an example file that can be read to get
        the shape (``filename`` using :func:`get_image_shape`) *must* be
        provided.

        Args:
            filename (:obj:`str` or None):
                An example file to use to get the image shape.
            det (:obj:`int`):
                1-indexed detector number to use when getting the image
                shape from the example file.
            shape (tuple, optional):
                Processed image shape
                Required if filename is None
                Ignored if filename is not None
            msbias (`numpy.ndarray`_, optional):
                Master bias frame used to identify bad pixels

        Returns:
            `numpy.ndarray`_: An integer array with a masked value set
            to 1 and an unmasked value set to 0.  All values are set to
            0.
        """
        # Call the base-class method to generate the empty bpm
        bpm_img = super().bpm(filename, det, shape=shape, msbias=msbias)

        msgs.info("Using hard-coded BPM for  MODS1R")

        # TODO: Fix this
        # Get the binning
        hdu = io.fits_open(filename)
        header = hdu[0].header
        xbin, ybin = header['CCDXBIN'], header['CCDYBIN']
        hdu.close()

        # Apply the mask
        bpm_img[6278 // xbin:6289 // xbin, 1544 // ybin:1634 // ybin] = 1
        bpm_img[4202 // xbin:4204 // xbin, 1474 // ybin:1544 // ybin] = 1
        bpm_img[3551 // xbin:3558 // xbin, 2391 // ybin:2903 // ybin] = 1
        bpm_img[3553 // xbin:3558 // xbin, 1454 // ybin:1544 // ybin] = 1

        bpm_img[5650 // xbin, 1280 // ybin:1544 // ybin] = 1
        bpm_img[4780 // xbin, 1406 // ybin:1536 // ybin] = 1
        bpm_img[3554 // xbin, 1544 // ybin:2392 // ybin] = 1
        bpm_img[163 // xbin, 1544 // ybin:1963 // ybin] = 1

        return bpm_img
Пример #25
0
    def from_fitsfile(cls, fits_file, det=None, chk_version=True):
        """
        Instantiate from a FITS file

        Also tag on the Header

        Args:
            fits_file (str):
            det (int, optional):
                Only load SpecObj matching this det value
            chk_version (:obj:`bool`):
                If False, allow a mismatch in datamodel to proceed

        Returns:
            specobsj.SpecObjs

        """
        # HDUList
        hdul = io.fits_open(fits_file)
        # Init
        slf = cls()
        # Add on the header
        slf.header = hdul[0].header
        # Keep track of HDUList for closing later

        detector_hdus = {}
        # Loop for Detectors first as we need to add these to the objects
        for hdu in hdul[1:]:
            if 'DETECTOR' in hdu.name:
                detector_hdus[hdu.header[
                    'DET']] = detector_container.DetectorContainer.from_hdu(
                        hdu)
        # Now the objects
        for hdu in hdul[1:]:
            if 'DETECTOR' in hdu.name:
                continue
            sobj = specobj.SpecObj.from_hdu(hdu, chk_version=chk_version)
            # Restrict on det?
            if det is not None and sobj.DET != det:
                continue
            # Check for detector
            if sobj.DET in detector_hdus.keys():
                sobj.DETECTOR = detector_hdus[sobj.DET]
            # Append
            slf.add_sobj(sobj)
        # Return
        hdul.close()
        return slf
Пример #26
0
    def bpm(self, filename, det, shape=None, msbias=None):
        """
        Generate a default bad-pixel mask.

        Even though they are both optional, either the precise shape for
        the image (``shape``) or an example file that can be read to get
        the shape (``filename`` using :func:`get_image_shape`) *must* be
        provided.

        Args:
            filename (:obj:`str` or None):
                An example file to use to get the image shape.
            det (:obj:`int`):
                1-indexed detector number to use when getting the image
                shape from the example file.
            shape (tuple, optional):
                Processed image shape
                Required if filename is None
                Ignored if filename is not None
            msbias (`numpy.ndarray`_, optional):
                Master bias frame used to identify bad pixels

        Returns:
            `numpy.ndarray`_: An integer array with a masked value set
            to 1 and an unmasked value set to 0.  All values are set to
            0.
        """
        # Call the base-class method to generate the empty bpm
        bpm_img = super().bpm(filename, det, shape=shape, msbias=msbias)

        msgs.info("Using hard-coded BPM for det=1 on MMIRS")

        # Get the binning
        hdu = io.fits_open(filename)
        binning = hdu[1].header['CCDSUM']
        hdu.close()

        # Apply the mask
        xbin, ybin = int(binning.split(' ')[0]), int(binning.split(' ')[1])
        bpm_img[:, 187 // ybin] = 1

        return bpm_img
Пример #27
0
def append_MIRI():
    # Load
    hdulist = io.fits_open('filtercurves.fits')
    curr_filters = [hdu.name for hdu in hdulist]
    #
    miri = Table.read('miri_filter/miri_imaging.txt',format='ascii.basic')
    filters = ['F560W','F770W','F1000W', 'F1130W', 'F1280W','F1500W','F1800W','F2100W','F2550W']
    for filt in filters:
        flt_name = 'MIRI-{}'.format(filt)
        if flt_name in curr_filters:
            print("Filter {} already there, skipping".format(flt_name))
            continue
        # load in the transmission
        wave = miri['Wave']*1e4
        trans = miri[filt]
        # Add it
        hdu = tohdu(wave,trans,flt_name)
        hdulist.append(hdu)
    # Write
    hdulist.writeto('filtercurves.fits', overwrite=True)
Пример #28
0
    def bpm(self, filename, det, shape=None, msbias=None):
        """
        Generate a default bad-pixel mask.

        Even though they are both optional, either the precise shape for
        the image (``shape``) or an example file that can be read to get
        the shape (``filename`` using :func:`get_image_shape`) *must* be
        provided.

        Args:
            filename (:obj:`str` or None):
                An example file to use to get the image shape.
            det (:obj:`int`):
                1-indexed detector number to use when getting the image
                shape from the example file.
            shape (tuple, optional):
                Processed image shape
                Required if filename is None
                Ignored if filename is not None
            msbias (`numpy.ndarray`_, optional):
                Master bias frame used to identify bad pixels

        Returns:
            `numpy.ndarray`_: An integer array with a masked value set
            to 1 and an unmasked value set to 0.  All values are set to
            0.
        """
        # Call the base-class method to generate the empty bpm
        bpm_img = super().bpm(filename, det, shape=shape, msbias=msbias)

        # Get the binning
        msgs.info("Custom bad pixel mask for MAGE")
        hdu = io.fits_open(filename)
        binspatial, binspec = parse.parse_binning(hdu[0].header['BINNING'])
        hdu.close()
        # Do it
        bpm_img[:, :10 //
                binspatial] = 1.  # Setting BPM on the edge of the detector often leads to false edges
        bpm_img[:, 1020 // binspatial:] = 1.
        # Return
        return bpm_img
Пример #29
0
    def from_file(cls, file, det, chk_version=True):
        """
        Overload :func:`pypeit.datamodel.DataContainer.from_file` to allow det
        input and to slurp the header

        Args:
            file (:obj:`str`):
            det (:obj:`int`):
            chk_version (:obj:`bool`):
                If False, allow a mismatch in datamodel to proceed

        Returns:
            `Spec2DObj`:

        """
        hdul = io.fits_open(file)
        # Quick check on det
        if not np.any(['DET{:02d}'.format(det) in hdu.name for hdu in hdul]):
            msgs.error("Requested detector {} is not in this file - {}".format(det, file))
        #
        slf = super(Spec2DObj, cls).from_hdu(hdul, hdu_prefix=spec2d_hdu_prefix(det), chk_version=chk_version)
        slf.head0 = hdul[0].header
        return slf
Пример #30
0
    def from_file(cls, ifile):
        """
        Over-load :func:`pypeit.datamodel.DataContainer.from_file`
        to deal with the header

        Args:
            ifile (str):  Filename holding the object

        Returns:
            :class:`OneSpec`:

        """
        hdul = io.fits_open(ifile)
        slf = super(OneSpec, cls).from_hdu(hdul)

        # Internals
        slf.filename = ifile
        slf.head0 = hdul[0].header
        # Meta
        slf.spectrograph = load_spectrograph(slf.PYP_SPEC)
        slf.spect_meta = slf.spectrograph.parse_spec_header(slf.head0)
        #
        return slf