Skip to content

Commit

Permalink
new features: postburst_slow_ahp_values, time_to_postburst_slow_ahp (#…
Browse files Browse the repository at this point in the history
…289)

* new features: postburst_slow_ahp_values, time_to_postburst_slow_ahp

* remove std::cout in LibV1

* fix edge case when index is stim_end_index or end_index

* new feature: postburst_fast_ahp_values

* new feature: postburst_adp_peak_values

* add new features: interburst_XX_percent_values for 20, 40, 60%

* adding test, docs for postburst_fast_ahp_values, postburst_adp_peak_values

* fix time_to_postburst_adp_peak for edge case when there are less adp peaks than bursts

* add test and doc for feature time_to_postburst_fast_ahp

* add test and doc for feature time_to_postburst_adp_peak

* add test and docs to interburst 20%, 40%, 60% features

* turn 40%, 60% into 25%, 30% for interburst voltage

* add interburst 10% and 15% voltage values features

* interburst features: removed 10%, restored 40% and 60%

* new feature: interburst_duration

* update docs and tests with new features

* update memoization of new features

* fix docs, units and tests for latest new features

* create interburst_percent_indices function to reduce code duplication

* remove deprecated bind2nd

* refactor interburst_XXpercent_indices

* merging all interburst_XXpercent_values in the docs

---------

Co-authored-by: Jaquier Aurélien Tristan <[email protected]>
  • Loading branch information
AurelienJaquier and Jaquier Aurélien Tristan authored Apr 29, 2024
1 parent 69f1c1b commit 53733b0
Show file tree
Hide file tree
Showing 10 changed files with 1,643 additions and 24 deletions.
207 changes: 206 additions & 1 deletion docs/source/eFeatures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ The burst detection can be fine-tuned by changing the setting strict_burst_facto
- **Units**: mV
- **Pseudocode**: ::

interburst_min = [
postburst_min = [
numpy.min(
v[peak_indices[i]:peak_indices[i + 1]]
) for i in burst_end_indices if i + 1 < len(peak_indices)
Expand All @@ -551,6 +551,36 @@ The burst detection can be fine-tuned by changing the setting strict_burst_facto
v[peak_indices[burst_end_indices[-1]]:]
))

`LibV5`_ : postburst_slow_ahp_values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The slow AHP voltage after the end of a burst.

The number of ms to skip after the spike to skip fast AHP and look for slow AHP can be set with sahp_start.
Default is 5.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: peak_indices, burst_end_indices
- **Units**: mV
- **Pseudocode**: ::

postburst_slow_ahp = []
for i in burst_end_indices:
i_start = numpy.where(t >= t[peak_indices[i]] + sahp_start)[0][0]
if i + 1 < len(peak_indices):
postburst_slow_ahp.append(numpy.min(v[i_start:peak_indices[i + 1]]))
else:
if t[burst_end_indices[-1]] < stim_end:
end_idx = numpy.where(t >= stim_end)[0][0]
postburst_slow_ahp.append(numpy.min(v[i_start:end_idx]))
else:
postburst_slow_ahp.append(numpy.min(v[i_start:]))

`LibV5`_ : time_to_interburst_min
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -573,6 +603,181 @@ The burst detection can be fine-tuned by changing the setting strict_burst_facto
for i in burst_end_indices if i + 1 < len(peak_indices)
]

`LibV5`_ : time_to_postburst_slow_ahp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The time between the last spike of a burst and the slow ahp afterwards.

The number of ms to skip after the spike to skip fast AHP and look for slow AHP can be set with sahp_start.
Default is 5.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: postburst_slow_ahp_indices, burst_end_indices, peak_time
- **Units**: ms
- **Pseudocode**: ::

time_to_postburst_slow_ahp_py = t[postburst_slow_ahp_indices] - peak_time[burst_end_indices]

`LibV5`_ : postburst_fast_ahp_values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The fast AHP voltage after the end of a burst.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: peak_indices, burst_end_indices
- **Units**: mV
- **Pseudocode**: ::

postburst_fahp = []
for i in burst_end_indices:
if i + 1 < len(peak_indices):
stop_i = peak_indices[i + 1]
elif i + 1 < stim_end_index:
stop_i = stim_end_index
else:
stop_i = len(v) - 1
v_crop = v[peak_indices[i]:stop_i]
# get where the voltage is going up
crop_args = numpy.argwhere(numpy.diff(v_crop) >= 0)[:,0]
# the voltage should go up for at least two consecutive points
crop_arg_arg = numpy.argwhere(numpy.diff(crop_args) == 1)[0][0]
crop_arg = crop_args[crop_arg_arg]
end_i = peak_indices[i] + crop_arg + 1
# the fast ahp is between last peak of burst and the point where voltage is going back up
postburst_fahp.append(numpy.min(v[peak_indices[i]:end_i]))

