예제 #1
0
    # 10 consecutive channels must be above the MAD level to be real emission.
    num_chans = 7

    peak_snr = 4.5
    # Cutoff level
    min_snr = 3
    # Where to cut at the line edges
    edge_thresh = 0.5

    # Smooth the cube, then create a noise model
    spec_kernel = Box1DKernel(smooth_chans)
    smooth_cube = cube.spectral_smooth(spec_kernel)

    noise = Noise(smooth_cube)
    noise.estimate_noise(spectral_flat=True)
    noise.get_scale_cube()

    snr = noise.snr.copy()

    posns = np.where(snr.max(axis=0) >= min_snr)

    bad_pos = np.where(snr.max(axis=0) < min_snr)
    mask[:, bad_pos[0], bad_pos[1]] = False

    # In case single spectra need to be inspected.
    verbose = False

    for i, j in ProgressBar(zip(*posns)):

        spectrum = cube[:, i, j].value
예제 #2
0
    # 10 consecutive channels must be above the MAD level to be real emission.
    num_chans = 7

    peak_snr = 4.5
    # Cutoff level
    min_snr = 3
    # Where to cut at the line edges
    edge_thresh = 0.5

    # Smooth the cube, then create a noise model
    spec_kernel = Box1DKernel(smooth_chans)
    smooth_cube = cube.spectral_smooth(spec_kernel)

    noise = Noise(smooth_cube)
    noise.estimate_noise(spectral_flat=True)
    noise.get_scale_cube()

    snr = noise.snr.copy()

    posns = np.where(snr.max(axis=0) >= min_snr)

    bad_pos = np.where(snr.max(axis=0) < min_snr)
    mask[:, bad_pos[0], bad_pos[1]] = False

    # In case single spectra need to be inspected.
    verbose = False

    for i, j in ProgressBar(zip(*posns)):

        spectrum = cube[:, i, j].value
예제 #3
0
def make_signal_mask(cube, smooth_chans=200. / 66., min_chan=7, peak_snr=5.,
                     min_snr=3.5, edge_thresh=1.5, verbose=False):
    '''
    Create a robust signal mask by requiring spatial and spectral
    connectivity.
    '''

    import astropy.units as u
    from astropy.convolution import Box1DKernel
    from signal_id import Noise
    from scipy import ndimage as nd
    from astropy.wcs.utils import proj_plane_pixel_scales
    from astropy.utils.console import ProgressBar
    import skimage.morphology as mo
    import numpy as np
    from radio_beam import Beam
    from itertools import groupby, chain
    from operator import itemgetter
    import matplotlib.pyplot as p

    pixscale = proj_plane_pixel_scales(cube.wcs)[0]

    # # Want to smooth the mask edges
    mask = cube.mask.include().copy()

    # Set smoothing parameters and # consecutive channels.
    smooth_chans = int(round_up_to_odd(smooth_chans))

    # consecutive channels to be real emission.
    num_chans = min_chan

    # Smooth the cube, then create a noise model
    spec_kernel = Box1DKernel(smooth_chans)
    smooth_cube = cube.spectral_smooth(spec_kernel)

    noise = Noise(smooth_cube)
    noise.estimate_noise(spectral_flat=True)
    noise.get_scale_cube()

    snr = noise.snr.copy()

    snr[np.isnan(snr)] = 0.0

    posns = np.where(snr.max(axis=0) >= min_snr)

    bad_pos = np.where(snr.max(axis=0) < min_snr)
    mask[:, bad_pos[0], bad_pos[1]] = False

    for i, j in ProgressBar(zip(*posns)):

        # Look for all pixels above min_snr
        good_posns = np.where(snr[:, i, j] > min_snr)[0]

        # Reject if the total is less than connectivity requirement
        if good_posns.size < num_chans:
            mask[:, i, j] = False
            continue

        # Find connected pixels
        sequences = []
        for k, g in groupby(enumerate(good_posns), lambda (i, x): i - x):
            sequences.append(map(itemgetter(1), g))

        # Check length and peak. Require a minimum of 3 pixels above the noise
        # to grow from.
        sequences = [seq for seq in sequences if len(seq) >= 3 and
                     np.nanmax(snr[:, i, j][seq]) >= peak_snr]

        # Continue if no good sequences found
        if len(sequences) == 0:
            mask[:, i, j] = False
            continue

        # Now take each valid sequence and expand the edges until the smoothed
        # spectrum approaches zero.
        edges = [[seq[0], seq[-1]] for seq in sequences]
        for n, edge in enumerate(edges):
            # Lower side
            if n == 0:
                start_posn = edge[0]
                stop_posn = 0
            else:
                start_posn = edge[0] - edges[n - 1][0]
                stop_posn = edges[n - 1][0]

            for pt in np.arange(start_posn, stop_posn, -1):
                # if smoothed[pt] <= mad * edge_thresh:
                if snr[:, i, j][pt] <= edge_thresh:
                    break

                sequences[n].insert(0, pt)

            # Upper side
            start_posn = edge[1]
            if n == len(edges) - 1:
                stop_posn = cube.shape[0]
            else:
                stop_posn = edges[n + 1][0]

            for pt in np.arange(start_posn, stop_posn, 1):
                # if smoothed[pt] <= mad * edge_thresh:
                if snr[:, i, j][pt] <= edge_thresh:
                    break

                sequences[n].insert(0, pt)

        # Final check for the min peak level and ensure all meet the
        # spectral connectivity requirement
        sequences = [seq for seq in sequences if len(seq) >= num_chans and
                     np.nanmax(snr[:, i, j][seq]) >= peak_snr]

        if len(sequences) == 0:
            mask[:, i, j] = False
            continue

        bad_posns = \
            list(set(np.arange(cube.shape[0])) - set(list(chain(*sequences))))

        mask[:, i, j][bad_posns] = False

        if verbose:
            p.subplot(121)
            p.plot(cube.spectral_axis.value, noise.snr[:, i, j])
            min_val = cube.spectral_axis.value[np.where(mask[:, i, j])[0][-1]]
            max_val = cube.spectral_axis.value[np.where(mask[:, i, j])[0][0]]
            p.vlines(min_val, 0,
                     np.nanmax(noise.snr[:, i, j]))
            p.vlines(max_val, 0,
                     np.nanmax(noise.snr[:, i, j]))
            p.plot(cube.spectral_axis.value,
                   noise.snr[:, i, j] * mask[:, i, j], 'bD')

            p.subplot(122)
            p.plot(cube.spectral_axis.value, cube[:, i, j], label='Cube')
            p.plot(cube.spectral_axis.value, smooth_cube[:, i, j],
                   label='Smooth Cube')
            p.axvline(min_val)
            p.axvline(max_val)
            p.plot(cube.spectral_axis.value,
                   smooth_cube[:, i, j] * mask[:, i, j], 'bD')
            p.draw()
            raw_input("Next spectrum?")
            p.clf()