<commit_before># -*- coding: utf-8 -*-
"""
Module for mathematical analysis of voltage traces from electrophysiology.

AUTHOR: <NAME> <EMAIL>

"""
import scipy.stats
import numpy as np
import math

def smooth(x,window_len=11,window='hanning'):
    """Smooth the data using a window with requested size.
    
    This function is useful for smoothing out experimental data.
    This method utilises the convolution of a scaled window with the signal.
    The signal is prepared by introducing reflected copies of the signal 
    (with the window size) in both ends so that transient parts are minimized
    in the begining and end part of the output signal.
    
    :param x: the input signal 
    :param window_len: the dimension of the smoothing window; should be an odd integer
    :param window: the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman', flat window will produce a moving average smoothing.

    :return: smoothed signal
        
    example:

    .. code-block:: python
       
       t=linspace(-2,2,0.1)
       x=sin(t)+randn(len(t))*0.1
       y=smooth(x)
    
    .. seealso::

       numpy.hanning
       numpy.hamming
       numpy.bartlett
       numpy.blackman
       numpy.convolve
       scipy.signal.lfilter
    """

    if x.ndim != 1:
        raise ValueError, "smooth only accepts 1 dimension arrays."

    if x.size < window_len:
        raise ValueError, "Input vector needs to be bigger than window size."

    if window_len<3:
        return x

    if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:
        raise ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'"

    s=np.r_[x[window_len-1:0:-1],x,x[-1:-window_len:-1]]
    #print(len(s))
    if window == 'flat': #moving average
        w=np.ones(window_len,'d')
    else:
        w=eval('np.'+window+'(window_len)')

    y=np.convolve(w/w.sum(),s,mode='valid')

    edge=window_len/2
    return y[edge:-edge]

def linear_fit(t, y):
    """ Fits data to a line
        
    :param t: time vector
    :param y: variable which varies with time (such as voltage)
    :returns: Gradient M for a formula of the type y=C+M*x
    """

    vals=np.array(y)
    m,C = np.polyfit(t, vals, 1)
    return m


def three_spike_adaptation(t,y):
    """ Linear fit of amplitude vs time of first three AP spikes

    Initial action potential amplitudes may very substaintially in amplitude
    and then settle down.
    
    :param t: time vector (AP times)
    :param y: corresponding AP amplitude
    :returns: Gradient M for a formula of the type y=C+M*x for first three action potentials
    """

    t=np.array(t)
    y=np.array(y)

    t=t[0:3]
    y=y[0:3]
    
    m=linear_fit(t,y)

    return m
    

def exp_fit(t, y):
    """
    Fits data to an exponential.
        
    Returns K for a formula of the type y=A*exp(K*x)
        
    :param t: time vector
    :param y: variable which varies with time (such as voltage)
    
    """

    vals=np.array(y)
    C=np.min(vals)
    vals=vals-C+1e-9 #make sure the data is all positive
    vals = np.log(vals)
    K, A_log = np.polyfit(t, vals, 1)
    return K


def max_min(a,t,delta=0,peak_threshold=0):
    """
    Find the maxima and minima of a voltage trace.
    
    :param a: time-dependent variable (usually voltage)
    :param t: time-vector
    :param delta: the value by which a peak or trough has to exceed its
        neighbours to be considered outside of the noise
    :param peak_threshold: peaks below this value are discarded
        
    :return: turning_points, dictionary containing number of max, min and 
        their locations
        
    .. note::

       minimum value between two peaks is in some ways a better way
       of obtaining a minimum since it guarantees an answer, this may be
       something which should be implemented.
        
    """

    gradients=np.diff(a)
        
    maxima_info=[]
    minima_info=[]
        
    count=0
    
    for i in gradients[:-1]:
        count+=1

        if ((cmp(i,0)>0) & (cmp(gradients[count],0)<0) & (i != gradients[count])):
            #found a maximum
            maximum_value=a[count]
            maximum_location=count
            maximum_time=t[count]
            preceding_point_value=a[maximum_location-1]
            succeeding_point_value=a[maximum_location+1]

            #filter:
            maximum_valid=False #logically consistent but not very pythonic..
            if ((maximum_value-preceding_point_value)>delta)*((maximum_value-succeeding_point_value)>delta):
                maximum_valid=True
            if maximum_value<peak_threshold:
                maximum_valid=False
            if maximum_valid:
                maxima_info.append((maximum_value,maximum_location,maximum_time))
   
    maxima_num=len(maxima_info)
    
    if maxima_num>0:
        minima_num=maxima_num-1
    else:
        minima_num=0
    <commit_msg>small mods to traceanalysis, prettiness only<commit_after># -*- coding: utf-8 -*-
"""
Module for mathematical analysis of voltage traces from electrophysiology.

AUTHOR: <NAME> <EMAIL>

"""
import scipy.stats
import numpy as np
import math

