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']})
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']
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
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'] } })
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)
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']
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']})
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)
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
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)
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)
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
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')
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
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)
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)
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)
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"