Skip to content

Commit 0be8632

Browse files
authored
Merge pull request #23 from smoia/enh/decorator
Better check functions input, transforming physio_or_numpy function into decorator
2 parents baee7df + 5a67c14 commit 0be8632

File tree

8 files changed

+74
-37
lines changed

8 files changed

+74
-37
lines changed

.all-contributorsrc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
"commit": false,
1111
"commitConvention": "none",
1212
"contributors": [
13+
{
14+
"login": "mathdugre",
15+
"name": "Mathieu Dugré",
16+
"avatar_url": "https://avatars.githubusercontent.com/u/16450132?v=4",
17+
"profile": "https://github.com/mathdugre",
18+
"contributions": [
19+
"code"
20+
]
21+
},
1322
{
1423
"login": "goodalse2019",
1524
"name": "Sarah Goodale",
@@ -39,7 +48,9 @@
3948
"avatar_url": "https://avatars.githubusercontent.com/u/77584086?v=4",
4049
"profile": "https://github.com/me-pic",
4150
"contributions": [
42-
"infra"
51+
"infra",
52+
"review",
53+
"bug"
4354
]
4455
},
4556
{

.github/workflows/auto-release.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# # This workflows will create a release using auto when a PR is merged in master.
1+
# This workflows will create a release using auto when a PR is merged in master.
22

3-
name: Format and auto-release on PR merge
3+
name: Auto-release on PR merge
44

55
on:
66
# ATM, this is the closest trigger to a PR merging
@@ -10,7 +10,7 @@ on:
1010

1111
jobs:
1212
auto-release:
13-
runs-on: ubuntu-20.04
13+
runs-on: ubuntu-22.04
1414
# Set skip ci to avoid loops
1515
if: "!contains(github.event.head_commit.message, 'ci skip') && !contains(github.event.head_commit.message, 'skip ci')"
1616
# Set bash as default shell for jobs
@@ -19,7 +19,7 @@ jobs:
1919
shell: bash
2020
steps:
2121
- name: Checkout source
22-
uses: actions/checkout@v2
22+
uses: actions/checkout@v4
2323
with:
2424
# Fetch all history for all branches and tags
2525
fetch-depth: 0
Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# # This workflows will upload a Python Package using Twine when a release is created
2-
# # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
1+
# This workflows will upload a Python Package using Twine when a release is created
2+
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
33

44
name: Upload Python Package
55

@@ -10,15 +10,15 @@ on:
1010
jobs:
1111
deploy:
1212

13-
runs-on: ubuntu-20.04
13+
runs-on: ubuntu-22.04
1414

1515
steps:
1616
- name: Checkout source
17-
uses: actions/checkout@v2
17+
uses: actions/checkout@v4
1818
- name: Set up Python
19-
uses: actions/setup-python@v2
19+
uses: actions/setup-python@v5
2020
with:
21-
python-version: '3.6'
21+
python-version: 3.11
2222
- name: Install dependencies
2323
run: |
2424
python -m pip install --upgrade pip
@@ -29,4 +29,5 @@ jobs:
2929
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
3030
run: |
3131
python setup.py sdist bdist_wheel
32+
twine check dist/*
3233
twine upload dist/*

.zenodo.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,25 @@
2323
"type": "personal"
2424
}
2525
},
26+
{
27+
"affiliations": [
28+
{
29+
"name": "Concordia University"
30+
}
31+
],
32+
"person_or_org": {
33+
"family_name": "Dugré",
34+
"given_name": "Mathieu",
35+
"identifiers": [
36+
{
37+
"identifier": "0000-0003-2828-6031",
38+
"scheme": "orcid"
39+
}
40+
],
41+
"name": "Dugré, Mathieu",
42+
"type": "personal"
43+
}
44+
},
2645
{
2746
"affiliations": [
2847
{

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ physioQC
2424
[![Supports python version](https://img.shields.io/pypi/pyversions/physioqc)](https://pypi.org/project/physioqc/)
2525

2626
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
27-
[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-)
27+
[![All Contributors](https://img.shields.io/badge/all_contributors-8-orange.svg?style=flat-square)](#contributors-)
2828
<!-- ALL-CONTRIBUTORS-BADGE:END -->
2929

3030
``physioqc`` is a python3 library meant to do something.
@@ -70,12 +70,15 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
7070
<table>
7171
<tbody>
7272
<tr>
73+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/mathdugre"><img src="https://avatars.githubusercontent.com/u/16450132?v=4?s=100" width="100px;" alt="Mathieu Dugré"/><br /><sub><b>Mathieu Dugré</b></sub></a><br /><a href="https://github.com/physiopy/physioqc/commits?author=mathdugre" title="Code">💻</a></td>
7374
<td align="center" valign="top" width="14.28%"><a href="https://github.com/goodalse2019"><img src="https://avatars.githubusercontent.com/u/60117796?v=4?s=100" width="100px;" alt="Sarah Goodale"/><br /><sub><b>Sarah Goodale</b></sub></a><br /><a href="#eventOrganizing-goodalse2019" title="Event Organizing">📋</a> <a href="#ideas-goodalse2019" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/physiopy/physioqc/pulls?q=is%3Apr+reviewed-by%3Agoodalse2019" title="Reviewed Pull Requests">👀</a></td>
7475
<td align="center" valign="top" width="14.28%"><a href="https://github.com/smoia"><img src="https://avatars.githubusercontent.com/u/35300580?v=4?s=100" width="100px;" alt="Stefano Moia"/><br /><sub><b>Stefano Moia</b></sub></a><br /><a href="https://github.com/physiopy/physioqc/commits?author=smoia" title="Code">💻</a> <a href="#ideas-smoia" title="Ideas, Planning, & Feedback">🤔</a> <a href="#infra-smoia" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#projectManagement-smoia" title="Project Management">📆</a></td>
75-
<td align="center" valign="top" width="14.28%"><a href="https://github.com/me-pic"><img src="https://avatars.githubusercontent.com/u/77584086?v=4?s=100" width="100px;" alt="Marie-Eve Picard"/><br /><sub><b>Marie-Eve Picard</b></sub></a><br /><a href="#infra-me-pic" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
76+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/me-pic"><img src="https://avatars.githubusercontent.com/u/77584086?v=4?s=100" width="100px;" alt="Marie-Eve Picard"/><br /><sub><b>Marie-Eve Picard</b></sub></a><br /><a href="#infra-me-pic" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/physiopy/physioqc/pulls?q=is%3Apr+reviewed-by%3Ame-pic" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/physiopy/physioqc/issues?q=author%3Ame-pic" title="Bug reports">🐛</a></td>
7677
<td align="center" valign="top" width="14.28%"><a href="https://github.com/celprov"><img src="https://avatars.githubusercontent.com/u/77437752?v=4?s=100" width="100px;" alt="celprov"/><br /><sub><b>celprov</b></sub></a><br /><a href="https://github.com/physiopy/physioqc/commits?author=celprov" title="Code">💻</a> <a href="#ideas-celprov" title="Ideas, Planning, & Feedback">🤔</a></td>
7778
<td align="center" valign="top" width="14.28%"><a href="https://github.com/SRSteinkamp"><img src="https://avatars.githubusercontent.com/u/17494653?v=4?s=100" width="100px;" alt="Simon Steinkamp"/><br /><sub><b>Simon Steinkamp</b></sub></a><br /><a href="https://github.com/physiopy/physioqc/commits?author=SRSteinkamp" title="Code">💻</a> <a href="#ideas-SRSteinkamp" title="Ideas, Planning, & Feedback">🤔</a></td>
7879
<td align="center" valign="top" width="14.28%"><a href="https://github.com/RayStick"><img src="https://avatars.githubusercontent.com/u/50215726?v=4?s=100" width="100px;" alt="Rachael Stickland"/><br /><sub><b>Rachael Stickland</b></sub></a><br /><a href="#infra-RayStick" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
80+
</tr>
81+
<tr>
7982
<td align="center" valign="top" width="14.28%"><a href="https://github.com/neuralkn0t"><img src="https://avatars.githubusercontent.com/u/86740625?v=4?s=100" width="100px;" alt="Neuralkn0t"/><br /><sub><b>Neuralkn0t</b></sub></a><br /><a href="https://github.com/physiopy/physioqc/commits?author=neuralkn0t" title="Code">💻</a></td>
8083
</tr>
8184
</tbody>

physioqc/metrics/multimodal.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def signal_fct(signal):
2626
return signal
2727

2828

29+
@physio_or_numpy
2930
def std(signal):
3031
"""
3132
Calculate standard deviation across input channels of signal.
@@ -40,11 +41,11 @@ def std(signal):
4041
N-sized array :obj:`numpy.ndarray`
4142
Standard deviation of signal.
4243
"""
43-
signal = physio_or_numpy(signal)
4444
std_val = np.std(signal, axis=0)
4545
return std_val
4646

4747

48+
@physio_or_numpy
4849
def mean(signal: np.array):
4950
"""
5051
Calculate mean across input channels of signal.
@@ -59,11 +60,11 @@ def mean(signal: np.array):
5960
N-sized array :obj:`numpy.ndarray`
6061
Mean of signal.
6162
"""
62-
signal = physio_or_numpy(signal)
6363
mean_val = np.mean(signal, axis=0)
6464
return mean_val
6565

6666

67+
@physio_or_numpy
6768
def tSNR(signal):
6869
"""
6970
Calculate temporal signal to noise ratio of signal.
@@ -78,11 +79,11 @@ def tSNR(signal):
7879
N-sized array :obj:`numpy.ndarray`
7980
Temporal signal to noise ratio of signal.
8081
"""
81-
signal = physio_or_numpy(signal)
8282
tSNR_val = np.mean(signal, axis=0) / np.std(signal, axis=0)
8383
return tSNR_val
8484

8585

86+
@physio_or_numpy
8687
def CoV(signal):
8788
"""
8889
Calculate coefficient of variation of signal.
@@ -97,11 +98,11 @@ def CoV(signal):
9798
N-sized array :obj:`numpy.ndarray`
9899
Temporal signal to noise ratio of signal.
99100
"""
100-
signal = physio_or_numpy(signal)
101101
cov_val = np.std(signal, axis=0) / np.mean(signal, axis=0)
102102
return cov_val
103103

104104

105+
@physio_or_numpy
105106
def min(signal: np.array):
106107
"""
107108
Calculate min across input channels of signal.
@@ -116,11 +117,11 @@ def min(signal: np.array):
116117
N-sized array :obj:`numpy.ndarray`
117118
min of signal.
118119
"""
119-
signal = physio_or_numpy(signal)
120120
min_val = np.min(signal, axis=0)
121121
return min_val
122122

123123

124+
@physio_or_numpy
124125
def max(signal: np.array):
125126
"""
126127
Calculate max across input channels of signal.
@@ -135,11 +136,11 @@ def max(signal: np.array):
135136
N-sized array :obj:`numpy.ndarray`
136137
max of signal.
137138
"""
138-
signal = physio_or_numpy(signal)
139139
max_val = np.max(signal, axis=0)
140140
return max_val
141141

142142

143+
@physio_or_numpy
143144
def iqr(signal: np.array, q_high: float = 75, q_low: float = 25):
144145
"""Calculate the Inter Quantile Range (IQR) over the input signal.
145146
@@ -157,13 +158,13 @@ def iqr(signal: np.array, q_high: float = 75, q_low: float = 25):
157158
np.array
158159
iqr of the signal
159160
"""
160-
signal = physio_or_numpy(signal)
161161
p_high, p_low = np.percentile(signal, [q_high, q_low], axis=0)
162162
iqr_val = p_high - p_low
163163

164164
return iqr_val
165165

166166

167+
@physio_or_numpy
167168
def percentile(signal: np.array, perc: float = 2):
168169
"""Calculate the percentile perc over the signal.
169170
@@ -179,7 +180,6 @@ def percentile(signal: np.array, perc: float = 2):
179180
np.array
180181
percentile of the signal
181182
"""
182-
signal = physio_or_numpy(signal)
183183
perc_val = np.percentile(signal, axis=0, q=perc)
184184

185185
return perc_val

physioqc/metrics/utils.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Miscellaneous utility functions for metric calculation."""
22

3+
import functools
34
import logging
45

56
LGR = logging.getLogger(__name__)
@@ -32,24 +33,29 @@ def print_metric_call(metric, args):
3233
LGR.info(msg)
3334

3435

35-
def physio_or_numpy(signal):
36+
def physio_or_numpy(func):
3637
"""
37-
Return data from a peakdet.physio.Physio object or a np.ndarray-like object.
38+
Check if the function input is a Physio object or a np.ndarray-like object.
39+
40+
The "signal" argument must always be the first one.
3841
3942
Parameters
4043
----------
41-
data : peakdet.physio.Physio, np.ndarray, or list
42-
object to get data from
44+
func: function to run the wrapper around
4345
4446
Returns
4547
-------
46-
np.ndarray-like object
47-
Either a np.ndarray or a list
48+
function
4849
"""
49-
if hasattr(signal, "history"):
50-
signal = signal.data
5150

52-
return signal
51+
@functools.wraps(func)
52+
def wrapper(*args, **kwargs):
53+
# signal must always be args[0]
54+
if hasattr(args[0], "history"):
55+
args[0] = args[0].data
56+
return func(*args, **kwargs)
57+
58+
return wrapper
5359

5460

5561
def has_peakfind_physio(signal) -> bool:

setup.cfg

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@
22
name = physioqc
33
url = https://github.com/physiopy/physioqc
44
download_url = https://github.com/physiopy/physioqc
5-
author = Physiopy community
6-
maintainer = Stefano Moia
5+
author = The Physiopy Community
6+
maintainer = The Physiopy Community
77
maintainer_email = [email protected]
88
classifiers =
9-
Development Status :: 1 - Planning
9+
Development Status :: 3 - Alpha
1010
Intended Audience :: Science/Research
1111
License :: OSI Approved :: Apache Software License
12-
Programming Language :: Python :: 3.7
13-
Programming Language :: Python :: 3.8
14-
Programming Language :: Python :: 3.9
15-
Programming Language :: Python :: 3.10
12+
Programming Language :: Python :: 3
1613
license = Apache-2.0
1714
description = A toolbox to run automatic quality control of physiological data.
1815
long_description = file:README.md

0 commit comments

Comments
 (0)