예제 #1
0
파일: utils.py 프로젝트: uberstig/astropy
    def validate(cls, model, bounding_box):
        """
        Validate a given bounding box sequence against the given model (which
        may be either a subclass of `~astropy.modeling.Model` or an instance
        thereof, so long as the ``.inputs`` attribute is defined.

        Currently this just checks that the bounding_box is either a 2-tuple
        of lower and upper bounds for 1-D models, or an N-tuple of 2-tuples
        for N-D models.

        This also returns a normalized version of the bounding_box input to
        ensure it is always an N-tuple (even for the 1-D case).
        """

        nd = model.n_inputs

        if nd == 1:
            MESSAGE = "Bounding box for {0} model must be a sequence of length "
            "2 consisting of a lower and upper bound, or a 1-tuple "
            "containing such a sequence as its sole element.".format(
                model.name)

            try:
                valid_shape = np.shape(bounding_box) in ((2, ), (1, 2))
            except TypeError:
                # np.shape does not work with lists of Quantities
                valid_shape = np.shape([b.to_value() for b in bounding_box
                                        ]) in ((2, ), (1, 2))
            except ValueError:
                raise ValueError(MESSAGE)

            if not isiterable(bounding_box) or not valid_shape:
                raise ValueError(MESSAGE)

            if len(bounding_box) == 1:
                return cls((tuple(bounding_box[0]), ))
            else:
                return cls(tuple(bounding_box))
        else:
            MESSAGE = "Bounding box for {0} model must be a sequence of length "
            "{1} (the number of model inputs) consisting of pairs of "
            "lower and upper bounds for those inputs on which to "
            "evaluate the model.".format(model.name, nd)

            try:
                valid_shape = all([len(i) == 2 for i in bounding_box])
            except TypeError:
                valid_shape = False
            if len(bounding_box) != nd:
                valid_shape = False

            if not isiterable(bounding_box) or not valid_shape:
                raise ValueError(MESSAGE)

            return cls(tuple(bounds) for bounds in bounding_box)
예제 #2
0
파일: utils.py 프로젝트: dhomeier/astropy
    def validate(cls, model, bounding_box):
        """
        Validate a given bounding box sequence against the given model (which
        may be either a subclass of `~astropy.modeling.Model` or an instance
        thereof, so long as the ``.inputs`` attribute is defined.

        Currently this just checks that the bounding_box is either a 2-tuple
        of lower and upper bounds for 1-D models, or an N-tuple of 2-tuples
        for N-D models.

        This also returns a normalized version of the bounding_box input to
        ensure it is always an N-tuple (even for the 1-D case).
        """

        nd = model.n_inputs

        if nd == 1:
            MESSAGE = "Bounding box for {0} model must be a sequence of length "
            "2 consisting of a lower and upper bound, or a 1-tuple "
            "containing such a sequence as its sole element.".format(model.name)

            try:
                valid_shape = np.shape(bounding_box) in ((2,), (1, 2))
            except TypeError:
                # np.shape does not work with lists of Quantities
                valid_shape = np.shape([b.to_value() for b in bounding_box]) in ((2,), (1, 2))
            except ValueError:
                raise ValueError(MESSAGE)

            if not isiterable(bounding_box) or not valid_shape:
                raise ValueError(MESSAGE)

            if len(bounding_box) == 1:
                return cls((tuple(bounding_box[0]),))
            else:
                return cls(tuple(bounding_box))
        else:
            MESSAGE = "Bounding box for {0} model must be a sequence of length "
            "{1} (the number of model inputs) consisting of pairs of "
            "lower and upper bounds for those inputs on which to "
            "evaluate the model.".format(model.name, nd)

            try:
                valid_shape = all([len(i) == 2 for i in bounding_box])
            except TypeError:
                valid_shape = False
            if len(bounding_box) != nd:
                valid_shape = False

            if not isiterable(bounding_box) or not valid_shape:
                    raise ValueError(MESSAGE)

            return cls(tuple(bounds) for bounds in bounding_box)
예제 #3
0
def test_quantity_iterability():
    """Regressiont est for issue #878.

    Scalar quantities should not be iterable and should raise a type error on
    iteration.
    """

    q1 = [15.0, 17.0] * u.m
    assert isiterable(q1)

    q2 = next(iter(q1))
    assert q2 == 15.0 * u.m
    assert not isiterable(q2)
    pytest.raises(TypeError, iter, q2)
예제 #4
0
    def plot_lnprob(self, tipmag, alphargb, alphaother, fracother, magrng=100, doplot=True, delog=False, **plotkwargs):
        """
        Plots (optionally) and returns arrays suitable for plotting the pdf. If
        `magrng` is a scalar, it gives the number of samples over the data
        domain.  If an array, it's used as the x axis.
        """
        from copy import copy
        from astropy.utils import isiterable
        from matplotlib import pyplot as plt

        fakemod = copy(self)
        if isiterable(magrng):
            fakemod.magdata = np.sort(magrng)
        else:
            fakemod.magdata = np.linspace(self.mindata, self.maxdata, magrng)

        if fakemod.magunc is not None:
            sorti = np.argsort(self.magdata)
            fakemod.magunc = np.interp(fakemod.magdata, self.magdata[sorti], self.magunc[sorti])

        lnpb = fakemod.lnprob(tipmag, alphargb, alphaother, fracother)
        if delog:
            lnpb = np.exp(lnpb - np.min(lnpb))

        if doplot:
            plt.plot(fakemod.magdata, lnpb, **plotkwargs)

        return fakemod.magdata, lnpb
예제 #5
0
 def __call__(self, x, y):
     input_values = np.asarray(x), np.asarray(y)
     output_values = [np.zeros_like(arg) for arg in input_values]
     output_values.append(np.zeros_like(input_values[0]))
     result = self.regions_mask[x, y]
     if not astu.isiterable(result):
         if result != 0:
             return self._selector[result[0]](*input_values)
         else:
             return None #input_values
     unique_regions = np.unique(result).tolist()
     try:
         unique_regions.remove(0)
     except ValueError:
         pass
     try:
         unique_regions.remove("")
     except ValueError:
         pass
     ra = []
     dec = []
     lam = []
     for i in unique_regions:
         indices = (result==i)
         transform = self._selector[i]
         xyind = [val[indices] for val in input_values]
         r, d, l = transform(x[indices], y[indices])
         ra.extend(r)
         dec.extend(d)
         lam.extend(l)
     return np.asarray(ra), np.asarray(dec), np.asarray(lam)
예제 #6
0
def z_to_array(z):
    """
    Convert input scalar or array to an array

    Parameters
    ----------
    z: float or ndarray
      Redshift

    Returns
    -------
    z: ndarray
    flg_z: int
      0 -- Input was a scalar
      1 -- Input was an array

    """
    # float or ndarray?
    if not isiterable(z):
        z = np.array([z])
        flg_z = 0
    else:
        flg_z = 1
    # Return
    return z, flg_z
예제 #7
0
def _tofloat(value):
    """Convert a parameter to float or float array"""

    if isiterable(value):
        try:
            value = np.asanyarray(value, dtype=float)
        except (TypeError, ValueError):
            # catch arrays with strings or user errors like different
            # types of parameters in a parameter set
            raise InputParameterError(
                "Parameter of {0} could not be converted to "
                "float".format(type(value)))
    elif isinstance(value, Quantity):
        # Quantities are fine as is
        pass
    elif isinstance(value, np.ndarray):
        # A scalar/dimensionless array
        value = float(value.item())
    elif isinstance(value, (numbers.Number, np.number)):
        value = float(value)
    elif isinstance(value, bool):
        raise InputParameterError(
            "Expected parameter to be of numerical type, not boolean")
    else:
        raise InputParameterError(
            "Don't know how to convert parameter of {0} to "
            "float".format(type(value)))
    return value
