<commit_before>""" Perform calculations on Spectral Energy Distributions (SEDs).

Based on the SED module in astLib by <NAME>, with some routines
copied from there (LGPL): http://astlib.sourceforge.net

- VEGA: The SED of Vega, used for calculation of magnitudes on the Vega system.
- AB: Flat spectrum SED, used for calculation of magnitudes on the AB system.
- SUN: The SED of the Sun.

"""
import os, math
import warnings

import numpy as np
from convolve import convolve_psf
from io import readtabfits
from constants import c, c_kms, Jy
from utilities import get_data_path
import extinction

try:
    import matplotlib.pyplot as pl
except:
    print "WARNING: failed to import matplotlib - some functions will not work."

datapath = get_data_path()
PATH_PASSBAND = datapath + '/passbands/'
PATH_EXTINCT = datapath + '/atmos_extinction/'
PATH_TEMPLATE = datapath + '/templates/'

def _listfiles(topdir):
    names = [n for n in os.listdir(topdir) if os.path.isdir(topdir + n)]
    files = dict([(n, []) for n in names])
    for name in sorted(names):
        for n in sorted(os.listdir(topdir + name)):
            if n != 'README' and not os.path.isdir(topdir + name + '/'+ n) and \
                   not n.startswith('effic') and \
                   not n.endswith('.py') and not n.endswith('.pdf'):
                files[name].append(n)
    return files

TEMPLATES = _listfiles(PATH_TEMPLATE)
PASSBANDS = _listfiles(PATH_PASSBAND)

def get_bands(instr=None, names=None, ccd=None):
    """ Get one or more passbands by giving the instrument and
    filename.

    If `names` is not given, then every passband for that instrument
    is returned.  Passband instruments and filenames are listed in the
    dictionary PASSBANDS. names can be a list, a single string, or a
    comma-separated string of values.

    Examples
    --------
    
    >>> sdss = get_bands('SDSS', 'u,g,r,i,z')  # get the SDSS passbands
    >>> U = get_bands('LBC', 'u')    # get the LBC U_spec filter
    """
    if instr is None:
        return _listfiles(PATH_PASSBAND)
    if isinstance(names, basestring):
        if ',' in names:
            names = [n.strip() for n in names.split(',')]
        else:
            return Passband(instr + '/' + names)
    elif names is None:
        names = PASSBANDS[instr]

    return [Passband(instr + '/' + n, ccd=ccd) for n in names]

def get_SEDs(kind=None, names=None):
    """ Get one or more SEDs based on their type and filename 

    If `names` is not given, then every SED of that type is returned.
    SED types and filenames are listed in the dictionary TEMPLATES.

    Examples
    --------
    >>> pickles = get_SEDs('pickles')   # pickles stellar library SEDs
    >>> lbga = get_SEDs('LBG', 'lbg_abs.dat')  # LBG absorption spectrum
    """
    if kind is None:
        return _listfiles(PATH_TEMPLATE)
    if isinstance(names, basestring):
        if ',' in names:
            names = [n.strip() for n in names.split(',')]
        else:
            return SED(kind + '/' + names)
    elif names is None:
        names = TEMPLATES[kind]

    return [SED(kind + '/' + n) for n in names]

def get_extinction(filename=None, airmass=1.):
    """ return the atmospheric extinction from the given file.

    returns extinction = 10^(0.4 * extinction_in_mags * airmass),

    where flux_true = flux_extincted * extinction
    """ 
    if filename is None:
        return sorted(os.listdir(PATH_EXTINCT))

    wa, emag = np.loadtxt(PATH_EXTINCT + filename, unpack=1)
    return wa, 10**(-0.4 * emag * airmass)


class Passband(object):
    """This class describes a filter transmission curve. Passband
    objects are created by loading data from from text files
    containing wavelength in angstroms in the first column, relative
    transmission efficiency in the second column (whitespace
    delimited). For example, to create a Passband object for the 2MASS
    J filter:
    
    passband = Passband('J_2MASS.res')

    where 'J_2MASS.res' is a file in the current working directory
    that describes the filter.

    The available passbands are in PASSBANDS.
    
    Attributes
    ----------
    wa : array of floats
      Wavelength in Angstroms
    tr : array of floats
      Normalised transmission, including atmospheric extinction and
      detector efficiency. May or may not include extinction from the
      optical path.
    effective_wa : float
      Effective wavelength of the passband.

    Methods
    -------
    plot
    """
    def __init__(self, filename, ccd=None):
        if not filename.startswith(PATH_PASSBAND):
            filepath = PATH_PASSBAND + filename
        self.wa, self.tr = np.loadtxt(filepath, usecols=(0,1), unpack=True)
        # check wavelengths are sorted lowest -> highest
        isort = self.wa.argsort()
        self.wa = self.wa[isort]
        self.tr = self.tr[isort]

        # get the name of th filter/passband file and the name of the
        # directory in which it lives (the instrument).
        prefix, filtername = os.path.split(filename)
        _, instr = os.path.split(prefix)
        self.name = filename

        if instr == 'LBC' and ccd is None:
            if filtername.startswith('LBCB') or filtername in 'ug':
                ccd = 'blue'
            elif filtername.startswith('LBCR') or filtername in 'riz':
                ccd = 'red'
        elif instr == 'FORS' and ccd is None:
            warnings.warn('No cdd ("red" or "blue") given, assuming red.')
            ccd = 'red'<commit_msg>Fix to read fits passband files<commit_after>""" Perform calculations on Spectral Energy Distributions (SEDs).

Based on the SED module in astLib by <NAME>, with some routines
copied from there (LGPL): http://astlib.sourceforge.net

- VEGA: The SED of Vega, used for calculation of magnitudes on the Vega system.
- AB: Flat spectrum SED, used for calculation of magnitudes on the AB system.
- SUN: The SED of the Sun.

"""
import os, math
import warnings

