Skip to content

Commit

Permalink
update C++ codebase for handling of feature dependencies [vcs: #minor] (
Browse files Browse the repository at this point in the history
#334)

* throw runtime_error, rm exit(1) in featuretype&calcfeatures

* rename type->input_type

* throw EfelAssertionError to avoid exit(-1)

* add test to trigger C++->Python AssertionError

* remove featurename.find(";") check

* typo in docstring

* add feature's name to the error message

* Revert "remove featurename.find(";") check"

This reverts commit 954613a.

* remove setversion function

* draft: removing alternative wildcard syntax

* remove variable features in LibV5

* remove variable (alias) features in LibV2

* simplify feature pointers representation in cppcore, remove wildcards

* make AddUniqueItem void

* remove empty function getDependencyList

* directly check stream's state after opening the file

* remove dead code in efel and cfeature

* merge efel into cppcore

* add template to getParam

* add getFeatures fn to get all dependent features

* LibV5.cpp update until time_to_last_spike

* libv5 update ISI computations

* LibV5 remove ISI first, second etc. duplication

* calculateInvISI throw except instead of return 0

* use getFeatures in depolarized_base

* use getFeatures in steady_state_hyper

* depolarized_based consider retVal==0 failure

* use getFeatures in LibV2

* use getFeatures in LibV1

* using to replace scope resolution

* define distinct errors: FeatureComputationError, EmptyFeatureError

* use getFeature/s in LibV5 for consistent handling of edge cases

* remove unnecessary initializer_list

* min_AHP_indices to use getFeatures

* AHP_depth_abs with getFeature

* spike_half_width to use getFeatures

* AP_begin_indices to use getFeatures

* use getFeatures in current_base

* getfeatures in burst_begin_indices

* decay_time_constant_after_stim to use getFeatures

* libv5 exception handling

* remove getVec completely

* make format

* replace throw EmptyFeatureError with return -1 for consistency

* remove redundant else condition

* avoid fetching ignore_first_ISI twice

* in the spikewidth2 error message mention spikewidth2

* update maximum_voltage's success case to be same asminimum_voltages

* make peakvoltage vector a reference in amp_drop_first_last

* remove obsolete empty feature checks in spike_width1

* remove else after throw

* update new line in code comment for readability

* replace GErrorStr+1 and return -1 via exception

* add test to cover single spike case in min_voltage_between_spikes

* cover stimulus_current==0.0 edge case in ohmic resistance features

* remove else after throw in 3 LibV5 places

* typo in test name

* test_ohmic_input_resistance_zero_stimulus_current update stim params

* update fail case for spikecount & spikecount_stimint

* add test calling all features on constant trace

* remove re imported import in test

* impute Spikecount missing val to 0.0 in GranuleCellDeap1.ipynb

* remove unnecessary variable

* move Spikecount implementation to Python

* change doc of Spikecount as Python efeature

* move Spikecount_stimint to Python

* add validation module with check_ais_initiation

* add bpap_attenuation as a multitrace feature

* move burst_number and strict_burst_number to Python

* update impedance, remove spikecount is None check

* add CHANGELOG.md

* docs: add multitrace and validation modules to API

* Docs: add name change warnings

* add int/double template instantiations to cfeature

* remove getDistance_cpp, use python implementation

* move trace_check to pyfeatures

* lint fix

* add from __future__ import annotations

* add stimulus_current to test_allfeatures_on_constant_V

* allow both spike_count and Spikecount

* move validation.py inside pyfeatures

* Revert "add stimulus_current to test_allfeatures_on_constant_V"

This reverts commit 41b087e.

* add spike_count expect it to be 0 for allfeatures_on_constant_voltage

* encourage use of spike_count instead of Spikecount

* update deprecation note in the docs
  • Loading branch information
anilbey authored Jan 10, 2024
1 parent d03928c commit cc9a2b7
Show file tree
Hide file tree
Showing 47 changed files with 2,513 additions and 5,460 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ bin
*.ipynb_checkpoints
lib
fllog.txt
*.DS_Store
*.DS_Store
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [5.4.0] - 2024-01

### C++ changes
- New C++ function `getFeatures` replaced `getVec`.
- `getFeatures` automatically handles failures & distinguishes empty results from failures.
- Centralized error handling in `getFeatures` shortens the code by removing repetitions.
- C++ features' access is restricted. Read-only references are marked `const`.
- Removed wildcard features from C++ API. Use of Python is encouraged for that purpose.

### Python changes
- `bpap_attenuation` feature is added to the Python API.
- `Spikecount`, `Spikecount_stimint`, `burst_number`, `strict_burst_number` and `trace_check` features migrated to Python from C++.
- `check_ais_initiation` is added to the Python API.
2 changes: 2 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Submodules

api
io
pyfeatures.multitrace
pyfeatures.pyfeatures
pyfeatures.validation
units
settings
137 changes: 17 additions & 120 deletions docs/source/eFeatures.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,22 @@ time from stimulus start to last spike
else:
time_to_last_spike = 0

`LibV1`_ : Spikecount
~~~~~~~~~~~~~~~~~~~~~
`Python efeature`_ : spike_count
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

number of spikes in the trace, including outside of stimulus interval

- **Required features**: LibV1:peak_indices
- **Units**: constant
- **Pseudocode**: ::

Spikecount = len(peak_indices)
spike_count = len(peak_indices)

`LibV5`_ : Spikecount_stimint
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Note**: "spike_count" is the new name for the feature "Spikecount".
"Spikecount", while still available, will be removed in the future.

`Python efeature`_ : spike_count_stimint
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

number of spikes inside the stimulus interval

Expand All @@ -171,7 +174,10 @@ number of spikes inside the stimulus interval
- **Pseudocode**: ::

peaktimes_stimint = numpy.where((peak_time >= stim_start) & (peak_time <= stim_end))
Spikecount_stimint = len(peaktimes_stimint)
spike_count_stimint = len(peaktimes_stimint)

**Note**: "spike_count_stimint" is the new name for the feature "Spikecount_stimint".
"Spikecount_stimint", while still available, will be removed in the future.

`LibV5`_ : number_initial_spikes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -343,23 +349,6 @@ The adaptation index is zero for a constant firing rate and bigger than zero for
ISI_sub = ISI_values[1:] - ISI_values[:-1]
adaptation_index = numpy.mean(ISI_sum / ISI_sub)


`LibV5`_ : check_AISInitiation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Check initiation of AP in AIS

- **Required features**: t, V, stim_start, stim_end, AP_begin_time, AP_begin_time;location_AIS
- **Units**: constant
- **Pseudocode**: ::

if len(AP_begin_time) != len(AP_begin_time;location_AIS):
return None
for soma_time, ais_time in zip(AP_begin_time, AP_begin_time;location_AIS):
if soma_time < ais_time:
return None
return [1]

`LibV1`_ : burst_mean_freq
~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -419,8 +408,8 @@ The burst detection can be fine-tuned by changing the setting strict_burst_facto
)
)