예제 #8
0
파일: utils.py 프로젝트: FRBs/FRB
def halomass_from_stellarmass(log_mstar, z=0):
    """ Halo mass from Stellar mass (Moster+2013).
    Inverts the function `stellarmass_from_halomass`
    numerically.

    Args:
        log_mstar (float or numpy.ndarray): log_10 stellar mass
            in solar mass units.
        z (float, optional): galaxy redshift

    Returns:
        log_Mhalo (float): log_10 halo mass
            in solar mass units.
    """
    try:
        log_mstar * z
    except ValueError:
        raise TypeError(
            "log_mstar and z can't be broadcast together for root finding. Use numpy arrays of same length or scalar values.")

    f = lambda x: stellarmass_from_halomass(x, z=z) - log_mstar
    guess = 2 + log_mstar
    if isiterable(log_mstar):
        return fsolve(f, guess)
    else:
        return fsolve(f, guess)[0]
예제 #9
0
 def __init__(self, num_axes, ref_system=None, ref_pos=None, units=None, axes_names=None, name=None):
     """ Initialize a frame"""
     if units is not None and astu.isiterable(units):
         if len(units) != num_axes:
             raise ValueError("Number of units does not match number of axes")
     self._units=units
     if axes_names is not None and astu.isiterable(axes_names):
         if len(axes_names) != num_axes:
             raise ValueError("Number of axes names does not match number of axes")
     self._axes_names = axes_names
     self._reference_system = ref_system
     self._reference_position = ref_pos
     if name is None:
         self._name = ref_system
     else:
         self._name = name
예제 #10
0
    def set(self, islice, attr, value):
        """
        Set the attribute for a slice of the specobjs

        Args:
            islice (int, ndarray of bool, slice):  Indicates SpecObj to affect
            attr (str):
            value (anything) : Value of the item

        Returns:

        """
        sub_sobjs = self.specobjs[islice]
        if isiterable(value):
            if sub_sobjs.size == len(value):  # Assume you want each paired up
                for kk, sobj in enumerate(sub_sobjs):
                    setattr(sobj, attr, value[kk])
                    return
        # Assuming scalar assignment
        if isinstance(sub_sobjs, SpecObj):
            setattr(sub_sobjs, attr, value)
        else:
            for sobj in sub_sobjs:
                setattr(sobj, attr, value)
        return
예제 #11
0
    def pixel_to_world(self, *quantity_axis_list):
        """
        Convert a pixel coordinate to a data (world) coordinate by using
        `~gwcs.wcs.WCS`.

        This method expects input and returns output in the same order as the
        array dimensions. (Which is the reverse of the underlying WCS object.)

        Parameters
        ----------
        quantity_axis_list : iterable
            An iterable of `~astropy.units.Quantity` with unit as pixel `pix`.

        Returns
        -------
        coord : `list`
            A list of arrays containing the output coordinates.
        """
        world = self.wcs.pixel_to_world(*quantity_axis_list[::-1])

        # Convert list to tuple as a more standard return type
        if isinstance(world, list):
            world = tuple(world)

        # If our return is an iterable then reverse it to match pixel dims.
        if isiterable(world):
            return world[::-1]

        return world
예제 #12
0
 def __call__(self, x, y):
     input_values = np.asarray(x), np.asarray(y)
     output_values = [np.zeros_like(arg) for arg in input_values]
     output_values.append(np.zeros_like(input_values[0]))
     result = self.regions_mask[x, y]
     if not astu.isiterable(result):
         if result != 0:
             return self._selector[result[0]](*input_values)
         else:
             return None  #input_values
     unique_regions = np.unique(result).tolist()
     try:
         unique_regions.remove(0)
     except ValueError:
         pass
     try:
         unique_regions.remove("")
     except ValueError:
         pass
     ra = []
     dec = []
     lam = []
     for i in unique_regions:
         indices = (result == i)
         transform = self._selector[i]
         xyind = [val[indices] for val in input_values]
         r, d, l = transform(x[indices], y[indices])
         ra.extend(r)
         dec.extend(d)
         lam.extend(l)
     return np.asarray(ra), np.asarray(dec), np.asarray(lam)
예제 #13
0
    def __new__(cls, angle, unit=None, dtype=None, copy=True, **kwargs):

        if not isinstance(angle, u.Quantity):
            if unit is not None:
                unit = cls._convert_unit_to_angle_unit(u.Unit(unit))

            if isinstance(angle, tuple):
                angle = cls._tuple_to_float(angle, unit)

            elif isinstance(angle, str):
                angle, angle_unit = util.parse_angle(angle, unit)
                if angle_unit is None:
                    angle_unit = unit

                if isinstance(angle, tuple):
                    angle = cls._tuple_to_float(angle, angle_unit)

                if angle_unit is not unit:
                    # Possible conversion to `unit` will be done below.
                    angle = u.Quantity(angle, angle_unit, copy=False)

            elif (isiterable(angle)
                  and not (isinstance(angle, np.ndarray)
                           and angle.dtype.kind not in 'SUVO')):
                angle = [Angle(x, unit, copy=False) for x in angle]

        return super().__new__(cls,
                               angle,
                               unit,
                               dtype=dtype,
                               copy=copy,
                               **kwargs)
예제 #14
0
    def test_freq_recovery(self):
        # define a bunch of arrays of times to make sure SuperFreq isn't
        #   sensitive to the times
        ts = [np.linspace(0., 150., 12000),
              np.linspace(0., 150., 24414),
              np.linspace(0., 150., 42104),
              np.linspace(150., 300., 12000),
              np.linspace(150., 300., 24414),
              np.linspace(150., 300., 42104),
              np.linspace(0., 150., 12000) + 50*(2*np.pi/self.omega[0])]

        for i,t in enumerate(ts):
            print(i, t.min(), t.max(), len(t))
            f = self.make_f(t)
            nfreq = len(self.omega)

            if not isiterable(self.p):
                ps = [self.p]
            else:
                ps = self.p

            for p in ps:
                print(i, p)
                # create SuperFreq object for this time array
                sf = SuperFreq(t, p=p)

                # solve for the frequencies
                w,amp,phi = sf.frecoder(f[:sf.n], break_condition=1E-5)

                np.testing.assert_allclose(self.omega, w[:nfreq], rtol=1E-7)
                np.testing.assert_allclose(self.A, amp[:nfreq], rtol=1E-5)
                np.testing.assert_allclose(self.phi, phi[:nfreq], rtol=1E-3)
예제 #15
0
def _tofloat(value):
    """Convert a parameter to float or float array"""

    if isiterable(value):
        try:
            value = np.asanyarray(value, dtype=float)
        except (TypeError, ValueError):
            # catch arrays with strings or user errors like different
            # types of parameters in a parameter set
            raise InputParameterError(
                f"Parameter of {type(value)} could not be converted to float")
    elif isinstance(value, Quantity):
        # Quantities are fine as is
        pass
    elif isinstance(value, np.ndarray):
        # A scalar/dimensionless array
        value = float(value.item())
    elif isinstance(value, (numbers.Number, np.number)):
        value = float(value)
    elif isinstance(value, bool):
        raise InputParameterError(
            "Expected parameter to be of numerical type, not boolean")
    else:
        raise InputParameterError(
            f"Don't know how to convert parameter of {type(value)} to float")
    return value
예제 #16
0
    def __init__(self,
                 naxes,
                 axes_type,
                 axes_order,
                 reference_frame=None,
                 reference_position=None,
                 unit=None,
                 axes_names=None,
                 name=None,
                 axis_physical_types=None):
        self._naxes = naxes
        self._axes_order = tuple(axes_order)
        if isinstance(axes_type, str):
            self._axes_type = (axes_type, )
        else:
            self._axes_type = tuple(axes_type)

        self._reference_frame = reference_frame
        if unit is not None:
            if astutil.isiterable(unit):
                unit = tuple(unit)
            else:
                unit = (unit, )
            if len(unit) != naxes:
                raise ValueError(
                    "Number of units does not match number of axes.")
            else:
                self._unit = tuple([u.Unit(au) for au in unit])
        else:
            self._unit = tuple("" for na in range(naxes))
        if axes_names is not None:
            if isinstance(axes_names, str):
                axes_names = (axes_names, )
            else:
                axes_names = tuple(axes_names)
            if len(axes_names) != naxes:
                raise ValueError(
                    "Number of axes names does not match number of axes.")
        else:
            axes_names = tuple([""] * naxes)
        self._axes_names = axes_names

        if name is None:
            self._name = self.__class__.__name__
        else:
            self._name = name

        self._reference_position = reference_position

        if len(self._axes_type) != naxes:
            raise ValueError(
                "Length of axes_type does not match number of axes.")
        if len(self._axes_order) != naxes:
            raise ValueError(
                "Length of axes_order does not match number of axes.")

        super(CoordinateFrame, self).__init__()
        self._axis_physical_types = self._set_axis_physical_types(
            axis_physical_types)