import numpy as np
from convolve import convolve_psf
from io import readtabfits
from constants import c, c_kms, Jy
from utilities import get_data_path
import extinction

try:
    import matplotlib.pyplot as pl
except:
    print "WARNING: failed to import matplotlib - some functions will not work."

datapath = get_data_path()
PATH_PASSBAND = datapath + '/passbands/'
PATH_EXTINCT = datapath + '/atmos_extinction/'
PATH_TEMPLATE = datapath + '/templates/'

def _listfiles(topdir):
    names = [n for n in os.listdir(topdir) if os.path.isdir(topdir + n)]
    files = dict([(n, []) for n in names])
    for name in sorted(names):
        for n in sorted(os.listdir(topdir + name)):
            if n != 'README' and not os.path.isdir(topdir + name + '/'+ n) and \
                   not n.startswith('effic') and \
                   not n.endswith('.py') and not n.endswith('.pdf'):
                files[name].append(n)
    return files

TEMPLATES = _listfiles(PATH_TEMPLATE)
PASSBANDS = _listfiles(PATH_PASSBAND)

def get_bands(instr=None, names=None, ccd=None):
    """ Get one or more passbands by giving the instrument and
    filename.

    If `names` is not given, then every passband for that instrument
    is returned.  Passband instruments and filenames are listed in the
    dictionary PASSBANDS. names can be a list, a single string, or a
    comma-separated string of values.

    Examples
    --------
    
    >>> sdss = get_bands('SDSS', 'u,g,r,i,z')  # get the SDSS passbands
    >>> U = get_bands('LBC', 'u')    # get the LBC U_spec filter
    """
    if instr is None:
        return _listfiles(PATH_PASSBAND)
    if isinstance(names, basestring):
        if ',' in names:
            names = [n.strip() for n in names.split(',')]
        else:
            return Passband(instr + '/' + names)
    elif names is None:
        names = PASSBANDS[instr]

    return [Passband(instr + '/' + n, ccd=ccd) for n in names]

def get_SEDs(kind=None, names=None):
    """ Get one or more SEDs based on their type and filename 

    If `names` is not given, then every SED of that type is returned.
    SED types and filenames are listed in the dictionary TEMPLATES.

    Examples
    --------
    >>> pickles = get_SEDs('pickles')   # pickles stellar library SEDs
    >>> lbga = get_SEDs('LBG', 'lbg_abs.dat')  # LBG absorption spectrum
    """
    if kind is None:
        return _listfiles(PATH_TEMPLATE)
    if isinstance(names, basestring):
        if ',' in names:
            names = [n.strip() for n in names.split(',')]
        else:
            return SED(kind + '/' + names)
    elif names is None:
        names = TEMPLATES[kind]

    return [SED(kind + '/' + n) for n in names]

def get_extinction(filename=None, airmass=1.):
    """ return the atmospheric extinction from the given file.

    returns extinction = 10^(0.4 * extinction_in_mags * airmass),

    where flux_true = flux_extincted * extinction
    """ 
    if filename is None:
        return sorted(os.listdir(PATH_EXTINCT))

    wa, emag = np.loadtxt(PATH_EXTINCT + filename, unpack=1)
    return wa, 10**(-0.4 * emag * airmass)


class Passband(object):
    """This class describes a filter transmission curve. Passband
    objects are created by loading data from from text files
    containing wavelength in angstroms in the first column, relative
    transmission efficiency in the second column (whitespace
    delimited). For example, to create a Passband object for the 2MASS
    J filter:
    
    passband = Passband('J_2MASS.res')

    where 'J_2MASS.res' is a file in the current working directory
    that describes the filter.

    The available passbands are in PASSBANDS.
    
    Attributes
    ----------
    wa : array of floats
      Wavelength in Angstroms
    tr : array of floats
      Normalised transmission, including atmospheric extinction and
      detector efficiency. May or may not include extinction from the
      optical path.
    effective_wa : float
      Effective wavelength of the passband.

    Methods
    -------
    plot
    """
    def __init__(self, filename, ccd=None):
        if not filename.startswith(PATH_PASSBAND):
            filepath = PATH_PASSBAND + filename
        else:
            filepath = filename
        if filepath.endswith('.fits'):
            import pyfits
            rec = pyfits.getdata(filepath, 1)
            self.wa, self.tr = rec.wa, rec.tr
        else:
            self.wa, self.tr = np.loadtxt(filepath, usecols=(0,1), unpack=True)
        # check wavelengths are sorted lowest -> highest
        isort = self.wa.argsort()
        self.wa = self.wa[isort]
        self.tr = self.tr[isort]

        # get the name of th filter/passband file and the name of the
        # directory in which it lives (the instrument).
        prefix, filtername = os.path.split(filename)
        _, instr = os.path.split(prefix)
        self.name = filename

        if instr == 'LBC' and ccd is None:
            if filtername.startswith('LBCB') or filtername in 'ug':
                ccd = 'blue'
            elif filtername.startswith('LBCR') or filtername in 'riz':
                ccd = 'red'
        elif instr == 'FORS' and ccd is None:
            warnings.warn('No cdd ("red" or "blue") given, assuming red.')
            ccd = 'red'
{'fraction_non_alphanumeric': 0.10013339261894175, 'fraction_numerical': 0.0027567807914628726, 'mean_word_length': 2.564500792393027, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3980787', 'n_tokens_mistral': 3522, 'n_tokens_neox': 3378, 'n_words': 1205}