def ignored_warning(warning): '''Context manager during which a warning is ignored''' try: set_ignored_warning(warning, True) yield finally: set_ignored_warning(warning, False)
def repair( inputfile: Path, # pylint: disable=too-many-arguments outputfile: Path, axons: Optional[List[Path]] = None, seed: int = 0, cut_leaves_coordinates: Optional[NDArray[(3, Any)]] = None, legacy_detection: bool = False, plot_file: Optional[Path] = None, repair_flags: Optional[Dict[RepairType, bool]] = None, apical_point: List = None, params: Dict = None): '''The repair function Args: inputfile: the input morph outputfile: the output morph axons: the axons seed: the numpy seed cut_leaves_coordinates: List of 3D coordinates from which to start the repair plot_file: the filename of the plot repair_flags: a dict of flags where key is a RepairType and value is whether it should be repaired or not. If not provided, all types will be repaired. apical_point: 3d vector for apical point, else, the automatic apical detection is used params: repair internal parameters, None will use defaults ''' ignored_warnings = ( # We append the section at the wrong place and then we reposition them # afterwards so we can ignore the warning morphio.Warning.wrong_duplicate, # the repair process creates new sections that may not have siblings morphio.Warning.only_child, # We are appending empty section and filling them later on morphio.Warning.appending_empty_section, ) for warning in ignored_warnings: morphio.set_ignored_warning(warning, True) if axons is None: axons = list() if params is None: params = _PARAMS obj = Repair(inputfile, axons=axons, seed=seed, cut_leaves_coordinates=cut_leaves_coordinates, legacy_detection=legacy_detection, repair_flags=repair_flags, apical_point=apical_point, params=params) obj.run(outputfile, plot_file=plot_file) for warning in ignored_warnings: morphio.set_ignored_warning(warning, False)
def repair(inputfile: Path, outputfile: Path, axons: Optional[Path] = None, seed: int = 0, cut_leaves_coordinates: Optional[NDArray[(3, Any)]] = None, legacy_detection: bool = False, plot_file: Optional[Path] = None, repair_flags: Optional[Dict[RepairType, bool]] = None): '''The repair function Args: inputfile: the input morph outputfile: the output morph axons: the axons seed: the numpy seed cut_leaves_coordinates: List of 3D coordinates from which to start the repair plot_file: the filename of the plot repair_flags: a dict of flags where key is a RepairType and value is whether it should be repaired or not. If not provided, all types will be repaired. ''' ignored_warnings = ( # We append the section at the wrong place and then we reposition them # afterwards so we can ignore the warning morphio.Warning.wrong_duplicate, # the repair process creates new sections that may not have siblings morphio.Warning.only_child, # We are appending empty section and filling them later on morphio.Warning.appending_empty_section) for warning in ignored_warnings: morphio.set_ignored_warning(warning, True) if axons is None: axons = list() obj = Repair(inputfile, axons=axons, seed=seed, cut_leaves_coordinates=cut_leaves_coordinates, legacy_detection=legacy_detection, repair_flags=repair_flags) obj.run(outputfile, plot_file=plot_file) for warning in ignored_warnings: morphio.set_ignored_warning(warning, False)
def __init__(self, filename, name=None): """Neuron constructor. Args: filename (str|Path): a filename name (str): a option neuron name """ try: morphio.set_ignored_warning([ morphio.Warning.wrong_root_point, morphio.Warning.no_soma_found, morphio.Warning.zero_diameter ], True) morphio.set_raise_warnings(True) super().__init__(filename) finally: morphio.set_raise_warnings(False) self.name = name if name else 'Neuron' self.morphio_soma = super().soma self.neurom_soma = make_soma(self.morphio_soma)
def test_equality(): set_ignored_warning([Warning.wrong_duplicate, Warning.only_child], True) filename = joinp(DATA, 'simple2.asc') neuron_ref = Morphology(filename) ok_(not diff(neuron_ref, neuron_ref)) ok_(not diff(neuron_ref, filename)) ok_(not diff(neuron_ref, neuron_ref.as_immutable())) def mundane_section(neuron): '''Not a root section, not a leaf section''' return neuron.root_sections[0].children[0] a = Morphology(joinp(DATA, 'simple2.asc')) mundane_section(a).type = SectionType.apical_dendrite result = diff(neuron_ref, a) ok_(result) assert_equal(result.info, 'Section(id=1, points=[(0 5 0),..., (-6 5 0)]) and Section(id=1, points=[(0 5 0),..., (-6 5 0)]) have different section types') a = Morphology(joinp(DATA, 'simple2.asc')) mundane_section(a).points = [[0,0,0], [0,0,0], [0,0,1]] result = diff(neuron_ref, a) ok_(result) assert_equal(result.info, '\n'.join(['Attributes Section.points of:', 'Section(id=1, points=[(0 5 0),..., (-6 5 0)])', 'Section(id=1, points=[(0 0 0),..., (0 0 1)])', 'have the same shape but different values'])) a = Morphology(joinp(DATA, 'simple2.asc')) mundane_section(a).diameters = [0,0,0] result = diff(neuron_ref, a) ok_(result) assert_equal(result.info, '\n'.join(['Attributes Section.diameters of:', 'Section(id=1, points=[(0 5 0),..., (-6 5 0)])', 'Section(id=1, points=[(0 5 0),..., (-6 5 0)])', 'have the same shape but different values'])) a = Morphology(joinp(DATA, 'simple2.asc')) for section in a.iter(): section.perimeters = [1] * len(section.points) result = diff(neuron_ref, a) ok_(result) assert_equal(result.info, '\n'.join(['Attributes Section.perimeters of:', 'Section(id=0, points=[(0 0 0),..., (0 5 0)])', 'Section(id=0, points=[(0 0 0),..., (0 5 0)])', 'have different shapes: (0,) vs (2,)'])) a = Morphology(joinp(DATA, 'simple2.asc')) mundane_section(a).append_section(PointLevel([[-6, 5, 0], [4, 5, 6]], [2, 3])) result = diff(neuron_ref, a) ok_(result) assert_equal(result.info, 'Section(id=1, points=[(0 5 0),..., (-6 5 0)]) and Section(id=1, points=[(0 5 0),..., (-6 5 0)]) have different a different number of children') a = Morphology(joinp(DATA, 'simple2.asc')) a.delete_section(a.root_sections[0]) result = diff(neuron_ref, a) ok_(result) assert_equal(result.info, 'Both morphologies have different a different number of root sections') result = diff(joinp(DATA, 'single_child.asc'), joinp(DATA, 'not_single_child.asc')) ok_(not result) set_ignored_warning([Warning.wrong_duplicate, Warning.only_child], False)
def repair(morphology, section, intact_sections, axon_branches, used_axon_branches, y_extent): '''Axonal repair Reimplementation of: https://bbpcode.epfl.ch/browse/code/platform/BlueRepairSDK/tree/BlueRepairSDK/src/repair.cpp#n727 1) Find the most similar section in INTACT_SECTIONS list to SECTION 2) Sort AXON_BRANCHES according to a similarity score to the section found at step 1 3) Loop through the sorted AXON_BRANCHES to find a section with same strahler orders and that, when appended, does not extend further than Y_EXTENT 4) Append the first section that meets the conditions of step 3) 5) Mark this section as used and do not re-use it Args: morphology (neurom.Neuron): the morphology to repair section (neurom.core._neuron.Section): the section to repair intact_sections (List[Section]): a list of all sections from this morphology that are part of an intact subtree. Note: these section won't be grafted axon_branches (List[Section]): a list a intact sections coming from donor morphologies These are the sections that will be appended ..note:: The original code used to have more parameters. In the context of the bbp-morphology-workflow it seems that some of the parameters were always used with the same value. This reimplementation assumes the following BlueRepairSDK options: - --overlap=true - --incremental=false - --restrict=true - --distmethod=mirror' ''' if not intact_sections: L.debug("No intact axon found. Not repairing!") return similar = _similar_section(intact_sections, section) branch_pool = _sort_intact_sections_by_score(section, similar, axon_branches) strahler_orders = { intact_section: strahler_order(intact_section) for intact_section in intact_sections + branch_pool } L.debug('Branch pool count: %s', len(branch_pool)) for branch in branch_pool: if (branch in used_axon_branches or strahler_orders[similar] != strahler_orders[branch]): continue L.debug("Pasting axon branch with ID %s", branch.id) end_point = section.points[-1, COLS.XYZ] appended = section.append_section(branch) translation = section.points[-1, COLS.XYZ] - appended.points[0, COLS.XYZ] align(appended, translation) translate(appended, translation) # Make sure the child section first point is exactly the end point of the parent section appended_points = np.copy(appended.points) appended_points[0] = end_point appended.points = appended_points if any( np.any(section.points[:, COLS.Y] > y_extent) for section in appended.iter()): L.debug("Discarded, exceeds y-limit") morphology.delete_section(appended) else: L.debug('Section appended') used_axon_branches.add(branch) return morphio.set_ignored_warning(morphio.Warning.wrong_duplicate, False)
def test_equality(): set_ignored_warning([Warning.wrong_duplicate, Warning.only_child], True) filename = DATA / 'simple2.asc' neuron_ref = Morphology(filename) assert not diff(neuron_ref, neuron_ref) assert not diff(neuron_ref, filename) assert not diff(neuron_ref, neuron_ref.as_immutable()) def mundane_section(neuron): '''Not a root section, not a leaf section''' return neuron.root_sections[0].children[0] a = Morphology(DATA / 'simple2.asc') mundane_section(a).type = SectionType.apical_dendrite result = diff(neuron_ref, a) assert result assert result.info == 'Section(id=1, points=[(0 5 0),..., (-6 5 0)]) and Section(id=1, points=[(0 5 0),..., (-6 5 0)]) have different section types' a = Morphology(DATA / 'simple2.asc') mundane_section(a).points = [[0,0,0], [0,0,0], [0,0,1]] result = diff(neuron_ref, a) assert result assert (result.info == '\n'.join(['Attributes Section.points of:', 'Section(id=1, points=[(0 5 0),..., (-6 5 0)])', 'Section(id=1, points=[(0 0 0),..., (0 0 1)])', 'have the same shape but different values', 'Vector points differs at index 0: [0. 5. 0.] != [0. 0. 0.]'])) a = Morphology(DATA / 'simple2.asc') mundane_section(a).diameters = [0,0,0] result = diff(neuron_ref, a) assert result assert (result.info == '\n'.join(['Attributes Section.diameters of:', 'Section(id=1, points=[(0 5 0),..., (-6 5 0)])', 'Section(id=1, points=[(0 5 0),..., (-6 5 0)])', 'have the same shape but different values', 'Vector diameters differs at index 0: 3.0 != 0.0'])) a = Morphology(DATA / 'simple2.asc') for section in a.iter(): section.perimeters = [1] * len(section.points) result = diff(neuron_ref, a) assert result assert (result.info == '\n'.join(['Attributes Section.perimeters of:', 'Section(id=0, points=[(0 0 0),..., (0 5 0)])', 'Section(id=0, points=[(0 0 0),..., (0 5 0)])', 'have different shapes: (0,) vs (2,)'])) a = Morphology(DATA / 'simple2.asc') mundane_section(a).append_section(PointLevel([[-6, 5, 0], [4, 5, 6]], [2, 3])) result = diff(neuron_ref, a) assert result assert result.info == 'Section(id=1, points=[(0 5 0),..., (-6 5 0)]) and Section(id=1, points=[(0 5 0),..., (-6 5 0)]) have a different number of children' a = Morphology(DATA / 'simple2.asc') a.delete_section(a.root_sections[0]) result = diff(neuron_ref, a) assert result assert result.info == 'Both morphologies have a different number of root sections' result = diff(DATA / 'single_child.asc', DATA / 'not_single_child.asc') if parse_version(get_distribution("morphio").version) < parse_version("3"): assert not result else: assert result set_ignored_warning([Warning.wrong_duplicate, Warning.only_child], False)