예제 #17
0
파일: models.py 프로젝트: sosey/jwst
 def __init__(self, slits, models):
     super(Slit2Msa, self).__init__()
     if isiterable(slits[0]):
         self._slits = [tuple(s) for s in slits]
         self.slit_ids = [s[0] for s in self._slits]
     else:
         self._slits = list(slits)
         self.slit_ids = self._slits
     self.models = models
예제 #18
0
파일: models.py 프로젝트: sosey/jwst
 def __init__(self, slits, models):
     super(Slit2Msa, self).__init__()
     if isiterable(slits[0]):
         self._slits = [tuple(s) for s in slits]
         self.slit_ids = [s[0] for s in self._slits]
     else:
         self._slits = list(slits)
         self.slit_ids = self._slits
     self.models = models
예제 #19
0
    def __init__(self, naxes, axes_order=(0, 1), reference_frame=None, reference_position=None,
                 unit=None, axes_names=None, name=None):
        """ Initialize a frame"""
        self._axes_order = axes_order
        # map data axis into frame axes - 0-based
        self._naxes = naxes

        if unit is not None:
            if astutil.isiterable(unit):
                if len(unit) != naxes:
                    raise ValueError("Number of units does not match number of axes.")
                else:
                    self._unit = [u.Unit(au) for au in unit]
            else:
                self._unit = [u.Unit(unit)]
        else:
            self._unit = reference_frame.representation_component_units.values()

        if axes_names is not None and astutil.isiterable(axes_names):
            if len(axes_names) != naxes:
                raise ValueError("Number of axes names does not match number of axes.")
        else:
            axes_names = reference_frame.representation_component_names.values()
        self._axes_names = axes_names

        self._reference_frame = reference_frame

        if name is None:
            try:
                self._name = reference_frame.name
            except AttributeError:
                self._name = repr(reference_frame)
        else:
            self._name = name

        if reference_position is not None:
            self._reference_position = reference_position
        else:
            try:
                self._reference_position = reference_frame.reference_position
            except AttributeError:
                self._reference_position = None

        super(CoordinateFrame, self).__init__()
예제 #20
0
파일: image.py 프로젝트: MaxNoe/astropy
    def _getdata(self, keys):
        for idx, (key, axis) in enumerate(zip(keys, self.hdu.shape)):
            if isinstance(key, slice):
                ks = range(*key.indices(axis))
                break
            elif isiterable(key):
                # Handle both integer and boolean arrays.
                ks = np.arange(axis, dtype=int)[key]
                break
            # This should always break at some point if _getdata is called.

        data = [self[keys[:idx] + (k,) + keys[idx + 1:]] for k in ks]

        if any(isinstance(key, slice) or isiterable(key)
               for key in keys[idx + 1:]):
            # data contains multidimensional arrays; combine them.
            return np.array(data)
        else:
            # Only singleton dimensions remain; concatenate in a 1D array.
            return np.concatenate([np.atleast_1d(array) for array in data])
예제 #21
0
    def _getdata(self, keys):
        for idx, (key, axis) in enumerate(zip(keys, self.hdu.shape)):
            if isinstance(key, slice):
                ks = range(*key.indices(axis))
                break
            elif isiterable(key):
                # Handle both integer and boolean arrays.
                ks = np.arange(axis, dtype=int)[key]
                break
            # This should always break at some point if _getdata is called.

        data = [self[keys[:idx] + (k,) + keys[idx + 1:]] for k in ks]

        if any(isinstance(key, slice) or isiterable(key)
               for key in keys[idx + 1:]):
            # data contains multidimensional arrays; combine them.
            return np.array(data)
        else:
            # Only singleton dimensions remain; concatenate in a 1D array.
            return np.concatenate([np.atleast_1d(array) for array in data])
예제 #22
0
def pythonify(node):
    for key, item in node.items():
        if hasattr(item, 'items'):
            pythonify(item)
        else:
            if hasattr(item,'tolist'):
                node[key] = item.tolist()

            elif isiterable(item) and not isinstance(item, str):
                node[key] = map(float, list(item))

            else:
                node[key] = float(item)
예제 #23
0
    def __init__(self,
                 defaultvalue='',
                 description=None,
                 cfgtype=None,
                 module=None,
                 aliases=None):
        from astropy.utils import isiterable

        if module is None:
            module = find_current_module(2)
            if module is None:
                msg1 = 'Cannot automatically determine get_config module, '
                msg2 = 'because it is not called from inside a valid module'
                raise RuntimeError(msg1 + msg2)
            else:
                module = module.__name__

        self.module = module
        self.description = description
        self.__doc__ = description

        # now determine cfgtype if it is not given
        if cfgtype is None:
            if (isiterable(defaultvalue)
                    and not isinstance(defaultvalue, str)):
                # it is an options list
                dvstr = [str(v) for v in defaultvalue]
                cfgtype = 'option(' + ', '.join(dvstr) + ')'
                defaultvalue = dvstr[0]
            elif isinstance(defaultvalue, bool):
                cfgtype = 'boolean'
            elif isinstance(defaultvalue, int):
                cfgtype = 'integer'
            elif isinstance(defaultvalue, float):
                cfgtype = 'float'
            elif isinstance(defaultvalue, str):
                cfgtype = 'string'
                defaultvalue = str(defaultvalue)

        self.cfgtype = cfgtype

        self._validate_val(defaultvalue)
        self.defaultvalue = defaultvalue

        if aliases is None:
            self.aliases = []
        elif isinstance(aliases, str):
            self.aliases = [aliases]
        else:
            self.aliases = aliases
예제 #24
0
파일: _growth.py 프로젝트: sibirrer/skypy
def growth_function_carroll(redshift, cosmology):
    '''Growth function.

    This function returns the growth function as a function of redshift for a
    given cosmology as approximated by Carroll, Press & Turner (1992),
    equation 29 in [1]_.

    Parameters
    ----------
    redshift : (nz,) array_like
        Array of redshifts at which to evaluate the growth function.
    cosmology : astropy.cosmology.Cosmology
        Cosmology object providing methods for the evolution history of
        omega_matter and omega_lambda with redshift.

    Returns
    -------
    growth : (nz,) array_like
        The growth function evaluated at the input redshifts for the given
        cosmology.

    Examples
    --------

    This example returns the growth function for a given array of redshifts
    and for the Astropy default cosmology:

    >>> import numpy as np
    >>> from astropy.cosmology import default_cosmology
    >>> redshift = np.array([0, 1, 2])
    >>> cosmology = default_cosmology.get()
    >>> growth_function_carroll(redshift, cosmology)
    array([0.781361..., 0.476280..., 0.327549...])

    References
    ----------
    .. [1] Carroll, M. and Press, W. and Turner, E., (1992),
        doi : 10.1146/annurev.aa.30.090192.002435
    '''

    if isiterable(redshift):
        redshift = np.asarray(redshift)
    if np.any(redshift < 0):
        raise ValueError('Redshifts must be non-negative')

    Om = cosmology.Om(redshift)
    Ode = cosmology.Ode(redshift)
    Dz = 2.5 * Om / (1 + redshift)
    return Dz / (np.power(Om, 4.0 / 7.0) - Ode + (1 + 0.5 * Om) *
                 (1.0 + Ode / 70.0))
