def test_rename(): with tempfile.TemporaryDirectory() as tmp: shutil.copytree(TESTPATH1, op.join(tmp, 'BIDSTEST1')) src_bt = BIDSTree(op.join(tmp, 'BIDSTEST1')) # renaming a subject subj = src_bt.project('test1').subject(2) subj.rename('4') assert subj.ID == 'sub-4' for _, _, files in os.walk(subj.path): for fname in files: assert 'sub-2' not in fname sess = subj.session(2) assert 'sub-4' in sess.scans[0].raw_file # renaming a session sess.rename('3') assert sess.ID == 'ses-3' for _, _, files in os.walk(subj.path): for fname in files: assert 'ses-2' not in fname df = pd.read_csv(sess.scans_tsv, sep='\t') for row in df['filename']: assert 'ses-3' in row assert 'sub-4' in row # test renaming a folder-less session to have a session label shutil.copytree(TESTPATH2, op.join(tmp, 'BIDSTEST2')) src_bt = BIDSTree(op.join(tmp, 'BIDSTEST2')) sess = src_bt.project('test1').subject(2).session('none') orig_path = sess.path sess.rename('1') assert sess.path == op.join(orig_path, 'ses-1')
def test_bidstree_to_bidstree(): # Test writing one BIDSTree object to a new empty BIDSTree location. with tempfile.TemporaryDirectory() as tmp: dest_bf = BIDSTree(tmp, False) src_bt = BIDSTree(TESTPATH2) dest_bf.add(src_bt) assert len(dest_bf.projects) == 1 assert dest_bf.project('test1').subject('1').subject_data['age'] == 2.0
def test_merge_bidstrees(): # Test completely merging one BIDS folder into another. with tempfile.TemporaryDirectory() as tmp: # copy the dst to a temp folder shutil.copytree(TESTPATH2, op.join(tmp, 'BIDSTEST2')) src_bt = BIDSTree(TESTPATH1) dst_bt = BIDSTree(op.join(tmp, 'BIDSTEST2')) with pytest.warns(UserWarning): dst_bt.add(src_bt) assert len(dst_bt.projects) == 2 # proj:test1, subj:2, sess: 1 will not have been merged assert (src_bt.project('test1').subject(2).session(2) not in dst_bt.project('test1').subject(2)) # To rectify this, rename the folder-less session then re-add dst_bt.project('test1').subject(2).session('none').rename('1') dst_bt.project('test1').subject(2).add( src_bt.project('test1').subject(2).session(2)) assert len(dst_bt.project('test1').subject(2).sessions) == 2 # check that extra files are brought along sess = dst_bt.project('test2').subject(3).session(1) assert 'code' in sess.extra_data assert 'extradata' in sess.extra_data assert op.exists(op.join(sess.path, 'code', 'analysis.py')) assert op.exists(op.join(sess.path, 'extradata', 'extra.txt'))
def test_add_new_project_recursively(): # Add a scan existing in a project that doesn't exist in the dst folder # This will recursively add the project, subject and session. with tempfile.TemporaryDirectory() as tmp: # copy the dst to a temp folder shutil.copytree(TESTPATH2, op.join(tmp, 'BIDSTEST2')) src_bt = BIDSTree(TESTPATH1) dst_bt = BIDSTree(op.join(tmp, 'BIDSTEST2')) scan = src_bt.project('test2').subject('3').session('1').scan( task='resting', run='1') assert scan.emptyroom is not None dst_bt.add(scan) # make sure the project was added assert len(dst_bt.projects) == 2 assert op.exists(dst_bt.project('test2').readme) assert op.exists(dst_bt.project('test2').description) # make sure the subject was added and the empty room data was too assert len(dst_bt.project('test2').subjects) == 2 # make sure the scan was added scans_tsv = dst_bt.project('test2').subject('3').session('1').scans_tsv assert op.exists(scans_tsv) dst_bt.project('test2').subject('emptyroom')
def test_copy_errors(): # Test trying to copy the wrong things into the wrong places. with tempfile.TemporaryDirectory() as tmp: # copy the dst to a temp folder shutil.copytree(TESTPATH2, op.join(tmp, 'BIDSTEST2')) src_bt = BIDSTree(TESTPATH1) dst_bt = BIDSTree(op.join(tmp, 'BIDSTEST2')) # try add one project to another with different ID's # try and add an object you shouldn't do: proj = src_bt.project('test1') with pytest.raises(TypeError): dst_bt.project('test1').subject('1').session('1').add(proj) with pytest.raises(TypeError): dst_bt.project('test1').subject('1').add(proj) with pytest.raises(TypeError): dst_bt.project('test1').add(src_bt) proj = src_bt.project('test2') sub = proj.subject('3') ses = sub.session('1') scan = ses.scan(task='resting', run='1') # try and add objects in the wrong project: with pytest.raises(ValueError): dst_bt.project('test1').add(proj) with pytest.raises(AssociationError): dst_bt.project('test1').add(sub) with pytest.raises(AssociationError): dst_bt.project('test1').add(ses) with pytest.raises(AssociationError): dst_bt.project('test1').add(scan) # try and add objects to the wrong subject: with pytest.raises(ValueError): dst_bt.project('test1').subject('1').add(sub) with pytest.raises(AssociationError): dst_bt.project('test1').subject('1').add(ses) with pytest.raises(AssociationError): dst_bt.project('test1').subject('1').add(scan) # try and add objects to the wrong session: with pytest.raises(ValueError): session = src_bt.project('test1').subject('1').session('2') dst_bt.project('test1').subject('1').session('1').add(session) with pytest.raises(AssociationError): dst_bt.project('test1').subject('1').session('1').add(scan)
def test_query(): folder = BIDSTree(TESTPATH1) # query a BIDSTree object # query some subject information assert len(folder.query('subject', 'age', '=', 4)) == 1 assert len(folder.query('subject', 'age', '>', 2)) == 2 assert len(folder.query('subject', 'age', '>=', 2)) == 3 assert len(folder.query('subject', 'sex', '=', 'M')) == 1 assert len(folder.query('subject', 'sex', '!=', 'M')) == 3 assert len(folder.query('subject', 'group', '=', 'autistic')) == 2 # query some tasks assert len(folder.query('scan', 'task', '=', 'resting')) == 2 # ask if any of the subjects has *any* tasks that aren't 'resting' assert (folder.project('test1').subject('1') in folder.query('subject', 'task', '!=', 'resting')) # ask if any of the subjects have not got a task called 'resting' assert (folder.project('test1').subject('2') in folder.query('subject', 'task', '!!=', 'resting')) with pytest.raises(ValueError, match='Condition'): folder.query('subject', 'task', '>', 'resting') # query the recording date ref_datetime = '2018-10-26T11:32:33' ref_date = '2018-10-26' assert len(folder.query('scan', 'rec_date', '=', ref_datetime)) == 1 assert len(folder.query('scan', 'rec_date', '<=', ref_datetime)) == 5 assert len(folder.query('scan', 'rec_date', '>', ref_datetime)) == 1 assert len(folder.query('scan', 'rec_date', '=', ref_date)) == 6 assert len(folder.query('session', 'rec_date', '=', ref_date)) == 5 # query some data in the sidecar.json: assert len(folder.query('project', 'PowerLineFrequency', '=', 50)) == 2 assert len(folder.query('subject', 'MiscChannelCount', '=', 93)) == 4 assert len(folder.query('session', 'TaskName', '=', 'resting')) == 2 assert len(folder.query('scan', 'RecordingDuration', '>=', 5)) == 6 # query for number of subjects, sessions, or scans assert len(folder.query('project', 'subjects', '=', 2)) == 2 assert len(folder.query('project', 'sessions', '!=', 3)) == 1 assert len(folder.query('subject', 'sessions', '<', 2)) == 3 assert len(folder.query('project', 'scans', '>', 4)) == 0 assert len(folder.query('subject', 'scans', '<=', 2)) == 3 assert len(folder.query('session', 'scans', '<', 2)) == 4 with pytest.raises(ValueError): folder.query('subject', 'subjects', '=', 2) with pytest.raises(ValueError): folder.query('session', 'sessions', '=', 1) with pytest.raises(ValueError): folder.query('scan', 'scans', '=', 1) # query a Project object (test1): proj = folder.query('project', 'sessions', '=', 3) assert len(proj.query('subject', 'sessions', '=', 2)) == 1 assert len(proj.query('subject', 'group', '=', 'neurotypical')) == 1 assert len(proj.query('session', 'scans', '<=', 3)) == 3 # query a Subject object (sub-1): subj = proj.query('subject', 'sessions', '=', 2)[0] assert len(subj.query('session', 'scans', '>=', 1)) == 2 with pytest.raises(ValueError, match='Invalid query'): subj.query('project', 'subjects', '=', 1) # query a Session object (ses-1): sess = subj.query('session', 'scans', '>', 1)[0] assert len(sess.query('scan', 'task', '=', 'resting')) == 1 # query a scan object: scan = sess.query('scan', 'task', '=', 'resting')[0] assert len(scan.query('scan', 'MEGChannelCount', '=', 160)) == 1 # perform a compound query: subjs = folder.query('subject', 'age', '>', 2) assert len(subjs.query('scan', 'task', '=', 'resting')) == 1 projs = folder.query('project', 'subjects', '>', 1) assert (folder.project('test1') in projs.query('project', 'sessions', '=', 3)) subjs = folder.query('subject', 'sex', '=', 'F') assert (folder.project('test2').subject('3') in subjs.query('subject', 'sessions', '=', 1)) sesss = folder.query('session', 'scans', '=', 1) assert len(sesss) == 4 assert (folder.project('test2').subject('3').session('1') in sesss.query('session', 'TaskName', '=', 'resting'))