`LibV1`_ : burst_number
~~~~~~~~~~~~~~~~~~~~~~~
`Python efeature`_ : burst_number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The number of bursts

Expand All @@ -430,8 +419,8 @@ The number of bursts

burst_number = len(burst_mean_freq)

`LibV5`_ : strict_burst_number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
`Python efeature`_ : strict_burst_number
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The number of bursts

Expand Down Expand Up @@ -1287,98 +1276,6 @@ Slope of the V, dVdt phasespace plot at the beginning of every spike
range_min_idxs = AP_begin_indices - AP_phseslope_range
AP_phaseslope = (dvdt[range_max_idxs] - dvdt[range_min_idxs]) / (v[range_max_idxs] - v[range_min_idxs])

`LibV5`_ : AP_phaseslope_AIS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Same as AP_phaseslope, but for AIS location

Please, notice that you have to provide t, v, stim_start and stim_end for location.

- **Required features**: T;location_AIS, V;location_AIS, stim_start;location_AIS, stim_end;location_AIS, LibV5:AP_begin_indices;location_AIS
- **Parameters**: AP_phaseslope_range
- **Units**: 1/(ms)
- **Pseudocode**: ::

range_max_idxs = AP_begin_indices + AP_phseslope_range
range_min_idxs = AP_begin_indices - AP_phseslope_range
AP_phaseslope_AIS = (dvdt[range_max_idxs] - dvdt[range_min_idxs]) / (v[range_max_idxs] - v[range_min_idxs])

`LibV5`_ : BPAPHeightLoc1
~~~~~~~~~~~~~~~~~~~~~~~~~

Voltage height (difference betwen peaks and voltage base) at dendrite location

Please, notice that you have to provide t, v, stim_start and stim_end for location.

