Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved conditions for closing nwb when using hdf5 backend #3150

Merged
merged 2 commits into from
Jul 8, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions src/spikeinterface/extractors/nwbextractors.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,13 +626,29 @@ def __init__(
"file": file,
}

def _close_hdf5_file(self):
has_hdf5_backend = hasattr(self, "_file")
if has_hdf5_backend:
import h5py

main_file_id = self._file.id
open_object_ids_main = h5py.h5f.get_obj_ids(main_file_id, types=h5py.h5f.OBJ_ALL)
for object_id in open_object_ids_main:
object_name = h5py.h5i.get_name(object_id).decode("utf-8")
try:
object_id.close()
except:
import warnings

warnings.warn(f"Error closing object {object_name}")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this is the same function as the Sorting object, why not making a separate unique function?

def _close_hdf5_file(extraxctor):
    has_hdf5_backend = hasattr(extraxctor, "_file")
    ....

then you would just call it in the __del__ with _close_hdf5_file(self)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right that this repetition is unecessary but I wanted to use self, check out the latest commit. I implemented a mixing class that should hold the methods that need the state of the nwb extractor and are common to both recording and sorting.


def __del__(self):
# backend mode
if hasattr(self, "_file"):
if hasattr(self._file, "store"):
self._file.store.close()
else:
self._file.close()
self._close_hdf5_file()
# pynwb mode
elif hasattr(self, "_nwbfile"):
io = self._nwbfile.get_read_io()
Expand Down Expand Up @@ -1111,19 +1127,41 @@ def __init__(
"t_start": self.t_start,
}

def _close_hdf5_file(self):
has_hdf5_backend = hasattr(self, "_file")
if has_hdf5_backend:
import h5py

main_file_id = self._file.id
open_object_ids_main = h5py.h5f.get_obj_ids(main_file_id, types=h5py.h5f.OBJ_ALL)
for object_id in open_object_ids_main:
object_name = h5py.h5i.get_name(object_id).decode("utf-8")
try:
object_id.close()
except:
import warnings

warnings.warn(f"Error closing object {object_name}")

def __del__(self):
# backend mode
if hasattr(self, "_file"):
if hasattr(self._file, "store"):
self._file.store.close()
else:
self._file.close()
self._close_hdf5_file()
# pynwb mode
elif hasattr(self, "_nwbfile"):
io = self._nwbfile.get_read_io()
if io is not None:
io.close()

# pynwb mode
elif hasattr(self, "_nwbfile"): # hdf
io = self._nwbfile.get_read_io()
if io is not None:
io.close()

def _fetch_sorting_segment_info_pynwb(
self, unit_table_path: str = None, samples_for_rate_estimation: int = 1000, cache: bool = False
):
Expand Down