def estimate_time_constant_at_end(self):
     """Calculate the membrane time constant by fitting the voltage response with a single expontial at the end of a hyperpolarising
     stimulus.
       
     Returns
     -------
     tau : membrane time constant in seconds
     """
     
     # Assumes this is being done on a hyperpolarizing step
     v_peak, peak_index = self.voltage_deflection("min")
     v_baseline = self.sweep_feature("v_baseline")
     if self.end:
         start_index = ft.find_time_index(self.t, self.end)
     else:
         start_index = ft.find_time_index(self.t, 0.7)
         
     frac = 0.1
     search_result = np.flatnonzero(self.v[start_index:] >= frac * (v_baseline - v_peak) + v_peak)
     if not search_result.size:
         raise ft.FeatureError("Could not find interval for time constant estimate")
     fit_start = self.t[search_result[0] + start_index]
     fit_end = self.t[-1]
     b, inv_tau, A = ft.fit_membrane_time_constant_at_end(self.v, self.t, fit_start, fit_end)
     
     return 1. / inv_tau
    def voltage_deflection(self, deflect_type=None):
        """Measure deflection (min or max, between start and end if specified).

        Parameters
        ----------
        deflect_type : measure minimal ('min') or maximal ('max') voltage deflection
            If not specified, it will check to see if the current (i) is positive or negative
            between start and end, then choose 'max' or 'min', respectively
            If the current is not defined, it will default to 'min'.

        Returns
        -------
        deflect_v : peak
        deflect_index : index of peak deflection
        """

        deflect_dispatch = {
            "min": np.argmin,
            "max": np.argmax,
        }

        start = self.start
        if not start:
            start = 0
        start_index = ft.find_time_index(self.t, start)

        end = self.end - 0.1  # Let us add -0.1 because we don't expect to find a trough that close to the end of current stimulation
                              # This actually helps us ignore cases where the voltage acts funny (i.e. drops mistakenly taken as trough)
                              # right at current stimulation end.
        if not end:
            end = self.t[-1]
        end_index = ft.find_time_index(self.t, end)


        if deflect_type is None:
            if self.i is not None:
                halfway_index = ft.find_time_index(self.t, (end - start) / 2. + start)
                if self.i[halfway_index] >= 0:
                    deflect_type = "max"
                else:
                    deflect_type = "min"
            else:
                deflect_type = "min"

        deflect_func = deflect_dispatch[deflect_type]

        v_window = self.v[start_index:end_index]
        deflect_index = deflect_func(v_window) + start_index

        return self.v[deflect_index], deflect_index
    def estimate_sag(self, peak_width=0.005):
        """Calculate the sag in a hyperpolarizing voltage response.

        Parameters
        ----------
        peak_width : window width to get more robust peak estimate in sec (default 0.005)

        Returns
        -------
        sag : fraction that membrane potential relaxes back to baseline
        sag_ratio: ratio of steady state voltage decrease to the largest voltage decrease
        """

        t = self.t
        v = self.v

        start = self.start
        if not start:
            start = 0
        
        end = self.end      # To calculate the steady state, not the peak deflection (see code below)
        if not end:
            end = self.t[-1]

        v_peak, peak_index = self.voltage_deflection("min")
        
        # There was one cell with a noisy (?) peak downwards (to -250 mV) unfortunately. That's why we have the if-statement here.
        # You can delete this if-statement if you have normal traces.
        # If this all still didn't work as expected, then hopefully there are more hyperpolarisation traces for which tau can be estimated
        if (self.v[peak_index] < -200) :
            print("A DOWNWARD PEAK WAS OBSERVED GOING TO LESS THAN 200 MV!!!")
            # Look for another local minimum closer to stimulus onset
            # A spike should only last about a couple of milliseconds, so let's look a bit before the 'spike'
            peak_index = peak_index - (ft.find_time_index(t, 0.12) - ft.find_time_index(t, 0.1))
        
        #print(t[peak_index])
        v_peak_avg = ft.average_voltage(v, t, start=t[peak_index] - peak_width / 2.,
                                      end=t[peak_index] + peak_width / 2.)
        v_baseline = self.sweep_feature("v_baseline")
        v_steady = ft.average_voltage(v, t, start=end - self.baseline_interval, end=end)
        #print('v_stead: ', v_steady)
        #print('v_baseline: ', v_baseline)
        #print('v_peak_avg: ', v_peak_avg)
        #print('denominater=v_stead-v_baseline: ', v_steady-v_baseline)
        #print('numerator=v_peak_avg-v_baseline: ', v_peak_avg-v_baseline)
        sag = (v_peak_avg - v_steady) / (v_peak_avg - v_baseline)
        sag_ratio = (v_peak_avg - v_baseline)/(v_steady-v_baseline)
        #print(sag_ratio)
        return sag, sag_ratio
