Skip to content

Commit 7c12115

Browse files
authored
Merge pull request #1117 from JuliaSprenger/upd/CI_conda
[CI] use conda environment for IO tests
2 parents 94365b3 + 8e7ffc2 commit 7c12115

File tree

4 files changed

+92
-82
lines changed

4 files changed

+92
-82
lines changed

.github/workflows/io-test.yml

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ jobs:
2020
# "macos-latest", "windows-latest"
2121
os: ["ubuntu-latest", ]
2222
python-version: ['3.8', ]
23+
defaults:
24+
# by default run in bash mode (required for conda usage)
25+
run:
26+
shell: bash -l {0}
2327
steps:
24-
- name: Set up Python ${{ matrix.python-version }}
25-
uses: actions/setup-python@v2
26-
with:
27-
python-version: ${{ matrix.python-version }}
2828

2929
- name: Checkout repository
3030
uses: actions/checkout@v2
@@ -33,49 +33,51 @@ jobs:
3333
id: date
3434
run: echo "::set-output name=date::$(date +'%Y-%m')"
3535

36-
- uses: actions/cache@v2
36+
- name: Get ephy_testing_data current head hash
37+
# the key depend on the last commit repo https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git
38+
id: vars
39+
run: |
40+
echo "::set-output name=HASH_EPHY_DATASET::$(git ls-remote https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git HEAD | cut -f1)"
41+
42+
- uses: actions/cache@v3
43+
# Loading cache of ephys_testing_dataset
44+
id: cache-datasets
45+
with:
46+
path: ~/ephy_testing_data
47+
key: ${{ runner.os }}-datasets-${{ steps.vars.outputs.HASH_EPHY_DATASET }}
48+
49+
- uses: conda-incubator/setup-miniconda@v2
50+
with:
51+
activate-environment: neo-test-env
52+
python-version: ${{ matrix.python-version }}
53+
clean-patched-environment-file: false
54+
55+
- uses: actions/cache@v3
3756
# the cache for python package is reset:
3857
# * every month
3958
# * when requirements/requirements_testing change
40-
id: cache-venv
59+
id: cache-conda-env
4160
with:
42-
path: ~/test_env
43-
key: ${{ runner.os }}-venv-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements_testing.txt') }}-${{ steps.date.outputs.date }}
44-
restore-keys: |
45-
${{ runner.os }}-venv-
61+
path: /usr/share/miniconda/envs/neo-test-env
62+
key: ${{ runner.os }}-conda-env-${{ hashFiles('**/requirements.txt') }}-${{ hashFiles('**/requirements_testing.txt') }}-${{ hashFiles('**/environment_testing.txt') }}-${{ steps.date.outputs.date }}
63+
64+
- name: Install testing dependencies
65+
# testing environment is only installed if no cache was found
66+
if: steps.cache-conda-env.outputs.cache-hit != 'true'
67+
run: |
68+
conda env update neo-test-env --file environment_testing.yml
4669
47-
- name: Install dependencies
70+
- name: Configure git
4871
run: |
49-
# this is for datalad and download testing datasets
50-
sudo apt install git git-annex
51-
# needed for correct operation of git/git-annex/DataLad
5272
git config --global user.email "neo_ci@fake_mail.com"
5373
git config --global user.name "neo CI"
54-
# create an environment and install everything
55-
python -m venv ~/test_env
56-
source ~/test_env/bin/activate
57-
python -m pip install --upgrade pip
58-
# pip install -r requirements.txt
59-
pip install -r requirements_testing.txt
60-
pip install -e .
6174
62-
- name: Get ephy_testing_data current head hash
63-
# the key depend on the last comit repo https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git
64-
id: vars
75+
- name: Install neo
6576
run: |
66-
echo "::set-output name=HASH_EPHY_DATASET::$(git ls-remote https://gin.g-node.org/NeuralEnsemble/ephy_testing_data.git HEAD | cut -f1)"
67-
68-
- uses: actions/cache@v2
69-
id: cache-datasets
70-
with:
71-
path: ~/ephy_testing_data
72-
key: ${{ runner.os }}-datasets-${{ steps.vars.outputs.HASH_EPHY_DATASET }}
73-
restore-keys: |
74-
${{ runner.os }}-datasets
77+
pip install --upgrade -e .
7578
7679
- name: Test with pytest
7780
run: |
78-
source ~/test_env/bin/activate
7981
# only neo.rawio and neo.io
8082
pytest --cov=neo neo/test/rawiotest
8183
pytest --cov=neo neo/test/iotest

environment_testing.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name: neo-test-env
2+
channels:
3+
- conda-forge
4+
dependencies:
5+
- datalad
6+
- pip
7+
- pip:
8+
- -r requirements_testing.txt

neo/test/iotest/test_edfio.py

Lines changed: 47 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -27,64 +27,64 @@ def test_read_block(self):
2727
"""
2828
Test reading the complete block and general annotations
2929
"""
30-
io = EDFIO(self.filename)
31-
bl = io.read_block()
32-
self.assertTrue(bl.annotations)
30+
with EDFIO(self.filename) as io:
31+
bl = io.read_block()
32+
self.assertTrue(bl.annotations)
3333

34-
seg = bl.segments[0]
35-
assert seg.name == 'Seg #0 Block #0'
36-
for anasig in seg.analogsignals:
37-
assert anasig.name is not None
34+
seg = bl.segments[0]
35+
assert seg.name == 'Seg #0 Block #0'
36+
for anasig in seg.analogsignals:
37+
assert anasig.name is not None
3838

