コード例 #1
0
def upload_behavioral(session_id, scanid, runs):
    print('processing behavioral')
    behav_targets = ['behavioral', 'behavior', 'Behavioral', 'Behavior']
    behav_acq = False
    scanidlist = scanid.split('_')
    pid = scanidlist[0]
    visit = scanidlist[1]
    session = scanidlist[2].split('.')[0]
    top_path = pjoin('/oak/stanford/groups/menon/rawdata/scsnl/', pid,
                     'visit' + str(visit), 'session' + str(session))
    for root, folders, files in os.walk(top_path):
        for folder in folders:
            if folder in behav_targets:
                behav_path = pjoin(root, folder)
                run_found = False
                for run in runs:
                    if '/' + run + '/' in behav_path:
                        run_found = True
                        run_id = runs[run]
                        upload_acq = run_id
                        break
                if not run_found:
                    if behav_acq == False:
                        behav_acq = fw.add_acquisition(
                            flywheel.Acquisition(session=session_id,
                                                 label='behavioral'))
                    upload_acq = behav_acq
                behav_files = os.listdir(behav_path)
                for behav_file in behav_files:
                    if not os.path.isfile(pjoin(behav_path, behav_file)):
                        print(
                            'creating acquisition for behavioral subfolder %s'
                            % pjoin(behav_path, behav_file))
                        upload_acq2 = fw.add_acquisition(
                            flywheel.Acquisition(session=session_id,
                                                 label='behavioral_' +
                                                 behav_file))
                        for root2, folders, files2 in os.walk(
                                pjoin(behav_path, behav_file)):
                            for file2 in files2:
                                fw.upload_file_to_acquisition(
                                    upload_acq2, pjoin(root2, file2))
                                fw.modify_acquisition_file(
                                    upload_acq2,
                                    file2,
                                    body={'measurements': ['behavioral']})
                        continue
                    print('uploading %s to acq %s' %
                          (pjoin(behav_path, behav_file), upload_acq))
                    fw.upload_file_to_acquisition(
                        upload_acq, pjoin(behav_path, behav_file))
                    fw.modify_acquisition_file(
                        upload_acq,
                        behav_file,
                        body={'measurements': ['behavioral']})
コード例 #2
0
def test_classify_using_acquisition_label():
    dcm = pydicom.read_file(get_testdata_files()[0])
    acquisition = flywheel.Acquisition(label="T2 FLAIR")
    if hasattr(dcm, "SeriesDescription"):
        del dcm.SeriesDescription
    with tempfile.TemporaryFile(suffix='.dcm') as fp:
        dcm.save_as(fp)
        dcm_metadata = {
            'modality': 'MR',
            'info': {
                'header': {
                    'dicom': {
                        "header": {
                            "dicom": {
                                "Modality": "MR"
                            }
                        }
                    }
                }
            }
        }
        ipp = [[0, 0, a] for a in range(100)]
        iop = [[0, 0, 0] for a in range(100)]
        df = pd.DataFrame({
            'ImagePositionPatient': ipp,
            'ImageOrientationPatient': iop
        })
        res = classify_MR(df, dcm, dcm_metadata, acquisition)
        assert res['classification']['Intent'] == ['Structural']
        assert res['classification']['Measurement'] == ['T2']
        assert res['classification']['Features'] == ['FLAIR']
コード例 #3
0
def upload_dwi(session_id, scanid):
    print('processing dwi')
    scanidlist = scanid.split('_')
    pid = scanidlist[0]
    visit = scanidlist[1]
    session = scanidlist[2].split('.')[0]
    dwi_acq = fw.add_acquisition(
        flywheel.Acquisition(session=session_id, label='dwi'))
    dwi_path = pjoin('/oak/stanford/groups/menon/rawdata/scsnl/', pid,
                     'visit' + str(visit), 'session' + str(session), 'dwi')
    if not os.path.exists(dwi_path):
        print('no dwi folder!')
        return False
    for root, folders, files in os.walk(dwi_path):
        for file in files:
            if 'dwi' in file and ('.nii' in file or '.json' in file):
                print('uploading %s to acq %s' %
                      (pjoin(root, file), str(dwi_acq)))
                fw.upload_file_to_acquisition(dwi_acq, pjoin(root, file))
                fw.modify_acquisition_file_classification(
                    dwi_acq, file, {
                        'modality': 'MR',
                        'replace': {
                            'Intent': ['Structural'],
                            'Measurement': ['Diffusion']
                        }
                    })
    return True