예제 #25
0
    def __init__(self,
                 naxes,
                 axes_type,
                 axes_order,
                 reference_frame=None,
                 reference_position=None,
                 unit=None,
                 axes_names=None,
                 name=None,
                 wcsobj=None):
        self._naxes = naxes
        self._axes_order = tuple(axes_order)
        if isinstance(axes_type, six.string_types):
            self._axes_type = (axes_type, )
        else:
            self._axes_type = tuple(axes_type)
        self._reference_frame = reference_frame
        if unit is not None:
            if astutil.isiterable(unit):
                unit = tuple(unit)
            else:
                unit = (unit, )
            if len(unit) != naxes:
                raise ValueError(
                    "Number of units does not match number of axes.")
            else:
                self._unit = tuple([u.Unit(au) for au in unit])
        if axes_names is not None:
            if isinstance(axes_names, six.string_types):
                axes_names = (axes_names, )
            else:
                axes_names = tuple(axes_names)
            if len(axes_names) != naxes:
                raise ValueError(
                    "Number of axes names does not match number of axes.")
        else:
            axes_names = tuple([""] * naxes)
        self._axes_names = axes_names
        if name is None:
            self._name = self.__class__.__name__
        else:
            self._name = name

        if reference_position is not None:
            self._reference_position = reference_position
        else:
            self._reference_position = None

        super(CoordinateFrame, self).__init__()
예제 #26
0
 def __init__(self,
              num_axes,
              ref_system=None,
              ref_pos=None,
              units=None,
              axes_names=None,
              name=None):
     """ Initialize a frame"""
     if units is not None and astu.isiterable(units):
         if len(units) != num_axes:
             raise ValueError(
                 "Number of units does not match number of axes")
     self._units = units
     if axes_names is not None and astu.isiterable(axes_names):
         if len(axes_names) != num_axes:
             raise ValueError(
                 "Number of axes names does not match number of axes")
     self._axes_names = axes_names
     self._reference_system = ref_system
     self._reference_position = ref_pos
     if name is None:
         self._name = ref_system
     else:
         self._name = name
예제 #27
0
    def coordinate_to_quantity(self, *coords):
        # list or tuple
        if len(coords) == 1 and astutil.isiterable(coords[0]):
            coords = list(coords[0])
        elif len(coords) == 2:
            coords = list(coords)
        else:
            raise ValueError("Unexpected number of coordinates in "
                             "input to frame {} : "
                             "expected 2, got  {}".format(self.name, len(coords)))

        for i in range(2):
            if not hasattr(coords[i], 'unit'):
                coords[i] = coords[i] * self.unit[i]
        return tuple(coords)
예제 #28
0
def sanitize_slices(slices, ndim):
    """
    Given a slice as input sanitise it to an easier to parse format.format

    This function returns a list ``ndim`` long containing slice objects (or ints).
    """

    if not isinstance(slices, (tuple, list)):  # We just have a single int
        slices = (slices, )

    if len(slices) > ndim:
        raise ValueError(
            f"The dimensionality of the specified slice {slices} can not be greater "
            f"than the dimensionality ({ndim}) of the wcs.")

    if any((isiterable(s) for s in slices)):
        raise IndexError(
            "This slice is invalid, only integer or range slices are supported."
        )

    slices = list(slices)

    if Ellipsis in slices:
        if slices.count(Ellipsis) > 1:
            raise IndexError(
                "an index can only have a single ellipsis ('...')")

        # Replace the Ellipsis with the correct number of slice(None)s
        e_ind = slices.index(Ellipsis)
        slices.remove(Ellipsis)
        n_e = ndim - len(slices)
        for i in range(n_e):
            ind = e_ind + i
            slices.insert(ind, slice(None))

    for i in range(ndim):
        if i < len(slices):
            slc = slices[i]
            if isinstance(slc, slice):
                if slc.step and slc.step != 1:
                    raise IndexError(
                        "Slicing WCS with a step is not supported.")
            elif not isinstance(slc, numbers.Integral):
                raise IndexError("Only integer or range slices are accepted.")
        else:
            slices.append(slice(None))

    return slices
예제 #29
0
def _unpack_params(p):
    params = p.copy()
    for key, item in p.items():
        if '_unit' in key:
            continue

        if isiterable(item) and not isinstance(item, str):
            params[key] = np.array(item).astype(float)
        else:
            params[key] = float(item)

        if key + '_unit' in params:
            params[key] = params[key] * u.Unit(params[key + '_unit'])
            del params[key + '_unit']

    return params
예제 #30
0
파일: io.py 프로젝트: adrn/gala
def _unpack_params(p):
    params = p.copy()
    for key, item in p.items():
        if '_unit' in key:
            continue

        if isiterable(item) and not isinstance(item, str):
            params[key] = np.array(item).astype(float)
        else:
            params[key] = float(item)

        if key+'_unit' in params:
            params[key] = params[key] * u.Unit(params[key+'_unit'])
            del params[key+'_unit']

    return params
예제 #31
0
    def get_selector(self, *inputs):
        """
        Get the selector value corresponding to this argument

        Parameters
        ----------
        *inputs :
            All the processed model evaluation inputs.
        """
        _selector = inputs[self.index]
        if isiterable(_selector):
            if len(_selector) == 1:
                return _selector[0]
            else:
                return tuple(_selector)
        return _selector
예제 #32
0
    def __init__(self, naxes, axes_type, axes_order, reference_frame=None,
                 reference_position=None, unit=None, axes_names=None,
                 name=None, axis_physical_types=None):
        self._naxes = naxes
        self._axes_order = tuple(axes_order)
        if isinstance(axes_type, str):
            self._axes_type = (axes_type,)
        else:
            self._axes_type = tuple(axes_type)

        self._reference_frame = reference_frame
        if unit is not None:
            if astutil.isiterable(unit):
                unit = tuple(unit)
            else:
                unit = (unit,)
            if len(unit) != naxes:
                raise ValueError("Number of units does not match number of axes.")
            else:
                self._unit = tuple([u.Unit(au) for au in unit])
        else:
            self._unit = tuple("" for na in range(naxes))
        if axes_names is not None:
            if isinstance(axes_names, str):
                axes_names = (axes_names,)
            else:
                axes_names = tuple(axes_names)
            if len(axes_names) != naxes:
                raise ValueError("Number of axes names does not match number of axes.")
        else:
            axes_names = tuple([""] * naxes)
        self._axes_names = axes_names
        
        if name is None:
            self._name = self.__class__.__name__
        else:
            self._name = name

        self._reference_position = reference_position

        if len(self._axes_type) != naxes:
            raise ValueError("Length of axes_type does not match number of axes.")
        if len(self._axes_order) != naxes:
            raise ValueError("Length of axes_order does not match number of axes.")

        super(CoordinateFrame, self).__init__()
        self._axis_physical_types = self._set_axis_physical_types(axis_physical_types)
예제 #33
0
    def __init__(self, defaultvalue='', description=None, cfgtype=None,
                 module=None, aliases=None):
        from astropy.utils import isiterable

        if module is None:
            module = find_current_module(2)
            if module is None:
                msg1 = 'Cannot automatically determine get_config module, '
                msg2 = 'because it is not called from inside a valid module'
                raise RuntimeError(msg1 + msg2)
            else:
                module = module.__name__

        self.module = module
        self.description = description
        self.__doc__ = description

        # now determine cfgtype if it is not given
        if cfgtype is None:
            if (isiterable(defaultvalue) and not
                    isinstance(defaultvalue, str)):
                # it is an options list
                dvstr = [str(v) for v in defaultvalue]
                cfgtype = 'option(' + ', '.join(dvstr) + ')'
                defaultvalue = dvstr[0]
            elif isinstance(defaultvalue, bool):
                cfgtype = 'boolean'
            elif isinstance(defaultvalue, int):
                cfgtype = 'integer'
            elif isinstance(defaultvalue, float):
                cfgtype = 'float'
            elif isinstance(defaultvalue, str):
                cfgtype = 'string'
                defaultvalue = str(defaultvalue)

        self.cfgtype = cfgtype

        self._validate_val(defaultvalue)
        self.defaultvalue = defaultvalue

        if aliases is None:
            self.aliases = []
        elif isinstance(aliases, str):
            self.aliases = [aliases]
        else:
            self.aliases = aliases
