Skip to content

Commit

Permalink
change strict_stiminterval and ignore_first_ISI to bool type
Browse files Browse the repository at this point in the history
  • Loading branch information
ilkilic committed May 2, 2024
1 parent e9bff83 commit dd163b3
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 56 deletions.
14 changes: 8 additions & 6 deletions efel/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def set_dependency_file_location(location: str | Path) -> None:
Raises:
FileNotFoundError: If the path to the dependency file doesn't exist.
"""
_settings.set_setting('dependencyfile_path', str(location))
set_setting('dependencyfile_path', str(location))


def get_dependency_file_location() -> str:
Expand All @@ -99,7 +99,7 @@ def set_threshold(new_threshold: float) -> None:
new_threshold: The new spike detection threshold value (in the same units
as the traces, e.g. mV).
"""
_settings.set_setting('Threshold', new_threshold)
set_setting('Threshold', new_threshold)


@deprecated("Use `set_setting('DerivativeThreshold', "
Expand All @@ -114,7 +114,7 @@ def set_derivative_threshold(new_derivative_threshold: float) -> None:
new_derivative_threshold: The new derivative threshold value (in the same units
as the traces, e.g. mV/ms).
"""
_settings.set_setting('DerivativeThreshold', new_derivative_threshold)
set_setting('DerivativeThreshold', new_derivative_threshold)


def get_feature_names() -> list[str]:
Expand Down Expand Up @@ -216,6 +216,8 @@ def _initialise() -> None:
# Set the settings in the cppcore
settings_attrs = vars(_settings)
for setting_name, setting_value in settings_attrs.items():
if isinstance(setting_value, bool):
setting_value = int(setting_value)
if isinstance(setting_value, int):
cppcore.setFeatureInt(setting_name, [setting_value])
elif isinstance(setting_value, float):
Expand All @@ -230,19 +232,19 @@ def _initialise() -> None:
@deprecated("Use `set_setting()` instead")
def set_int_setting(setting_name: str, new_value: int) -> None:
"""Set a certain integer setting to a new value."""
_settings.set_int(setting_name, new_value)
set_setting(setting_name, new_value)


@deprecated("Use `set_setting()` instead")
def set_double_setting(setting_name: str, new_value: float) -> None:
"""Set a certain double setting to a new value."""
_settings.set_double(setting_name, new_value)
set_setting(setting_name, new_value)


@deprecated("Use `set_setting()` instead")
def set_str_setting(setting_name: str, new_value: str) -> None:
"""Set a certain string setting to a new value."""
_settings.set_str(setting_name, new_value)
set_setting(setting_name, new_value)


@overload
Expand Down
31 changes: 10 additions & 21 deletions efel/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class Settings:
rise_end_perc (float): Rise end percentage (default: 1.0).
initial_perc (float): Initial percentage (default: 0.1).
min_spike_height (float): Minimum spike height (default: 20.0).
strict_stiminterval (int): Strict stimulus interval (default: 0).
strict_stiminterval (bool): Strict stimulus interval (default: False).
initburst_freq_threshold (int): Initial burst frequency threshold
(default: 50)
initburst_sahp_start (int): Initial burst SAHP start (default: 5).
Expand All @@ -63,7 +63,7 @@ class Settings:
current_base_mode (str): Current base mode (default: "mean").
precision_threshold (float): Precision threshold (default: 1e-10).
sahp_start (float): SAHP start (default: 5.0).
ignore_first_ISI (int): Ignore first ISI (default: 1).
ignore_first_ISI (bool): Ignore first ISI (default: True).
impedance_max_freq (float): Impedance maximum frequency (default: 50.0).
"""

Expand All @@ -87,7 +87,7 @@ class Settings:
rise_end_perc: float = 1.0
initial_perc: float = 0.1
min_spike_height: float = 20.0
strict_stiminterval: int = 0
strict_stiminterval: bool = False
initburst_freq_threshold: int = 50
initburst_sahp_start: int = 5
initburst_sahp_end: int = 100
Expand All @@ -96,15 +96,17 @@ class Settings:
current_base_mode: str = "mean"
precision_threshold: float = 1e-10
sahp_start: float = 5.0
ignore_first_ISI: int = 1
ignore_first_ISI: bool = True
impedance_max_freq: float = 50.0

def set_setting(self, setting_name: str, new_value: Union[int, float, str]) -> None:
def set_setting(self,
setting_name: str,
new_value: Union[int, float, str, bool]) -> None:
"""Set a certain setting to a new value.
Args:
setting_name (str): Name of the setting to be modified.
new_value (Union[int, float, str]): New value for the setting.
new_value (Union[int, float, str, bool]): New value for the setting.
Raises:
ValueError: If the value is of the wrong type.
Expand All @@ -114,10 +116,9 @@ def set_setting(self, setting_name: str, new_value: Union[int, float, str]) -> N
if hasattr(self, setting_name):
expected_types = {f.name: f.type for f in fields(self)}
expected_type = expected_types.get(setting_name)
if expected_type and expected_type != type(new_value):
expected_type_name = expected_type.__name__
if expected_type and not isinstance(new_value, expected_type):
raise ValueError(f"Invalid value for setting '{setting_name}'. "
f"Expected type: {expected_type_name}.")
f"Expected type: {expected_type.__name__}.")
else:
logger.warning("Setting '%s' not found in settings. "
"Adding it as a new setting.", setting_name)
Expand All @@ -130,18 +131,6 @@ def set_setting(self, setting_name: str, new_value: Union[int, float, str]) -> N

setattr(self, setting_name, new_value)

@deprecated("Use set_setting instead")
def set_int(self, setting_name: str, new_value: int) -> None:
self.set_setting(setting_name, new_value)

@deprecated("Use set_setting instead")
def set_double(self, setting_name: str, new_value: float) -> None:
self.set_setting(setting_name, new_value)

@deprecated("Use set_setting instead")
def set_str(self, setting_name: str, new_value: str) -> None:
self.set_setting(setting_name, new_value)

def reset_to_default(self):
"""Reset settings to their default values"""
default_settings = Settings()
Expand Down
27 changes: 13 additions & 14 deletions tests/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
from efel.io import load_ascii_input
from efel.api import get_feature_values
from efel.api import set_setting
from efel.api import set_derivative_threshold
from efel.api import get_distance


Expand Down Expand Up @@ -413,7 +412,7 @@ def test_setDerivativeThreshold():
features)
AP_begin_voltage_orig = feature_values[0]['AP_begin_voltage'][1]

set_derivative_threshold(5.0)
set_setting('DerivativeThreshold', 5.0)
feature_values = \
get_feature_values(
[trace],
Expand Down Expand Up @@ -541,7 +540,7 @@ def test_min_AHP_indices_strict():

import efel

for strict, n_of_ahp in [(0, 17), (1, 16)]:
for strict, n_of_ahp in [(False, 17), (True, 16)]:
efel.reset()
set_setting('strict_stiminterval', strict)

Expand Down Expand Up @@ -598,7 +597,7 @@ def test_strict_stiminterval():

import efel

for strict, n_of_spikes in [(0, 5), (1, 3)]:
for strict, n_of_spikes in [(False, 5), (True, 3)]:
efel.reset()
set_setting("strict_stiminterval", strict)

Expand Down Expand Up @@ -681,7 +680,7 @@ def test_ISI_values_noIgnore():

features = ['ISI_values']

set_setting("ignore_first_ISI", 0)
set_setting("ignore_first_ISI", False)

feature_values = \
get_feature_values(
Expand All @@ -690,7 +689,7 @@ def test_ISI_values_noIgnore():
isi_values_no_ignore = feature_values[0]['ISI_values']

efel.reset()
set_setting("ignore_first_ISI", 1)
set_setting("ignore_first_ISI", True)

feature_values = \
get_feature_values(
Expand Down Expand Up @@ -2038,7 +2037,7 @@ def test_unfinished_peak():
"""basic: Test if unfinished peak doesn't break spike_count"""

import efel
set_setting('strict_stiminterval', 1)
set_setting('strict_stiminterval', True)

dt = 0.1
v = numpy.zeros(int(100 / dt)) - 70.0
Expand Down Expand Up @@ -2368,7 +2367,7 @@ def test_AP_width_between_threshold_strict():

import efel
efel.reset()
set_setting('strict_stiminterval', 1)
set_setting('strict_stiminterval', True)

threshold = -48.0
set_setting("Threshold", threshold)
Expand Down Expand Up @@ -3085,7 +3084,7 @@ def test_burst_indices():
"""basic: Test burst_begin_indices and burst_end_indices"""
import efel
efel.reset()
set_setting('ignore_first_ISI', 0)
set_setting('ignore_first_ISI', False)

time, voltage = load_ascii_input(burst1_url)
time, voltage = interpolate(time, voltage, 0.1)
Expand Down Expand Up @@ -3121,7 +3120,7 @@ def test_strict_burst_mean_freq():
"""basic: Test strict_burst_mean_freq"""
import efel
efel.reset()
set_setting('ignore_first_ISI', 0)
set_setting('ignore_first_ISI', False)

time, voltage = load_ascii_input(burst1_url)
time, voltage = interpolate(time, voltage, 0.1)
Expand Down Expand Up @@ -3168,7 +3167,7 @@ def test_strict_burst_number():
"""basic: Test strict_burst_number"""
import efel
efel.reset()
set_setting('ignore_first_ISI', 0)
set_setting('ignore_first_ISI', False)

time, voltage = load_ascii_input(burst1_url)
time, voltage = interpolate(time, voltage, 0.1)
Expand Down Expand Up @@ -3216,7 +3215,7 @@ def test_strict_interburst_voltage():
"""basic: Test strict_interburst_voltage"""
import efel
efel.reset()
set_setting('ignore_first_ISI', 0)
set_setting('ignore_first_ISI', False)

time, voltage = load_ascii_input(burst1_url)
time, voltage = interpolate(time, voltage, 0.1)
Expand Down Expand Up @@ -3278,7 +3277,7 @@ def test_AP_width_spike_before_stim_start():

assert len(ap_width) == 15

set_setting('strict_stiminterval', 1)
set_setting('strict_stiminterval', True)
feature_values = \
get_feature_values(
[trace],
Expand Down Expand Up @@ -3316,7 +3315,7 @@ def test_ADP_peak_amplitude():
"""basic: Test ADP_peak_amplitude"""
import efel
efel.reset()
set_setting('strict_stiminterval', 1)
set_setting('strict_stiminterval', True)

stim_start = 250.0
stim_end = 1600.0
Expand Down
2 changes: 1 addition & 1 deletion tests/test_isi.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def test_single_burst_ratio(self):
assert self.feature_values["single_burst_ratio"] is None

# set ignore_first_ISI=False
efel.set_setting("ignore_first_ISI", 0)
efel.set_setting("ignore_first_ISI", False)
self.feature_values = get_feature_values(
[self.trace],
self.features, raise_warnings=False)[0]
Expand Down
59 changes: 45 additions & 14 deletions tests/test_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,10 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""

from pathlib import Path
import numpy

import pytest

from efel.settings import Settings
from efel.api import set_setting
from efel.api import set_setting, get_settings


def test_set_setting():
Expand All @@ -51,24 +48,16 @@ def test_set_setting_invalid_type():
"""Test that the set_setting method raises a ValueError
when given an invalid type."""
settings = Settings()
try:
with pytest.raises(ValueError):
settings.set_setting("Threshold", "-30.0")
except ValueError:
assert True
else:
assert False


def test_set_setting_dependencyfile_path_not_found():
"""Test that the set_setting method raises a FileNotFoundError
when given a nonexistent file."""
settings = Settings()
try:
with pytest.raises(FileNotFoundError):
settings.set_setting("dependencyfile_path", "nonexistent_file.txt")
except FileNotFoundError:
assert True
else:
assert False


def test_reset_to_default():
Expand All @@ -78,3 +67,45 @@ def test_reset_to_default():
settings.Threshold = -30.0
settings.reset_to_default()
assert settings.Threshold == -20.0


def test_get_settings():
"""Test that the get_settings method returns an instance of efel.Settings."""
settings = get_settings()
assert isinstance(settings, Settings)


def test_str_method():
"""Test that the __str__ method returns the correct string representation."""
settings = Settings()
expected_output = (
"Threshold: -20.0\n"
"DerivativeThreshold: 10.0\n"
"DownDerivativeThreshold: -12.0\n"
f"dependencyfile_path: {settings.dependencyfile_path}\n"
"spike_skipf: 0.1\n"
"max_spike_skip: 2\n"
"interp_step: 0.1\n"
"burst_factor: 1.5\n"
"strict_burst_factor: 2.0\n"
"voltage_base_start_perc: 0.9\n"
"voltage_base_end_perc: 1.0\n"
"current_base_start_perc: 0.9\n"
"current_base_end_perc: 1.0\n"
"rise_start_perc: 0.0\n"
"rise_end_perc: 1.0\n"
"initial_perc: 0.1\n"
"min_spike_height: 20.0\n"
"strict_stiminterval: False\n"
"initburst_freq_threshold: 50\n"
"initburst_sahp_start: 5\n"
"initburst_sahp_end: 100\n"
"DerivativeWindow: 3\n"
"voltage_base_mode: mean\n"
"current_base_mode: mean\n"
"precision_threshold: 1e-10\n"
"sahp_start: 5.0\n"
"ignore_first_ISI: True\n"
"impedance_max_freq: 50.0"
)
assert str(settings) == expected_output

0 comments on commit dd163b3

Please sign in to comment.