コード例 #4
0
def upload_anatomical(session_id, scanid):
    print('processing anatomical')
    scanidlist = scanid.split('_')
    pid = scanidlist[0]
    visit = scanidlist[1]
    session = scanidlist[2].split('.')[0]
    anatomical_acq = fw.add_acquisition(
        flywheel.Acquisition(session=session_id, label='anatomical'))
    anatomical_path = pjoin('/oak/stanford/groups/menon/rawdata/scsnl/', pid,
                            'visit' + str(visit), 'session' + str(session),
                            'anatomical')
    if not os.path.exists(anatomical_path):
        print('no anatomical folder!')
        return False
    for root, folders, files in os.walk(anatomical_path):
        for file in files:
            if ('spgr' in file or 'T2' in file) and 'old' not in root:
                print('uploading %s to acq %s' %
                      (pjoin(root, file), str(anatomical_acq)))
                fw.upload_file_to_acquisition(anatomical_acq,
                                              pjoin(root, file))
                fw.modify_acquisition_file_classification(
                    anatomical_acq, file, {
                        'modality': 'MR',
                        'replace': {
                            'Intent': ['Structural'],
                            'Measurement': ['T1']
                        }
                    })
コード例 #5
0
class TestGetDestination:
    @pytest.mark.parametrize(
        "parent,raising",
        [
            (flywheel.Subject(label="test"), does_not_raise()),
            (flywheel.Session(label="test"), does_not_raise()),
            (flywheel.Group(label="test"), pytest.raises(ValueError)),
            (flywheel.Project(label="test"), pytest.raises(ValueError)),
            (flywheel.Acquisition(label="test"), pytest.raises(ValueError)),
        ],
    )
    def test_container(self, sdk_mock, parent, raising):
        container = flywheel.models.analysis_output.AnalysisOutput(
            parent=parent, id="test"
        )
        sdk_mock.get_analysis.return_value = container
        sdk_mock.get.return_value = parent

        with raising:
            dest = get_destination(sdk_mock, "test")

            sdk_mock.get_analysis.assert_called_once_with("test")
            # assert dest.__class__ == parent.__class__
            assert isinstance(dest, parent.__class__)

    def test_analysis_does_not_exist(self, sdk_mock):
        container = flywheel.models.analysis_output.AnalysisOutput(
            parent=flywheel.Project(), id="test"
        )
        sdk_mock.get.side_effect = flywheel.rest.ApiException(status=404)
        sdk_mock.get_analysis.return_value = container
        with pytest.raises(flywheel.rest.ApiException):
            dest = get_destination(sdk_mock, "test")
            assert isinstance(dest, flywheel.Project)
コード例 #6
0
ファイル: test_pt_classifier.py プロジェクト: mhedehus/GRP-3B
def test_classify_PT():
    dcm_metadata = {
        'info': {
            'header': {
                'dicom': {
                    'SeriesDescription':
                    '[WB_CTAC] Body',
                    'ImageType': ['ORIGINAL', 'PRIMARY'],
                    'CorrectedImage':
                    ['DECY', 'RADL', 'ATTN', 'SCAT', 'DTIM', 'RAN', 'NORM'],
                    'RadiopharmaceuticalInformationSequence': [{
                        'RadionuclideCodeSequence': [{
                            'CodeValue': 'C-111A1'
                        }],
                        'RadiopharmaceuticalCodeSequence': [{
                            'CodeValue':
                            'C-B1031'
                        }]
                    }]
                }
            }
        }
    }
    ipp = [[0, 0, float(a)] for a in range(100)]
    df = pd.DataFrame({'ImagePositionPatient': ipp})
    acquisition = flywheel.Acquisition(label='Neck')
    res = classify_PT(df, dcm_metadata, acquisition)
    assert res['classification']['Isotope'] == ['F18']
    assert res['classification']['Processing'] == ['Attenuation Corrected']
    assert res['classification']['Tracer'] == ['FDG']
