From 18f7723135ce85786279da6dae30a98367eb5356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Jaquier?= <72930209+AurelienJaquier@users.noreply.github.com> Date: Tue, 21 May 2024 16:45:38 +0200 Subject: [PATCH] fix AHP_slow_time and min_AHP_values (#394) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix AHP_slow_time and min_AHP_values * do not allow empty list as a feature value * empty features should be None * do not hardcode return value for features computes outside of their function --------- Co-authored-by: Jaquier Aurélien Tristan --- efel/cppcore/SpikeEvent.cpp | 30 +++++++++++++++---- efel/cppcore/SpikeShape.cpp | 20 ++++++++++--- efel/cppcore/cfeature.cpp | 5 +++- efel/pyfeatures/pyfeatures.py | 4 +-- .../testdata/allfeatures/expectedresults.json | 16 +++++----- 5 files changed, 54 insertions(+), 21 deletions(-) diff --git a/efel/cppcore/SpikeEvent.cpp b/efel/cppcore/SpikeEvent.cpp index 2a6764d8..8ae355b2 100644 --- a/efel/cppcore/SpikeEvent.cpp +++ b/efel/cppcore/SpikeEvent.cpp @@ -557,7 +557,10 @@ int SpikeEvent::burst_begin_indices(mapStr2intVec& IntFeatureData, int SpikeEvent::burst_end_indices(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"burst_begin_indices"}); + int retVal = intFeatures.at("burst_begin_indices").size(); + if (retVal <= 0) return -1; + return retVal; } static int __strict_burst_mean_freq(const vector& PVTime, @@ -695,7 +698,10 @@ int SpikeEvent::interburst_min_indices(mapStr2intVec& IntFeatureData, int SpikeEvent::interburst_min_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"interburst_min_indices"}); + int retVal = intFeatures.at("interburst_min_indices").size(); + if (retVal <= 0) return -1; + return retVal; } static int __postburst_min_indices(const vector& t, @@ -767,7 +773,10 @@ int SpikeEvent::postburst_min_indices(mapStr2intVec& IntFeatureData, int SpikeEvent::postburst_min_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"postburst_min_indices"}); + int retVal = intFeatures.at("postburst_min_indices").size(); + if (retVal <= 0) return -1; + return retVal; } int SpikeEvent::time_to_interburst_min(mapStr2intVec& IntFeatureData, @@ -897,7 +906,10 @@ int SpikeEvent::postburst_slow_ahp_indices(mapStr2intVec& IntFeatureData, int SpikeEvent::postburst_slow_ahp_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"postburst_slow_ahp_indices"}); + int retVal = intFeatures.at("postburst_slow_ahp_indices").size(); + if (retVal <= 0) return -1; + return retVal; } int SpikeEvent::time_to_postburst_slow_ahp(mapStr2intVec& IntFeatureData, @@ -1010,7 +1022,10 @@ int SpikeEvent::postburst_fast_ahp_indices(mapStr2intVec& IntFeatureData, int SpikeEvent::postburst_fast_ahp_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"postburst_fast_ahp_indices"}); + int retVal = intFeatures.at("postburst_fast_ahp_indices").size(); + if (retVal <= 0) return -1; + return retVal; } static int __postburst_adp_peak_indices(const vector& t, const vector& v, @@ -1077,7 +1092,10 @@ int SpikeEvent::postburst_adp_peak_indices(mapStr2intVec& IntFeatureData, int SpikeEvent::postburst_adp_peak_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"postburst_adp_peak_indices"}); + int retVal = intFeatures.at("postburst_adp_peak_indices").size(); + if (retVal <= 0) return -1; + return retVal; } int SpikeEvent::time_to_postburst_fast_ahp(mapStr2intVec& IntFeatureData, diff --git a/efel/cppcore/SpikeShape.cpp b/efel/cppcore/SpikeShape.cpp index cbf0aad8..6de52496 100644 --- a/efel/cppcore/SpikeShape.cpp +++ b/efel/cppcore/SpikeShape.cpp @@ -475,7 +475,10 @@ int SpikeShape::min_AHP_indices(mapStr2intVec& IntFeatureData, int SpikeShape::min_AHP_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return -1; + const auto& intFeatures = getFeatures(IntFeatureData, {"min_AHP_indices"}); + int retVal = intFeatures.at("min_AHP_indices").size(); + if (retVal <= 0) return -1; + return retVal; } // Difference with SpikeShape is that this function doesn't return -1 if there are no @@ -550,7 +553,10 @@ int SpikeShape::AHP_depth_abs_slow(mapStr2intVec& IntFeatureData, int SpikeShape::AHP_slow_time(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return -1; + const auto& doubleFeatures = getFeatures(DoubleFeatureData, {"AHP_depth_abs_slow"}); + int retVal = doubleFeatures.at("AHP_depth_abs_slow").size(); + if (retVal <= 0) return -1; + return retVal; } // *** AHP_depth_slow *** @@ -818,7 +824,10 @@ int SpikeShape::ADP_peak_indices(mapStr2intVec& IntFeatureData, int SpikeShape::ADP_peak_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"ADP_peak_indices"}); + int retVal = intFeatures.at("ADP_peak_indices").size(); + if (retVal <= 0) return -1; + return retVal; } // strict_stiminterval should be True when using this feature @@ -994,7 +1003,10 @@ int SpikeShape::min_between_peaks_indices(mapStr2intVec& IntFeatureData, int SpikeShape::min_between_peaks_values(mapStr2intVec& IntFeatureData, mapStr2doubleVec& DoubleFeatureData, mapStr2Str& StringData) { - return 1; + const auto& intFeatures = getFeatures(IntFeatureData, {"min_between_peaks_indices"}); + int retVal = intFeatures.at("min_between_peaks_indices").size(); + if (retVal <= 0) return -1; + return retVal; } // *** AP_duration_half_width according to E8 and E16 *** diff --git a/efel/cppcore/cfeature.cpp b/efel/cppcore/cfeature.cpp index 834e5446..36fd7845 100644 --- a/efel/cppcore/cfeature.cpp +++ b/efel/cppcore/cfeature.cpp @@ -303,7 +303,10 @@ int cFeature::getFeature(string strName, vector& vec) { return -1; } vec = getMapData(strName, *dataMap); - if (vec.empty()) GErrorStr += "Feature [" + strName + "] data is missing\n"; + if (vec.empty()) { + GErrorStr += "Feature [" + strName + "] data is missing\n"; + return -1; + } logger << "Calculated feature " << strName << ":" << vec << endl; return vec.size(); diff --git a/efel/pyfeatures/pyfeatures.py b/efel/pyfeatures/pyfeatures.py index 097f1a8b..184e4a83 100644 --- a/efel/pyfeatures/pyfeatures.py +++ b/efel/pyfeatures/pyfeatures.py @@ -291,7 +291,7 @@ def spikes_per_burst(): burst_begin_indices = get_cpp_feature("burst_begin_indices") burst_end_indices = get_cpp_feature("burst_end_indices") - if burst_begin_indices is None: + if burst_begin_indices is None or len(burst_begin_indices) < 1: return None ap_per_bursts = [] @@ -304,7 +304,7 @@ def spikes_per_burst(): def spikes_per_burst_diff(): """Calculate the diff between the spikes in each burst and the next one""" spikes_per_burst_values = spikes_per_burst() - if spikes_per_burst_values is None: + if spikes_per_burst_values is None or len(spikes_per_burst_values) < 2: return None return spikes_per_burst_values[:-1] - spikes_per_burst_values[1:] diff --git a/tests/testdata/allfeatures/expectedresults.json b/tests/testdata/allfeatures/expectedresults.json index 27463db9..bb6e0145 100644 --- a/tests/testdata/allfeatures/expectedresults.json +++ b/tests/testdata/allfeatures/expectedresults.json @@ -435,8 +435,8 @@ "interburst_60percent_indices": null, "interburst_60percent_values": null, "interburst_duration": null, - "interburst_min_indices": [], - "interburst_min_values": [], + "interburst_min_indices": null, + "interburst_min_values": null, "interburst_voltage": [ -38.820613862535545 ], @@ -624,7 +624,7 @@ "strict_burst_number": [ 1 ], - "strict_interburst_voltage": [], + "strict_interburst_voltage": null, "time": [ 0.0, 0.1, @@ -30632,7 +30632,7 @@ "time_to_first_spike": [ 8.000000000092427 ], - "time_to_interburst_min": [], + "time_to_interburst_min": null, "time_to_last_spike": [ 1937.7999999986964 ], @@ -60680,7 +60680,7 @@ "spikes_per_burst": [ 2 ], - "spikes_per_burst_diff": [], + "spikes_per_burst_diff": null, "spikes_in_burst1_burst2_diff": null, "spikes_in_burst1_burstlast_diff": null, "depol_block": null, @@ -60723,7 +60723,7 @@ "strict_burst_mean_freq": [ 7.99041151 ], - "strict_interburst_voltage": [], + "strict_interburst_voltage": null, "ADP_peak_amplitude": [ 0.0, 2.6873666528663236, @@ -60748,8 +60748,8 @@ -41.12299346923828, -38.12341871769886 ], - "interburst_min_indices": [], - "interburst_min_values": [], + "interburst_min_indices": null, + "interburst_min_values": null, "postburst_min_indices": [ 26465 ],