예제 #34
0
파일: nbinteract.py 프로젝트: pllim/stginga
    def load_fits(self, fileorhdu, viewer_name='Main Viewer'):
        """Load FITS image into the desired Ginga image viewer.

        Parameters
        ----------
        fileorhdu
            File or HDU list object.

        viewer_name : str
            Name of Ginga image viewer to display to.

        Raises
        ------
        KeyError
            Viewer name does not exist.

        ValueError
            Invalid file or HDU list object, or HDU list does not contain any
            image.

        """
        if isinstance(fileorhdu, file):
            fileorhdu = fits.HDUList.fromfile(fileorhdu)

        if isiterable(fileorhdu):
            for hdui in fileorhdu:
                if hasattr(hdui, 'is_image') and hdui.is_image:
                    hdu = hdui
                    break
            else:
                raise ValueError(
                    'fileorhdu was iterable but did not contain any '
                    'image HDUs')
        elif hasattr(fileorhdu, 'data') and hasattr(fileorhdu, 'header'):
            # quacks like an HDU - give it a shot
            hdu = fileorhdu
        else:
            raise ValueError('fileorhdu was not a fits file or HDU-ish thing')

        viewer = self.viewers[viewer_name]
        if viewer.fitsimage.get_image() is None:
            aim = AstroImage(logger=self.logger)
            aim.load_hdu(hdu)
            viewer.fitsimage.set_image(aim)
        else:
            viewer.fitsimage.get_image().load_hdu(hdu)
예제 #35
0
    def load_fits(self, fileorhdu, viewer_name='Main Viewer'):
        """Load FITS image into the desired Ginga image viewer.

        Parameters
        ----------
        fileorhdu
            File or HDU list object.

        viewer_name : str
            Name of Ginga image viewer to display to.

        Raises
        ------
        KeyError
            Viewer name does not exist.

        ValueError
            Invalid file or HDU list object, or HDU list does not contain any
            image.

        """
        if isinstance(fileorhdu, file):
            fileorhdu = fits.HDUList.fromfile(fileorhdu)

        if isiterable(fileorhdu):
            for hdui in fileorhdu:
                if hasattr(hdui, 'is_image') and hdui.is_image:
                    hdu = hdui
                    break
            else:
                raise ValueError(
                    'fileorhdu was iterable but did not contain any '
                    'image HDUs')
        elif hasattr(fileorhdu, 'data') and hasattr(fileorhdu, 'header'):
            # quacks like an HDU - give it a shot
            hdu = fileorhdu
        else:
            raise ValueError('fileorhdu was not a fits file or HDU-ish thing')

        viewer = self.viewers[viewer_name]
        if viewer.fitsimage.get_image() is None:
            aim = AstroImage(logger=self.logger)
            aim.load_hdu(hdu)
            viewer.fitsimage.set_image(aim)
        else:
            viewer.fitsimage.get_image().load_hdu(hdu)
예제 #36
0
    def _init_knots(self, knots, has_bounds, lower, upper):
        if np.issubdtype(type(knots), np.integer):
            self._t = np.concatenate((lower, np.zeros(knots), upper))
        elif isiterable(knots):
            self._user_knots = True
            if has_bounds:
                self._t = np.concatenate((lower, np.array(knots), upper))
            else:
                if len(knots) < 2 * (self._degree + 1):
                    raise ValueError(
                        f"Must have at least {2*(self._degree + 1)} knots.")
                self._t = np.array(knots)
        else:
            raise ValueError(f"Knots: {knots} must be iterable or value")

        # check that knots form a viable spline
        self.bspline
예제 #37
0
    def plot_data_and_model(self, samplerorparams, perc=50, datakwargs={}, lfkwargs={}):
        from astropy.utils import isiterable
        from matplotlib import pyplot as plt

        if isiterable(samplerorparams):
            ps = samplerorparams
        else:
            sampler = samplerorparams
            ps = np.percentile(sampler.flatchain, perc, axis=0)
        self.plot_lnprob(*ps, **lfkwargs)

        n, edges = np.histogram(self.magdata, bins=datakwargs.pop('bins', 100))
        cens = (edges[1:]+edges[:-1])/2
        N = np.trapz(x=cens, y=n)
        plt.scatter(cens, np.log(n/N), **datakwargs)

        plt.ylabel('log(lf/data)')
예제 #38
0
파일: common.py 프로젝트: ltlancas/gala
    def _validate_prepare_time(self, t, pos_c):
        """
        Make sure that t is a 1D array and compatible with the C position array.
        """
        if hasattr(t, 'unit'):
            t = t.decompose(self.units).value

        if not isiterable(t):
            t = np.atleast_1d(t)

        t = np.ascontiguousarray(t.ravel())

        if len(t) > 1:
            if len(t) != pos_c.shape[0]:
                raise ValueError("If passing in an array of times, it must have a shape "
                                 "compatible with the input position(s).")

        return t
예제 #39
0
파일: common.py 프로젝트: adrn/gala
    def _validate_prepare_time(self, t, pos_c):
        """
        Make sure that t is a 1D array and compatible with the C position array.
        """
        if hasattr(t, 'unit'):
            t = t.decompose(self.units).value

        if not isiterable(t):
            t = np.atleast_1d(t)

        t = np.ascontiguousarray(t.ravel())

        if len(t) > 1:
            if len(t) != pos_c.shape[0]:
                raise ValueError("If passing in an array of times, it must have a shape "
                                 "compatible with the input position(s).")

        return t
예제 #40
0
 def __init__(self, indx, naxis):
     if _is_int(indx):
         if 0 <= indx < naxis:
             self.npts = 1
             self.offset = indx
             self.contiguous = True
         else:
             raise IndexError(f'Index {indx} out of range.')
     elif isinstance(indx, slice):
         start, stop, step = indx.indices(naxis)
         self.npts = (stop - start) // step
         self.offset = start
         self.contiguous = step == 1
     elif isiterable(indx):
         self.npts = len(indx)
         self.offset = 0
         self.contiguous = False
     else:
         raise IndexError(f'Illegal index {indx}')
예제 #41
0
def get_tau0(wrest, fosc, N, b):
    """Get the value of the optical depth at the line center,
    tau0. Taken from Draine 2011 (see Chapter 9). It neglects stimulated
    emission which is fine for IGM or ISM except for radio-frequency
    transitions.

    Parameters
    ----------
    wrest : Quantity
        Rest-frame wavelength of the transition
    fosc : float
        Oscillator strength of the transition
    N : Quantity or Quantity array
        Column density
    b : Quantity or Quantity array of same shape as N
        Doppler parameter

    Returns
    -------
    tau0: float or array
        Optical depth at the line center. If N and b are
        arrays they must be of same shape.
    """
    # check format for N and b
    if isiterable(N):
        if np.shape(N) != np.shape(b):
            raise IOError('If N is array, b must be array of same shape.')

    # convert to CGS
    b_cgs = b.to('cm/s')
    wrest_cgs = wrest.to('cm')
    N_cgs = N.to('1/cm2')

    # tau0
    tau0 = np.sqrt(
        np.pi
    ) * e2_me_c_cgs * N_cgs * fosc * wrest_cgs / b_cgs  # eq. 9.8 Draine 2011
    # check dimensionless
    tau0 = tau0.decompose()
    if tau0.unit != u.dimensionless_unscaled:
        raise IOError(
            'Something went wrong with the units, check input units.')
    return tau0.value
예제 #42
0
파일: image.py 프로젝트: MaxNoe/astropy
 def __init__(self, indx, naxis):
     if _is_int(indx):
         if 0 <= indx < naxis:
             self.npts = 1
             self.offset = indx
             self.contiguous = True
         else:
             raise IndexError('Index {} out of range.'.format(indx))
     elif isinstance(indx, slice):
         start, stop, step = indx.indices(naxis)
         self.npts = (stop - start) // step
         self.offset = start
         self.contiguous = step == 1
     elif isiterable(indx):
         self.npts = len(indx)
         self.offset = 0
         self.contiguous = False
     else:
         raise IndexError('Illegal index {}'.format(indx))