コード例 #7
0
def upload_anatomical(session_id, scanid):
    print('processing anatomical')
    scanidlist = scanid.split('_')
    pid = scanidlist[0]
    visit = scanidlist[1]
    session = scanidlist[2].split('.')[0]
    anatomical_acq = fw.add_acquisition(
        flywheel.Acquisition(session=session_id, label='anatomical'))
    anatomical_path = pjoin('/oak/stanford/groups/menon/rawdata/scsnl/', pid,
                            'visit' + str(visit), 'session' + str(session),
                            'anatomical')
    if not os.path.exists(anatomical_path):
        print('no anatomcal folder!')
        return False
    for root, folders, files in os.walk(anatomical_path):
        for file in files:
            if 'spgr' in file and 'old' not in root:
                print('uploading %s to acq %s' %
                      (pjoin(root, file), str(anatomical_acq)))
                fw.upload_file_to_acquisition(anatomical_acq,
                                              pjoin(root, file))
                fw.modify_acquisition_file(
                    anatomical_acq,
                    file,
                    body={'measurements': ['anatomy_t1w']})
コード例 #8
0
ファイル: test_unicode.py プロジェクト: ehlertjd/core-1
    def test_unicode_label(self):
        fw = self.fw

        for label in TEST_LABELS:
            acquisition = flywheel.Acquisition(label=label, session=self.session_id) 

            acquisition_id = fw.add_acquisition(acquisition)
            self.assertIsNotNone(acquisition_id)

            r_acquisition = fw.get_acquisition(acquisition_id)
            self.assertEqual(r_acquisition.label, label)
コード例 #9
0
def upload_extra(session_id, scanid):
    print('processing extra')
    scanidlist = scanid.split('_')
    pid = scanidlist[0]
    visit = scanidlist[1]
    session = scanidlist[2].split('.')[0]
    top_level = pjoin('/oak/stanford/groups/menon/rawdata/scsnl/', pid,
                      'visit' + str(visit), 'session' + str(session))
    if not os.path.exists(top_level):
        print('no top level folder!')
        return False
    top_level_folders = os.listdir(top_level)
    extra_folders = []
    for folder in top_level_folders:
        if folder not in ['fmri', 'anatomical', 'dwi']:
            print('extra folder found: %s' % folder)
            extra_folders.append(folder)
    if extra_folders == []:
        print('no extra folders found')
        return
    for folder in extra_folders:
        if not os.path.isdir(pjoin(top_level, folder)):
            print('skipping file %s' % folder)
            continue
        acqs = fw.get_session_acquisitions(session_id)
        upload_id = False
        for acq in acqs:
            if acq['label'] == folder:
                upload_id = acq['_id']
                break
        if upload_id == False:
            upload_id = fw.add_acquisition(
                flywheel.Acquisition(session=session_id, label=folder))
        extra_files = os.listdir(pjoin(top_level, folder))
        for extra_file in extra_files:
            if not os.path.isfile(pjoin(top_level, folder, extra_file)):
                print('taring folder %s and uploading to %s' %
                      (pjoin(top_level, folder, extra_file), folder))
                call('tar zcvf %s.tar.gz %s' %
                     (pjoin(top_level, folder,
                            extra_file), pjoin(top_level, folder, extra_file)),
                     shell=True)
                tarball = '%s.tar.gz' % pjoin(top_level, folder, extra_file)
                fw.upload_file_to_acquisition(upload_id, tarball)
                call('/bin/rm %s' % tarball, shell=True)
            else:
                print('taring folder %s and uploading to %s' %
                      (pjoin(top_level, folder, extra_file), folder))
                fw.upload_file_to_acquisition(
                    upload_id, pjoin(top_level, folder, extra_file))
    return True