- **Required features**: T;location_dend1, V;location_dend1, stim_start;location_dend1, stim_end;location_dend1, peak_voltage;location_dend1, voltage_base;location_dend1
- **Units**: mV
- **Pseudocode**: ::

BPAPHeightLoc1 = peak_voltage - voltage_base

`LibV5`_ : BPAPHeightLoc2
~~~~~~~~~~~~~~~~~~~~~~~~~

Same as BPAPHeightLoc1, but for dend2 location

- **Required features**: T;location_dend2, V;location_dend2, stim_start;location_dend2, stim_end;location_dend2, peak_voltage;location_dend2, voltage_base;location_dend2
- **Units**: mV
- **Pseudocode**: ::

BPAPHeightLoc2 = peak_voltage - voltage_base

`LibV5`_ : BPAPAmplitudeLoc1
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Amplitude at dendrite location

Please, notice that you have to provide t, v, stim_start and stim_end for location.

- **Required features**: T;location_dend1, V;location_dend1, stim_start;location_dend1, stim_end;location_dend1, peak_voltage;location_dend1, AP_begin_voltage;location_dend1
- **Units**: mV
- **Pseudocode**: ::

BPAPAmplitudeLoc1 = peak_voltage - AP_begin_voltage

`LibV5`_ : BPAPAmplitudeLoc2
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Same as BPAPAmplitudeLoc1, but for dend2 location

- **Required features**: T;location_dend2, V;location_dend2, stim_start;location_dend2, stim_end;location_dend2, peak_voltage;location_dend2, AP_begin_voltage;location_dend2
- **Units**: mV
- **Pseudocode**: ::

BPAPAmplitudeLoc2 = peak_voltage - AP_begin_voltage

`LibV5`_ : BAC_width
~~~~~~~~~~~~~~~~~~~~

AP width at epsp location

Please, notice that you have to provide t, v, stim_start and stim_end for location.

- **Required features**: T;location_epsp, V;location_epsp, stim_start;location_epsp, stim_end;location_epsp, AP_width;location_epsp
- **Units**: ms
- **Pseudocode**: ::

BAC_width = AP_width

`LibV5`_ : BAC_maximum_voltage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Maximuum voltage at epsp location

Please, notice that you have to provide t, v, stim_start and stim_end for location.

- **Required features**: T;location_epsp, V;location_epsp, stim_start;location_epsp, stim_end;location_epsp, maximum_voltage;location_epsp
- **Units**: mV
- **Pseudocode**: ::

BAC_maximum_voltage = maximum_voltage



Voltage features
----------------

Expand Down Expand Up @@ -2007,7 +1904,7 @@ Computes the impedance given a ZAP current input and its voltage response.
It will return the frequency at which the impedance is maximal, in the range (0, impedance_max_freq] Hz,
with impedance_max_freq being a setting with 50.0 as a default value.

- **Required features**: current, LibV1:Spikecount, LibV5:voltage_base, LibV5:current_base
- **Required features**: current, spike_count, LibV5:voltage_base, LibV5:current_base
- **Units**: Hz
- **Pseudocode**: ::

Expand Down
8 changes: 4 additions & 4 deletions docs/source/tex/efeatures.tex
Original file line number Diff line number Diff line change
Expand Up @@ -858,16 +858,16 @@ \section{Elementary features}
\end{efeature}

\begin{efeature}
{Spikecount}
{LibV1}
{Spikecount}
{spike_count}
{Python efeature}
{spike_count}
{none}
{peak indices\\&trace check}
{none}
{none}
{The number of peaks during stimulus}
{
APPEND length of peak\_indices TO Spikecount
APPEND length of peak\_indices TO spike_count
}
Yield the length of \myid{peak indices}.

