Exemple #1
0
def intervals_from_traces(recording: RecordingExtractor):
    """Extract interval times from TTL pulses."""
    traces = recording.get_traces(channel_ids=[1, 2])
    sf = recording.get_sampling_frequency()

    ttls = []
    states = []
    for tr in traces:
        threshold = np.ptp(tr) / 2 + np.min(tr)
        crossings = np.array(tr > threshold).astype("int8")

        rising = np.nonzero(np.diff(crossings, 1) > 0)[0]
        falling = np.nonzero(np.diff(crossings, 1) < 0)[0]

        ttl = np.concatenate((rising, falling))
        sort_order = np.argsort(ttl)
        ttl = np.sort(ttl)
        state = [1] * len(rising) + [-1] * len(falling)
        state = np.array(state)[sort_order]

        ttls.append(ttl)
        states.append(state)

    conditions = []
    for ttl, state in zip(ttls, states):
        assert len(ttl[state == 1]) == len(
            ttl[state == -1]), "Different number of rising/falling edges!"
        condition = np.zeros((len(ttl[state == 1]), 2), dtype="int")

        condition[:, 0] = ttl[state == 1] / sf
        condition[:, 1] = ttl[state == -1] / sf

        conditions.append(condition)

    return conditions
def estimate_noise_level(recording: se.RecordingExtractor):
    N = recording.get_num_frames()
    samplerate = recording.get_sampling_frequency()
    start_frame = 0
    end_frame = int(np.minimum(samplerate * 1, N))
    X = recording.get_traces(
        channel_ids=[int(id) for id in recording.get_channel_ids()],
        start_frame=start_frame,
        end_frame=end_frame)
    est_noise_level = np.median(np.abs(X.squeeze(
    ))) / 0.6745  # median absolute deviation (MAD) estimate of stdev
    if (est_noise_level == 0): est_noise_level = 1
    return est_noise_level
Exemple #3
0
def ephys_nlm_v1(recording: se.RecordingExtractor, *, opts: EphysNlmV1Opts, device: Union[None, str], verbose: int = 1) -> Tuple[OutputRecordingExtractor, EphysNlmV1Info]:
    """Denoise an ephys recording using non-local means.
    
    The input and output recordings are RecordingExtractors from SpikeInterface.

    Parameters
    ----------
    recording : se.RecordingExtractor
        The ephys recording to denoise (see SpikeInterface)
    opts : EphysNlmV1Opts
        Options created using EphysNlmV1Opts(...)
    device : Union[str, None]
        Either cuda or cpu (cuda is highly recommended, but you need to have
        CUDA/PyTorch working on your system). If None, then the EPHYS_NLM_DEVICE
        environment variable will be used.
    verbose : int, optional
        Verbosity level, by default 1

    Returns
    -------
    Tuple[OutputRecordingExtractor, EphysNlmV1Info]
        The output recording extractor see SpikeInterface
        and info about the run
    """
    channel_ids = recording.get_channel_ids()
    M = len(channel_ids)
    N = recording.get_num_frames()
    T = opts.clip_size
    assert T % 2 == 0, 'clip size must be divisible by 2.'
    info = EphysNlmV1Info()
    info.recording = recording
    info.opts = opts
    info.start_time = time.time()
    if opts.block_size is None:
        if opts.block_size_sec is None:
            raise Exception('block_size and block_size_sec are both None')
        opts.block_size = int(
            recording.get_sampling_frequency() * opts.block_size_sec)
    block_size = opts.block_size
    N = recording.get_num_frames()
    num_blocks = max(1, math.floor(N / block_size))
    assert opts.sigma == 'auto', 'Only sigma=auto allowed at this time'
    assert opts.whitening == 'auto', 'Only whitening=auto allowed at this time'

    if device is None:
        device = os.getenv('EPHYS_NLM_DEVICE', None)
        if device is None or device == '':
            print('Warning: EPHYS_NLM_DEVICE not set -- defaulting to cpu. To use GPU, set EPHYS_NLM_DEVICE=cuda')
            device = 'cpu'
    elif device == 'cpu':
        print('Using device=cpu. Warning: GPU is much faster. To use GPU, set device=cuda')
    if device == 'cuda':
        assert torch.cuda.is_available(), f'Cannot use device=cuda. PyTorch/CUDA is not configured properly -- torch.cuda.is_available() is returning False.'
        print('Using device=cuda')
    elif device == 'cpu':
        print('Using device=cpu')
    else:
        raise Exception(f'Invalid device: {device}') # pragma: no cover
    info.device = device
    opts._device = device  # for convenience

    neighborhoods = _get_neighborhoods(recording=recording, opts=opts)

    if verbose >= 1:
        print(f'Denoising recording of size {M} x {N} using {len(neighborhoods)} neighborhoods and {num_blocks} time blocks')

    initial_traces = recording.get_traces(
        start_frame=0, end_frame=min(N, block_size))
    _estimate_sigma_and_whitening(
        traces=initial_traces, neighborhoods=neighborhoods, opts=opts, verbose=verbose)

    recording_out = OutputRecordingExtractor(
        base_recording=recording, block_size=opts.block_size)

    for ii in range(num_blocks):
        if verbose >= 1:
            print(f'Denoising block {ii} of {num_blocks}')

        t1 = ii * block_size
        t2 = t1 + block_size
        # The last block is potentially larger
        if ii == num_blocks - 1:
            t2 = N

        block_traces = recording.get_traces(start_frame=t1, end_frame=t2)
        block_traces_denoised, block_info = _denoise_block(
            traces=block_traces,
            opts=opts,
            neighborhoods=neighborhoods,
            verbose=verbose
        )
        info.blocks.append(block_info)
        recording_out.add_block(block_traces_denoised)

    info.end_time = time.time()
    info.elapsed_time = info.end_time - info.start_time

    return recording_out, info