Пример #1
0
def _slice0(cube, axis, scale):
    """
    0th moment along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float

    Returns
    -------
    moment0_error : array
    """
    shp = _moment_shp(cube, axis)
    result = np.zeros(shp)

    view = [slice(None)] * 3

    valid = np.zeros(shp, dtype=np.bool)
    for i in range(cube.shape[axis]):
        view[axis] = i
        plane = cube._mask.include(data=cube._data, wcs=cube._wcs, view=view)
        valid |= plane
        result += plane
    result = scale * np.sqrt(result)
    result[~valid] = np.nan
    return result
Пример #2
0
def _slice1(cube, axis, scale, moment0, moment1):
    """
    1st moment along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float
    moment0 : 0th moment
    moment1 : 1st moment

    Returns
    -------
    moment1_error : array
    """
    shp = _moment_shp(cube, axis)
    result = np.zeros(shp)

    view = [slice(None)] * 3
    pix_cen = cube._pix_cen()[axis]

    for i in range(cube.shape[axis]):
        view[axis] = i
        result += np.power((pix_cen[view] - moment1), 2)
    return (scale / moment0) * np.sqrt(result)
Пример #3
0
def moment_raywise(cube, order, axis):
    """
    Compute moments by accumulating the answer one ray at a time
    """
    shp = _moment_shp(cube, axis)
    out = np.zeros(shp) * np.nan

    pix_cen = cube._pix_cen()[axis]
    pix_size = cube._pix_size()[axis]

    for x, y, slc in cube._iter_rays(axis):
        # the intensity, i.e. the weights
        include = cube._mask.include(data=cube._data, wcs=cube._wcs,
                                     view=slc)
        if not include.any():
            continue

        data = cube.flattened(slc).value * pix_size[slc][include]

        if order == 0:
            out[x, y] = data.sum()
            continue

        order1 = (data * pix_cen[slc][include]).sum() / data.sum()
        if order == 1:
            out[x, y] = order1
            continue

        ordern = (data * (pix_cen[slc][include] - order1) ** order).sum()
        ordern /= data.sum()

        out[x, y] = ordern
    return out
Пример #4
0
def _slice1(cube, axis, scale, moment0, moment1):
    """
    1st moment along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float or SpectralCube
    moment0 : 0th moment
    moment1 : 1st moment

    Returns
    -------
    moment1_error : array
    """

    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        _scale_cube = True
    else:
        _scale_cube = False

    # I don't think there is a way to do this with one pass.
    # The first 2 moments always have to be pre-computed.

    # Divide moment0 by the pixel size in the given axis so it represents the
    # sum.
    spec_unit = cube.spectral_axis.unit
    axis_sum = u.Quantity(moment0 /
                          (cube._pix_size_slice(axis) * spec_unit))

    shp = _moment_shp(cube, axis)
    result = np.zeros(shp) * spec_unit ** 2

    view = [slice(None)] * 3
    pix_cen = u.Quantity(cube._pix_cen()[axis] * spec_unit)

    # term2 does not depend on the plane.
    term2 = moment1 / axis_sum

    for i in range(cube.shape[axis]):
        view[axis] = i

        term1 = pix_cen[view] / axis_sum

        if _scale_cube:
            noise_plane = \
                np.nan_to_num(scale.filled_data[view])
        else:
            noise_plane = scale

        result += np.power((term1 - term2) * noise_plane, 2)

    return np.sqrt(result)
Пример #5
0
def _slice1(cube, axis, scale, moment0, moment1):
    """
    1st moment along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float or SpectralCube
    moment0 : 0th moment
    moment1 : 1st moment

    Returns
    -------
    moment1_error : array
    """

    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        _scale_cube = True
    else:
        _scale_cube = False

    # I don't think there is a way to do this with one pass.
    # The first 2 moments always have to be pre-computed.

    # Divide moment0 by the pixel size in the given axis so it represents the
    # sum.
    spec_unit = cube.spectral_axis.unit
    axis_sum = u.Quantity(moment0 /
                          (cube._pix_size_slice(axis) * spec_unit))

    shp = _moment_shp(cube, axis)
    result = np.zeros(shp) * spec_unit ** 2

    view = [slice(None)] * 3
    pix_cen = u.Quantity(cube._pix_cen()[axis] * spec_unit)

    # term2 does not depend on the plane.
    term2 = moment1 / axis_sum

    for i in range(cube.shape[axis]):
        view[axis] = i

        term1 = pix_cen[view] / axis_sum

        if _scale_cube:
            noise_plane = \
                np.nan_to_num(scale.filled_data[view])
        else:
            noise_plane = scale

        result += np.power((term1 - term2) * noise_plane, 2)

    return np.sqrt(result)
