Skip to content

Commit

Permalink
Merge pull request #234 from smoia/int/bids
Browse files Browse the repository at this point in the history
Move bids-related functions to dedicated file
  • Loading branch information
Stefano Moia authored Jun 15, 2020
2 parents acb963c + a2e7038 commit e417628
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 138 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ before_install:
pip install flake8;
fi
- if [ "${CHECK_TYPE}" == "test" ]; then
pip install "pytest>=3.6" pytest-cov coverage coveralls codecov;
pip install "pytest>=4.6" pytest-cov coverage coveralls codecov;
fi
- if [ "${CHECK_TYPE}" == "docdoctest" ]; then
pip install "sphinx>2.0" sphinx_rtd_theme pandas sphinx-argparse;
Expand Down
83 changes: 83 additions & 0 deletions phys2bids/bids_units.py → phys2bids/bids.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import os
import logging

from pathlib import Path

from phys2bids import utils

LGR = logging.getLogger(__name__)

UNIT_ALIASES = {
Expand Down Expand Up @@ -87,3 +92,81 @@ def bidsify_units(orig_unit):
LGR.warning(f'The given unit {orig_unit} does not have aliases, '
f'passing it as is')
return orig_unit


def use_heuristic(heur_file, sub, ses, filename, outdir, record_label=''):
"""
Import and use the heuristic specified by the user to rename the file.
Parameters
----------
heur_file: path
Fullpath to heuristic file.
sub: str or int
Name of subject.
ses: str or int or None
Name of session.
filename: path
Name of the input of phys2bids.
outdir: str or path
Path to the directory that will become the "site" folder
("root" folder of BIDS database).
record_label: str
Optional label for the "record" entry of BIDS.
Returns
-------
heurpath: str or path
Returned fullpath to tsv.gz new file (post BIDS formatting).
Raises
------
KeyError
if `bids_keys['task']` is empty
"""
utils.check_file_exists(heur_file)

# Initialise a dictionary of bids_keys that has already "recording"
bids_keys = {'sub': '', 'ses': '', 'task': '', 'acq': '', 'ce': '',
'dir': '', 'rec': '', 'run': '', 'recording': record_label}

# Start filling bids_keys dictionary and path with subject and session
if sub.startswith('sub-'):
bids_keys['sub'] = sub[4:]
fldr = os.path.join(outdir, sub)
else:
bids_keys['sub'] = sub
fldr = os.path.join(outdir, f'sub-{sub}')

if ses:
if ses.startswith('ses-'):
bids_keys['ses'] = ses[4:]
fldr = os.path.join(fldr, ses)
else:
bids_keys['ses'] = ses
fldr = os.path.join(fldr, f'ses-{ses}')

# Load heuristic and use it to fill dictionary
heur = utils.load_heuristic(heur_file)
bids_keys.update(heur.heur(Path(filename).stem))

# If bids_keys['task'] is still empty, stop the program
if not bids_keys['task']:
LGR.warning(f'The heuristic {heur_file} could not deal with'
f'{Path(filename).stem}')
raise KeyError('No "task" attribute found')

# Compose name by looping in the bids_keys dictionary
# and adding nonempty keys
name = ''
for key in bids_keys:
if bids_keys[key] != '':
name = f'{name}{key}-{bids_keys[key]}_'

# Finish path, create it, add filename, export
fldr = os.path.join(fldr, 'func')
utils.path_exists_or_make_it(fldr)

heurpath = os.path.join(fldr, f'{name}physio')

return heurpath
81 changes: 1 addition & 80 deletions phys2bids/phys2bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@
import datetime
import logging
from copy import deepcopy
from pathlib import Path

from numpy import savetxt

from phys2bids import utils, viz, _version
from phys2bids.bids import bidsify_units, use_heuristic
from phys2bids.cli.run import _get_parser
from phys2bids.physio_obj import BlueprintOutput
from phys2bids.bids_units import bidsify_units

LGR = logging.getLogger(__name__)

Expand Down Expand Up @@ -111,84 +110,6 @@ def print_json(outfile, samp_freq, time_offset, ch_name):
utils.writejson(outfile, summary, indent=4, sort_keys=False)


def use_heuristic(heur_file, sub, ses, filename, outdir, record_label=''):
"""
Import and use the heuristic specified by the user to rename the file.
Parameters
----------
heur_file: path
Fullpath to heuristic file.
sub: str or int
Name of subject.
ses: str or int or None
Name of session.
filename: path
Name of the input of phys2bids.
outdir: str or path
Path to the directory that will become the "site" folder
("root" folder of BIDS database).
record_label: str
Optional label for the "record" entry of BIDS.
Returns
-------
heurpath: str or path
Returned fullpath to tsv.gz new file (post BIDS formatting).
Raises
------
KeyError
if `bids_keys['task']` is empty
"""
utils.check_file_exists(heur_file)

# Initialise a dictionary of bids_keys that has already "recording"
bids_keys = {'sub': '', 'ses': '', 'task': '', 'acq': '', 'ce': '',
'dir': '', 'rec': '', 'run': '', 'recording': record_label}

# Start filling bids_keys dictionary and path with subject and session
if sub.startswith('sub-'):
bids_keys['sub'] = sub[4:]
fldr = os.path.join(outdir, sub)
else:
bids_keys['sub'] = sub
fldr = os.path.join(outdir, f'sub-{sub}')

if ses:
if ses.startswith('ses-'):
bids_keys['ses'] = ses[4:]
fldr = os.path.join(fldr, ses)
else:
bids_keys['ses'] = ses
fldr = os.path.join(fldr, f'ses-{ses}')

# Load heuristic and use it to fill dictionary
heur = utils.load_heuristic(heur_file)
bids_keys.update(heur.heur(Path(filename).stem))

# If bids_keys['task'] is still empty, stop the program
if not bids_keys['task']:
LGR.warning(f'The heuristic {heur_file} could not deal with'
f'{Path(filename).stem}')
raise KeyError('No "task" attribute found')

# Compose name by looping in the bids_keys dictionary
# and adding nonempty keys
name = ''
for key in bids_keys:
if bids_keys[key] != '':
name = f'{name}{key}-{bids_keys[key]}_'

# Finish path, create it, add filename, export
fldr = os.path.join(fldr, 'func')
utils.path_exists_or_make_it(fldr)

heurpath = os.path.join(fldr, f'{name}physio')

return heurpath


def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None,
sub=None, ses=None, chtrig=0, chsel=None, num_timepoints_expected=0,
tr=1, thr=None, ch_name=[], chplot='', debug=False, quiet=False):
Expand Down
60 changes: 60 additions & 0 deletions phys2bids/tests/test_bids.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import os