return postburst_fahp

`LibV5`_ : postburst_adp_peak_values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The small ADP peak after the fast AHP after the end of a burst.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: postburst_fast_ahp_indices, postburst_slow_ahp_indices
- **Units**: mV
- **Pseudocode**: ::

adp_peak_values = []
for i, sahpi in enumerate(postburst_sahpi):
if sahpi < postburst_fahpi[i]:
continue
adppeaki = numpy.argmax(v[postburst_fahpi[i]:sahpi]) + postburst_fahpi[i]
if adppeaki != sahpi - 1:
adp_peak_values.append(v[adppeaki])

if len(adp_peak_values) == 0:
return None
return adp_peak_values

`LibV5`_ : time_to_postburst_fast_ahp
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Time to the fast AHP after the end of a burst.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: postburst_fast_ahp_indices, burst_end_indices, peak_time
- **Units**: ms
- **Pseudocode**: ::

[t[fahpi] - peak_time[burst_endi[i]] for i, fahpi in enumerate(postburst_fahpi)]

`LibV5`_ : time_to_postburst_adp_peak
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Time to the small ADP peak after the fast AHP after the end of a burst.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: postburst_adp_peak_indices, burst_end_indices, peak_time
- **Units**: ms
- **Pseudocode**: ::

time_to_postburst_adp_peaks = []
n_peaks = len(peak_time)
for i, adppeaki in enumerate(postburst_adppeaki):
# there are not always an adp peak after each burst
# so make sure that the burst and adp peak indices are consistent
k = 0
while (
burst_endi[i] + k + 1 < n_peaks and peak_time[burst_endi[i] + k + 1] < t[adppeaki]
):
k += 1

time_to_postburst_adp_peaks.append(t[adppeaki] - peak_time[burst_endi[i] + k])

return time_to_postburst_adp_peaks


`LibV5`_ : interburst_15percent_values, interburst_20percent_values, interburst_25percent_values, interburst_30percent_values, interburst_40percent_values, interburst_60percent_values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Voltage value after a given percentage (15%, 20%, 25%, 30%, 40% or 60%) of the interburst duration after the fast AHP.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: postburst_fast_ahp_indices, burst_end_indices, peak_indices
- **Units**: mV
- **Pseudocode**: ::

interburst_XXpercent_values = []
for i, postburst_fahp_i in enumerate(postburst_fahpi):
if i < len(burst_endi) and burst_endi[i] + 1 < len(peaki):
time_interval = t[peaki[burst_endi[i] + 1]] - t[postburst_fahp_i]
time_at_XXpercent = t[postburst_fahp_i] + time_interval * percentage / 100.
index_at_XXpercent = numpy.argwhere(t >= time_at_XXpercent)[0][0]
interburst_XXpercent_values.append(v[index_at_XXpercent])

`LibV5`_ : interburst_duration
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Duration between the last spike of each burst and the next spike.

This implementation does not assume that every spike belongs to a burst.

The first spike is ignored by default. This can be changed by setting ignore_first_ISI to 0.

The burst detection can be fine-tuned by changing the setting strict_burst_factor. Defalt value is 2.0.

- **Required features**: burst_end_indices, peak_time
- **Units**: ms
- **Pseudocode**: ::

interburst_duration = [
peak_time[idx + 1] - peak_time[idx]
for idx in burst_end_indices
if idx + 1 < len(peak_time)
]