Пример #6
0
def _slice0(cube, axis, scale):
    """
    0th moment along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float

    Returns
    -------
    moment0_error : array
    """
    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        _scale_cube = True
    else:
        _scale_cube = False

    shp = _moment_shp(cube, axis)
    result = np.zeros(shp) * cube.unit ** 2

    view = [slice(None)] * 3
    valid = np.zeros(shp, dtype=np.bool)

    for i in range(cube.shape[axis]):
        view[axis] = i
        plane = cube._mask.include(data=cube._data, wcs=cube._wcs, view=view)
        valid |= plane

        if _scale_cube:
            noise_plane = np.nan_to_num(scale.filled_data[view])
        else:
            noise_plane = scale

        result += plane * np.power(noise_plane, 2)

    out_result = np.sqrt(result) * cube._pix_size_slice(axis)
    out_result[~valid] = np.nan

    return out_result
Пример #7
0
def _slice0(cube, axis, scale):
    """
    0th moment along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float

    Returns
    -------
    moment0_error : array
    """
    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        _scale_cube = True
    else:
        _scale_cube = False

    shp = _moment_shp(cube, axis)
    result = np.zeros(shp) * cube.unit ** 2

    view = [slice(None)] * 3
    valid = np.zeros(shp, dtype=np.bool)

    for i in range(cube.shape[axis]):
        view[axis] = i
        plane = cube._mask.include(data=cube._data, wcs=cube._wcs, view=view)
        valid |= plane

        if _scale_cube:
            noise_plane = np.nan_to_num(scale.filled_data[view])
        else:
            noise_plane = scale

        result += plane * np.power(noise_plane, 2)

    out_result = np.sqrt(result) * cube._pix_size_slice(axis)
    out_result[~valid] = np.nan

    return out_result
Пример #8
0
def _cube1(cube, axis, scale, moment0, moment1):
    '''
    Moment 1 error computed cube-wise.
    '''

    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        noise_plane = scale.filled_data[:]
    else:
        noise_plane = scale

    # I don't think there is a way to do this with one pass.
    # The first 2 moments always have to be pre-computed.

    # Divide moment0 by the pixel size in the given axis so it represents the
    # sum.
    spec_unit = cube.spectral_axis.unit
    axis_sum = u.Quantity(moment0 /
                          (cube._pix_size_slice(axis) * spec_unit))

    shp = _moment_shp(cube, axis)
    result = np.zeros(shp) * spec_unit

    pix_cen = cube._pix_cen()[axis] * spec_unit

    term1 = pix_cen / axis_sum
    term2 = moment1 / axis_sum

    result = np.sqrt(np.sum(np.power((term1 - term2) *
                                     np.nan_to_num(noise_plane), 2),
                            axis=axis))

    good_pix = np.isfinite(moment0) + np.isfinite(moment1)

    result[~good_pix] = np.NaN

    return result
Пример #9
0
def _cube1(cube, axis, scale, moment0, moment1):
    '''
    Moment 1 error computed cube-wise.
    '''

    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        noise_plane = scale.filled_data[:]
    else:
        noise_plane = scale

    # I don't think there is a way to do this with one pass.
    # The first 2 moments always have to be pre-computed.

    # Divide moment0 by the pixel size in the given axis so it represents the
    # sum.
    spec_unit = cube.spectral_axis.unit
    axis_sum = u.Quantity(moment0 /
                          (cube._pix_size_slice(axis) * spec_unit))

    shp = _moment_shp(cube, axis)
    result = np.zeros(shp) * spec_unit

    pix_cen = cube._pix_cen()[axis] * spec_unit

    term1 = pix_cen / axis_sum
    term2 = moment1 / axis_sum

    result = np.sqrt(np.sum(np.power((term1 - term2) *
                                     np.nan_to_num(noise_plane), 2),
                            axis=axis))

    good_pix = np.isfinite(moment0) + np.isfinite(moment1)

    result[~good_pix] = np.NaN

    return result