Esempio n. 4
0
    def voltage_deflection(self, deflect_type=None):
        """Measure deflection (min or max, between start and end if specified).

        Parameters
        ----------
        deflect_type : measure minimal ('min') or maximal ('max') voltage deflection
            If not specified, it will check to see if the current (i) is positive or negative
            between start and end, then choose 'max' or 'min', respectively
            If the current is not defined, it will default to 'min'.

        Returns
        -------
        deflect_v : peak
        deflect_index : index of peak deflection
        """

        deflect_dispatch = {
            "min": np.argmin,
            "max": np.argmax,
        }

        start = self.start
        if not start:
            start = 0
        start_index = ft.find_time_index(self.t, start)

        end = self.end
        if not end:
            end = self.t[-1]
        end_index = ft.find_time_index(self.t, end)


        if deflect_type is None:
            if self.i is not None:
                halfway_index = ft.find_time_index(self.t, (end - start) / 2. + start)
                if self.i[halfway_index] >= 0:
                    deflect_type = "max"
                else:
                    deflect_type = "min"
            else:
                deflect_type = "min"

        deflect_func = deflect_dispatch[deflect_type]

        v_window = self.v[start_index:end_index]
        deflect_index = deflect_func(v_window) + start_index

        return self.v[deflect_index], deflect_index
Esempio n. 5
0
    def voltage_deflection(self, deflect_type=None):
        """Measure deflection (min or max, between start and end if specified).

        Parameters
        ----------
        deflect_type : measure minimal ('min') or maximal ('max') voltage deflection
            If not specified, it will check to see if the current (i) is positive or negative
            between start and end, then choose 'max' or 'min', respectively
            If the current is not defined, it will default to 'min'.

        Returns
        -------
        deflect_v : peak
        deflect_index : index of peak deflection
        """

        deflect_dispatch = {
            "min": np.argmin,
            "max": np.argmax,
        }

        start = self.start
        if not start:
            start = 0
        start_index = ft.find_time_index(self.t, start)

        end = self.end
        if not end:
            end = self.t[-1]
        end_index = ft.find_time_index(self.t, end)

        if deflect_type is None:
            if self.i is not None:
                halfway_index = ft.find_time_index(self.t,
                                                   (end - start) / 2. + start)
                if self.i[halfway_index] >= 0:
                    deflect_type = "max"
                else:
                    deflect_type = "min"
            else:
                deflect_type = "min"

        deflect_func = deflect_dispatch[deflect_type]

        v_window = self.v[start_index:end_index]
        deflect_index = deflect_func(v_window) + start_index

        return self.v[deflect_index], deflect_index
Esempio n. 6
0
    def estimate_time_constant(self):
        """Calculate the membrane time constant by fitting the voltage response with a
        single exponential.

        Returns
        -------
        tau : membrane time constant in seconds
        """

        # Assumes this is being done on a hyperpolarizing step
        v_peak, peak_index = self.voltage_deflection("min")
        v_baseline = self.sweep_feature("v_baseline")

        if self.start:
            start_index = ft.find_time_index(self.t, self.start)
        else:
            start_index = 0

        frac = 0.1
        search_result = np.flatnonzero(self.v[start_index:] <= frac * (v_peak - v_baseline) + v_baseline)
        if not search_result.size:
            raise ft.FeatureError("could not find interval for time constant estimate")
        fit_start = self.t[search_result[0] + start_index]
        fit_end = self.t[peak_index]

        a, inv_tau, y0 = ft.fit_membrane_time_constant(self.v, self.t, fit_start, fit_end)

        return 1. / inv_tau
    def estimate_time_constant(self):
        """Calculate the membrane time constant by fitting the voltage response with a
        single exponential.

        Returns
        -------
        tau : membrane time constant in seconds
        """

        # Assumes this is being done on a hyperpolarizing step
        v_peak, peak_index = self.voltage_deflection("min")
        v_baseline = self.sweep_feature("v_baseline")

        if self.start:
            start_index = ft.find_time_index(self.t, self.start)
        else:
            start_index = 0

        frac = 0.1
        search_result = np.flatnonzero(self.v[start_index:] <= frac * (v_peak - v_baseline) + v_baseline)
        if not search_result.size:
            raise ft.FeatureError("could not find interval for time constant estimate")

        fit_start = self.t[search_result[0] + start_index]
        fit_end = self.t[peak_index]
        
        # There was one cell with a noisy (?) peak downwards (to -250 mV) unfortunately. That's why we have the if-statement here.
        # You can delete this if-statement if you have normal traces.
        # If this all still didn't work as expected, then hopefully there are more hyperpolarisation traces for which tau can be estimated
        if (self.v[peak_index] < -200) :
            print("A DOWNWARD PEAK WAS OBSERVED GOING TO LESS THAN 200 MV!!!")
            # Look for another local minimum closer to stimulus onset
            # We look for a couple of milliseconds after stimulus onset to 50 ms before the downward peak
            end_index = (start_index + 50) + np.argmin(self.v[start_index + 50 : peak_index - 1250])
            fit_end = self.t[end_index]
            fit_start = self.t[start_index + 50]
        
        a, inv_tau, y0 = ft.fit_membrane_time_constant(self.v, self.t, fit_start, fit_end)

        return 1. / inv_tau
Esempio n. 8
0
def _short_step_stim_amp(sweep):
    t_index = ft.find_time_index(sweep.t, sweep.start)
    return sweep.i[t_index + 1:].max()
def _short_step_stim_amp(sweep):
    t_index = ft.find_time_index(sweep.t, sweep.start)
    return sweep.i[t_index + 1:].max()