From 447c1fdac7d36704a6dad9fda1649f15bf0316be Mon Sep 17 00:00:00 2001 From: Eneko Date: Tue, 16 Jun 2020 16:43:23 +0200 Subject: [PATCH 01/22] Initial commit --- phys2bids/heuristics/participant.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 phys2bids/heuristics/participant.yml diff --git a/phys2bids/heuristics/participant.yml b/phys2bids/heuristics/participant.yml new file mode 100644 index 000000000..a509d8c1d --- /dev/null +++ b/phys2bids/heuristics/participant.yml @@ -0,0 +1,5 @@ +participant: + participant_id: # Required + age: n/a + sex: n/a + handedness: n/a \ No newline at end of file From e6f80f00b5b9420c5a9e952388be97c04540a48f Mon Sep 17 00:00:00 2001 From: Eneko Date: Tue, 16 Jun 2020 17:53:08 +0200 Subject: [PATCH 02/22] Phys2bids now automatically generates participants.tsv if the file does not exist --- phys2bids/cli/run.py | 5 +++++ phys2bids/phys2bids.py | 28 +++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/phys2bids/cli/run.py b/phys2bids/cli/run.py index 8b9118ccd..d24c61f0c 100644 --- a/phys2bids/cli/run.py +++ b/phys2bids/cli/run.py @@ -125,6 +125,11 @@ def _get_parser(): type=str, help='full path to store channels plot ', default='') + optional.add_argument('-yml', '--participant-yml', + dest='yml', + type=str, + help='file with info needed to generate participant.tsv file ', + default='participants.yml') optional.add_argument('-debug', '--debug', dest='debug', action='store_true', diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index 06d74fd65..6f2410a23 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -31,6 +31,7 @@ import logging from copy import deepcopy +import yaml from numpy import savetxt from phys2bids import utils, viz, _version @@ -112,7 +113,8 @@ def print_json(outfile, samp_freq, time_offset, ch_name): 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): + tr=1, thr=None, ch_name=[], chplot='', debug=False, quiet=False, + yml='participants.yml'): """ Main workflow of phys2bids. @@ -296,6 +298,30 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, phys_in.num_timepoints_found, uniq_freq, phys_out[uniq_freq].start_time, outfile) + # Generate participants.tsv file if it doesn't exist already + if heur_file: + participants_file = os.path.join(outdir, 'participants.tsv') + if not os.path.exists(participants_file): + # Read yaml info if file exists + if os.path.exists(os.path.join(indir, yml)): + with open(os.path.join(indir, yml)) as f: + yaml_data = yaml.load(f, Loader=yaml.FullLoader) + p_id = yaml_data['participant']['participant_id'] + p_age = yaml_data['participant']['age'] + p_sex = yaml_data['participant']['sex'] + p_handedness = yaml_data['participant']['handedness'] + else: + # Fill in with data from phys2bids + p_id = sub + p_age = 'n/a' + p_sex = 'n/a' + p_handedness = 'n/a' + + participants_data = (f'participant_id \t age \t sex \t handedness \n' + f'{p_id} \t {p_age} \t {p_sex} \t {p_handedness}') + + utils.writefile(participants_file, '', participants_data) + def _main(argv=None): options = _get_parser().parse_args(argv) From 05318eae8334886bc753cc9f74f248e9d8d3ff8e Mon Sep 17 00:00:00 2001 From: Eneko Date: Tue, 16 Jun 2020 18:05:45 +0200 Subject: [PATCH 03/22] Add yaml to setup.cfg --- setup.cfg | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.cfg b/setup.cfg index d184c7100..77211fa91 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,6 +51,7 @@ all = %(doc)s %(style)s %(test)s + yaml [options.package_data] abagen = From 88b913232b56fcb93129fd0ccaf957e4cfadac3f Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 10:35:26 +0200 Subject: [PATCH 04/22] Adds basic functionality for participants.tsv --- phys2bids/phys2bids.py | 27 ++++----------------- phys2bids/utils.py | 53 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index 6f2410a23..4eb13748d 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -31,7 +31,6 @@ import logging from copy import deepcopy -import yaml from numpy import savetxt from phys2bids import utils, viz, _version @@ -298,29 +297,11 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, phys_in.num_timepoints_found, uniq_freq, phys_out[uniq_freq].start_time, outfile) - # Generate participants.tsv file if it doesn't exist already + # Generate participants.tsv file if it doesn't exist already. + # Update the file if the subject is not in the file. + # Do not update if the subject is already in the file. if heur_file: - participants_file = os.path.join(outdir, 'participants.tsv') - if not os.path.exists(participants_file): - # Read yaml info if file exists - if os.path.exists(os.path.join(indir, yml)): - with open(os.path.join(indir, yml)) as f: - yaml_data = yaml.load(f, Loader=yaml.FullLoader) - p_id = yaml_data['participant']['participant_id'] - p_age = yaml_data['participant']['age'] - p_sex = yaml_data['participant']['sex'] - p_handedness = yaml_data['participant']['handedness'] - else: - # Fill in with data from phys2bids - p_id = sub - p_age = 'n/a' - p_sex = 'n/a' - p_handedness = 'n/a' - - participants_data = (f'participant_id \t age \t sex \t handedness \n' - f'{p_id} \t {p_age} \t {p_sex} \t {p_handedness}') - - utils.writefile(participants_file, '', participants_data) + utils.participants_file(indir, outdir, yml, sub) def _main(argv=None): diff --git a/phys2bids/utils.py b/phys2bids/utils.py index bb5954765..0aebb15ba 100644 --- a/phys2bids/utils.py +++ b/phys2bids/utils.py @@ -1,10 +1,12 @@ # -*- coding: utf-8 -*- +from csv import reader, writer import json import logging import os import sys from pathlib import Path +import yaml LGR = logging.getLogger(__name__) @@ -280,3 +282,54 @@ def load_heuristic(heuristic): except Exception as exc: raise ImportError(f'Failed to import heuristic {heuristic}: {exc}') return mod + + +def append_list_as_row(file_name, list_of_elem): + # Open file in append mode + with open(file_name, 'a+', newline='') as write_obj: + # Create a writer object from csv module + csv_writer = writer(write_obj, delimiter='\t') + # Add contents of list as last row in the csv file + csv_writer.writerow(list_of_elem) + + +def participants_file(indir, outdir, yml, sub): + + participants_file = os.path.join(outdir, 'participants.tsv') + if not os.path.exists(participants_file): + # Read yaml info if file exists + if os.path.exists(os.path.join(indir, yml)): + with open(os.path.join(indir, yml)) as f: + yaml_data = yaml.load(f, Loader=yaml.FullLoader) + p_id = yaml_data['participant']['participant_id'] + p_age = yaml_data['participant']['age'] + p_sex = yaml_data['participant']['sex'] + p_handedness = yaml_data['participant']['handedness'] + else: + # Fill in with data from phys2bids + p_id = sub + p_age = 'n/a' + p_sex = 'n/a' + p_handedness = 'n/a' + + header = ['participant_id', 'age', 'sex', 'handedness'] + append_list_as_row(participants_file, header) + + participants_data = [sub, p_age, p_sex, p_handedness] + append_list_as_row(participants_file, participants_data) + + else: + pf = open(participants_file, 'r') + header = pf.readline().split("\t") + pf.close() + p_id_idx = header.index('participant_id') + sub_exists = False + with open(participants_file) as pf: + tsvreader = reader(pf, delimiter="\t") + for line in tsvreader: + if sub in line[0]: + sub_exists = True + break + if not sub_exists: + participants_data = [sub, 'n/a', 'n/a','n/a'] + append_list_as_row(participants_file, participants_data) \ No newline at end of file From 89837f20750c09d44ddc07bd40a059e1a1c78e46 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 10:53:35 +0200 Subject: [PATCH 05/22] Correctly add yaml to setup.cfg --- setup.cfg | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup.cfg b/setup.cfg index 77211fa91..d6bef67db 100644 --- a/setup.cfg +++ b/setup.cfg @@ -46,12 +46,14 @@ test = pytest-cov interfaces = %(acq)s -all = +extra = + yaml %(interfaces)s +all = %(doc)s + %(extra)s %(style)s %(test)s - yaml [options.package_data] abagen = From cf2e7e3ee7ffa8b327cee54f7d15337d9e1b54a5 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 10:58:09 +0200 Subject: [PATCH 06/22] Fix linting errors --- phys2bids/utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/phys2bids/utils.py b/phys2bids/utils.py index 0aebb15ba..c13e387d2 100644 --- a/phys2bids/utils.py +++ b/phys2bids/utils.py @@ -315,7 +315,7 @@ def participants_file(indir, outdir, yml, sub): header = ['participant_id', 'age', 'sex', 'handedness'] append_list_as_row(participants_file, header) - participants_data = [sub, p_age, p_sex, p_handedness] + participants_data = [p_id, p_age, p_sex, p_handedness] append_list_as_row(participants_file, participants_data) else: @@ -327,9 +327,9 @@ def participants_file(indir, outdir, yml, sub): with open(participants_file) as pf: tsvreader = reader(pf, delimiter="\t") for line in tsvreader: - if sub in line[0]: + if sub in line[p_id_idx]: sub_exists = True break if not sub_exists: - participants_data = [sub, 'n/a', 'n/a','n/a'] - append_list_as_row(participants_file, participants_data) \ No newline at end of file + participants_data = [sub, 'n/a', 'n/a', 'n/a'] + append_list_as_row(participants_file, participants_data) From 0c1ba600f152a80c0a149d81099cd1cf69e7afbb Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 11:05:34 +0200 Subject: [PATCH 07/22] Second attempt to having the yaml dependency --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index d6bef67db..66531ad78 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,7 +47,7 @@ test = interfaces = %(acq)s extra = - yaml + pyyaml %(interfaces)s all = %(doc)s From 5f89cdcf5b8b1db6eca28a1b31376d69cb990319 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 11:15:08 +0200 Subject: [PATCH 08/22] Renamed PyYAML in setup.cfg --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 66531ad78..5d2a3feb1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,7 +47,7 @@ test = interfaces = %(acq)s extra = - pyyaml + PyYAML %(interfaces)s all = %(doc)s From e36b15818003811c820df4a21a82118215c08936 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 11:19:47 +0200 Subject: [PATCH 09/22] Made PyYAML required --- setup.cfg | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/setup.cfg b/setup.cfg index 5d2a3feb1..7da2fe982 100644 --- a/setup.cfg +++ b/setup.cfg @@ -24,6 +24,7 @@ python_requires = >=3.6.1 install_requires = numpy >=1.9.3 matplotlib >=3.1.1 + PyYAML tests_require = pytest >=3.6 test_suite = pytest @@ -46,12 +47,9 @@ test = pytest-cov interfaces = %(acq)s -extra = - PyYAML - %(interfaces)s all = %(doc)s - %(extra)s + %(interfaces)s %(style)s %(test)s From f3dd91725364ecd616771c6d70abbce900c4153b Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 11:23:29 +0200 Subject: [PATCH 10/22] Moved participants_file function to bids.py --- phys2bids/bids.py | 57 ++++++++++++++++++++++++++++++++++++++++++++++ phys2bids/utils.py | 45 +----------------------------------- requirements.txt | 1 + 3 files changed, 59 insertions(+), 44 deletions(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index a2782faf7..8dc8bfc7a 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -1,6 +1,8 @@ +from csv import reader import os import logging +import yaml from pathlib import Path from phys2bids import utils @@ -170,3 +172,58 @@ def use_heuristic(heur_file, sub, ses, filename, outdir, record_label=''): heurpath = os.path.join(fldr, f'{name}physio') return heurpath + + +def participants_file(indir, outdir, yml, sub): + """[summary] + + Args: + indir ([type]): [description] + outdir ([type]): [description] + yml ([type]): [description] + sub ([type]): [description] + """ + + file_path = os.path.join(outdir, 'participants.tsv') + if not os.path.exists(file_path): + # Read yaml info if file exists + if os.path.exists(os.path.join(indir, yml)): + with open(os.path.join(indir, yml)) as f: + yaml_data = yaml.load(f, Loader=yaml.FullLoader) + p_id = yaml_data['participant']['participant_id'] + p_age = yaml_data['participant']['age'] + p_sex = yaml_data['participant']['sex'] + p_handedness = yaml_data['participant']['handedness'] + else: + # Fill in with data from phys2bids + p_id = sub + p_age = 'n/a' + p_sex = 'n/a' + p_handedness = 'n/a' + + # Write to participants.tsv file + header = ['participant_id', 'age', 'sex', 'handedness'] + utils.append_list_as_row(file_path, header) + + participants_data = [p_id, p_age, p_sex, p_handedness] + utils.append_list_as_row(file_path, participants_data) + + else: # If participants.tsv exists only update when subject is not there + # Find participant_id column in header + pf = open(file_path, 'r') + header = pf.readline().split("\t") + pf.close() + p_id_idx = header.index('participant_id') + + # Check if subject is already in the file + sub_exists = False + with open(file_path) as pf: + tsvreader = reader(pf, delimiter="\t") + for line in tsvreader: + if sub in line[p_id_idx]: + sub_exists = True + break + # Only append to file if subject is not in the file + if not sub_exists: + participants_data = [sub, 'n/a', 'n/a', 'n/a'] + utils.append_list_as_row(file_path, participants_data) diff --git a/phys2bids/utils.py b/phys2bids/utils.py index c13e387d2..47051961f 100644 --- a/phys2bids/utils.py +++ b/phys2bids/utils.py @@ -1,12 +1,11 @@ # -*- coding: utf-8 -*- -from csv import reader, writer import json import logging import os import sys +from csv import writer from pathlib import Path -import yaml LGR = logging.getLogger(__name__) @@ -291,45 +290,3 @@ def append_list_as_row(file_name, list_of_elem): csv_writer = writer(write_obj, delimiter='\t') # Add contents of list as last row in the csv file csv_writer.writerow(list_of_elem) - - -def participants_file(indir, outdir, yml, sub): - - participants_file = os.path.join(outdir, 'participants.tsv') - if not os.path.exists(participants_file): - # Read yaml info if file exists - if os.path.exists(os.path.join(indir, yml)): - with open(os.path.join(indir, yml)) as f: - yaml_data = yaml.load(f, Loader=yaml.FullLoader) - p_id = yaml_data['participant']['participant_id'] - p_age = yaml_data['participant']['age'] - p_sex = yaml_data['participant']['sex'] - p_handedness = yaml_data['participant']['handedness'] - else: - # Fill in with data from phys2bids - p_id = sub - p_age = 'n/a' - p_sex = 'n/a' - p_handedness = 'n/a' - - header = ['participant_id', 'age', 'sex', 'handedness'] - append_list_as_row(participants_file, header) - - participants_data = [p_id, p_age, p_sex, p_handedness] - append_list_as_row(participants_file, participants_data) - - else: - pf = open(participants_file, 'r') - header = pf.readline().split("\t") - pf.close() - p_id_idx = header.index('participant_id') - sub_exists = False - with open(participants_file) as pf: - tsvreader = reader(pf, delimiter="\t") - for line in tsvreader: - if sub in line[p_id_idx]: - sub_exists = True - break - if not sub_exists: - participants_data = [sub, 'n/a', 'n/a', 'n/a'] - append_list_as_row(participants_file, participants_data) diff --git a/requirements.txt b/requirements.txt index 165bf7cc3..3118cec3e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ numpy>=1.9.3 matplotlib>=3.1.1 +PyYAML \ No newline at end of file From 005e5ad26e92f91e4fc709d694c0594a0116a447 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 11:30:34 +0200 Subject: [PATCH 11/22] Update call to participants_file --- phys2bids/phys2bids.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index 4eb13748d..3f39a77e2 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -34,7 +34,7 @@ from numpy import savetxt from phys2bids import utils, viz, _version -from phys2bids.bids import bidsify_units, use_heuristic +from phys2bids.bids import bidsify_units, use_heuristic, participants_file from phys2bids.cli.run import _get_parser from phys2bids.physio_obj import BlueprintOutput @@ -301,7 +301,7 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, # Update the file if the subject is not in the file. # Do not update if the subject is already in the file. if heur_file: - utils.participants_file(indir, outdir, yml, sub) + participants_file(indir, outdir, yml, sub) def _main(argv=None): From bcdff837cfb8ae79ca25af1ec531fdea498e47f1 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 11:49:01 +0200 Subject: [PATCH 12/22] Adds extra check to integration tests for participants.tsv --- phys2bids/tests/test_integration.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/phys2bids/tests/test_integration.py b/phys2bids/tests/test_integration.py index cb50eda93..9d285117d 100644 --- a/phys2bids/tests/test_integration.py +++ b/phys2bids/tests/test_integration.py @@ -4,6 +4,7 @@ import os import re import subprocess +from csv import reader from pkg_resources import resource_filename from phys2bids._version import get_versions @@ -336,6 +337,19 @@ def test_integration_heuristic(samefreq_short_txt_file): assert math.isclose(json_data['StartTime'], -189.6,) assert json_data['Columns'] == ['time', 'RESP - RSP100C', 'MR TRIGGER - Custom, HLT100C - A 5'] + # Check that participant.tsv gets updated + phys2bids(filename=test_full_path, chtrig=test_chtrig, outdir=test_outdir, + num_timepoints_expected=test_ntp, tr=test_tr, thr=test_thr, sub='002', + ses='01', heur_file=test_heur) + + counter = 0 + subject_list = ['participant_id', '006', '002'] + with open(os.path.join(test_path, 'participants.tsv')) as pf: + tsvreader = reader(pf, delimiter="\t") + for line in tsvreader: + assert subject_list[counter] in line[0] + counter += 1 + # Remove generated files for filename in glob.glob(os.path.join(test_path, 'phys2bids*')): os.remove(filename) From 92704bf34b4e732ddde8095919a8346cdf51d427 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 13:41:51 +0200 Subject: [PATCH 13/22] Adds extra check to run participants_file function --- phys2bids/phys2bids.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index 3f39a77e2..23f25d7db 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -300,7 +300,7 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, # Generate participants.tsv file if it doesn't exist already. # Update the file if the subject is not in the file. # Do not update if the subject is already in the file. - if heur_file: + if heur_file and sub: participants_file(indir, outdir, yml, sub) From 6e3f0c7036a7db20b3ae7728be7bfbd8df99cb21 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 14:35:31 +0200 Subject: [PATCH 14/22] Assess review comments --- phys2bids/bids.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index 8dc8bfc7a..c0d2c48e6 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -183,18 +183,22 @@ def participants_file(indir, outdir, yml, sub): yml ([type]): [description] sub ([type]): [description] """ - + LGR.info('Updating participants.tsv ...') file_path = os.path.join(outdir, 'participants.tsv') if not os.path.exists(file_path): + LGR.warning('phys2bids could not find participants.tsv') # Read yaml info if file exists if os.path.exists(os.path.join(indir, yml)): + LGR.info('Using yaml data to populate participants.tsv') with open(os.path.join(indir, yml)) as f: yaml_data = yaml.load(f, Loader=yaml.FullLoader) - p_id = yaml_data['participant']['participant_id'] + p_id = sub p_age = yaml_data['participant']['age'] p_sex = yaml_data['participant']['sex'] p_handedness = yaml_data['participant']['handedness'] else: + LGR.info('No yaml file was provided. Using phys2bids data to ' + 'populate participants.tsv') # Fill in with data from phys2bids p_id = sub p_age = 'n/a' @@ -209,6 +213,7 @@ def participants_file(indir, outdir, yml, sub): utils.append_list_as_row(file_path, participants_data) else: # If participants.tsv exists only update when subject is not there + LGR.info('phys2bids found participants.tsv. Updating if needed...') # Find participant_id column in header pf = open(file_path, 'r') header = pf.readline().split("\t") @@ -225,5 +230,6 @@ def participants_file(indir, outdir, yml, sub): break # Only append to file if subject is not in the file if not sub_exists: + LGR.info(f'Appending subjet {sub} to participants.tsv ...') participants_data = [sub, 'n/a', 'n/a', 'n/a'] utils.append_list_as_row(file_path, participants_data) From 9a16b379ef35e39b92ae11cd60b5f7f9c4791e3a Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 14:39:27 +0200 Subject: [PATCH 15/22] Removes the default yaml file --- phys2bids/bids.py | 2 +- phys2bids/cli/run.py | 2 +- phys2bids/phys2bids.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index c0d2c48e6..663ccc4ef 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -188,7 +188,7 @@ def participants_file(indir, outdir, yml, sub): if not os.path.exists(file_path): LGR.warning('phys2bids could not find participants.tsv') # Read yaml info if file exists - if os.path.exists(os.path.join(indir, yml)): + if yml is not None and os.path.exists(os.path.join(indir, yml)): LGR.info('Using yaml data to populate participants.tsv') with open(os.path.join(indir, yml)) as f: yaml_data = yaml.load(f, Loader=yaml.FullLoader) diff --git a/phys2bids/cli/run.py b/phys2bids/cli/run.py index d24c61f0c..cec605292 100644 --- a/phys2bids/cli/run.py +++ b/phys2bids/cli/run.py @@ -129,7 +129,7 @@ def _get_parser(): dest='yml', type=str, help='file with info needed to generate participant.tsv file ', - default='participants.yml') + default=None) optional.add_argument('-debug', '--debug', dest='debug', action='store_true', diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index 23f25d7db..aa321aaa9 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -113,7 +113,7 @@ def print_json(outfile, samp_freq, time_offset, ch_name): 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, - yml='participants.yml'): + yml=None): """ Main workflow of phys2bids. From e1992fd43f1079d8f69dff71e9d07f4f4b2da463 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 14:59:49 +0200 Subject: [PATCH 16/22] Move participants_file function to line 271 --- phys2bids/phys2bids.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index aa321aaa9..ef5e1b51c 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -265,6 +265,10 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, if heur_file and sub: LGR.info(f'Preparing BIDS output using {heur_file}') + # Generate participants.tsv file if it doesn't exist already. + # Update the file if the subject is not in the file. + # Do not update if the subject is already in the file. + participants_file(indir, outdir, yml, sub) elif heur_file and not sub: LGR.warning('While "-heur" was specified, option "-sub" was not.\n' 'Skipping BIDS formatting.') @@ -297,12 +301,6 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, phys_in.num_timepoints_found, uniq_freq, phys_out[uniq_freq].start_time, outfile) - # Generate participants.tsv file if it doesn't exist already. - # Update the file if the subject is not in the file. - # Do not update if the subject is already in the file. - if heur_file and sub: - participants_file(indir, outdir, yml, sub) - def _main(argv=None): options = _get_parser().parse_args(argv) From 94c7cefb328194b570d3978398931f3de111de4e Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 16:38:54 +0200 Subject: [PATCH 17/22] Assess smoia's review comments --- phys2bids/bids.py | 39 ++++++++++++++++++++++++--------------- phys2bids/phys2bids.py | 2 +- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index 663ccc4ef..f2d5b7a74 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -1,9 +1,9 @@ -from csv import reader import os import logging +from csv import reader +from pathlib import Path import yaml -from pathlib import Path from phys2bids import utils @@ -174,25 +174,32 @@ def use_heuristic(heur_file, sub, ses, filename, outdir, record_label=''): return heurpath -def participants_file(indir, outdir, yml, sub): - """[summary] +def participants_file(outdir, yml, sub): + """ + Create participants.tsv file if it does not exist. + If it exists and the subject is missing, then add it. + Otherwise, do nothing. + + Parameters + ---------- + outdir: path + Full path to the output directory. + yml: path + Full path to the yaml file. + sub: str + Subject ID. - Args: - indir ([type]): [description] - outdir ([type]): [description] - yml ([type]): [description] - sub ([type]): [description] """ LGR.info('Updating participants.tsv ...') file_path = os.path.join(outdir, 'participants.tsv') if not os.path.exists(file_path): LGR.warning('phys2bids could not find participants.tsv') # Read yaml info if file exists - if yml is not None and os.path.exists(os.path.join(indir, yml)): + if yml is not None and os.path.exists(yml): LGR.info('Using yaml data to populate participants.tsv') - with open(os.path.join(indir, yml)) as f: + with open(yml) as f: yaml_data = yaml.load(f, Loader=yaml.FullLoader) - p_id = sub + p_id = f'sub-{sub}' p_age = yaml_data['participant']['age'] p_sex = yaml_data['participant']['sex'] p_handedness = yaml_data['participant']['handedness'] @@ -200,7 +207,7 @@ def participants_file(indir, outdir, yml, sub): LGR.info('No yaml file was provided. Using phys2bids data to ' 'populate participants.tsv') # Fill in with data from phys2bids - p_id = sub + p_id = f'sub-{sub}' p_age = 'n/a' p_sex = 'n/a' p_handedness = 'n/a' @@ -217,6 +224,7 @@ def participants_file(indir, outdir, yml, sub): # Find participant_id column in header pf = open(file_path, 'r') header = pf.readline().split("\t") + header_length = len(header) pf.close() p_id_idx = header.index('participant_id') @@ -230,6 +238,7 @@ def participants_file(indir, outdir, yml, sub): break # Only append to file if subject is not in the file if not sub_exists: - LGR.info(f'Appending subjet {sub} to participants.tsv ...') - participants_data = [sub, 'n/a', 'n/a', 'n/a'] + LGR.info(f'Appending subjet sub-{sub} to participants.tsv ...') + participants_data = 'n/a' * header_length + participants_data[p_id_idx] = f'sub-{sub}' utils.append_list_as_row(file_path, participants_data) diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index ef5e1b51c..41c4dd043 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -268,7 +268,7 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, # Generate participants.tsv file if it doesn't exist already. # Update the file if the subject is not in the file. # Do not update if the subject is already in the file. - participants_file(indir, outdir, yml, sub) + participants_file(outdir, os.path.join(indir, yml), sub) elif heur_file and not sub: LGR.warning('While "-heur" was specified, option "-sub" was not.\n' 'Skipping BIDS formatting.') From db37484643861fbda7935c2f410927f4a3117b06 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 16:44:00 +0200 Subject: [PATCH 18/22] Fixes bug --- phys2bids/bids.py | 2 +- phys2bids/phys2bids.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index f2d5b7a74..a62012890 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -195,7 +195,7 @@ def participants_file(outdir, yml, sub): if not os.path.exists(file_path): LGR.warning('phys2bids could not find participants.tsv') # Read yaml info if file exists - if yml is not None and os.path.exists(yml): + if '.yml' in yml and os.path.exists(yml): LGR.info('Using yaml data to populate participants.tsv') with open(yml) as f: yaml_data = yaml.load(f, Loader=yaml.FullLoader) diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index 41c4dd043..3f9b3a4ff 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -268,6 +268,8 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, # Generate participants.tsv file if it doesn't exist already. # Update the file if the subject is not in the file. # Do not update if the subject is already in the file. + if yml is None: + yml = '' participants_file(outdir, os.path.join(indir, yml), sub) elif heur_file and not sub: LGR.warning('While "-heur" was specified, option "-sub" was not.\n' From 8cc444aea0f180f6f33324ef6ad9d8e026d75cd2 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 16:50:07 +0200 Subject: [PATCH 19/22] Bug fix, for real now --- phys2bids/bids.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index a62012890..6132c8202 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -195,7 +195,7 @@ def participants_file(outdir, yml, sub): if not os.path.exists(file_path): LGR.warning('phys2bids could not find participants.tsv') # Read yaml info if file exists - if '.yml' in yml and os.path.exists(yml): + if '.yml' in yml is not None and os.path.exists(yml): LGR.info('Using yaml data to populate participants.tsv') with open(yml) as f: yaml_data = yaml.load(f, Loader=yaml.FullLoader) @@ -239,6 +239,7 @@ def participants_file(outdir, yml, sub): # Only append to file if subject is not in the file if not sub_exists: LGR.info(f'Appending subjet sub-{sub} to participants.tsv ...') - participants_data = 'n/a' * header_length + breakpoint() + participants_data = ['n/a'] * header_length participants_data[p_id_idx] = f'sub-{sub}' utils.append_list_as_row(file_path, participants_data) From f1aec4f8da7b6649542b71258082fa95a37d6ee7 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 17:03:33 +0200 Subject: [PATCH 20/22] Removes breakpoint --- phys2bids/bids.py | 1 - 1 file changed, 1 deletion(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index 6132c8202..69621dd73 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -239,7 +239,6 @@ def participants_file(outdir, yml, sub): # Only append to file if subject is not in the file if not sub_exists: LGR.info(f'Appending subjet sub-{sub} to participants.tsv ...') - breakpoint() participants_data = ['n/a'] * header_length participants_data[p_id_idx] = f'sub-{sub}' utils.append_list_as_row(file_path, participants_data) From ab5854fb6c4a99b37ef0c248176362ec37160b33 Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 17:29:18 +0200 Subject: [PATCH 21/22] Yaml is now a full path --- phys2bids/bids.py | 2 +- phys2bids/cli/run.py | 4 ++-- phys2bids/phys2bids.py | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/phys2bids/bids.py b/phys2bids/bids.py index 69621dd73..b71d95824 100644 --- a/phys2bids/bids.py +++ b/phys2bids/bids.py @@ -195,7 +195,7 @@ def participants_file(outdir, yml, sub): if not os.path.exists(file_path): LGR.warning('phys2bids could not find participants.tsv') # Read yaml info if file exists - if '.yml' in yml is not None and os.path.exists(yml): + if '.yml' in yml and os.path.exists(yml): LGR.info('Using yaml data to populate participants.tsv') with open(yml) as f: yaml_data = yaml.load(f, Loader=yaml.FullLoader) diff --git a/phys2bids/cli/run.py b/phys2bids/cli/run.py index cec605292..e44f88717 100644 --- a/phys2bids/cli/run.py +++ b/phys2bids/cli/run.py @@ -128,8 +128,8 @@ def _get_parser(): optional.add_argument('-yml', '--participant-yml', dest='yml', type=str, - help='file with info needed to generate participant.tsv file ', - default=None) + help='full path to file with info needed to generate participant.tsv file ', + default='') optional.add_argument('-debug', '--debug', dest='debug', action='store_true', diff --git a/phys2bids/phys2bids.py b/phys2bids/phys2bids.py index 3f9b3a4ff..5745d0562 100644 --- a/phys2bids/phys2bids.py +++ b/phys2bids/phys2bids.py @@ -113,7 +113,7 @@ def print_json(outfile, samp_freq, time_offset, ch_name): 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, - yml=None): + yml=''): """ Main workflow of phys2bids. @@ -268,9 +268,7 @@ def phys2bids(filename, info=False, indir='.', outdir='.', heur_file=None, # Generate participants.tsv file if it doesn't exist already. # Update the file if the subject is not in the file. # Do not update if the subject is already in the file. - if yml is None: - yml = '' - participants_file(outdir, os.path.join(indir, yml), sub) + participants_file(outdir, yml, sub) elif heur_file and not sub: LGR.warning('While "-heur" was specified, option "-sub" was not.\n' 'Skipping BIDS formatting.') From f84cbd89eebebf30d3b75d57024d44526536433b Mon Sep 17 00:00:00 2001 From: Eneko Date: Wed, 17 Jun 2020 17:38:42 +0200 Subject: [PATCH 22/22] Fix linting error --- phys2bids/cli/run.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/phys2bids/cli/run.py b/phys2bids/cli/run.py index e44f88717..1aa0f2dd1 100644 --- a/phys2bids/cli/run.py +++ b/phys2bids/cli/run.py @@ -128,7 +128,8 @@ def _get_parser(): optional.add_argument('-yml', '--participant-yml', dest='yml', type=str, - help='full path to file with info needed to generate participant.tsv file ', + help='full path to file with info needed to generate ' + 'participant.tsv file ', default='') optional.add_argument('-debug', '--debug', dest='debug',