Example #1
0
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')
Example #2
0
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
Example #3
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'))
Example #4
0
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')
Example #5
0
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)
Example #6
0
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'))