Expand Down
48 changes: 2 additions & 46 deletions efel/DependencyV5.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
LibV1:interpolate
LibV5:peak_indices #LibV1:interpolate
LibV1:trace_check #LibV1:peak_time #LibV1:interpolate
LibV5:peak_indices #LibV1:interpolate
LibV1:ISI_values #LibV1:peak_time #LibV1:interpolate
LibV1:doublet_ISI #LibV1:peak_time #LibV1:interpolate
LibV1:peak_voltage #LibV5:peak_indices #LibV1:interpolate
Expand All @@ -13,7 +12,6 @@ LibV1:adaptation_index2 #LibV1:peak_time #LibV1:interpolate
LibV1:spike_width2 #LibV5:min_AHP_indices #LibV1:interpolate
LibV1:AP_width #LibV5:peak_indices #LibV5:min_AHP_indices #LibV1:interpolate
LibV1:burst_mean_freq #LibV1:burst_ISI_indices #LibV1:peak_time #LibV1:interpolate
LibV1:burst_number #LibV1:burst_mean_freq #LibV1:interpolate
LibV1:interburst_voltage #LibV1:burst_ISI_indices #LibV1:interpolate
LibV1:AP_height #LibV1:peak_voltage #LibV1:interpolate
LibV1:AP_amplitude #LibV5:AP_begin_indices #LibV1:peak_voltage #LibV1:peak_time #LibV1:interpolate
Expand All @@ -28,9 +26,7 @@ LibV1:maximum_voltage #LibV1:interpolate
LibV1:minimum_voltage #LibV1:interpolate
LibV1:steady_state_voltage #LibV1:interpolate
LibV3:depolarized_base #LibV5:AP_end_indices #LibV5:AP_begin_indices #LibV1:interpolate
LibV1:ISI_CV #LibV1:ISI_values #LibV1:interpolate
LibV1:Spikecount #LibV5:peak_indices #LibV1:interpolate
LibV5:Spikecount_stimint #LibV1:peak_time #LibV1:interpolate
LibV1:ISI_CV #LibV1:ISI_values #LibV1:interpolate
LibV1:AHP_depth #LibV5:voltage_base #LibV5:min_AHP_values #LibV1:interpolate
LibV1:AHP_depth_slow #LibV5:voltage_base #LibV1:AHP_depth_abs_slow #LibV1:interpolate
LibV2:AP_rise_indices #LibV5:peak_indices #LibV5:AP_begin_indices #LibV1:interpolate
Expand All @@ -49,38 +45,7 @@ LibV2:AP_rise_rate_change #LibV2:AP_rise_rate #LibV1:interpolate
LibV2:AP_fall_rate_change #LibV2:AP_fall_rate #LibV1:interpolate
LibV2:fast_AHP_change #LibV2:fast_AHP #LibV1:interpolate
LibV2:AP_duration_half_width_change #LibV2:AP_duration_half_width #LibV1:interpolate
LibV2:E6 #LibV1:AP_amplitude;APWaveForm #LibV1:interpolate
LibV2:E7 #LibV2:AP_duration;APWaveForm #LibV1:interpolate
LibV1:single_burst_ratio #LibV1:ISI_values #LibV1:interpolate
LibV2:BPAPatt2 #LibV1:peak_voltage;location_soma #LibV5:voltage_base;location #LibV1:interpolate
LibV2:BPAPatt3 #LibV1:peak_voltage;location_soma #LibV5:voltage_base;location #LibV1:interpolate
LibV2:E39 #LibV1:mean_frequency;IDthreshold #LibV1:interpolate
LibV2:E39_cod #LibV2:E39 #LibV1:interpolate
LibV2:E2 #LibV2:amp_drop_first_second;APDrop #LibV1:interpolate
LibV2:E3 #LibV2:amp_drop_first_last;APDrop #LibV1:interpolate
LibV2:E4 #LibV2:amp_drop_second_last;APDrop #LibV1:interpolate
LibV2:E5 #LibV2:max_amp_difference;APDrop #LibV1:interpolate
LibV2:E8 #LibV2:AP_duration_half_width;APWaveForm #LibV1:interpolate
LibV2:E9 #LibV2:AP_rise_time;APWaveForm #LibV1:interpolate
LibV2:E10 #LibV2:AP_fall_time;APWaveForm #LibV1:interpolate
LibV2:E11 #LibV2:AP_rise_rate;APWaveForm #LibV1:interpolate
LibV2:E12 #LibV2:AP_fall_rate;APWaveForm #LibV1:interpolate
LibV2:E13 #LibV2:fast_AHP;APWaveForm #LibV1:interpolate
LibV2:E14 #LibV1:peak_voltage;APWaveForm #LibV1:interpolate
LibV2:E15 #LibV2:AP_duration;APWaveForm #LibV1:interpolate
LibV2:E16 #LibV2:AP_duration_half_width;APWaveForm #LibV1:interpolate
LibV2:E17 #LibV2:AP_rise_time;APWaveForm #LibV1:interpolate
LibV2:E18 #LibV2:AP_fall_time;APWaveForm #LibV1:interpolate
LibV2:E19 #LibV2:AP_rise_rate;APWaveForm #LibV1:interpolate
LibV2:E20 #LibV2:AP_fall_rate;APWaveForm #LibV1:interpolate
LibV2:E21 #LibV2:fast_AHP;APWaveForm #LibV1:interpolate
LibV2:E22 #LibV2:AP_amplitude_change;APWaveForm #LibV1:interpolate
LibV2:E23 #LibV2:AP_duration_change;APWaveForm #LibV1:interpolate
LibV2:E24 #LibV2:AP_duration_half_width_change;APWaveForm #LibV1:interpolate
LibV2:E25 #LibV2:AP_rise_rate_change;APWaveForm #LibV1:interpolate
LibV2:E26 #LibV2:AP_fall_rate_change;APWaveForm #LibV1:interpolate
LibV2:E27 #LibV2:fast_AHP_change;APWaveForm #LibV1:interpolate
LibV2:E40 #LibV1:time_to_first_spike;IDrest #LibV1:interpolate
LibV2:steady_state_hyper #LibV1:interpolate
LibV2:amp_drop_first_second #LibV1:peak_voltage #LibV1:interpolate
LibV2:amp_drop_first_last #LibV1:peak_voltage #LibV1:interpolate
Expand Down Expand Up @@ -133,15 +98,7 @@ LibV5:is_not_stuck #LibV1:peak_time #LibV1:interpolate
LibV5:mean_AP_amplitude #LibV1:AP_amplitude #LibV1:interpolate
LibV5:voltage_after_stim #LibV1:interpolate
LibV5:AP2_AP1_begin_width_diff #LibV5:AP_begin_width #LibV1:interpolate
LibV5:BPAPHeightLoc1 #LibV1:peak_voltage;location_dend1 #LibV5:voltage_base;location_dend1 #LibV1:interpolate
LibV5:BPAPHeightLoc2 #LibV1:peak_voltage;location_dend2 #LibV5:voltage_base;location_dend2 #LibV1:interpolate
LibV5:BPAPAmplitudeLoc1 #LibV1:peak_voltage;location_dend1 #LibV5:AP_begin_voltage;location_dend1 #LibV1:interpolate
LibV5:BPAPAmplitudeLoc2 #LibV1:peak_voltage;location_dend2 #LibV5:AP_begin_voltage;location_dend2 #LibV1:interpolate
LibV5:check_AISInitiation #LibV5:AP_begin_time #LibV5:AP_begin_time;location_AIS #LibV1:interpolate
LibV5:AP_phaseslope #LibV5:AP_begin_indices #LibV1:interpolate
LibV5:AP_phaseslope_AIS #LibV5:AP_phaseslope;location_AIS #LibV1:interpolate
LibV5:BAC_width #LibV1:AP_width;location_epsp #LibV1:interpolate
LibV5:BAC_maximum_voltage #LibV1:maximum_voltage;location_epsp #LibV1:interpolate
LibV5:all_ISI_values #LibV1:peak_time #LibV1:interpolate
LibV5:AP_amplitude_from_voltagebase #LibV5:voltage_base #LibV1:peak_voltage #LibV1:interpolate
LibV5:min_voltage_between_spikes #LibV5:peak_indices #LibV1:interpolate
Expand All @@ -166,7 +123,6 @@ LibV5:AP_width_between_threshold #LibV5:min_between_peaks_indices #LibV1:inte
LibV5:burst_begin_indices #LibV5:all_ISI_values #LibV1:interpolate
LibV5:burst_end_indices #LibV5:burst_begin_indices #LibV1:interpolate
LibV5:strict_burst_mean_freq #LibV1:peak_time #LibV5:burst_begin_indices #LibV5:burst_end_indices #LibV1:interpolate
LibV5:strict_burst_number #LibV5:strict_burst_mean_freq #LibV1:interpolate
LibV5:strict_interburst_voltage #LibV5:peak_indices #LibV5:burst_begin_indices #LibV1:interpolate
LibV5:ADP_peak_indices #LibV5:min_AHP_indices #LibV5:min_between_peaks_indices #LibV1:interpolate
LibV5:ADP_peak_values #LibV5:ADP_peak_indices #LibV1:interpolate
Expand Down
Loading

0 comments on commit cc9a2b7

Please sign in to comment.