コード例 #10
0
    def test_notes_and_tags(self):
        # Notes, Tags
        fw = self.fw

        acquisition = flywheel.Acquisition(label=self.rand_string(),
                                           session=self.session_id)
        acquisition_id = fw.add_acquisition(acquisition)

        message = 'This is a note'
        fw.add_container_note(acquisition_id, message)

        tag = 'example-tag'
        fw.add_container_tag(acquisition_id, tag)

        # Replace Info
        fw.replace_container_info(acquisition_id, {'foo': 3, 'bar': 'qaz'})

        # Set Info
        fw.set_container_info(acquisition_id, {'foo': 42, 'hello': 'world'})

        # Check
        c_acquisition = fw.get_container(acquisition_id)

        self.assertEqual(len(c_acquisition.notes), 1)
        self.assertEqual(c_acquisition.notes[0].text, message)

        self.assertEqual(len(c_acquisition.tags), 1)
        self.assertEqual(c_acquisition.tags[0], tag)

        self.assertEqual(c_acquisition.info['foo'], 42)
        self.assertEqual(c_acquisition.info['bar'], 'qaz')
        self.assertEqual(c_acquisition.info['hello'], 'world')

        # Delete info fields
        fw.delete_container_info_fields(acquisition_id, ['foo', 'bar'])

        c_acquisition = fw.get_container(acquisition_id)
        self.assertNotIn('foo', c_acquisition.info)
        self.assertNotIn('bar', c_acquisition.info)
        self.assertEqual(c_acquisition.info['hello'], 'world')

        # Delete
        fw.delete_container(acquisition_id)

        acquisitions = fw.get_all_acquisitions()
        self.assertNotIn(c_acquisition, acquisitions)
コード例 #11
0
ファイル: test_acquisition.py プロジェクト: ehlertjd/core-1
    def test_acquisition_errors(self):
        fw = self.fw

        # Try to create acquisition without session id
        try:
            acquisition = flywheel.Acquisition(label=self.rand_string())
            acquisition_id = fw.add_acquisition(acquisition)
            self.fail('Expected ApiException creating invalid acquisition!')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 400)

        # Try to get an acquisition that doesn't exist
        try:
            fw.get_acquisition('DOES_NOT_EXIST')
            self.fail('Expected ApiException retrieving invalid acquisition!')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 404)
コード例 #12
0
def upload_fmri(session_id, scanid):
    print('processing fmri')
    scanidlist = scanid.split('_')
    pid = scanidlist[0]
    visit = scanidlist[1]
    session = scanidlist[2].split('.')[0]
    fmri_path = pjoin('/oak/stanford/groups/menon/rawdata/scsnl/', pid,
                      'visit' + str(visit), 'session' + str(session), 'fmri')
    if not os.path.exists(fmri_path):
        print('fmri path does not exist')
        return False
    fmri_image_paths = []
    for root, folders, files in os.walk(fmri_path):
        for file in files:
            if file == 'I.nii.gz' or file == 'I.nii':
                fmri_image_paths.append(pjoin(root, file))
    runs = {}
    for path in fmri_image_paths:
        path_split = path.split('/')
        unnormalized_found = False
        for i in range(len(path_split)):
            if 'unnormalized' in path_split[
                    i] and path_split[i] != 'unnormalized_cor':
                run = path_split[i - 1]
                unnormalized_found = True
                if run not in runs:
                    print('creating acquisition ' + run)
                    acquisition_id = fw.add_acquisition(
                        flywheel.Acquisition(session=session_id, label=run))
                    runs[run] = acquisition_id
        if not unnormalized_found:
            print('no unnormalized folder found for %s' % path)
            continue
        print('uploading %s to acquisition %s' % (path, runs[run]))
        fw.upload_file_to_acquisition(runs[run], path)
        fw.modify_acquisition_file_classification(
            runs[run],
            path.split('/')[-1], {
                'modality': 'MR',
                'replace': {
                    'Intent': ['Functional'],
                    'Measurement': ['T2*']
                }
            })
    return runs
