def test_sanitize(): m = Morphology() section = m.append_root_section( PointLevel([[1, 0, 0], [2, 0, 0]], [2, 2], [20, 20]), SectionType.axon) section.append_section(PointLevel([[2, 0, 0], [3, 0, 0]], [2, 2], [20, 20])) with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): m.sanitize() assert_equal(len(list(m.iter())), 1) assert_equal( err.getvalue().strip(), 'Warning: section 1 is the only child of section: 0\nIt will be merged ' 'with the parent section') # Checking that sanitize() issues a warning on missing duplicate m = Morphology() section = m.append_root_section( PointLevel([[1, 0, 0], [2, 0, 0]], [2, 2], [20, 20]), SectionType.axon) section.append_section(PointLevel([[2, 0, 0], [3, 0, 0]], [2, 2], [20, 20])) with captured_output() as (_, err): with ostream_redirect(): section.append_section( PointLevel([[2, 1, 0], [2, 0, 0]], [2, 2], [20, 20])) with captured_output() as (_, err): with ostream_redirect(): m.sanitize() assert_equal( err.getvalue().strip(), 'Warning: while appending section: 2 to parent: 0\nThe section first point should be parent section last point: \n : X Y Z Diameter\nparent last point :[2.000000, 0.000000, 0.000000, 2.000000]\nchild first point :[2.000000, 1.000000, 0.000000, 2.000000]' )
def test_neurite_wrong_root_point(): '''Test that for 3 points soma, the neurites are attached to first soma point''' # Not 3-points soma --> OK with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): n = Morphology(os.path.join(_path, 'soma_cylinders.swc')) assert_equal('', err.getvalue().strip()) assert_equal(len(n.root_sections), 1) with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): n = Morphology(os.path.join(_path, 'neurite_wrong_root_point.swc')) assert_string_equal( '''Warning: with a 3 points soma, neurites must be connected to the first soma point: {}/neurite_wrong_root_point.swc:4:warning {}/neurite_wrong_root_point.swc:6:warning'''.format(_path, _path), err.getvalue()) assert_equal(len(n.root_sections), 2) assert_array_equal(n.root_sections[0].points, [[0, 0, 0], [0, 0, 1]]) with ignored_warning(Warning.wrong_root_point): with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): n = Morphology( os.path.join(_path, 'neurite_wrong_root_point.swc')) assert_equal('', err.getvalue().strip())
def test_mitochondria(): morpho = Morphology() morpho.soma.points = [[0, 0, 0], [1, 1, 1]] morpho.soma.diameters = [1, 1] neuronal_section_ids = [0, 0] relative_pathlengths = np.array([0.5, 0.6], dtype=np.float32) diameters = [10, 20] mito_id = morpho.mitochondria.append_root_section( MitochondriaPointLevel(neuronal_section_ids, relative_pathlengths, diameters)) mito_id.append_section( MitochondriaPointLevel([0, 0, 0, 0], [0.6, 0.7, 0.8, 0.9], [20, 30, 40, 50])) with setup_tempdir('test_mitochondria') as tmp_folder: morpho.write(os.path.join(tmp_folder, "test.h5")) with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): morpho.write(os.path.join(tmp_folder, "test.swc")) assert_string_equal( err.getvalue(), "Warning: this cell has mitochondria, they cannot be saved in " " ASC or SWC format. Please use H5 if you want to save them." ) with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): morpho.write(os.path.join(tmp_folder, "test.asc")) assert_string_equal( err.getvalue(), "Warning: this cell has mitochondria, they cannot be saved in " " ASC or SWC format. Please use H5 if you want to save them." ) mito = ImmutMorphology(os.path.join(tmp_folder, 'test.h5')).mitochondria assert_array_equal(mito.root_sections[0].diameters, diameters) assert_array_equal(mito.root_sections[0].neurite_section_ids, neuronal_section_ids) assert_array_equal(mito.root_sections[0].relative_path_lengths, relative_pathlengths) assert_equal(len(mito.root_sections), 1) mito = Morphology(os.path.join(tmp_folder, 'test.h5')).mitochondria assert_equal(len(mito.root_sections), 1) assert_equal(mito.root_sections[0].neurite_section_ids, neuronal_section_ids) assert_array_equal(mito.section(0).diameters, diameters) assert_array_equal( mito.section(0).neurite_section_ids, neuronal_section_ids)
def test_write_no_soma(): morpho = Morphology() dendrite = morpho.append_root_section( PointLevel([[0, 0, 0], [0, 5, 0]], [2, 2]), SectionType.basal_dendrite) dendrite = morpho.append_root_section( PointLevel([[0, 1, 0], [0, 7, 0]], [2, 2]), SectionType.basal_dendrite) with setup_tempdir('test_write_no_soma') as tmp_folder: for ext in ['asc', 'h5', 'swc']: with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): outfile = os.path.join(tmp_folder, 'tmp.' + ext) morpho.write(outfile) assert_equal(err.getvalue().strip(), 'Warning: writing file without a soma') read = Morphology(outfile) assert_equal(len(read.soma.points), 0) assert_equal(len(read.root_sections), 2) assert_array_equal(read.root_sections[0].points, [[0, 0, 0], [0, 5, 0]]) assert_array_equal(read.root_sections[1].points, [[0, 1, 0], [0, 7, 0]])
def test_nested_single_child(): with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): n = Morphology(os.path.join(_path, 'nested_single_children.asc')) assert_array_equal( n.root_sections[0].points, [[0., 0., 0.], [0., 0., 1.], [0., 0., 2.], [0., 0., 3.], [0., 0., 4.]])
def test_write_merge_only_child_asc_h5(): '''The root section has only one child When writing, children should *not* be merged with their parent section. Note: See `test_write_merge_only_child_swc` for the SWC case. ''' morpho = Morphology() morpho.soma.points = [[0, 0, 0]] morpho.soma.diameters = [2] root = morpho.append_root_section( PointLevel([[0, 0, 0], [0, 5, 0]], [2, 2]), SectionType.basal_dendrite) child = root.append_section(PointLevel([[0, 5, 0], [0, 6, 0]], [2, 3])) with setup_tempdir('test_write_merge_only_child') as tmp_folder: for extension in ['asc', 'h5']: with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): filename = Path(tmp_folder, 'test.{}'.format(extension)) morpho.write(filename) read = Morphology(filename) root = read.root_sections[0] assert_array_equal(root.points, [[0, 0, 0], [0, 5, 0]]) assert len(root.children) == 1
def test_empty_neurite(): m = Morphology() with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): root = m.append_root_section(PointLevel(), SectionType.axon) assert_equal(err.getvalue().strip(), 'Warning: appending empty section with id: 0') assert_equal(len(m.root_sections), 1) assert_equal(m.root_sections[0].type, SectionType.axon) with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): root.append_section(PointLevel(), SectionType.axon) assert_equal(err.getvalue().strip(), 'Warning: appending empty section with id: 1')
def test_single_point_root_section(): m = Morphology() points = [] diameters = [] # Too hide the warning: appending empty section with captured_output(): with ostream_redirect(stdout=True, stderr=True): m.append_root_section(PointLevel(points, diameters), SectionType(2)) with setup_tempdir('test_single_point_root_section', no_cleanup=True) as tmp_folder: assert_raises( SectionBuilderError, m.write, os.path.join(tmp_folder, "h5/empty_vasculature.h5")) m = Morphology() points = [[1., 1., 1.]] diameters = [2.] m.append_root_section(PointLevel(points, diameters), SectionType(2)) with setup_tempdir('test_single_point_root_section', no_cleanup=True) as tmp_folder: assert_raises(SectionBuilderError, m.write, os.path.join(tmp_folder, "h5/empty_vasculature.h5"))
def test_duplicate_different_diameter(): '''Test that starting a child section with a different diamete work as expected''' morpho = Morphology() morpho.soma.points = [[0, 0, 0], [1, 1, 1]] morpho.soma.diameters = [1, 1] section = morpho.append_root_section( PointLevel([[2, 2, 2], [3, 3, 3]], [4, 4]), SectionType.axon, ) section.append_section(PointLevel([[3, 3, 3], [4, 4, 4]], [10, 12])) section.append_section(PointLevel([[3, 3, 3], [5, 5, 5]], [11, 12])) with setup_tempdir('test_write_duplicate_different_diameter', no_cleanup=True) as tmp_folder: for ext in ['asc', 'h5', 'swc']: with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): outfile = os.path.join(tmp_folder, 'tmp.' + ext) morpho.write(outfile) read = Morphology(outfile) assert_equal(len(read.root_sections[0].children), 2) child1, child2 = read.root_sections[0].children assert_array_equal(child1.points, [[3, 3, 3], [4, 4, 4]]) assert_array_equal(child2.points, [[3, 3, 3], [5, 5, 5]]) assert_array_equal(child1.diameters, [10, 12]) assert_array_equal(child2.diameters, [11, 12])
def test_write_empty_file(): '''Check that empty morphology are not written to disk''' with captured_output() as (_, _): with ostream_redirect(stdout=True, stderr=True): with setup_tempdir('test_write_empty_file', no_cleanup=True) as tmp_folder: for ext in ['asc', 'swc', 'h5']: outname = os.path.join(tmp_folder, 'empty.' + ext) Morphology().write(outname) ok_(not os.path.exists(outname))
def test_nested_single_child(): with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): n = Morphology(DATA_DIR / 'nested_single_children.asc') n.remove_unifurcations() assert_array_equal( n.root_sections[0].points, [[0., 0., 0.], [0., 0., 1.], [0., 0., 2.], [0., 0., 3.], [0., 0., 4.]]) assert_array_equal(n.root_sections[0].diameters, np.array([8, 7, 6, 5, 4], dtype=np.float32))
def test_disconnected_neurite(): with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): n = Morphology(os.path.join(_path, 'disconnected_neurite.swc')) assert_equal( _path + '''/disconnected_neurite.swc:10:warning Warning: found a disconnected neurite. Neurites are not supposed to have parentId: -1 (although this is normal if this neuron has no soma)''', strip_color_codes(err.getvalue().strip()))
def test_no_duplicate(): with captured_output(): with ostream_redirect(stdout=True, stderr=True): m = Morphology(SIMPLE, options=Option.no_duplicates) neurite1 = [[[0., 0., 0.], [0, 5, 0]], [[-5, 5, 0]], [[6, 5, 0]]] neurite2 = [[[0, 0, 0], [0, -4, 0]], [[6, -4, 0]], [[-5, -4, 0]]] assert_array_equal([section.points.tolist() for section in m.iter()], neurite1 + neurite2) # Combining options NO_DUPLICATES and NRN_ORDER with captured_output(): with ostream_redirect(stdout=True, stderr=True): m = Morphology(SIMPLE, options=Option.no_duplicates | Option.nrn_order) assert_array_equal([section.points.tolist() for section in m.iter()], neurite2 + neurite1)
def test_no_duplicate(): with captured_output(): with ostream_redirect(stdout=True, stderr=True): m = Morphology(SIMPLE, options=Option.no_duplicates) neurite1 = np.array([[0., 0., 0.], [0, 5, 0], [-5, 5, 0], [6, 5, 0]]) neurite2 = np.array([[0, 0, 0], [0, -4, 0], [6, -4, 0], [-5, -4, 0]]) assert_array_equal(np.vstack([section.points for section in m.iter()]), np.vstack([neurite1, neurite2])) # Combining options NO_DUPLICATES and NRN_ORDER with captured_output(): with ostream_redirect(stdout=True, stderr=True): m = Morphology(SIMPLE, options=Option.no_duplicates | Option.nrn_order) assert_array_equal(np.vstack([section.points for section in m.iter()]), np.vstack([neurite2, neurite1]))
def test_no_soma(): swc_content = '''1 2 0 0 0 3.0 -1 2 2 0 0 0 3.0 1 3 2 0 0 0 3.0 2''' with captured_output() as (_, err): with ostream_redirect( stdout=True, stderr=True), tmp_swc_file(swc_content) as tmp_file: n = Morphology(tmp_file.name) assert ('{}:0:warning\nWarning: no soma found in file'.format( tmp_file.name) == strip_color_codes(err.getvalue().strip()))
def test_neurite_followed_by_soma(): # Capturing the output to keep the unit test suite stdout clean with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): _test_swc_exception( '''# An orphan neurite with a soma child 1 3 0 0 1 0.5 -1 2 3 0 0 2 0.5 1 3 3 0 0 3 0.5 2 4 3 0 0 4 0.5 3 5 3 0 0 5 0.5 4 6 1 0 0 0 3.0 5 # <-- soma child''', SomaError, 'Found a soma point with a neurite as parent', ':7:error')
def test_zero_diameter(): with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True),\ tmp_swc_file('''1 1 1 0 0 3.0 -1 2 1 2 0 0 3.0 1 3 1 3 0 0 3.0 2 4 3 4 0 0 0.0 1 5 3 5 0 0 3.0 4 ''') as tmp_file: Morphology(tmp_file.name) assert_string_equal( f'{tmp_file.name}:4:warning\nWarning: zero diameter in file\n', err.getvalue())
def test_write_merge_only_child(): '''The root section has only one child The child should be merged with its parent section Special care must be given for the potential duplicate point o / / son 1 root child / o--------o----------o< \ \ son 2 \ o ''' morpho = Morphology() morpho.soma.points = [[0, 0, 0]] morpho.soma.diameters = [2] root = morpho.append_root_section( PointLevel([[0, 0, 0], [0, 5, 0]], [2, 2]), SectionType.basal_dendrite) child = root.append_section(PointLevel([[0, 5, 0], [0, 6, 0]], [2, 3])) son1 = child.append_section(PointLevel([[0, 6, 0], [0, 7, 0]], [2, 3])) son2 = child.append_section(PointLevel([[0, 6, 0], [4, 5, 6]], [3, 3])) with setup_tempdir('test_write_merge_only_child') as tmp_folder: for extension in ['swc', 'asc', 'h5']: with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): filename = os.path.join(tmp_folder, 'test.{}'.format(extension)) morpho.write(filename) assert_equal(err.getvalue().strip(), 'Warning: section 1 is the only child of section: 0\nIt will be merged with the parent section') read = Morphology(filename) root = read.root_sections[0] assert_array_equal(root.points, [[0, 0, 0], [0, 5, 0], [0, 6, 0]]) assert_equal(len(root.children), 2) assert_array_equal(root.children[0].points, [[0, 6, 0], [0, 7, 0]]) assert_array_equal(root.children[1].points, [[0, 6, 0], [4, 5, 6]])
def test_single_children(): '''Single children are merged with their parent''' with tmp_asc_file(''' ((Dendrite) (3 -4 0 2) (3 -6 0 2) (3 -8 0 2) (3 -10 0 2) ( (3 -10 0 2) ; merged with parent section (0 -10 0 2) ; merged with parent section (-3 -10 0 2) ; merged with parent section ( (-5 -5 5 5) | (-6 -6 6 6) ) ) ) ''') as tmp_file: with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): n = Morphology(tmp_file.name) assert_substring('is the only child of section: 0 starting at:', err.getvalue().strip()) assert_substring('It will be merged with the parent section', err.getvalue().strip()) nt.assert_equal(len(n.soma.points), 0) nt.assert_equal(len(n.soma.points), 0) assert_equal(len(n.root_sections), 1) assert_array_equal(n.root_sections[0].points, np.array([[3, -4, 0], [3, -6, 0], [3, -8, 0], [3, -10, 0], [0, -10, 0], [-3, -10, 0]], dtype=np.float32)) assert_equal(len(n.root_sections[0].children), 2) assert_array_equal(n.root_sections[0].children[0].points, np.array([[-3, -10, 0], [-5, -5, 5]])) assert_array_equal(n.root_sections[0].children[1].points, np.array([[-3, -10, 0], [-6, -6, 6]]))
def test_append_no_duplicate(): m = Morphology() section = m.append_root_section( PointLevel([[1, 2, 3], [4, 5, 6]], [2, 2], [20, 20]), SectionType.axon) assert_equal(section.id, 0) with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): section.append_section( PointLevel([[400, 5, 6], [7, 8, 9]], [2, 3], [20, 30])) assert_equal( err.getvalue().strip(), 'Warning: while appending section: 1 to parent: 0\n' 'The section first point should be parent section last point: \n' ' : X Y Z Diameter\n' 'parent last point :[4.000000, 5.000000, 6.000000, 2.000000]\n' 'child first point :[400.000000, 5.000000, 6.000000, 2.000000]' )
def test_annotation(): with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): with tmp_asc_file('''((Dendrite) (3 -4 0 2) (3 -6 0 2) (3 -8 0 2) (3 -10 0 2) ( (3 -10 0 2) (0 -10 0 2) (-3 -10 0 2) | ; <-- empty sibling but still works ! ) ) ''') as tmp_file: n = Morphology(tmp_file.name) assert_equal(len(n.annotations), 1) annotation = n.annotations[0] assert_equal(annotation.type, morphio.AnnotationType.single_child)
def test_empty_sibling(): '''The empty sibling will be removed and the single child will be merged with its parent''' with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): with tmp_asc_file('''((Dendrite) (3 -4 0 10) (3 -6 0 9) (3 -8 0 8) (3 -10 0 7) ( (3 -10 0 6) (0 -10 0 5) (-3 -10 0 4) | ; <-- empty sibling but still works ! ) ) ''') as tmp_file: n = Morphology(tmp_file.name) n.remove_unifurcations() assert_substring('is the only child of section: 0', err.getvalue().strip()) assert_substring('It will be merged with the parent section', err.getvalue().strip()) assert len(n.root_sections) == 1 assert_array_equal( n.root_sections[0].points, np.array([[3, -4, 0], [3, -6, 0], [3, -8, 0], [3, -10, 0], [0, -10, 0], [-3, -10, 0]], dtype=np.float32)) assert_array_equal(n.root_sections[0].diameters, np.array([10, 9, 8, 7, 5, 4], dtype=np.float32)) assert len(n.annotations) == 1 annotation = n.annotations[0] assert annotation.type == morphio.AnnotationType.single_child assert annotation.line_number == -1 assert_array_equal(annotation.points, [[3, -10, 0], [0, -10, 0], [-3, -10, 0]]) assert_array_equal(annotation.diameters, [6, 5, 4])
def test_empty_sibling(): '''The empty sibling will be removed and the single child will be merged with its parent''' with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): with tmp_asc_file('''((Dendrite) (3 -4 0 2) (3 -6 0 2) (3 -8 0 2) (3 -10 0 2) ( (3 -10 0 2) (0 -10 0 2) (-3 -10 0 2) | ; <-- empty sibling but still works ! ) ) ''') as tmp_file: n = Morphology(tmp_file.name) assert_substring('is the only child of section: 0 starting at:', err.getvalue().strip()) assert_substring('It will be merged with the parent section', err.getvalue().strip()) assert_equal(len(n.root_sections), 1) assert_array_equal(n.root_sections[0].points, np.array([[3, -4, 0], [3, -6, 0], [3, -8, 0], [3, -10, 0], [0, -10, 0], [-3, -10, 0]], dtype=np.float32)) assert_equal(len(n.annotations), 1) annotation = n.annotations[0] assert_equal(annotation.type, morphio.AnnotationType.single_child) assert_equal(annotation.line_number, 6) assert_array_equal(annotation.points, [[3, -10, 0], [0, -10, 0], [-3, -10, 0]]) assert_array_equal(annotation.diameters, [2, 2, 2])
def test_annotation(): with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): with tmp_asc_file("""((Dendrite) (3 -4 0 2) (3 -6 0 2) (3 -8 0 2) (3 -10 0 2) ( (3 -10 0 2) (0 -10 0 2) (-3 -10 0 2) | ; <-- empty sibling but still works ! ) ) """) as tmp_file: cell = Morphology(tmp_file.name) cell.remove_unifurcations() for n in (cell, cell.as_immutable(), cell.as_immutable().as_mutable()): assert len(n.annotations) == 1 annotation = n.annotations[0] assert annotation.type == morphio.AnnotationType.single_child
def test_single_children(): with captured_output() as (_, _): with ostream_redirect(stdout=True, stderr=True): neuron = Morphology(H5V1_PATH / 'two_child_unmerged.h5') assert len(list(neuron.iter())) == 8
def test_single_children(): with captured_output() as (_, _): with ostream_redirect(stdout=True, stderr=True): neuron = Morphology( os.path.join(H5V1_PATH, 'two_child_unmerged.h5')) assert_equal(len(list(neuron.iter())), 3)
def test_soma_type(): '''The ordering of IDs is not required''' # 1 point soma with tmp_swc_file('''1 1 0 0 0 3.0 -1''') as tmp_file: assert_equal( Morphology(tmp_file.name).soma_type, SomaType.SOMA_SINGLE_POINT) # 2 point soma with tmp_swc_file('''1 1 0 0 0 3.0 -1 2 1 0 0 0 3.0 1''') as tmp_file: assert_equal( Morphology(tmp_file.name).soma_type, SomaType.SOMA_UNDEFINED) # > 3 points soma with tmp_swc_file('''1 1 0 0 0 3.0 -1 2 1 0 0 0 3.0 1 3 1 0 0 0 3.0 2 4 1 0 0 0 3.0 3 5 1 0 0 0 3.0 4''') as tmp_file: assert_equal( Morphology(tmp_file.name).soma_type, SomaType.SOMA_CYLINDERS) # 3 points soma can be of type SOMA_CYLINDERS or SOMA_NEUROMORPHO_THREE_POINT_CYLINDERS # depending on the point layout # SOMA_NEUROMORPHO_THREE_POINT_CYLINDERS are characterized by # one soma point with 2 children with tmp_swc_file('''1 1 0 0 0 3.0 -1 2 1 0 -3 0 3.0 1 3 1 0 3 0 3.0 1 # PID is 1''') as tmp_file: assert_equal( Morphology(tmp_file.name).soma_type, SomaType.SOMA_NEUROMORPHO_THREE_POINT_CYLINDERS) with captured_output() as (_, err): with ostream_redirect(stdout=True, stderr=True): with tmp_swc_file('''1 1 0 0 0 3.0 -1 2 1 1 -3 0 3.0 1 3 1 0 0 0 3.0 1 # PID is 1''') as tmp_file: assert_equal( Morphology(tmp_file.name).soma_type, SomaType.SOMA_NEUROMORPHO_THREE_POINT_CYLINDERS) assert_string_equal( '''{}:0:warning Warning: the soma does not conform the three point soma spec The only valid neuro-morpho soma is: 1 1 x y z r -1 2 1 x (y-r) z r 1 3 1 x (y+r) z r 1 Got: 1 1 0 0 0 3 -1 2 1 1.000000 (exp. 0.000000) -3.000000 0.000000 3.000000 1 3 1 0.000000 0.000000 (exp. 3.000000) 0.000000 3.000000 1''' .format(tmp_file.name), err.getvalue(), ) # If this configuration is not respected -> SOMA_CYLINDERS with tmp_swc_file('''1 1 0 0 0 3.0 -1 2 1 0 0 0 3.0 1 3 1 0 0 0 3.0 2 # PID is 2''') as tmp_file: assert_equal( Morphology(tmp_file.name).soma_type, SomaType.SOMA_CYLINDERS)