예제 #43
0
    def __init__(self, naxes, axes_type, axes_order, reference_frame=None,
                 reference_position=None, unit=None, axes_names=None,
                 name=None, wcsobj=None):
        self._naxes = naxes
        self._axes_order = tuple(axes_order)
        if isinstance(axes_type, six.string_types):
            self._axes_type = (axes_type,)
        else:
            self._axes_type = tuple(axes_type)
        self._reference_frame = reference_frame
        if unit is not None:
            if astutil.isiterable(unit):
                unit = tuple(unit)
            else:
                unit = (unit,)
            if len(unit) != naxes:
                raise ValueError("Number of units does not match number of axes.")
            else:
                self._unit = tuple([u.Unit(au) for au in unit])
        if axes_names is not None:
            if isinstance(axes_names, six.string_types):
                axes_names = (axes_names,)
            else:
                axes_names = tuple(axes_names)
            if len(axes_names) != naxes:
                raise ValueError("Number of axes names does not match number of axes.")
        else:
            axes_names = tuple([""] * naxes)
        self._axes_names = axes_names
        if name is None:
            self._name = self.__class__.__name__
        else:
            self._name = name

        if reference_position is not None:
            self._reference_position = reference_position
        else:
            self._reference_position = None

        super(CoordinateFrame, self).__init__()
예제 #44
0
def get_tau0(wrest, fosc, N, b):
    """Get the value of the optical depth at the line center,
    tau0. Taken from Draine 2011 (see Chapter 9). It neglects stimulated
    emission which is fine for IGM or ISM except for radio-frequency
    transitions.

    Parameters
    ----------
    wrest : Quantity
        Rest-frame wavelength of the transition
    fosc : float
        Oscillator strength of the transition
    N : Quantity or Quantity array
        Column density
    b : Quantity or Quantity array of same shape as N
        Doppler parameter

    Returns
    -------
    tau0: float or array
        Optical depth at the line center. If N and b are
        arrays they must be of same shape.
    """
    # check format for N and b
    if isiterable(N):
        if np.shape(N) != np.shape(b):
            raise IOError('If N is array, b must be array of same shape.')

    # convert to CGS
    b_cgs = b.to('cm/s')
    wrest_cgs = wrest.to('cm')
    N_cgs = N.to('1/cm2')

    # tau0
    tau0 = np.sqrt(np.pi) * e2_me_c_cgs * N_cgs * fosc * wrest_cgs  / b_cgs  # eq. 9.8 Draine 2011
    # check dimensionless
    tau0 = tau0.decompose()
    if tau0.unit != u.dimensionless_unscaled:
        raise IOError('Something went wrong with the units, check input units.')
    return tau0.value
예제 #45
0
    def plot_lnprob(self, tipmag, alphargb, alphaother, fracother, magrng=100, doplot=True, delog=False):
        """
        Plots (optionally) and returns arrays suitable for plotting the pdf. If
        `magrng` is a scalar, it gives the number of samples over the data
        domain.  If an array, it's used as the x axis.
        """
        from astropy.utils import isiterable
        from matplotlib import pyplot as plt

        if isiterable(magrng):
            fakemod = self.__class__(magrng)
        else:
            fakemod = self.__class__(np.linspace(self.mindata, self.maxdata, magrng))

        lnpb = fakemod.lnprob(tipmag, alphargb, alphaother, fracother)
        if delog:
            lnpb = np.exp(lnpb - np.min(lnpb))

        if doplot:
            plt.plot(fakemod.magdata, lnpb)

        return fakemod.magdata, lnpb
예제 #46
0
    def create_distortion_transform(self, distortion):
        dist_info = copy.deepcopy(distortion)
        try:
            dist_info.pop('title')
        except KeyError:
            pass
        trans = []
        mods = dist_info['models']

        for m in mods:
            name = m.pop('model_name')
            mclass = getattr(models, name)
            for p in m:
                if astu.isiterable(m[p]) and 'convert2array' in m[p]:
                    a = np.array(m[p]['value'])
                    a.shape = m[p]['convert2array']
                    m[p] = a
            trans.append(mclass(**m))
        if len(trans) > 1:
            return SCompositeModel(trans, inmap, outmap)
        else:
            return trans[0]
예제 #47
0
    def _validate_shape(interval):
        """Validate the shape of an interval representation"""
        MESSAGE = """An interval must be some sort of sequence of length 2"""

        try:
            shape = np.shape(interval)
        except TypeError:
            try:
                # np.shape does not work with lists of Quantities
                if len(interval) == 1:
                    interval = interval[0]
                shape = np.shape([b.to_value() for b in interval])
            except (ValueError, TypeError, AttributeError):
                raise ValueError(MESSAGE)

        valid_shape = shape in ((2,), (1, 2), (2, 0))
        if not valid_shape:
            valid_shape = (len(shape) > 0) and (shape[0] == 2) and \
                all(isinstance(b, np.ndarray) for b in interval)

        if not isiterable(interval) or not valid_shape:
            raise ValueError(MESSAGE)
예제 #48
0
 def undistort(self, x, y):
     input_values = np.asarray(x), np.asarray(y)
     output_values = [np.zeros_like(arg) for arg in input_values]
     output_values.append(np.zeros_like(input_values[0]))
     result = self.regions_mask[x, y]
     if not astu.isiterable(result):
         if result != 0:
             return self._selector[result[0]](*input_values)
         else:
             return None #input_values
     unique_regions = np.unique(result).tolist()
     unique_regions.remove(0)
     focx = []
     focy = []
     for i in unique_regions:
         indices = (result==i)
         transform = self._selector[i]
         xyind = [val[indices] for val in input_values]
         r, d  = transform.undistort(x[indices], y[indices])
         focx.extend(r)
         focy.extend(d)
     return np.asarray(focx), np.asarray(focy)
예제 #49
0
 def undistort(self, x, y):
     input_values = np.asarray(x), np.asarray(y)
     output_values = [np.zeros_like(arg) for arg in input_values]
     output_values.append(np.zeros_like(input_values[0]))
     result = self.regions_mask[x, y]
     if not astu.isiterable(result):
         if result != 0:
             return self._selector[result[0]](*input_values)
         else:
             return None  #input_values
     unique_regions = np.unique(result).tolist()
     unique_regions.remove(0)
     focx = []
     focy = []
     for i in unique_regions:
         indices = (result == i)
         transform = self._selector[i]
         xyind = [val[indices] for val in input_values]
         r, d = transform.undistort(x[indices], y[indices])
         focx.extend(r)
         focy.extend(d)
     return np.asarray(focx), np.asarray(focy)
예제 #50
0
    def __call__(self, f=None, helps=None):
        """Add a helper to a numpy function.

        Normally used as a decorator.

        If ``helps`` is given, it should be the numpy function helped (or an
        iterable of numpy functions helped).

        If ``helps`` is not given, it is assumed the function helped is the
        numpy function with the same name as the decorated function.
        """
        if f is not None:
            if helps is None:
                helps = getattr(np, f.__name__)
            if not isiterable(helps):
                helps = (helps, )
            for h in helps:
                self.assignments[h] = f
            return f
        elif helps is not None:
            return functools.partial(self.__call__, helps=helps)
        else:  # pragma: no cover
            raise ValueError("function_helper requires at least one argument.")
예제 #51
0
    def test_rolling_window(self):
        ts = [np.linspace(0.+dd, 100.+dd, 10000) for dd in np.linspace(0,20,64)]
        for i,t in enumerate(ts):
            print(i, t.min(), t.max(), len(t))
            f = self.make_f(t)
            nfreq = len(self.omega)

            if not isiterable(self.p):
                ps = [self.p]
            else:
                ps = self.p

            for p in ps:
                print(i, p)

                # create SuperFreq object for this time array
                sf = SuperFreq(t, p=p)

                # try recovering the strongest frequency
                w,amp,phi = sf.frecoder(f[:sf.n], break_condition=1E-5)

                np.testing.assert_allclose(self.omega, w[:nfreq], rtol=1E-7)
                np.testing.assert_allclose(self.A, amp[:nfreq], rtol=1E-5)
                np.testing.assert_allclose(self.phi, phi[:nfreq], rtol=1E-4)
