def setUpClass(self): self.beams = 50 self.anatomy = Anatomy([ Structure(0, 'PTV', True, A=np.random.rand(100, self.beams)), Structure(1, 'OAR1', False, A=np.random.rand(300, self.beams)), Structure(2, 'OAR2', False, A=np.random.rand(250, self.beams)) ])
def setUpClass(self): self.beams = 50 self.anatomy = Anatomy([ Structure(0, 'PTV', True, A=np.random.rand(100, self.beams)), Structure(1, 'OAR1', False, A=np.random.rand(300, self.beams)), Structure(2, 'OAR2', False, A=np.random.rand(250, self.beams)) ]) self.anatomy['PTV'].constraints += D(80) > 40 * Gy self.anatomy['PTV'].constraints += D(20) < 45 * Gy
def setUpClass(self): self.m, self.n = m, n = 500, 100 self.m_target = m_target = 100 self.m_oar = m_oar = m - m_target self.anatomy = Anatomy() self.anatomy += Structure(0, 'tumor', True, A=np.random.rand(m_target, n)) self.anatomy += Structure(1, 'oar', True, A=np.random.rand(m_oar, n))
def setUpClass(self): self.beams = 50 self.anatomy = Anatomy([ Structure(0, 'PTV', True, A=np.random.rand(100, self.beams)), Structure(1, 'OAR1', False, A=np.random.rand(300, self.beams)), Structure(2, 'OAR2', False, A=np.random.rand(250, self.beams)) ]) self.panel_assignments = {0: 0, 1: 0, 2: 0} self.names = {0: 'PTV', 1: 'OAR1', 2: 'OAR2'} self.case = Case(anatomy=self.anatomy)
def test_case_accessor_update(self): ca = CaseAccessor(filesystem=FilesystemTestCaching()) ptr = ca.save_case(self.case, 'case0', 'dir') case_entry = ca.DB.get(ptr) self.case.anatomy += Structure(1, 'oar', False) ptr2 = ca.update_case_entry(case_entry, self.case, 'dir', case_ID=ptr) self.assertEqual(ptr2, ptr) self.case.anatomy += Structure(2, 'oar2', False) ptr3 = ca.update_case_entry(case_entry, self.case, 'dir') self.assertNotEqual(ptr3, ptr)
def test_cdba_record_entry(self): cdba = ConradDBAccessor(filesystem=FilesystemTestCaching()) # unrecorded basic types for val in [None, 1, 1.0, '1', {'1': 2, 3: 4.0, '5': '6'}]: res = cdba.record_entry('dir', 'name', val) self.assertEqual(res, val) # unhandled basic types for val in [set(), list()]: with self.assertRaises(TypeError): cdba.record_entry('dir', 'name', val) # recorded data types for val in [ np.random.rand(30), np.random.rand(30, 20), sp.rand(30, 20, 0.2, format='csr'), { 1: np.random.rand(30), 2: np.random.rand(30) } ]: res = cdba.record_entry('dir', 'name', val) self.assertTrue(cdba.DB.has_key(res)) # unhandled custom types for val in [Structure(0, 'name', False), StructureEntry()]: with self.assertRaises(TypeError): cdba.record_entry('dir', 'name', val)
def test_anatomy_accessor_save_load(self): aa = AnatomyAccessor() anatomy_in = Anatomy() anatomy_in += Structure(0, 'name0', False) anatomy_in += Structure(1, 'name1', False) ptr = aa.save_anatomy(anatomy_in) self.assertTrue(aa.DB.has_key(ptr)) a = aa.load_anatomy(ptr) self.assertIsInstance(a, Anatomy) self.assertEqual(len(a.list), 2) self.assertEqual(a['name0'].label, 0) self.assertFalse(a['name0'].is_target) self.assertEqual(a[1].name, 'name1') self.assertFalse(a[1].is_target)
def setUpClass(self): self.beams = 50 self.anatomy = Anatomy([ Structure( 0, 'PTV', True, A=np.random.rand(100, self.beams)), Structure( 1, 'OAR1', False, A=np.random.rand(300, self.beams)), Structure( 2, 'OAR2', False, A=np.random.rand(250, self.beams)) ]) self.anatomy['PTV'].constraints += D(80) > 25 * Gy self.anatomy['PTV'].constraints += D(30) < 28 * Gy self.anatomy['OAR1'].constraints += D(20) < 10 * Gy self.panels = {s.label: 0 for s in self.anatomy} self.names = {s.label: s.name for s in self.anatomy} self.case = Case(anatomy=self.anatomy)
def setUpClass(self): self.m_target = 100 self.m_oar = 400 self.m = self.m_target + self.m_oar self.n = 207 # Structure labels self.label_tumor = 0 self.label_oar = 1 # Voxel labels on beam matrix self.label_order = [self.label_tumor, self.label_oar] self.voxel_labels = [self.label_tumor] * self.m_target self.voxel_labels += [self.label_oar] * self.m_oar self.anatomy = Anatomy() self.anatomy += Structure(self.label_tumor, 'tumor', True) self.anatomy += Structure(self.label_oar, 'oar', False)
def test_solver_dimcheck(self): m0 = 100 m1 = 150 n = 50 n_mismatch = 52 s = Solver() structures = [] structures.append(Structure(0, 'tumor', True, A=np.random.rand(m0, n))) structures.append(Structure(1, 'OAR', False, A=np.random.rand(m1, n))) self.assertEqual( s._Solver__check_dimensions(structures), n ) structures[0] = Structure( 0, 'tumor', True, A=np.random.rand(m0, n_mismatch)) with self.assertRaises(ValueError): s._Solver__check_dimensions(structures)
def test_structure_accessor_save_load(self): sa = StructureAccessor() ptr = sa.save_structure(Structure(0, 'name', True, w_under=2.75)) self.assertTrue(sa.DB.has_key(ptr)) s = sa.load_structure(ptr) self.assertIsInstance(s, Structure) self.assertEqual(s.label, 0) self.assertEqual(s.name, 'name') self.assertTrue(s.is_target) self.assertEqual(s.objective.weight_underdose_raw, 2.75)
class StructureConstraintsGraphTestCase(ConradTestCase): @classmethod def setUpClass(self): self.PTV = Structure(0, 'PTV', True) self.PTV.constraints += D(30) < 50 * Gy self.PTV.constraints += D(80) > 45 * Gy def test_structure_constraints_graph_init_properties(self): # initialization pd = self.PTV.plotting_data(constraints_only=True) scg = StructureConstraintsGraph(pd) # test constraints, color, maxdose self.assertEqual(len(scg.constraints), 2) self.assertEqual(scg.color, LineAesthetic().scale_rgb('black')) self.assertEqual(scg.maxdose, 50.0) # alternate initialization scg = StructureConstraintsGraph(self.PTV) self.assertEqual(len(scg.constraints), 2) def test_structure_constraints_graph_iterator(self): scg = StructureConstraintsGraph(self.PTV) for constraint_graph in scg: self.assertIsInstance(constraint_graph, PercentileConstraintGraph) def test_structure_constraints_graph_draw_undraw(self): scg = StructureConstraintsGraph(self.PTV) ax = mpl.figure.Figure().add_subplot(1, 1, 1) # test draw scg.draw(ax, markersize=12) for constr in scg: self.assertIs(constr.axes, ax) self.assertTrue(all(map(lambda g: g in ax.lines, constr.graph))) # test hide/show scg.hide() for constr in scg: self.assertFalse( any(map(lambda g: g.get_visible(), constr.graph))) scg.show() for constr in scg: self.assertTrue( all(map(lambda g: g.get_visible(), constr.graph))) # test undraw scg.undraw() self.assertTrue(constr.axes is None) self.assertTrue(all(map(lambda g: g not in ax.lines, constr.graph)))
def setUpClass(self): m, n = 100, 50 self.anatomy = Anatomy([ Structure(0, 'PTV', True), Structure(1, 'OAR1', False), Structure(2, 'OAR2', False) ]) self.physics = Physics(dose_matrix=np.random.rand(m, n), voxel_labels=(3 * np.random.rand(m)).astype(int)) # let T = average value of target voxel rows of dose matrix # N = average value of non-target rows, # then # target_snr = T / N target_snr = 4. for i, label in enumerate(self.physics.voxel_labels): if label == 0: self.physics.dose_matrix.data[i, :] *= target_snr self.prescription = Prescription([{ 'name': 'PTV', 'label': 0, 'is_target': True, 'dose': '1 Gy', 'constraints': ['D85 > 0.8 rx', 'D1 < 1.2 Gy'] }, { 'name': 'OAR_RESILIENT', 'label': 1, 'is_target': False, 'dose': None, 'constraints': ['D50 < 0.6 Gy', 'D2 < 0.8 Gy'] }])
def test_caseio_case_YAML_transfers(self): # build a case, dump to YAML caseio = CaseIO(FS_constructor=FilesystemTestCaching) directory = os.path.dirname(__file__) case_name = 'yaml_testing_case' yaml_store = caseio.case_to_YAML(self.case, case_name, directory) self.__files.append(yaml_store) self.assertTrue( os.path.exists(yaml_store) ) # take example YAML, build a case caseio2 = CaseIO() case = caseio.YAML_to_case(yaml_store) self.assertIsInstance( case, Case ) for s in self.case.anatomy: self.assertIn( s.label, case.anatomy ) self.assert_vector_equal( case.A, self.case.A ) # test anatomy->physics (on save), # physics->anatomy transfer (on load) m1, m2, n = 30, 30, 20 A1 = np.random.rand(m1, n) A2 = np.random.rand(m2, n) case2 = Case() case2.anatomy += Structure(0, 'target', True, A=A1) case2.anatomy += Structure(1, 'OAR', False, A=A2) self.assertTrue( case2.plannable ) yaml_store2 = caseio.case_to_YAML(case2, 'yaml_testing_2', directory) self.__files.append(yaml_store2) self.assertTrue( os.path.exists(yaml_store2) ) # take example YAML, build a case caseio2 = CaseIO() case2 = caseio.YAML_to_case(yaml_store2) self.assertTrue( case2.plannable )
def test_cdba_pop_record(self): cdba = ConradDBAccessor(filesystem=FilesystemTestCaching()) input_dict = {} result = cdba.pop_and_record(input_dict, 'key', 'dir') self.assertIsNone(result) for val in [2, 2.0, '2', {'some data': 'value'}]: # test unrecorded types input_dict['key'] = val result = cdba.pop_and_record(input_dict, 'key', 'dir') self.assertEqual(result, val) self.assertEqual(len(cdba.FS.files), 0) # test alternate keys input_dict.pop('key') input_dict['alternate_key'] = val result = cdba.pop_and_record(input_dict, 'key', 'dir', alternate_keys=['alternate_key']) self.assertEqual(result, val) self.assertEqual(len(cdba.FS.files), 0) # test nested keys input_dict.pop('alternate_key') input_dict['key2'] = {'subkey': val} result = cdba.pop_and_record( input_dict, 'key', 'dir', alternate_keys=['alternate_key', ['key2', 'subkey']]) self.assertEqual(result, val) self.assertEqual(len(cdba.FS.files), 0) # test rejected types for val in [ list(), set(), Structure(0, 'name', False), StructureEntry() ]: with self.assertRaises(TypeError): cdba.pop_and_record({'key': val}, 'key', 'dir') # test recorded types for val in [ np.random.rand(30), np.random.rand(30, 20), sp.rand(30, 20, 0.2, format='csr') ]: result = cdba.pop_and_record({'key': val}, 'key', 'dir') self.assertIsInstance(result, str) self.assertTrue(cdba.DB.has_key(result)) rex = r'dir/key.*.npy' entry_vals = cdba.DB.get(result).flat_dictionary.values() self.assertTrue( any([re.match(rex, str(s)) != None for s in entry_vals])) result = cdba.pop_and_record({'key': val}, 'key', 'dir', name_base='base_name') self.assertIsInstance(result, str) self.assertTrue(cdba.DB.has_key(result)) entry_vals = cdba.DB.get(result).flat_dictionary.values() rex = r'dir/base_name_key.*.npy' entry_vals = cdba.DB.get(result).flat_dictionary.values() self.assertTrue( any([re.match(rex, str(s)) != None for s in entry_vals]))
def test_case_init(self): m, n = voxels, beams = 100, 50 # bare initialization c0 = Case() self.assertIsInstance(c0._Case__physics, Physics) self.assertIsInstance(c0.physics, Physics) self.assertIsInstance(c0._Case__anatomy, Anatomy) self.assertIsInstance(c0.anatomy, Anatomy) self.assertIsInstance(c0._Case__prescription, Prescription) self.assertIsInstance(c0.prescription, Prescription) self.assertIsInstance(c0._Case__problem, PlanningProblem) self.assertIsInstance(c0.problem, PlanningProblem) self.assertIsInstance(c0.structures, dict) self.assertEqual(len(c0.structures), 0) self.assertIsNone(c0.A) self.assertEqual(c0.n_structures, 0) self.assertIsNone(c0.n_voxels) self.assertIsNone(c0.n_beams) self.assertFalse(c0.physics.plannable) self.assertFalse(c0.anatomy.plannable) self.assertFalse(c0.plannable) self.assertIsInstance(c0.plotting_data(), dict) self.assertEqual(len(c0.plotting_data()), 0) # anatomy & physics-based intialization a = Anatomy() a += Structure(0, 'organ at risk', False) p = Physics(voxels, beams) c1 = Case(anatomy=a, physics=p) self.assertEqual(c1.n_structures, 1) self.assertEqual(c1.n_voxels, voxels) self.assertEqual(c1.n_beams, beams) self.assertFalse(c1.physics.plannable) self.assertFalse(c1.anatomy.plannable) self.assertFalse(c1.plannable) # at least one target makes anatomy plannable (but needs dose matrix) c1.anatomy += Structure(1, 'target', True) self.assertEqual(c1.n_structures, 2) self.assertFalse(c1.physics.plannable) self.assertFalse(c1.anatomy.plannable) self.assertFalse(c1.plannable) # dose matrix... p.dose_matrix = np.random.rand(voxels, beams) self.assertIsNotNone(c1.A) self.assertEqual(c1.A.shape, (voxels, beams)) self.assertFalse(c1.physics.plannable) self.assertFalse(c1.anatomy.plannable) self.assertFalse(c1.plannable) # ...and voxel labels makes physics plannable, rendering # the case object plannable upon data transfer from physics to # anatomy (invoked by checking property "plannable") p.voxel_labels = (2 * np.random.rand(m)).astype(int) self.assertTrue(c1.physics.plannable) self.assertFalse(c1.anatomy.plannable) self.assertTrue(c1.plannable) self.assertTrue(c1.anatomy.plannable) # inline version of anatomy & physics-based initialization c2 = Case( Anatomy([Structure(0, 'oar', False), Structure(1, 'tumor', True)]), Physics(dose_matrix=np.random.rand(voxels, beams), voxel_labels=(2 * np.random.rand(voxels)).astype(int))) self.assertEqual(c2.n_structures, 2) self.assertEqual(c2.n_voxels, voxels) self.assertEqual(c2.n_beams, beams) self.assertIsNotNone(c2.A) self.assertEqual(c2.A.shape, (voxels, beams)) self.assertTrue(c2.physics.plannable) self.assertFalse(c2.anatomy.plannable) self.assertTrue(c2.plannable) self.assertTrue(c2.anatomy.plannable)
def setUpClass(self): self.PTV = Structure(0, 'PTV', True) self.PTV.constraints += D(30) < 50 * Gy self.PTV.constraints += D(80) > 45 * Gy
def setUpClass(self): self.structures = [ Structure(0, 'target', True, A=5 * np.random.rand(30, 20)), Structure(0, 'avoid', False, A=np.random.rand(100, 20)), ]
def setUp(self): self.A = np.random.rand(30, 20) self.case = Case(physics=Physics(dose_matrix=self.A), anatomy=Anatomy([Structure(0, 'ptv', True)]))