From 0c3957751d1939ae4afe02728ac682fade1db12b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Jaquier?= <72930209+AurelienJaquier@users.noreply.github.com> Date: Mon, 27 May 2024 16:40:58 +0200 Subject: [PATCH] fix edge case in AP_begin_indices (#397) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix edge case in AP_begin_indices * update changelog --------- Co-authored-by: Jaquier Aurélien Tristan --- CHANGELOG.rst | 5 +++++ efel/cppcore/SpikeShape.cpp | 15 ++++++++++++--- tests/test_basic.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index f238b511..8af2a86a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog `_, and this project adheres to `Semantic Versioning `_. +5.6.27 - 2024-05 +---------------- + +- FIxed edge case (1 spike and no min_AHP_indices dependency) in AP_begin_indices + 5.6.20 - 2024-05 ---------------- diff --git a/efel/cppcore/SpikeShape.cpp b/efel/cppcore/SpikeShape.cpp index 6de52496..3b7605b4 100644 --- a/efel/cppcore/SpikeShape.cpp +++ b/efel/cppcore/SpikeShape.cpp @@ -1679,11 +1679,20 @@ static int __AP_begin_indices(const vector& t, const vector& v, int SpikeShape::AP_begin_indices(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { + vector min_ahp_idx; // Retrieve all required double and int features at once const auto& doubleFeatures = getFeatures(DoubleFeatureData, {"T", "V", "stim_start", "stim_end"}); const auto& intFeatures = - getFeatures(IntFeatureData, {"peak_indices", "min_AHP_indices"}); + getFeatures(IntFeatureData, {"peak_indices"}); + try{ + const auto& intFeaturesSpecial = getFeatures(IntFeatureData, + {"min_AHP_indices"}); + min_ahp_idx = intFeaturesSpecial.at("min_AHP_indices"); + // Edge case for 1 spike and no min_AHP_indices: + // continue with empty vector. + } catch (const EmptyFeatureError& e) {} + catch (const FeatureComputationError& e) {} vector apbi; @@ -1706,8 +1715,8 @@ int SpikeShape::AP_begin_indices(mapStr2intVec& IntFeatureData, retVal = __AP_begin_indices( doubleFeatures.at("T"), doubleFeatures.at("V"), doubleFeatures.at("stim_start")[0], doubleFeatures.at("stim_end")[0], - intFeatures.at("peak_indices"), intFeatures.at("min_AHP_indices"), apbi, - dTh[0], derivative_window[0]); + intFeatures.at("peak_indices"), min_ahp_idx, apbi, dTh[0], + derivative_window[0]); // Save feature value if (retVal >= 0) { diff --git a/tests/test_basic.py b/tests/test_basic.py index 1c7c88af..d139d2d1 100644 --- a/tests/test_basic.py +++ b/tests/test_basic.py @@ -1258,6 +1258,38 @@ def test_derivwindow1(): numpy.testing.assert_allclose(AP_begin_voltage, -45.505521563640386) +def test_AP_begin_indices_edge_case(): + """basic: Test AP_begin_indices edge case. + + Edge case: one spike, with no AHP_min_indices afterwards. + """ + import efel + efel.reset() + + stim_start = 100.0 + stim_end = 1000.0 + + time, voltage = load_ascii_input(derivwindow1_url) + trace = {} + + # remove last parts of data to be in case where + # min_AHP_indices is None + trace['T'] = time[:-50] + trace['V'] = voltage[:-50] + trace['stim_start'] = [stim_start] + trace['stim_end'] = [stim_end] + + features = ['AP_begin_indices', 'min_AHP_indices'] + + feature_values = \ + get_feature_values( + [trace], + features) + assert feature_values[0]['min_AHP_indices'] is None + # even though min_AHP_indices is None, we can still find AP_begin_indices + feature_values[0]['AP_begin_indices'][0] == 9772 + + def test_spike_count1(): """basic: Test spike_count 1"""