예제 #52
0
파일: funcs.py 프로젝트: Cadair/astropy
def concatenate(coords):
    """
    Combine multiple coordinate objects into a single
    `~astropy.coordinates.SkyCoord`.

    "Coordinate objects" here mean frame objects with data,
    `~astropy.coordinates.SkyCoord`, or representation objects.  Currently,
    they must all be in the same frame, but in a future version this may be
    relaxed to allow inhomogenous sequences of objects.

    Parameters
    ----------
    coords : sequence of coordinate objects
        The objects to concatenate

    Returns
    -------
    cskycoord : SkyCoord
        A single sky coordinate with its data set to the concatenation of all
        the elements in ``coords``
    """
    if getattr(coords, 'isscalar', False) or not isiterable(coords):
        raise TypeError('The argument to concatenate must be iterable')

    scs = [SkyCoord(coord, copy=False) for coord in coords]

    # Check that all frames are equivalent
    for sc in scs[1:]:
        if not sc.is_equivalent_frame(scs[0]):
            raise ValueError("All inputs must have equivalent frames: "
                             "{0} != {1}".format(sc, scs[0]))

    # TODO: this can be changed to SkyCoord.from_representation() for a speed
    # boost when we switch to using classmethods
    return SkyCoord(concatenate_representations([c.data for c in coords]),
                    frame=scs[0].frame)
예제 #53
0
    def get_ebv(self, coordinates, interpolate=True, order=1):
        """Get E(B-V) value(s) at given coordinate(s).

        Parameters
        ----------
        coordinates : astropy Coordinates object or tuple
            If tuple, treated as (RA, Dec) in degrees in the ICRS (e.g.,
            "J2000") system. RA and Dec can each be float or list or numpy
            array.
        interpolate : bool
            Interpolate between the map values using
            `scipy.ndimage.map_coordinates`. Default is ``True``.
        order : int
            Interpolation order, if interpolate=True. Default is ``1``.

        Returns
        -------
        ebv : float or `~numpy.ndarray`
            Specific extinction E(B-V) at the given locations.
        """

        # Parse input
        if not isinstance(coordinates, SkyCoord):
            ra, dec = coordinates
            coordinates = SkyCoord(ra=ra, dec=dec, frame='icrs', unit=u.degree)

        # Convert to galactic coordinates.
        coordinates = coordinates.galactic
        l = coordinates.l.radian
        b = coordinates.b.radian

        # Check if l, b are scalar. If so, convert to 1-d arrays.
        return_scalar = False
        if not isiterable(l):
            return_scalar = True
            l, b = np.array([l]), np.array([b])

        # Initialize return array
        ebv = np.empty_like(l)

        # Treat north (b>0) separately from south (b<0).
        for sign, mask, ext in [(1, b >= 0, 'ngp'), (-1, b < 0, 'sgp')]:
            if not np.any(mask):
                continue

            # Only load the FITS file for this hemisphere if it is needed
            # and has not been previously loaded. Once loaded, it will be
            # kept in memory for subsequent calls.
            if self.__dict__[ext] is None:
                hdulist = fits.open(self.fname.format(ext))
                header = hdulist[0].header
                self.__dict__[ext] = {'CRPIX1': header['CRPIX1'],
                                      'CRPIX2': header['CRPIX2'],
                                      'LAM_SCAL': header['LAM_SCAL'],
                                      'data': hdulist[0].data}
                hdulist.close()

            d = self.__dict__[ext]

            # Project from galactic longitude/latitude to lambert pixels.
            # (See SFD98).
            x = d['CRPIX1']-1. + (d['LAM_SCAL'] * np.cos(l[mask]) *
                                  np.sqrt(1. - sign*np.sin(b[mask])))
            y = d['CRPIX2']-1. - sign*(d['LAM_SCAL'] * np.sin(l[mask]) *
                                       np.sqrt(1. - sign*np.sin(b[mask])))

            # Get map values at these pixel coordinates.
            if interpolate:
                ebv[mask] = map_coordinates(d['data'], [y, x], order=order)
            else:
                x = np.round(x).astype(np.int)
                y = np.round(y).astype(np.int)
                ebv[mask] = d['data'][y, x]

        if return_scalar:
            return ebv[0]
        return ebv
예제 #54
0
파일: core.py 프로젝트: adrn/gala
    def plot_density_contours(self, grid, filled=True, ax=None, labels=None,
                              subplots_kw=dict(), **kwargs):
        """
        Plot density contours. Computes the density on a grid
        (specified by the array `grid`).

        .. warning:: Right now the grid input must be arrays and must already be in
            the unit system of the potential. Quantity support is coming...

        Parameters
        ----------
        grid : tuple
            Coordinate grids or slice value for each dimension. Should be a
            tuple of 1D arrays or numbers.
        filled : bool (optional)
            Use :func:`~matplotlib.pyplot.contourf` instead of
            :func:`~matplotlib.pyplot.contour`. Default is ``True``.
        ax : matplotlib.Axes (optional)
        labels : iterable (optional)
            List of axis labels.
        subplots_kw : dict
            kwargs passed to matplotlib's subplots() function if an axes object
            is not specified.
        kwargs : dict
            kwargs passed to either contourf() or plot().

        Returns
        -------
        fig : `~matplotlib.Figure`

        """

        import matplotlib.pyplot as plt
        from matplotlib import cm

        # figure out which elements are iterable, which are numeric
        _grids = []
        _slices = []
        for ii, g in enumerate(grid):
            if isiterable(g):
                _grids.append((ii, g))
            else:
                _slices.append((ii, g))

        # figure out the dimensionality
        ndim = len(_grids)

        # if ndim > 2, don't know how to handle this!
        if ndim > 2:
            raise ValueError("ndim > 2: you can only make contours on a 2D grid. For other "
                             "dimensions, you have to specify values to slice.")

        if ax is None:
            # default figsize
            fig, ax = plt.subplots(1, 1, **subplots_kw)
        else:
            fig = ax.figure

        if ndim == 1:
            # 1D curve
            x1 = _grids[0][1]
            r = np.zeros((len(_grids) + len(_slices), len(x1)))
            r[_grids[0][0]] = x1

            for ii, slc in _slices:
                r[ii] = slc

            Z = self.density(r*self.units['length']).value
            ax.plot(x1, Z, **kwargs)

            if labels is not None:
                ax.set_xlabel(labels[0])
                ax.set_ylabel("potential")
        else:
            # 2D contours
            x1, x2 = np.meshgrid(_grids[0][1], _grids[1][1])
            shp = x1.shape
            x1, x2 = x1.ravel(), x2.ravel()

            r = np.zeros((len(_grids) + len(_slices), len(x1)))
            r[_grids[0][0]] = x1
            r[_grids[1][0]] = x2

            for ii, slc in _slices:
                r[ii] = slc

            Z = self.density(r*self.units['length']).value

            # make default colormap not suck
            cmap = kwargs.pop('cmap', cm.Blues)
            if filled:
                cs = ax.contourf(x1.reshape(shp), x2.reshape(shp), Z.reshape(shp),
                                 cmap=cmap, **kwargs)
            else:
                cs = ax.contour(x1.reshape(shp), x2.reshape(shp), Z.reshape(shp),
                                cmap=cmap, **kwargs)

            # cs.cmap.set_under('w')
            # cs.cmap.set_over('k')

            if labels is not None:
                ax.set_xlabel(labels[0])
                ax.set_ylabel(labels[1])

        return fig
