Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ Fixed
- Fix bugs in utility function `torch_ecg.utils.make_serializable`: the previous implementation
does not drop some types of unserializable items correctly. Two additional parameters
`drop_unserializable` and `drop_paths` are added.
- Fix ``CkptMixin.save()`` silently truncating checkpoint filenames that contain
decimal values (e.g. ``…metric_0.91``): ``pathlib.Path.with_suffix(".safetensors")``
treated ``.91`` as the existing suffix and replaced it, producing
``…metric_0.safetensors`` instead of the correct ``…metric_0.91.safetensors``.
The method now appends ``.safetensors`` for paths without a recognised
extension, and returns the final ``Path`` used so callers can track it.
- Fix ``BaseTrainer`` checkpoint cleanup permanently failing: ``saved_models``
stored the raw stem path while the actual file on disk had a ``.safetensors``
suffix, causing every ``os.remove()`` call to raise ``FileNotFoundError``.
The trainer now stores the path returned by ``save_checkpoint()``, and handles
both single-file (``os.remove``) and directory (``shutil.rmtree``) checkpoints.
Comment on lines +75 to +85

Security
~~~~~~~~
Expand Down
11 changes: 1 addition & 10 deletions benchmarks/train_crnn_cinc2020/scoring_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,10 @@
metrics from the official scoring repository
"""

from numbers import Real
from typing import List, Sequence, Tuple

import numpy as np

try:
import torch_ecg # noqa: F401
except ModuleNotFoundError:
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).absolute().parents[2]))

from torch_ecg.databases.aux_data.cinc2020_aux_data import load_weights

__all__ = [
Expand Down Expand Up @@ -168,7 +159,7 @@ def compute_f_measure(labels: np.ndarray, outputs: np.ndarray) -> float:


# Compute F-beta and G-beta measures from the unofficial phase of the Challenge.
def compute_beta_measures(labels: np.ndarray, outputs: np.ndarray, beta: Real) -> Tuple[float, float]:
def compute_beta_measures(labels: np.ndarray, outputs: np.ndarray, beta: float) -> Tuple[float, float]:
"""checked,"""
num_recordings, num_classes = np.shape(labels)

Expand Down
11 changes: 1 addition & 10 deletions benchmarks/train_crnn_cinc2021/scoring_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,10 @@
metrics from the official scoring repository
"""

from numbers import Real
from typing import List, Sequence, Tuple, Union

import numpy as np

try:
import torch_ecg # noqa: F401
except ModuleNotFoundError:
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).absolute().parents[2]))

from torch_ecg.databases.aux_data.cinc2021_aux_data import load_weights