def smooth(x,window_len=11,window='hanning'):
    """Smooth the data using a window with requested size.
    
    This function is useful for smoothing out experimental data.
    This method utilises the convolution of a scaled window with the signal.
    The signal is prepared by introducing reflected copies of the signal 
    (with the window size) in both ends so that transient parts are minimized
    in the begining and end part of the output signal.
    
    :param x: the input signal 
    :param window_len: the dimension of the smoothing window; should be an odd integer
    :param window: the type of window from 'flat', 'hanning', 'hamming', 'bartlett', 'blackman', flat window will produce a moving average smoothing.

    :return: smoothed signal
        
    example:

    .. code-block:: python
       
       t=linspace(-2,2,0.1)
       x=sin(t)+randn(len(t))*0.1
       y=smooth(x)
    
    .. seealso::

       numpy.hanning
       numpy.hamming
       numpy.bartlett
       numpy.blackman
       numpy.convolve
       scipy.signal.lfilter
    """

    if x.ndim != 1:
        raise ValueError, "smooth only accepts 1 dimension arrays."

    if x.size < window_len:
        raise ValueError, "Input vector needs to be bigger than window size."

    if window_len<3:
        return x

    if not window in ['flat', 'hanning', 'hamming', 'bartlett', 'blackman']:
        raise ValueError, "Window is on of 'flat', 'hanning', 'hamming', 'bartlett', 'blackman'"

    s=np.r_[x[window_len-1:0:-1],x,x[-1:-window_len:-1]]
    #print(len(s))
    if window == 'flat': #moving average
        w=np.ones(window_len,'d')
    else:
        w=eval('np.'+window+'(window_len)')

    y=np.convolve(w/w.sum(),s,mode='valid')

    edge=window_len/2
    return y[edge:-edge]

def linear_fit(t, y):
    """ Fits data to a line
        
    :param t: time vector
    :param y: variable which varies with time (such as voltage)
    :returns: Gradient M for a formula of the type y=C+M*x
    """

    vals=np.array(y)
    m,C = np.polyfit(t, vals, 1)
    return m


def three_spike_adaptation(t,y):
    """ Linear fit of amplitude vs time of first three AP spikes

    Initial action potential amplitudes may very substaintially in amplitude
    and then settle down.
    
    :param t: time vector (AP times)
    :param y: corresponding AP amplitude
    :returns: Gradient M for a formula of the type y=C+M*x for first three action potentials
    """

    t = np.array(t)
    y = np.array(y)

    t = t[0:3]
    y = y[0:3]
    
    m = linear_fit(t,y)

    return m
    

def exp_fit(t, y):
    """
    Fits data to an exponential.
        
    Returns K for a formula of the type y=A*exp(K*x)
        
    :param t: time vector
    :param y: variable which varies with time (such as voltage)
    
    """

    vals = np.array(y)
    C = np.min(vals)
    vals = vals-C+1e-9 #make sure the data is all positive
    vals = np.log(vals)
    K, A_log = np.polyfit(t, vals, 1)

    return K


def max_min(a,t,delta=0,peak_threshold=0):
    """
    Find the maxima and minima of a voltage trace.
    
    :param a: time-dependent variable (usually voltage)
    :param t: time-vector
    :param delta: the value by which a peak or trough has to exceed its
        neighbours to be considered outside of the noise
    :param peak_threshold: peaks below this value are discarded
        
    :return: turning_points, dictionary containing number of max, min and 
        their locations
        
    .. note::

       minimum value between two peaks is in some ways a better way
       of obtaining a minimum since it guarantees an answer, this may be
       something which should be implemented.
        
    """

    gradients = np.diff(a)
        
    maxima_info = []
    minima_info = []
        
    count = 0
    
    for i in gradients[:-1]:
        count+=1

        if ((cmp(i,0)>0) & (cmp(gradients[count],0)<0) & (i != gradients[count])):
            #found a maximum
            maximum_value=a[count]
            maximum_location=count
            maximum_time=t[count]
            preceding_point_value=a[maximum_location-1]
            succeeding_point_value=a[maximum_location+1]

            #filter:
            maximum_valid=False #logically consistent but not very pythonic..
            if ((maximum_value-preceding_point_value)>delta)*((maximum_value-succeeding_point_value)>delta):
                maximum_valid=True
            if maximum_value<peak_threshold:
                maximum_valid=False
            if maximum_valid:
                maxima_info.append((maximum_value,maximum_location,maximum_time))
   
    maxima_num=len(maxima_info)
    
    if maxima_num>0:
        minima_num=maxima_num-1
    else:
        minima_num=0
    
{'fraction_non_alphanumeric': 0.09772544283413849, 'fraction_numerical': 0.008051529790660225, 'mean_word_length': 2.449149600833044, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7634869', 'n_tokens_mistral': 3190, 'n_tokens_neox': 3041, 'n_words': 995}