`Python efeature`_ : single_burst_ratio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
24 changes: 23 additions & 1 deletion efel/DependencyV5.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,27 @@ LibV5:ADP_peak_amplitude #LibV5:ADP_peak_values #LibV5:min_AHP_values #LibV1:in
LibV5:interburst_min_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV1:interpolate
LibV5:interburst_min_values #LibV5:interburst_min_indices #LibV1:interpolate
LibV5:postburst_min_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV1:interpolate
LibV5:postburst_min_values #LibV5:postburst_min_indices #LibV1:interpolate
LibV5:postburst_min_values #LibV5:postburst_min_indices #LibV1: interpolate
LibV5:postburst_slow_ahp_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV1:interpolate
LibV5:postburst_slow_ahp_values #LibV5:postburst_slow_ahp_indices #LibV1:interpolate
LibV5:time_to_interburst_min #LibV5:interburst_min_indices #LibV1:peak_time #LibV5:burst_end_indices #LibV1:interpolate
LibV5:time_to_postburst_slow_ahp #LibV5:postburst_slow_ahp_indices #LibV1:peak_time #LibV5:burst_end_indices #LibV1:interpolate
LibV5:postburst_fast_ahp_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV1:interpolate
LibV5:postburst_fast_ahp_values #LibV5:postburst_fast_ahp_indices #LibV1:interpolate
LibV5:postburst_adp_peak_indices #LibV5:postburst_fast_ahp_indices #LibV5:postburst_slow_ahp_indices #LibV1:interpolate
LibV5:postburst_adp_peak_values #LibV5:postburst_adp_peak_indices #LibV1:interpolate
LibV5:time_to_postburst_fast_ahp #LibV5:postburst_fast_ahp_indices #LibV1:peak_time #LibV5:burst_end_indices #LibV1:interpolate
LibV5:time_to_postburst_adp_peak #LibV5:postburst_adp_peak_indices #LibV1:peak_time #LibV5:burst_end_indices #LibV1:interpolate
LibV5:interburst_15percent_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV5:postburst_fast_ahp_indices #LibV1:interpolate
LibV5:interburst_15percent_values #LibV5:interburst_15percent_indices #LibV1:interpolate
LibV5:interburst_20percent_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV5:postburst_fast_ahp_indices #LibV1:interpolate
LibV5:interburst_20percent_values #LibV5:interburst_20percent_indices #LibV1:interpolate
LibV5:interburst_25percent_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV5:postburst_fast_ahp_indices #LibV1:interpolate
LibV5:interburst_25percent_values #LibV5:interburst_25percent_indices #LibV1:interpolate
LibV5:interburst_30percent_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV5:postburst_fast_ahp_indices #LibV1:interpolate
LibV5:interburst_30percent_values #LibV5:interburst_30percent_indices #LibV1:interpolate
LibV5:interburst_40percent_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV5:postburst_fast_ahp_indices #LibV1:interpolate
LibV5:interburst_40percent_values #LibV5:interburst_40percent_indices #LibV1:interpolate
LibV5:interburst_60percent_indices #LibV5:peak_indices #LibV5:burst_end_indices #LibV5:postburst_fast_ahp_indices #LibV1:interpolate
LibV5:interburst_60percent_values #LibV5:interburst_60percent_indices #LibV1:interpolate
LibV5:interburst_duration #LibV1:peak_time #LibV5:burst_end_indices #LibV1:interpolate
70 changes: 70 additions & 0 deletions efel/cppcore/FillFptrTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,77 @@ int FillFptrTable() {
FptrTableV5["interburst_min_values"] = &LibV5::interburst_min_values;
FptrTableV5["postburst_min_indices"] = &LibV5::postburst_min_indices;
FptrTableV5["postburst_min_values"] = &LibV5::postburst_min_values;
FptrTableV5["postburst_slow_ahp_indices"] = &LibV5::postburst_slow_ahp_indices;
FptrTableV5["postburst_slow_ahp_values"] = &LibV5::postburst_slow_ahp_values;
FptrTableV5["time_to_interburst_min"] = &LibV5::time_to_interburst_min;
FptrTableV5["time_to_postburst_slow_ahp"] = &LibV5::time_to_postburst_slow_ahp;
FptrTableV5["postburst_fast_ahp_indices"] = &LibV5::postburst_fast_ahp_indices;
FptrTableV5["postburst_fast_ahp_values"] = &LibV5::postburst_fast_ahp_values;
FptrTableV5["postburst_adp_peak_indices"] = &LibV5::postburst_adp_peak_indices;
FptrTableV5["postburst_adp_peak_values"] = &LibV5::postburst_adp_peak_values;
FptrTableV5["time_to_postburst_fast_ahp"] = &LibV5::time_to_postburst_fast_ahp;
FptrTableV5["time_to_postburst_adp_peak"] = &LibV5::time_to_postburst_adp_peak;
FptrTableV5["interburst_15percent_indices"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 15);
};
FptrTableV5["interburst_15percent_values"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 15);
};
FptrTableV5["interburst_20percent_indices"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 20);
};
FptrTableV5["interburst_20percent_values"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 20);
};
FptrTableV5["interburst_25percent_indices"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 25);
};
FptrTableV5["interburst_25percent_values"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 25);
};
FptrTableV5["interburst_30percent_indices"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 30);
};
FptrTableV5["interburst_30percent_values"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 30);
};
FptrTableV5["interburst_40percent_indices"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 40);
};
FptrTableV5["interburst_40percent_values"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 40);
};
FptrTableV5["interburst_60percent_indices"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 60);
};
FptrTableV5["interburst_60percent_values"] = [](mapStr2intVec& intData,
mapStr2doubleVec& doubleData,
mapStr2Str& strData) {
return LibV5::interburst_XXpercent_indices(intData, doubleData, strData, 60);
};
FptrTableV5["interburst_duration"] = &LibV5::interburst_duration;

//****************** end of FptrTableV5 *****************************

Expand Down
Loading

0 comments on commit 53733b0

Please sign in to comment.