コード例 #13
0
    def test_container_analysis(self):
        fw = self.fw

        acquisition = flywheel.Acquisition(session=self.session_id,
                                           label=self.rand_string())

        # Add
        acquisition_id = fw.add_acquisition(acquisition)
        self.assertNotEmpty(acquisition_id)

        poem = 'Troubles my sight: a waste of desert sand;'
        fw.upload_file_to_container(acquisition_id,
                                    flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(id=acquisition_id,
                                          type='acquisition',
                                          name='yeats.txt')

        analysis = flywheel.AnalysisInput(label=self.rand_string(),
                                          description=self.rand_string(),
                                          inputs=[file_ref])

        # Add
        analysis_id = fw.add_container_analysis(acquisition_id, analysis)
        self.assertNotEmpty(analysis_id)

        # Get the list of analyses in the acquisition
        analyses = fw.get_container_analyses(acquisition_id)
        self.assertEqual(len(analyses), 1)

        r_analysis = analyses[0]

        self.assertEqual(r_analysis.id, analysis_id)
        self.assertEmpty(r_analysis.job)

        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)

        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')
コード例 #14
0
def test_get_container_metadata():
    info_dict = {
        'python': {
            'spam': 'eggs'
        },
        'header': {
            'dicom': {
                'PatientID': 'FLYWHEEL'
            }
        }
    }
    file = flywheel.FileEntry(type='file',
                              id='test_id',
                              info=info_dict,
                              modality='MR')
    file._parent = flywheel.Acquisition(parents=flywheel.ContainerParents(
        project='project_id'))
    export_dict = {
        'file': {
            'whitelist':
            ['info.python.spam', 'modality', 'info.header.dicom.PatientID']
        }
    }
    expected_output = {
        'info': {
            'python': {
                'spam': 'eggs'
            },
            'export': {
                'origin_id': util.hash_value('test_id', salt='project_id')
            }
        },
        'modality': 'MR'
    }
    output = get_container_metadata(origin_container=file,
                                    export_dict=export_dict)
    assert output == expected_output
コード例 #15
0
ファイル: test_acquisition.py プロジェクト: ehlertjd/core-1
    def test_acquisitions(self):
        fw = self.fw

        acquisition_name = self.rand_string()
        acquisition = flywheel.Acquisition(label=acquisition_name,
                                           session=self.session_id)

        # Add
        acquisition_id = fw.add_acquisition(acquisition)
        self.assertNotEmpty(acquisition_id)

        # Get
        r_acquisition = fw.get_acquisition(acquisition_id)
        self.assertEqual(r_acquisition.id, acquisition_id)
        self.assertEqual(r_acquisition.label, acquisition_name)
        self.assertTimestampBeforeNow(r_acquisition.created)
        self.assertGreaterEqual(r_acquisition.modified, r_acquisition.created)

        # Generic Get is equivalent
        self.assertEqual(
            fw.get(acquisition_id).to_dict(), r_acquisition.to_dict())

        # Get All
        acquisitions = fw.get_all_acquisitions()
        self.sanitize_for_collection(r_acquisition, info_exists=False)
        self.assertIn(r_acquisition, acquisitions)

        # Modify
        new_name = self.rand_string()
        r_acquisition.update(label=new_name, info={'another-key': 52})

        changed_acquisition = r_acquisition.reload()
        self.assertEqual(changed_acquisition.label, new_name)
        self.assertEqual(changed_acquisition.created, r_acquisition.created)
        self.assertGreater(changed_acquisition.modified,
                           r_acquisition.modified)

        # Notes, Tags
        message = 'This is a note'
        r_acquisition.add_note(message)

        tag = 'example-tag'
        r_acquisition.add_tag(tag)

        # Replace Info
        r_acquisition.replace_info({'foo': 3, 'bar': 'qaz'})

        # Set Info
        r_acquisition.update_info({'foo': 42, 'hello': 'world'})

        # Check
        r_acquisition = r_acquisition.reload()

        self.assertEqual(len(r_acquisition.notes), 1)
        self.assertEqual(r_acquisition.notes[0].text, message)

        self.assertEqual(len(r_acquisition.tags), 1)
        self.assertEqual(r_acquisition.tags[0], tag)

        self.assertEqual(r_acquisition.info['foo'], 42)
        self.assertEqual(r_acquisition.info['bar'], 'qaz')
        self.assertEqual(r_acquisition.info['hello'], 'world')

        # Delete info fields
        r_acquisition.delete_info('foo', 'bar')

        r_acquisition = r_acquisition.reload()
        self.assertNotIn('foo', r_acquisition.info)
        self.assertNotIn('bar', r_acquisition.info)
        self.assertEqual(r_acquisition.info['hello'], 'world')

        # Delete
        fw.delete_acquisition(acquisition_id)

        acquisitions = fw.get_all_acquisitions()
        self.sanitize_for_collection(r_acquisition)
        self.assertNotIn(r_acquisition, acquisitions)