from pkg_resources import resource_filename

import pytest

from phys2bids.bids import bidsify_units, use_heuristic
from phys2bids.bids import UNIT_ALIASES


def test_bidsify_units():
# Add a dictionary of test possibilities
unit_tests = {
# test unit with standard prefix
'centik': 'cK', 'CENTIk': 'cK',
# test unit with not standard prefix
'matV': 'matV', 'BigV': 'BigV',
# test unit that are not bids standard
'mmHg': 'mmHg', 'mmlie': 'mmlie', 'MMLIE': 'MMLIE',
}
# Actually test
for unit_key in unit_tests.keys():
assert bidsify_units(unit_key) == unit_tests[unit_key]
# test there is not problem with every unit in the dict
for unit_key in UNIT_ALIASES.keys():
assert bidsify_units(unit_key) == UNIT_ALIASES[unit_key]


@pytest.mark.parametrize('test_sub', ['SBJ01', 'sub-006', '006'])
@pytest.mark.parametrize('test_ses', ['', 'S05', 'ses-42', '42'])
def test_use_heuristic(tmpdir, test_sub, test_ses):
test_heur_path = resource_filename('phys2bids', 'heuristics')
test_heur_file = 'heur_test_acq.py'
test_full_heur_path = os.path.join(test_heur_path, test_heur_file)
test_input_path = resource_filename('phys2bids', 'tests/data')
test_input_file = 'Test_belt_pulse_samefreq.acq'
test_full_input_path = os.path.join(test_input_path, test_input_file)
test_outdir = tmpdir
test_record_label = 'test'

heur_path = use_heuristic(test_full_heur_path, test_sub, test_ses,
test_full_input_path, test_outdir, test_record_label)

if test_sub[:4] == 'sub-':
test_sub = test_sub[4:]

test_result_path = (f'{tmpdir}/sub-{test_sub}')
test_result_name = (f'sub-{test_sub}')

if test_ses[:4] == 'ses-':
test_ses = test_ses[4:]

if test_ses:
test_result_path = (f'{test_result_path}/ses-{test_ses}')
test_result_name = (f'{test_result_name}_ses-{test_ses}')

test_result = (f'{test_result_path}/func/{test_result_name}'
f'_task-test_rec-biopac_run-01_recording-test_physio')

assert os.path.normpath(test_result) == os.path.normpath(str(heur_path))
20 changes: 0 additions & 20 deletions phys2bids/tests/test_bids_units.py

This file was deleted.

37 changes: 0 additions & 37 deletions phys2bids/tests/test_phys2bids.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

import json
import os
from pkg_resources import resource_filename

import pytest

from phys2bids import phys2bids

Expand Down Expand Up @@ -44,37 +41,3 @@ def test_print_json(tmpdir):
loaded_data = json.load(src)

assert test_json_data == loaded_data


@pytest.mark.parametrize('test_sub', ['SBJ01', 'sub-006', '006'])
@pytest.mark.parametrize('test_ses', ['', 'S05', 'ses-42', '42'])
def test_use_heuristic(tmpdir, test_sub, test_ses):
test_heur_path = resource_filename('phys2bids', 'heuristics')
test_heur_file = 'heur_test_acq.py'
test_full_heur_path = os.path.join(test_heur_path, test_heur_file)
test_input_path = resource_filename('phys2bids', 'tests/data')
test_input_file = 'Test_belt_pulse_samefreq.acq'
test_full_input_path = os.path.join(test_input_path, test_input_file)
test_outdir = tmpdir
test_record_label = 'test'

heur_path = phys2bids.use_heuristic(test_full_heur_path, test_sub, test_ses,
test_full_input_path, test_outdir, test_record_label)

if test_sub[:4] == 'sub-':
test_sub = test_sub[4:]

test_result_path = (f'{tmpdir}/sub-{test_sub}')
test_result_name = (f'sub-{test_sub}')

if test_ses[:4] == 'ses-':
test_ses = test_ses[4:]

if test_ses:
test_result_path = (f'{test_result_path}/ses-{test_ses}')
test_result_name = (f'{test_result_name}_ses-{test_ses}')

test_result = (f'{test_result_path}/func/{test_result_name}'
f'_task-test_rec-biopac_run-01_recording-test_physio')

assert os.path.normpath(test_result) == os.path.normpath(str(heur_path))

0 comments on commit e417628

Please sign in to comment.