예제 #55
0
def animate_source(source, label=None, fps=30, length=20.,
                   phase_range=(None, None), wave_range=(None, None),
                   match_peakphase=True, match_peakflux=True,
                   peakwave=4000., fname=None, still=False):
    """Animate spectral timeseries of model(s) using matplotlib.animation.

    *Note:* Requires matplotlib v1.1 or higher.

    Parameters
    ----------
    source : `~sncosmo.Source` or str or iterable thereof
        The Source to animate or list of sources to animate.
    label : str or list of str, optional
        If given, label(s) for Sources, to be displayed in a legend on
        the animation.
    fps : int, optional
        Frames per second. Default is 30.
    length : float, optional
        Movie length in seconds. Default is 15.
    phase_range : (float, float), optional
        Phase range to plot (in the timeframe of the first source if multiple
        sources are given). `None` indicates to use the maximum extent of the
        source(s).
    wave_range : (float, float), optional
        Wavelength range to plot. `None` indicates to use the maximum extent
        of the source(s).
    match_peakflux : bool, optional
        For multiple sources, scale fluxes so that the peak of the spectrum
        at the peak matches that of the first source. Default is
        True.
    match_peakphase : bool, optional
        For multiple sources, shift additional sources so that the source's
        reference phase matches that of the first source.
    peakwave : float, optional
        Wavelength used in match_peakflux and match_peakphase. Default is
        4000.
    fname : str, optional
        If not `None`, save animation to file `fname`. Requires ffmpeg
        to be installed with the appropriate codecs: If `fname` has
        the extension '.mp4' the libx264 codec is used. If the
        extension is '.webm' the VP8 codec is used. Otherwise, the
        'mpeg4' codec is used. The first frame is also written to a
        png.
    still : bool, optional
        When writing to a file, also save the first frame as a png file.
        This is useful for displaying videos on a webpage.

    Returns
    -------
    ani : `~matplotlib.animation.FuncAnimation`
        Animation object that can be shown or saved.
    """

    from matplotlib import pyplot as plt
    from matplotlib import animation

    warn_once('animate_source', '1.4', '2.0')

    # Convert input to a list (if it isn't already).
    if (not isiterable(source)) or isinstance(source, six.string_types):
        sources = [source]
    else:
        sources = source

    # Check that all entries are Source or strings.
    for m in sources:
        if not (isinstance(m, six.string_types) or isinstance(m, Source)):
            raise ValueError('str or Source instance expected for '
                             'source(s)')
    sources = [get_source(m) for m in sources]

    # Get the source labels
    if label is None:
        labels = [None] * len(sources)
    elif isinstance(label, six.string_types):
        labels = [label]
    else:
        labels = label
    if len(labels) != len(sources):
        raise ValueError('if given, length of label must match '
                         'that of source')

    # Get a wavelength array for each source.
    waves = [np.arange(m.minwave(), m.maxwave(), 10.) for m in sources]

    # Phase offsets needed to match peak phases.
    peakphases = [m.peakphase(peakwave) for m in sources]
    if match_peakphase:
        phase_offsets = [p - peakphases[0] for p in peakphases]
    else:
        phase_offsets = [0.] * len(sources)

    # Determine phase range to display.
    minphase, maxphase = phase_range
    if minphase is None:
        minphase = min([sources[i].minphase() - phase_offsets[i] for
                        i in range(len(sources))])
    if maxphase is None:
        maxphase = max([sources[i].maxphase() - phase_offsets[i] for
                        i in range(len(sources))])

    # Determine the wavelength range to display.
    minwave, maxwave = wave_range
    if minwave is None:
        minwave = min([m.minwave() for m in sources])
    if maxwave is None:
        maxwave = max([m.maxwave() for m in sources])

    # source time interval between frames
    phase_interval = (maxphase - minphase) / (length * fps)

    # maximum flux density of entire spectrum at the peak phase
    # for each source
    max_fluxes = [np.max(m.flux(phase, w))
                  for m, phase, w in zip(sources, peakphases, waves)]

    # scaling factors
    if match_peakflux:
        peakfluxes = [m.flux(phase, peakwave)  # Not the same as max_fluxes!
                      for m, phase in zip(sources, peakphases)]
        scaling_factors = [peakfluxes[0] / f for f in peakfluxes]
        global_max_flux = max_fluxes[0]
    else:
        scaling_factors = [1.] * len(sources)
        global_max_flux = max(max_fluxes)

    ymin = -0.06 * global_max_flux
    ymax = 1.1 * global_max_flux

    # Set up the figure, the axis, and the plot element we want to animate
    fig = plt.figure()
    ax = plt.axes(xlim=(minwave, maxwave), ylim=(ymin, ymax))
    plt.axhline(y=0., c='k')
    plt.xlabel('Wavelength ($\\AA$)')
    plt.ylabel('Flux Density ($F_\lambda$)')
    phase_text = ax.text(0.05, 0.95, '', ha='left', va='top',
                         transform=ax.transAxes)
    empty_lists = 2 * len(sources) * [[]]
    lines = ax.plot(*empty_lists, lw=1)
    if label is not None:
        for line, l in zip(lines, labels):
            line.set_label(l)
        legend = plt.legend(loc='upper right')

    def init():
        for line in lines:
            line.set_data([], [])
        phase_text.set_text('')
        return tuple(lines) + (phase_text,)

    def animate(i):
        current_phase = minphase + phase_interval * i
        for j in range(len(sources)):
            y = sources[j].flux(current_phase + phase_offsets[j], waves[j])
            lines[j].set_data(waves[j], y * scaling_factors[j])
        phase_text.set_text('phase = {0:.1f}'.format(current_phase))
        return tuple(lines) + (phase_text,)

    ani = animation.FuncAnimation(fig, animate, init_func=init,
                                  frames=int(fps*length), interval=(1000./fps),
                                  blit=True)

    # Save the animation as an mp4 or webm file.
    # This requires that ffmpeg is installed.
    if fname is not None:
        if still:
            i = fname.rfind('.')
            stillfname = fname[:i] + '.png'
            plt.savefig(stillfname)
        ext = fname[i+1:]
        codec = {'mp4': 'libx264', 'webm': 'libvpx'}.get(ext, 'mpeg4')
        ani.save(fname, fps=fps, codec=codec, extra_args=['-vcodec', codec],
                 writer='ffmpeg_file', bitrate=1800)
        plt.close()
    else:
        return ani
예제 #56
0
def _parse_args(args):
    # first try pulling out separate coordinates
    c1 = args.pop('coord1', None)
    c2 = args.pop('coord2', None)
    cargs = (c1, c2)

    # if either are None, check for a coordstr
    if c1 is None or c2 is None:
        coordstr = args.pop('coordstr', None)
        cargs = (coordstr,)

    if (c1 is None or c2 is None) and (coordstr is None):
        # TODO: throw a error
        raise ValueError("Shitty arguments, yo.")

    # default units are degrees
    c1u = u.Unit(args.pop('coord1unit', u.deg))
    c2u = u.Unit(args.pop('coord2unit', u.deg))

    to_system = args.pop('to')
    from_system = args.pop('from')

    # extra arguments to pass to the coordinate frames
    fromargs = dict()
    toargs = dict()
    for k, v in args.items():
        if k.startswith('from_'):
            fromargs[k.split('from_')[1]] = v

        if k.startswith('to_'):
            toargs[k.split('to_')[1]] = v

    fromargs['frame'] = from_system.lower()

    # get the 'to' frame class
    ToFrame = frame_transform_graph.lookup_name(to_system.lower())

    c = SkyCoord(*cargs, unit=(c1u, c2u), **fromargs).transform_to(frame=ToFrame(**toargs))

    comps = []
    for compnm in c.representation_component_names:
        compval = getattr(c, compnm)
        uout = c.representation_component_units.get(compnm, None)
        if uout is not None:
            compval.to(uout)
        comps.append((compnm, compval))

    output = {}
    for i, (compnm, comp) in enumerate(comps):
        # container for information for this coordinate
        this_coord = dict()

        ip1s = str(i + 1)
        if not isiterable(comp.value):
            val = [comp.value]
        else:
            val = comp.value

        this_coord['data'] = list(val)
        this_coord['name'] = compnm
        this_coord['unit'] = str(comp.unit)
        output['coord' + ip1s] = this_coord

    for fattr_nm in c.get_frame_attr_names():
        output['frame_' + fattr_nm] = str(getattr(c, fattr_nm))

    return output