99def infer_reversal_potential (current , times , voltage_segments , voltages ,
1010 ax = None , output_path = None , plot = None ,
1111 known_Erev = None , figsize = (5 , 3 )):
12-
13- if output_path :
14- dirname = os .path .dirname (output_path )
15- if not os .path .exists (dirname ):
16- os .makedirs (dirname )
17-
18- if (ax or output_path ) and plot is not False :
19- plot = True
20-
21- # Find indices of observations during the reversal ramp
22- ramps = [line for line in voltage_segments if line [2 ] != line [3 ]]
23-
24- # Assume the last ramp is the reversal ramp (convert to ms)
25- tstart , tend = np .array (ramps )[- 1 , :2 ]
12+ """
13+ Infers a reversal potential in a time series, based on a reversal ramp.
14+
15+ The data is denoised by fitting a 4-th order polynomial through the ramp
16+ data, from which a reversal potential is then detected. If no polynomial
17+ can be fit or the resulting zero-crossing is outside of
18+ ``min(voltages), max(voltages)``, then ``np.nan`` is returned.
19+
20+ @param current: The currents that make up a time series with ``times``
21+ @param times: The sampled times
22+ @param voltage_segments: A list of tuples (tstart, tend, vstart, vend)
23+ describing voltage steps or ramps. It is assumed the final ramp is the
24+ reversal ramp.
25+ @param voltages: The sampled voltages (WHY ORDER t,V,I NOT CONSISTENT?)
26+ @param ax: An optional matplotlib axes to create a plot on
27+ @param output_path: If ``ax is None``, this can specify a path to create a plot at
28+ @param plot: A THIRD WAY TO ASK FOR A PLOT, WHAT IS THIS ARG FOR? SETTING
29+ TRUE WITHOUT OTHER TWO = ERROR
30+ @param known_Erev: A known reversal potential to include in the plot
31+ @param figsize: A size for the plot.
32+
33+ @return: The inferred reversal potential
34+ """
35+
36+ # Find all ramps, then assume last one is the reversal ramp
37+ rev_ramp = [line for line in voltage_segments if line [2 ] != line [3 ]][- 1 ]
38+ tstart , tend = rev_ramp [:2 ]
2639
2740 istart = np .argmax (times > tstart )
2841 iend = np .argmax (times > tend )
2942
30- times = times [istart :iend ]
3143 current = current [istart :iend ]
3244 voltages = voltages [istart :iend ]
3345
46+ # Fit a 4-th order polynomial
3447 try :
3548 fitted_poly = poly .Polynomial .fit (voltages , current , 4 )
3649 except ValueError as exc :
3750 logging .warning (str (exc ))
3851 return np .nan
3952
53+ # Try extracting the polynomial's roots, accepting only ones that are
54+ # within the range of sampled voltages (so not using ramp info here!)
4055 try :
56+ vmin , vmax = np .min (voltages ), np .max (voltages )
4157 roots = np .unique ([np .real (root ) for root in fitted_poly .roots ()
42- if root > np . min ( voltages ) and root < np . max ( voltages ) ])
58+ if root > vmin and root < vmax ])
4359 except np .linalg .LinAlgError as exc :
4460 logging .warning (str (exc ))
4561 return np .nan
@@ -50,6 +66,17 @@ def infer_reversal_potential(current, times, voltage_segments, voltages,
5066
5167 if len (roots ) == 0 :
5268 return np .nan
69+ erev = roots [- 1 ]
70+
71+ # Optional plot
72+
73+ if output_path :
74+ dirname = os .path .dirname (output_path )
75+ if not os .path .exists (dirname ):
76+ os .makedirs (dirname )
77+
78+ if (ax or output_path ) and plot is not False :
79+ plot = True
5380
5481 if plot :
5582 created_fig = False
@@ -59,12 +86,12 @@ def infer_reversal_potential(current, times, voltage_segments, voltages,
5986 fig = plt .figure (figsize = figsize )
6087 ax = fig .subplots ()
6188
62- ax .set_xlabel ('$V$ (mV)' )
89+ ax .set_xlabel ('$V$ (mV)' ) # Assuming mV here
6390 ax .set_ylabel ('$I$ (nA)' )
6491
6592 # Now plot current vs voltage
6693 ax .plot (voltages , current , 'x' , markersize = 2 , color = 'grey' , alpha = .5 )
67- ax .axvline (roots [ - 1 ] , linestyle = '--' , color = 'grey' , label = r'$E_\mathrm{obs}$' )
94+ ax .axvline (erev , linestyle = '--' , color = 'grey' , label = r'$E_\mathrm{obs}$' )
6895 if known_Erev :
6996 ax .axvline (known_Erev , linestyle = '--' , color = 'orange' ,
7097 label = "Calculated $E_{Kr}$" )
@@ -79,4 +106,4 @@ def infer_reversal_potential(current, times, voltage_segments, voltages,
79106 if created_fig :
80107 plt .close (fig )
81108
82- return roots [ - 1 ]
109+ return erev
0 commit comments