Пример #10
0
def _slice2(cube, axis, scale, moment0, moment1, moment2,
            moment1_err):
    """
    2nd moment error along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float
    moment0 : 0th moment
    moment1 : 1st moment
    moment2 : 2nd moment
    moment1_err : 1st moment error

    Returns
    -------
    moment1_error : array
    """
    shp = _moment_shp(cube, axis)
    term1 = np.zeros(shp)
    term2 = np.zeros(shp)

    view = [slice(None)] * 3
    pix_cen = cube._pix_cen()[axis]
    pix_size = cube._pix_size()[axis]

    for i in range(cube.shape[axis]):
        view[axis] = i
        plane = cube._get_filled_data(fill=0, view=view)

        term1 += scale**2 * \
            np.power((np.power((pix_cen[view] - moment1), 2) -
                     moment2), 2)

        term2 += (plane*pix_size[view]) * (pix_cen[view] - moment1)

    return (1/moment0) * np.sqrt(term1 + 4*np.power(moment1_err*term2, 2))
Пример #11
0
def _slice2(cube, axis, scale, moment0, moment1, moment2,
            moment1_err):
    """
    2nd moment error along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float or SpectralCube
    moment0 : 0th moment
    moment1 : 1st moment
    moment2 : 2nd moment
    moment1_err : 1st moment error

    Returns
    -------
    moment1_error : array
    """

    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        _scale_cube = True
    else:
        _scale_cube = False

    # Divide moment0 by the pixel size in the given axis so it represents the
    # sum.
    spec_unit = cube.spectral_axis.unit
    axis_sum = u.Quantity(moment0 /
                          (cube._pix_size_slice(axis) * spec_unit))

    shp = _moment_shp(cube, axis)
    term1 = np.zeros(shp) * spec_unit ** 4
    term2 = np.zeros(shp) * spec_unit * cube.unit

    view = [slice(None)] * 3
    pix_cen = cube._pix_cen()[axis] * spec_unit

    # term12 does not depend on plane.
    term12 = moment2 / axis_sum

    for i in range(cube.shape[axis]):
        view[axis] = i
        plane = np.nan_to_num(cube.filled_data[view])

        term11 = np.power((pix_cen[view] - moment1), 2) / axis_sum

        if _scale_cube:
            noise_plane = \
                np.nan_to_num(scale.filled_data[view])
        else:
            noise_plane = scale

        term1 += np.power((term11 - term12) * noise_plane, 2)

        term2 += np.nan_to_num(plane) * (pix_cen[view] - moment1)

    term2 = 4 * np.power((moment1_err * term2) / (axis_sum), 2)

    return np.sqrt(term1 + term2)
Пример #12
0
def _slice2(cube, axis, scale, moment0, moment1, moment2,
            moment1_err):
    """
    2nd moment error along an axis, calculated slicewise

    Parameters
    ----------
    cube : SpectralCube
    axis : int
    scale : float or SpectralCube
    moment0 : 0th moment
    moment1 : 1st moment
    moment2 : 2nd moment
    moment1_err : 1st moment error

    Returns
    -------
    moment1_error : array
    """

    if isinstance(scale, SpectralCube):
        # scale should then have the same shape as the cube.
        if cube.shape != scale.shape:
            raise IndexError("When scale is a SpectralCube, it must have the"
                             " same shape as the cube.")
        _scale_cube = True
    else:
        _scale_cube = False

    # Divide moment0 by the pixel size in the given axis so it represents the
    # sum.
    spec_unit = cube.spectral_axis.unit
    axis_sum = u.Quantity(moment0 /
                          (cube._pix_size_slice(axis) * spec_unit))

    shp = _moment_shp(cube, axis)
    term1 = np.zeros(shp) * spec_unit ** 4
    term2 = np.zeros(shp) * spec_unit * cube.unit

    view = [slice(None)] * 3
    pix_cen = cube._pix_cen()[axis] * spec_unit

    # term12 does not depend on plane.
    term12 = moment2 / axis_sum

    for i in range(cube.shape[axis]):
        view[axis] = i
        plane = np.nan_to_num(cube.filled_data[view])

        term11 = np.power((pix_cen[view] - moment1), 2) / axis_sum

        if _scale_cube:
            noise_plane = \
                np.nan_to_num(scale.filled_data[view])
        else:
            noise_plane = scale

        term1 += np.power((term11 - term12) * noise_plane, 2)

        term2 += np.nan_to_num(plane) * (pix_cen[view] - moment1)

    term2 = 4 * np.power((moment1_err * term2) / (axis_sum), 2)

    return np.sqrt(term1 + term2)