diff --git a/src/pynwb/base.py b/src/pynwb/base.py index a00414745..36c71cbb1 100644 --- a/src/pynwb/base.py +++ b/src/pynwb/base.py @@ -288,13 +288,29 @@ def __add_link(self, links_key, link): self.fields.setdefault(links_key, list()).append(link) def _generate_field_html(self, key, value, level, access_code): - def get_object_path(obj): - path = '/'.join([a.name for a in obj.get_ancestors()[::-1]]) - return f'{path}/{obj.name}' + def find_location_in_memory_nwbfile(current_location: str, neurodata_object) -> str: + """ + Method for determining the location of a neurodata object within an in-memory NWBFile object. Adapted from + neuroconv package. + """ + parent = neurodata_object.parent + if parent is None: + return neurodata_object.name + "/" + current_location + elif parent.name == 'root': + # Items in defined top-level places like acquisition, intervals, etc. do not act as 'containers' + # in that they do not set the `.parent` attribute; ask if object is in their in-memory dictionaries + # instead + for parent_field_name, parent_field_value in parent.fields.items(): + if isinstance(parent_field_value, dict) and neurodata_object.name in parent_field_value: + return parent_field_name + "/" + neurodata_object.name + "/" + current_location + return neurodata_object.name + "/" + current_location + return find_location_in_memory_nwbfile( + current_location=neurodata_object.name + "/" + current_location, neurodata_object=parent + ) # reassign value if linked timestamp or linked data to avoid recursion error if key in ['timestamps', 'data'] and isinstance(value, TimeSeries): - path_to_linked_object = get_object_path(value) + path_to_linked_object = find_location_in_memory_nwbfile(key, value) if key == 'timestamps': value = value.timestamps elif key == 'data': @@ -302,7 +318,8 @@ def get_object_path(obj): key = f'{key} (link to {path_to_linked_object})' if key in ['timestamp_link', 'data_link']: - value = [get_object_path(v) for v in value] + linked_key = 'timestamps' if key == 'timestamp_link' else 'data' + value = [find_location_in_memory_nwbfile(linked_key, v) for v in value] return super()._generate_field_html(key, value, level, access_code) diff --git a/tests/unit/test_base.py b/tests/unit/test_base.py index d8e152fa4..3bc0bc6e3 100644 --- a/tests/unit/test_base.py +++ b/tests/unit/test_base.py @@ -465,71 +465,15 @@ def test_file_with_starting_time_and_timestamps_in_construct_mode(self): ) def test_repr_html(self): - """ Test that html representation of linked timestamp data will occur as expected and will not cause a Recursion - Error + """ Test that html representation of linked timestamp data will occur as expected and will not cause a + RecursionError """ data1 = [0, 1, 2, 3] data2 = [4, 5, 6, 7] timestamps = [0.0, 0.1, 0.2, 0.3] ts1 = TimeSeries(name="test_ts1", data=data1, unit="grams", timestamps=timestamps) ts2 = TimeSeries(name="test_ts2", data=data2, unit="grams", timestamps=ts1) - expected_output = ('\n \n \n \n