コード例 #16
0
def test_file_exporter():
    classification_dict = {
        "Custom": ["Spam", "Eggs"],
        "Measurement": "T1",
        "Intent": ["Invalid", "Structural"],
        "InvalidKey": "InvalidValue",
        "Features": [],
    }
    info_dict = {
        "header": {
            "dicom": {
                "InstanceNumber": 1,
                "PatientPosition": "HFS",
                "PatientSex": "O",
                "PatientID": "SPAM_Subject",
                "SeriesDescription": "SPAM_study",
            }
        }
    }
    dicom_map_dict = {
        "PatientID": "Flywheel",
    }
    file_entry = flywheel.FileEntry(
        modality="MR",
        classification=classification_dict,
        name='fi:l*e/p"a?t>h|.t<xt',
        id="test_id",
        info=info_dict,
    )

    def upload_func(container_id, file, metadata):
        return container_id, file, metadata

    file_exporter = FileExporter(file_entry, MR_CLASSIFICATION_SCHEMA,
                                 upload_func, dicom_map_dict)
    # test get_modaility
    assert FileExporter.get_modality(file_entry) == "MR"
    assert (FileExporter.get_modality(
        flywheel.FileEntry(name="test.mriqc.qa.html")) == "MR")
    # test classification
    assert file_exporter.classification == {
        "Custom": ["Spam", "Eggs"],
        "Measurement": ["T1"],
        "Intent": ["Structural"],
    }
    exp_info = {
        "header": {
            "dicom": {
                "InstanceNumber": 1,
                "PatientPosition": "HFS",
                "PatientSex": "O",
                "PatientID": "Flywheel",
                "SeriesDescription": "SPAM_study",
            }
        },
        "export": {
            "origin_id":
            "0fb27832c685c35889ba3653994bae061237518c40ed57d3b41eae17bf923137"
        },
    }
    # test info
    assert file_exporter.info == exp_info
    # test fw_dicom_header
    assert file_exporter.fw_dicom_header == exp_info["header"]["dicom"]
    # test setter
    exp_info["header"]["dicom"].pop("SeriesDescription")
    file_exporter.fw_dicom_header = exp_info["header"]["dicom"]
    assert file_exporter.info == exp_info
    with pytest.raises(ValueError):
        file_exporter.fw_dicom_header = "not a dict"
    # test from_client
    mock_client = MagicMock(spec=dir(flywheel.Client))
    mock_client.get_modality = lambda x: {
        "classification": MR_CLASSIFICATION_SCHEMA
    }
    mock_client.upload_file_to_container = upload_func
    file_exporter = FileExporter.from_client(mock_client, file_entry,
                                             dicom_map_dict)
    # test get_classification_schema
    assert (file_exporter.get_classification_schema(
        mock_client, "MR") == MR_CLASSIFICATION_SCHEMA)

    # Raise with a status that is not 404 and will not get caught with backoff
    def raise_func(*args):
        raise flywheel.ApiException(status=400)

    mock_client.get_modality = raise_func
    with pytest.raises(flywheel.ApiException):
        file_exporter.get_classification_schema(mock_client, "MR")
    # test find_file_copy
    file_entry.info = file_exporter.info.copy()
    export_parent = flywheel.Acquisition(label="SPAM_study",
                                         files=[file_entry],
                                         id="test_id")
    assert file_exporter.find_file_copy(export_parent)
    # test create_file_copy
    setattr(file_entry, "download", lambda x: None)
    assert file_exporter.create_file_copy(export_parent)
    # test find_or_create_file_copy
    fn, created = file_exporter.find_or_create_file_copy(export_parent)
    assert not created
    export_parent.files = list()
    fn, created = file_exporter.find_or_create_file_copy(export_parent)
    assert created
    # test update_dicom
    _, temp_path = tempfile.mkstemp()

    assert not file_exporter.update_dicom(temp_path)
    file_exporter.fw_dicom_header = dict()
    # returns local path if no header is defined
    assert file_exporter.update_dicom(temp_path)
    os.remove(temp_path)
