# Path: sedfitter/utils/validator.py
# def validate_scalar(name, value, domain=None, physical_type=None):
# 
#     validate_physical_type(name, value, physical_type)
# 
#     if not physical_type:
#         if np.isscalar(value) or not np.isreal(value):
#             raise TypeError("{0} should be a scalar floating point value".format(name))
# 
#     if domain == 'positive':
#         if value < 0.:
#             raise ValueError("{0} should be positive".format(name))
#     elif domain == 'strictly-positive':
#         if value <= 0.:
#             raise ValueError("{0} should be strictly positive".format(name))
#     elif domain == 'negative':
#         if value > 0.:
#             raise ValueError("{0} should be negative".format(name))
#     elif domain == 'strictly-negative':
#         if value >= 0.:
#             raise ValueError("{0} should be strictly negative".format(name))
#     elif type(domain) in [tuple, list] and len(domain) == 2:
#         if value < domain[0] or value > domain[-1]:
#             raise ValueError("{0} should be in the range [{1}:{2}]".format(name, domain[0], domain[-1]))
# 
#     return value
# 
# def validate_array(name, value, domain=None, ndim=1, shape=None, physical_type=None):
# 
#     validate_physical_type(name, value, physical_type)
# 
#     # First convert to a Numpy array:
#     if type(value) in [list, tuple]:
#         value = np.array(value)
# 
#     # Check the value is an array with the right number of dimensions
#     if not isinstance(value, np.ndarray) or value.ndim != ndim:
#         if ndim == 1:
#             raise TypeError("{0} should be a 1-d sequence".format(name))
#         else:
#             raise TypeError("{0} should be a {1:d}-d array".format(name, ndim))
# 
#     # Check that the shape matches that expected
#     if shape is not None and value.shape != shape:
#         if ndim == 1:
#             raise ValueError("{0} has incorrect length (expected {1} but found {2})".format(name, shape[0], value.shape[0]))
#         else:
#             # On Windows, shapes can contain long integers, so we fix this to
#             # have consistent error messages across platforms.
#             expected_shape = tuple(int(x) for x in shape)
#             actual_shape = tuple(int(x) for x in value.shape)
#             raise ValueError("{0} has incorrect shape (expected {1} but found {2})".format(name, expected_shape, actual_shape))
# 
#     return value
# 
# Path: sedfitter/sed/helpers.py
# def parse_unit_safe(unit_string):
#     if unit_string in UNIT_MAPPING:
#         return UNIT_MAPPING[unit_string]
#     else:
#         return u.Unit(unit_string, parse_strict=False)
# 
# def table_to_hdu(table):
#     hdu = fits.BinTableHDU(np.array(table))
#     for i in range(len(table.columns)):
#         if table.columns[i].unit is not None:
#             hdu.columns[i].unit = table.columns[i].unit.to_string(format='fits')
#     return hdu
# 
# def assert_allclose_quantity(q1, q2):
#     if q1 is None and q2 is None:
#         return True
#     if q1 is None or q2 is None:
#         raise AssertionError()
#     else:
#         np.testing.assert_allclose(q1.value, q2.to(q1.unit).value)


