예제 #1
0
def piecewise_pulse_fast(step_func,
                         t_off,
                         t_currents,
                         currents,
                         T,
                         n=20,
                         n_pulse=2):
    """
    Computes response from double pulses (negative then positive)
    T: Period (e.g. 25 Hz base frequency, 0.04 s period)
    """

    # Use early out scheme for speed. Can turn assertions off with "python -O"
    assert (n_pulse == 1 or n_pulse
            == 2), NotImplementedError("n_pulse must be either 1 or 2")

    # Get gauss-legendre points and weights early since n never changes inside here
    x, w = _cached_roots_legendre(n)

    if n_pulse == 1:
        response = piecewise_ramp_fast(step_func, t_off, t_currents, currents,
                                       x, w)
    elif n_pulse == 2:
        response = piecewise_ramp_fast_diff(step_func, t_off, t_off + 0.5 * T,
                                            t_currents, currents, x, w)
    return response
예제 #2
0
def piecewise_pulse_fast(
    step_func, t_off, t_currents, currents, T, n=20, n_pulse=2
):
    """
    Computes response from double pulses (negative then positive)
    T: Period (e.g. 25 Hz base frequency, 0.04 s period)
    """

    # Use early out scheme for speed. Can turn assertions off with "python -O"
    assert (n_pulse == 1 or n_pulse == 2), NotImplementedError("n_pulse must be either 1 or 2")

    # Get gauss-legendre points and weights early since n never changes inside here
    x, w = _cached_roots_legendre(n)

    if n_pulse == 1:
        response = piecewise_ramp_fast(
                step_func, t_off, t_currents, currents, x, w
        )
    elif n_pulse == 2:
        response = piecewise_ramp_fast_diff(
                step_func, t_off, t_off+0.5*T, t_currents, currents, x, w
            )
    return response
예제 #3
0
def waveform(times, resp, times_wanted, wave_time, wave_amp, nquad=3):
    """Apply a source waveform to the signal.

    Parameters
    ----------
    times : ndarray
        Times of calculated input response; should start before and
        end after `times_wanted`.

    resp : ndarray
        EM-response corresponding to `times`.

    times_wanted : ndarray
        Wanted times.

    wave_time : ndarray
        Time steps of the wave.

    wave_amp : ndarray
        Amplitudes of the wave corresponding to `wave_time`, usually
        in the range of [0, 1].

    nquad : int
        Number of Gauss-Legendre points for the integration. Default is 3.

    Returns
    -------
    resp_wanted : ndarray
        EM field for `times_wanted`.

    """

    # Interpolate on log.
    PP = iuSpline(np.log10(times), resp)

    # Wave time steps.
    dt = np.diff(wave_time)
    dI = np.diff(wave_amp)
    dIdt = dI / dt

    # Gauss-Legendre Quadrature; 3 is generally good enough.
    g_x, g_w = _cached_roots_legendre(nquad)

    # Pre-allocate output.
    resp_wanted = np.zeros_like(times_wanted)

    # Loop over wave segments.
    for i, cdIdt in enumerate(dIdt):

        # We only have to consider segments with a change of current.
        if cdIdt == 0.0:
            continue

        # If wanted time is before a wave element, ignore it.
        ind_a = wave_time[i] < times_wanted
        if ind_a.sum() == 0:
            continue

        # If wanted time is within a wave element, we cut the element.
        ind_b = wave_time[i + 1] > times_wanted[ind_a]

        # Start and end for this wave-segment for all times.
        ta = times_wanted[ind_a] - wave_time[i]
        tb = times_wanted[ind_a] - wave_time[i + 1]
        tb[ind_b] = 0.0  # Cut elements

        # Gauss-Legendre for this wave segment. See
        # https://en.wikipedia.org/wiki/Gaussian_quadrature#Change_of_interval
        # for the change of interval, which makes this a bit more complex.
        logt = np.log10(np.outer((tb - ta) / 2, g_x) + (ta + tb)[:, None] / 2)
        fact = (tb - ta) / 2 * cdIdt
        resp_wanted[ind_a] += fact * np.sum(np.array(PP(logt) * g_w), axis=1)

    return resp_wanted