コード例 #17
0
    def test_container_files(self):
        fw = self.fw

        acquisition = flywheel.Acquisition(label=self.rand_string(),
                                           session=self.session_id)
        acquisition_id = fw.add_acquisition(acquisition)

        # Upload a file
        poem = 'Turning and turning in the widening gyre'
        fw.upload_file_to_container(acquisition_id,
                                    flywheel.FileSpec('yeats.txt', poem))

        # Check that the file was added to the acquisition
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(len(c_acquisition.files), 1)
        self.assertEqual(c_acquisition.files[0].name, 'yeats.txt')
        self.assertEqual(c_acquisition.files[0].size, 40)
        self.assertEqual(c_acquisition.files[0].mimetype, 'text/plain')

        # Download the file and check content
        self.assertDownloadFileTextEquals(
            fw.download_file_from_container_as_data, acquisition_id,
            'yeats.txt', poem)

        # Test unauthorized download with ticket for the file
        self.assertDownloadFileTextEqualsWithTicket(
            fw.get_container_download_url, acquisition_id, 'yeats.txt', poem)

        # Test file attributes
        self.assertEqual(c_acquisition.files[0].modality, None)
        self.assertEmpty(c_acquisition.files[0].classification)
        self.assertEqual(c_acquisition.files[0].type, 'text')

        resp = fw.modify_container_file(
            acquisition_id, 'yeats.txt',
            flywheel.FileEntry(modality='modality', type='type'))

        # Check that no jobs were triggered, and attrs were modified
        self.assertEqual(resp.jobs_spawned, 0)

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].modality, "modality")
        self.assertEmpty(c_acquisition.files[0].classification)
        self.assertEqual(c_acquisition.files[0].type, 'type')

        # Test classifications
        resp = fw.modify_container_file_classification(
            acquisition_id, 'yeats.txt', {
                'modality': 'modality2',
                'replace': {
                    'Custom': ['measurement1', 'measurement2'],
                }
            })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].modality, 'modality2')
        self.assertEqual(c_acquisition.files[0].classification,
                         {'Custom': ['measurement1', 'measurement2']})

        resp = fw.set_container_file_classification(acquisition_id,
                                                    'yeats.txt',
                                                    {'Custom': ['HelloWorld']})
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        resp = fw.delete_container_file_classification_fields(
            acquisition_id, 'yeats.txt', {'Custom': ['measurement2']})
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].classification, {
            'Custom': ['measurement1', 'HelloWorld'],
        })

        # Test file info
        self.assertEmpty(c_acquisition.files[0].info)
        fw.replace_container_file_info(acquisition_id, 'yeats.txt', {
            'a': 1,
            'b': 2,
            'c': 3,
            'd': 4
        })

        fw.set_container_file_info(acquisition_id, 'yeats.txt', {'c': 5})

        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].info['a'], 1)
        self.assertEqual(c_acquisition.files[0].info['b'], 2)
        self.assertEqual(c_acquisition.files[0].info['c'], 5)
        self.assertEqual(c_acquisition.files[0].info['d'], 4)

        fw.delete_container_file_info_fields(acquisition_id, 'yeats.txt',
                                             ['c', 'd'])
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEqual(c_acquisition.files[0].info['a'], 1)
        self.assertEqual(c_acquisition.files[0].info['b'], 2)
        self.assertNotIn('c', c_acquisition.files[0].info)
        self.assertNotIn('d', c_acquisition.files[0].info)

        fw.replace_container_file_info(acquisition_id, 'yeats.txt', {})
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEmpty(c_acquisition.files[0].info)

        # Delete file
        fw.delete_container_file(acquisition_id, 'yeats.txt')
        c_acquisition = fw.get_container(acquisition_id)
        self.assertEmpty(c_acquisition.files)

        # Delete acquisition
        fw.delete_container(acquisition_id)