import abc
import numpy as np
import six
from astropy import units as u
from astropy.io import fits
from astropy.table import Table
from ..utils.validator import validate_scalar, validate_array
from .helpers import parse_unit_safe, table_to_hdu, assert_allclose_quantity
        from .sed import SED
        # Open FILE file
        hdulist = fits.open(filename, memmap=memmap)

        # Extract distance
        cube.distance = hdulist[0].header['DISTANCE'] * u.cm

        # Get validity
        cube.valid = hdulist[0].data.astype(bool)

        # Extract model names
        cube.names = hdulist['MODEL_NAMES'].data['MODEL_NAME'].astype(str)

        # Extract wavelengths
        hdu_spectral = hdulist['SPECTRAL_INFO']

        cube.wav = u.Quantity(hdu_spectral.data['WAVELENGTH'],
                              parse_unit_safe(hdu_spectral.columns[0].unit))

        # Extract apertures
        try:
            hdu_apertures = hdulist['APERTURES']
        except KeyError:
            pass
        else:
            cube.apertures = u.Quantity(hdu_apertures.data['APERTURE'],
                                        parse_unit_safe(hdu_apertures.columns[0].unit))

        # Extract value
        hdu_val = hdulist['VALUES']
        cube.val = u.Quantity(hdu_val.data,

# Path: sedfitter/utils/validator.py
# def validate_scalar(name, value, domain=None, physical_type=None):
# 
#     validate_physical_type(name, value, physical_type)
# 
#     if not physical_type:
#         if np.isscalar(value) or not np.isreal(value):
#             raise TypeError("{0} should be a scalar floating point value".format(name))
# 
#     if domain == 'positive':
#         if value < 0.:
#             raise ValueError("{0} should be positive".format(name))
#     elif domain == 'strictly-positive':
#         if value <= 0.:
#             raise ValueError("{0} should be strictly positive".format(name))
#     elif domain == 'negative':
#         if value > 0.:
#             raise ValueError("{0} should be negative".format(name))
#     elif domain == 'strictly-negative':
#         if value >= 0.:
#             raise ValueError("{0} should be strictly negative".format(name))
#     elif type(domain) in [tuple, list] and len(domain) == 2:
#         if value < domain[0] or value > domain[-1]:
#             raise ValueError("{0} should be in the range [{1}:{2}]".format(name, domain[0], domain[-1]))
# 
#     return value
# 
# def validate_array(name, value, domain=None, ndim=1, shape=None, physical_type=None):
# 
#     validate_physical_type(name, value, physical_type)
# 
#     # First convert to a Numpy array:
#     if type(value) in [list, tuple]:
#         value = np.array(value)
# 
#     # Check the value is an array with the right number of dimensions
#     if not isinstance(value, np.ndarray) or value.ndim != ndim:
#         if ndim == 1:
#             raise TypeError("{0} should be a 1-d sequence".format(name))
#         else:
#             raise TypeError("{0} should be a {1:d}-d array".format(name, ndim))
# 
#     # Check that the shape matches that expected
#     if shape is not None and value.shape != shape:
#         if ndim == 1:
#             raise ValueError("{0} has incorrect length (expected {1} but found {2})".format(name, shape[0], value.shape[0]))
#         else:
#             # On Windows, shapes can contain long integers, so we fix this to
#             # have consistent error messages across platforms.
#             expected_shape = tuple(int(x) for x in shape)
#             actual_shape = tuple(int(x) for x in value.shape)
#             raise ValueError("{0} has incorrect shape (expected {1} but found {2})".format(name, expected_shape, actual_shape))
# 
#     return value
# 
# Path: sedfitter/sed/helpers.py
# def parse_unit_safe(unit_string):
#     if unit_string in UNIT_MAPPING:
#         return UNIT_MAPPING[unit_string]
#     else:
#         return u.Unit(unit_string, parse_strict=False)
# 
# def table_to_hdu(table):
#     hdu = fits.BinTableHDU(np.array(table))
#     for i in range(len(table.columns)):
#         if table.columns[i].unit is not None:
#             hdu.columns[i].unit = table.columns[i].unit.to_string(format='fits')
#     return hdu
# 
# def assert_allclose_quantity(q1, q2):
#     if q1 is None and q2 is None:
#         return True
#     if q1 is None or q2 is None:
#         raise AssertionError()
#     else:
#         np.testing.assert_allclose(q1.value, q2.to(q1.unit).value)


# Path: sedfitter/sed/cube.py
import abc
import numpy as np
import six
from astropy import units as u
from astropy.io import fits
from astropy.table import Table
from ..utils.validator import validate_scalar, validate_array
from .helpers import parse_unit_safe, table_to_hdu, assert_allclose_quantity
        from .sed import SED

        # Open FILE file
        hdulist = fits.open(filename, memmap=memmap)

        # Extract distance
        cube.distance = hdulist[0].header['DISTANCE'] * u.cm

        # Get validity
        cube.valid = hdulist[0].data.astype(bool)

        # Extract model names
        cube.names = hdulist['MODEL_NAMES'].data['MODEL_NAME'].astype(str)

        # Extract wavelengths
        hdu_spectral = hdulist['SPECTRAL_INFO']

        cube.wav = u.Quantity(hdu_spectral.data['WAVELENGTH'],
                              parse_unit_safe(hdu_spectral.columns[0].unit))

        # Extract apertures
        try:
            hdu_apertures = hdulist['APERTURES']
        except KeyError:
            pass
        else:
            cube.apertures = u.Quantity(hdu_apertures.data['APERTURE'],
                                        parse_unit_safe(hdu_apertures.columns[0].unit))

        # Extract value
        hdu_val = hdulist['VALUES']
        cube.val = u.Quantity(hdu_val.data,

                              parse_unit_safe(hdu_val.header['BUNIT']),