3939
def test_read_segment_with_time_slice(self):
4040
"""
4141
Test loading of a time slice and check resulting times
4242
"""
43-
io = EDFIO(self.filename)
44-
seg = io.read_segment(time_slice=None)
45-
46-
# data file does not contain spike, event or epoch timestamps
47-
self.assertEqual(len(seg.spiketrains), 0)
48-
self.assertEqual(len(seg.events), 1)
49-
self.assertEqual(len(seg.events[0]), 0)
50-
self.assertEqual(len(seg.epochs), 1)
51-
self.assertEqual(len(seg.epochs[0]), 0)
52-
for asig in seg.analogsignals:
53-
self.assertEqual(asig.shape[0], 256)
54-
n_channels = sum(a.shape[-1] for a in seg.analogsignals)
55-
self.assertEqual(n_channels, 5)
56-
57-
t_start, t_stop = 500 * pq.ms, 800 * pq.ms
58-
seg = io.read_segment(time_slice=(t_start, t_stop))
59-
60-
self.assertAlmostEqual(seg.t_start.rescale(t_start.units), t_start, delta=5.)
61-
self.assertAlmostEqual(seg.t_stop.rescale(t_stop.units), t_stop, delta=5.)
43+
with EDFIO(self.filename) as io:
44+
seg = io.read_segment(time_slice=None)
45+
46+
# data file does not contain spike, event or epoch timestamps
47+
self.assertEqual(len(seg.spiketrains), 0)
48+
self.assertEqual(len(seg.events), 1)
49+
self.assertEqual(len(seg.events[0]), 0)
50+
self.assertEqual(len(seg.epochs), 1)
51+
self.assertEqual(len(seg.epochs[0]), 0)
52+
for asig in seg.analogsignals:
53+
self.assertEqual(asig.shape[0], 256)
54+
n_channels = sum(a.shape[-1] for a in seg.analogsignals)
55+
self.assertEqual(n_channels, 5)
56+
57+
t_start, t_stop = 500 * pq.ms, 800 * pq.ms
58+
seg = io.read_segment(time_slice=(t_start, t_stop))
59+
60+
self.assertAlmostEqual(seg.t_start.rescale(t_start.units), t_start, delta=5.)
61+
self.assertAlmostEqual(seg.t_stop.rescale(t_stop.units), t_stop, delta=5.)
6262

6363
def test_compare_data(self):
6464
"""
6565
Compare data from AnalogSignal with plain data stored in text file
6666
"""
67-
io = EDFIO(self.filename)
68-
plain_data = np.loadtxt(io.filename.replace('.edf', '.txt'), dtype=np.int16)
69-
seg = io.read_segment(lazy=True)
70-
71-
anasigs = seg.analogsignals
72-
self.assertEqual(len(anasigs), 5) # all channels have different units, so expecting 5
73-
for aidx, anasig in enumerate(anasigs):
74-
# comparing raw data to original values
75-
ana_data = anasig.load(magnitude_mode='raw')
76-
np.testing.assert_array_equal(ana_data.magnitude, plain_data[:, aidx:aidx + 1])
77-
78-
# comparing floating data to original values * gain factor
79-
ch_head = io.edf_reader.getSignalHeader(aidx)
80-
physical_range = ch_head['physical_max'] - ch_head['physical_min']
81-
# number of digital values used (+1 to account for '0' value)
82-
digital_range = ch_head['digital_max'] - ch_head['digital_min'] + 1
83-
84-
gain = physical_range / digital_range
85-
ana_data = anasig.load(magnitude_mode='rescaled')
86-
rescaled_data = plain_data[:, aidx:aidx + 1] * gain
87-
np.testing.assert_array_equal(ana_data.magnitude, rescaled_data)
67+
with EDFIO(self.filename) as io:
68+
plain_data = np.loadtxt(io.filename.replace('.edf', '.txt'), dtype=np.int16)
69+
seg = io.read_segment(lazy=True)
70+
71+
anasigs = seg.analogsignals
72+
self.assertEqual(len(anasigs), 5) # all channels have different units, so expecting 5
73+
for aidx, anasig in enumerate(anasigs):
74+
# comparing raw data to original values
75+
ana_data = anasig.load(magnitude_mode='raw')
76+
np.testing.assert_array_equal(ana_data.magnitude, plain_data[:, aidx:aidx + 1])
77+
78+
# comparing floating data to original values * gain factor
79+
ch_head = io.edf_reader.getSignalHeader(aidx)
80+
physical_range = ch_head['physical_max'] - ch_head['physical_min']
81+
# number of digital values used (+1 to account for '0' value)
82+
digital_range = ch_head['digital_max'] - ch_head['digital_min'] + 1
83+
84+
gain = physical_range / digital_range
85+
ana_data = anasig.load(magnitude_mode='rescaled')
86+
rescaled_data = plain_data[:, aidx:aidx + 1] * gain
87+
np.testing.assert_array_equal(ana_data.magnitude, rescaled_data)
8888

8989

9090
if __name__ == "__main__":

requirements_testing.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
pytest
22
pytest-cov
3-
datalad==0.14.8 # 0.15. is incompatible with default apt git-annex version
3+
# datalad # this dependency is covered by conda (environment_testing.yml)
44
scipy>=1.0.0
55
pyedflib
66
h5py

0 commit comments

Comments
 (0)