__all__ = [
Expand Down Expand Up @@ -233,7 +224,7 @@ def compute_f_measure(labels: np.ndarray, outputs: np.ndarray) -> Tuple[float, n


# Compute F-beta and G-beta measures from the unofficial phase of the Challenge.
def compute_beta_measures(labels: np.ndarray, outputs: np.ndarray, beta: Real) -> Tuple[float, float]:
def compute_beta_measures(labels: np.ndarray, outputs: np.ndarray, beta: float) -> Tuple[float, float]:
"""checked,"""
num_recordings, num_classes = np.shape(labels)

Expand Down
33 changes: 16 additions & 17 deletions benchmarks/train_crnn_cinc2021/special_detectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"""

from itertools import repeat
from numbers import Real
from typing import Any, Optional, Sequence

import numpy as np
Expand Down Expand Up @@ -54,7 +53,7 @@

def special_detectors(
raw_sig: np.ndarray,
fs: Real,
fs: int,
sig_fmt: str = "channel_first",
leads: Sequence[str] = Standard12Leads,
verbose: int = 0,
Expand All @@ -66,7 +65,7 @@ def special_detectors(
----------
raw_sig: ndarray,
the raw multi-lead ecg signal, with units in mV
fs: real number,
fs: int,
sampling frequency of `sig`
sig_fmt: str, default "channel_first",
format of the multi-lead ecg signal,
Expand Down Expand Up @@ -133,19 +132,19 @@ def special_detectors(

def pacing_rhythm_detector(
raw_sig: np.ndarray,
fs: Real,
fs: int,
sig_fmt: str = "channel_first",
leads: Sequence[str] = Standard12Leads,
ret_prob: bool = True,
verbose: int = 0,
) -> Real:
) -> float:
"""to be improved (fine-tuning hyper-parameters in cfg.py),

Parameters
----------
raw_sig: ndarray,
the raw multi-lead ecg signal, with units in mV
fs: real number,
fs: int,
sampling frequency of `sig`
sig_fmt: str, default "channel_first",
format of the multi-lead ecg signal,
Expand Down Expand Up @@ -238,7 +237,7 @@ def pacing_rhythm_detector(
def electrical_axis_detector(
filtered_sig: np.ndarray,
rpeaks: np.ndarray,
fs: Real,
fs: int,
sig_fmt: str = "channel_first",
leads: Sequence[str] = Standard12Leads,
method: Optional[str] = None,
Expand All @@ -255,7 +254,7 @@ def electrical_axis_detector(
the filtered multi-lead ecg signal, with units in mV
rpeaks: ndarray,
array of indices of the R peaks
fs: real number,
fs: int,
sampling frequency of `sig`
sig_fmt: str, default "channel_first",
format of the multi-lead ecg signal,
Expand Down Expand Up @@ -375,8 +374,8 @@ def electrical_axis_detector(

def brady_tachy_detector(
rpeaks: np.ndarray,
fs: Real,
normal_rr_range: Optional[Sequence[Real]] = None,
fs: int,
normal_rr_range: Optional[Sequence[int]] = None,
verbose: int = 0,
) -> str:
"""to be improved (fine-tuning hyper-parameters in cfg.py),
Expand All @@ -391,7 +390,7 @@ def brady_tachy_detector(
----------
rpeaks: ndarray,
array of indices of the R peaks
fs: real number,
fs: int,
sampling frequency of the ecg signal
normal_rr_range: sequence of int, optional,
the range of normal rr interval, with units in ms;
Expand Down Expand Up @@ -438,7 +437,7 @@ def brady_tachy_detector(
def LQRSV_detector(
filtered_sig: np.ndarray,
rpeaks: np.ndarray,
fs: Real,
fs: int,
sig_fmt: str = "channel_first",
leads: Sequence[str] = Standard12Leads,
verbose: int = 0,
Expand All @@ -451,7 +450,7 @@ def LQRSV_detector(
the filtered multi-lead ecg signal, with units in mV
rpeaks: ndarray,
array of indices of the R peaks
fs: real number,
fs: int,
sampling frequency of the ecg signal
sig_fmt: str, default "channel_first",
format of the 12 lead ecg signal,
Expand Down Expand Up @@ -511,7 +510,7 @@ def LQRSV_detector(
def LQRSV_detector_backup(
filtered_sig: np.ndarray,
rpeaks: np.ndarray,
fs: Real,
fs: int,
sig_fmt: str = "channel_first",
leads: Sequence[str] = Standard12Leads,
verbose: int = 0,
Expand All @@ -524,7 +523,7 @@ def LQRSV_detector_backup(
the filtered 12-lead ecg signal, with units in mV
rpeaks: ndarray,
array of indices of the R peaks
fs: real number,
fs: int,
sampling frequency of the ecg signal
sig_fmt: str, default "channel_first",
format of the 12 lead ecg signal,
Expand Down Expand Up @@ -608,7 +607,7 @@ def LQRSV_detector_backup(
def PRWP_detector(
filtered_sig: np.ndarray,
rpeaks: np.ndarray,
fs: Real,
fs: int,
sig_fmt: str = "channel_first",
leads: Sequence[str] = Standard12Leads,
verbose: int = 0,
Expand All @@ -621,7 +620,7 @@ def PRWP_detector(
the filtered multi-lead ecg signal, with units in mV
rpeaks: ndarray,
array of indices of the R peaks
fs: real number,
fs: int,
sampling frequency of the ecg signal
sig_fmt: str, default "channel_first",
format of the 12 lead ecg signal,
Expand Down
11 changes: 5 additions & 6 deletions benchmarks/train_crnn_cinc2023/data_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import re
import warnings
from ast import literal_eval
from numbers import Real
from pathlib import Path
from typing import Any, Dict, List, Literal, Optional, Sequence, Tuple, Union

Expand Down Expand Up @@ -599,9 +598,9 @@ def load_data(
return_channels: bool = False,
) -> Union[
np.ndarray,
Tuple[np.ndarray, Real],
Tuple[np.ndarray, int],
Tuple[np.ndarray, List[str]],
Tuple[np.ndarray, Real, List[str]],
Tuple[np.ndarray, int, List[str]],
]:
"""Load EEG data from the record.

Expand Down Expand Up @@ -640,7 +639,7 @@ def load_data(
-------
data : numpy.ndarray
The loaded EEG data.
data_fs : numbers.Real, optional
data_fs : int, optional
Sampling frequency of the output signal.
Returned if `return_fs` is True.
data_channels : list of str, optional
Expand Down Expand Up @@ -721,7 +720,7 @@ def load_bipolar_data(
units: Literal["mV", "uV", "muV", "μV", None] = "uV",
fs: Optional[int] = None,
return_fs: bool = False,
) -> Union[np.ndarray, Tuple[np.ndarray, Real]]:
) -> Union[np.ndarray, Tuple[np.ndarray, int]]:
"""Load bipolar EEG data from the record.

Bipolar EEG is the difference between two channels.
Expand Down Expand Up @@ -754,7 +753,7 @@ def load_bipolar_data(
-------
data : numpy.ndarray
The loaded EEG data.
data_fs : numbers.Real, optional
data_fs : int, optional
Sampling frequency of the output signal.

"""
Expand Down
12 changes: 1 addition & 11 deletions benchmarks/train_hybrid_cpsc2020/metrics.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,8 @@
""" """

from numbers import Real
from typing import List, Sequence, Tuple, Union

import numpy as np

try:
import torch_ecg # noqa: F401
except ModuleNotFoundError:
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).absolute().parents[2]))

from cfg import BaseCfg

from torch_ecg.cfg import CFG
Expand Down Expand Up @@ -323,7 +313,7 @@ def compute_f_measure(labels: np.ndarray, outputs: np.ndarray) -> float:


# Compute F-beta and G-beta measures from the unofficial phase of the Challenge.
def compute_beta_measures(labels: np.ndarray, outputs: np.ndarray, beta: Real) -> Tuple[float, float]:
def compute_beta_measures(labels: np.ndarray, outputs: np.ndarray, beta: float) -> Tuple[float, float]:
"""checked,"""
num_recordings, num_classes = np.shape(labels)

Expand Down
13 changes: 2 additions & 11 deletions benchmarks/train_hybrid_cpsc2020/signal_processing/ecg_denoise.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,10 @@
to add
"""

from numbers import Real
from typing import List

import numpy as np

try:
import torch_ecg # noqa: F401
except ModuleNotFoundError:
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).absolute().parents[3]))

from torch_ecg.cfg import CFG
from torch_ecg.utils.utils_data import mask_to_intervals

Expand All @@ -36,7 +27,7 @@
]


def ecg_denoise(filtered_sig: np.ndarray, fs: Real, config: CFG) -> List[List[int]]:
def ecg_denoise(filtered_sig: np.ndarray, fs: int, config: CFG) -> List[List[int]]:
"""

a naive function removing non-ECG segments (flat and motion artefact)
Expand All @@ -45,7 +36,7 @@ def ecg_denoise(filtered_sig: np.ndarray, fs: Real, config: CFG) -> List[List[in
----------
filtered_sig: ndarray,
1d filtered (typically bandpassed) ECG signal,
fs: real number,
fs: int,
sampling frequency of `filtered_sig`
config: dict,
configs of relavant parameters, like window, step, etc.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import os
import time
from copy import deepcopy
from numbers import Real
from typing import Dict, Optional

import numpy as np
Expand Down Expand Up @@ -64,14 +63,14 @@
]


def preprocess_signal(raw_sig: np.ndarray, fs: Real, config: Optional[CFG] = None) -> Dict[str, np.ndarray]:
def preprocess_signal(raw_sig: np.ndarray, fs: int, config: Optional[CFG] = None) -> Dict[str, np.ndarray]:
"""

Parameters
----------
raw_sig: ndarray,
the raw ecg signal
fs: real number,
fs: int,
sampling frequency of `raw_sig`
config: dict, optional,
extra process configuration,
Expand Down Expand Up @@ -135,7 +134,7 @@ def preprocess_signal(raw_sig: np.ndarray, fs: Real, config: Optional[CFG] = Non

def parallel_preprocess_signal(
raw_sig: np.ndarray,
fs: Real,
fs: int,
config: Optional[CFG] = None,
save_dir: Optional[str] = None,
save_fmt: str = "npy",
Expand All @@ -147,7 +146,7 @@ def parallel_preprocess_signal(
----------
raw_sig: ndarray,
the raw ecg signal
fs: real number,
fs: int,
sampling frequency of `raw_sig`
config: dict, optional,
extra process configuration,
Expand Down
Loading
Loading