コード例 #18
0
def test_container_hierarchy():
    hierarchy_dict = {
        "group":
        flywheel.Group(id="test_group", label="Test Group"),
        "project":
        flywheel.Project(label="test_project"),
        "subject":
        flywheel.Subject(label="test_subject", sex="other"),
        "session":
        flywheel.Session(
            age=31000000,
            label="test_session",
            weight=50,
        ),
    }
    # test from_dict
    test_hierarchy = ContainerHierarchy.from_dict(hierarchy_dict)
    # test deepcopy
    assert deepcopy(test_hierarchy) != test_hierarchy
    # test path
    assert test_hierarchy.path == "test_group/test_project/test_subject/test_session"
    # test parent
    assert test_hierarchy.parent.label == "test_subject"
    # test from_container
    mock_client = MagicMock(spec=dir(flywheel.Client))
    parent_dict = dict()
    for item in ("group", "project", "subject"):
        value = hierarchy_dict.copy().get(item)
        parent_dict[item] = item
        setattr(mock_client, f"get_{item}", lambda x: value)
    session = flywheel.Session(age=31000000, label="test_session", weight=50)
    session.parents = parent_dict
    assert (ContainerHierarchy.from_container(
        mock_client, session).container_type == "session")
    # test _get_container
    assert test_hierarchy._get_container(None, None, None) is None
    with pytest.raises(ValueError) as exc:
        test_hierarchy._get_container(None, "garbage", "garbage_id")
        assert str(exc) == "Cannot get a container of type garbage"
    mock_client = MagicMock(spec=dir(flywheel.Client))
    mock_client.get_session = lambda x: x
    assert (test_hierarchy._get_container(mock_client, "session",
                                          "session_id") == "session_id")
    # test container_type
    assert test_hierarchy.container_type == "session"
    # test dicom_map
    exp_map = {
        "PatientWeight": 50,
        "PatientAge": "011M",
        "ClinicalTrialTimePointDescription": "test_session",
        "PatientSex": "O",
        "PatientID": "test_subject",
    }
    assert exp_map == test_hierarchy.dicom_map
    # test get
    assert test_hierarchy.get("container_type") == "session"
    # test get_patient_sex_from_subject
    assert test_hierarchy.get_patientsex_from_subject(flywheel.Subject()) == ""
    # test get_patientage_from_session
    assert test_hierarchy.get_patientage_from_session(
        flywheel.Session()) is None

    # test get_child_hierarchy
    test_acquisition = flywheel.Acquisition(label="test_acquisition")
    acq_hierarchy = test_hierarchy.get_child_hierarchy(test_acquisition)
    assert acq_hierarchy.dicom_map[
        "SeriesDescription"] == test_acquisition.label
    # test get_parent_hierarchy
    parent_hierarchy = test_hierarchy.get_parent_hierarchy()
    assert parent_hierarchy.container_type == "subject"