From 932d7e3076cd592b1d3e4ac6e0da5b4aee84d2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaquier=20Aur=C3=A9lien=20Tristan?= Date: Thu, 21 Mar 2024 10:57:21 +0100 Subject: [PATCH 1/5] select nwb traces according to v_file field --- bluepyefe/cell.py | 3 ++- bluepyefe/nwbreader.py | 30 +++++++++++++++++++++++++++--- bluepyefe/reader.py | 7 ++++++- 3 files changed, 35 insertions(+), 5 deletions(-) diff --git a/bluepyefe/cell.py b/bluepyefe/cell.py index b2eae03..2ce2464 100644 --- a/bluepyefe/cell.py +++ b/bluepyefe/cell.py @@ -62,7 +62,8 @@ def reader(self, config_data, recording_reader=None): if "v_file" in config_data: filename = config_data["v_file"] - elif "filepath" in config_data: + # if both present: use filepath. e.g. for some nwb that 'contain' igor files + if "filepath" in config_data: filename = config_data["filepath"] if recording_reader: diff --git a/bluepyefe/nwbreader.py b/bluepyefe/nwbreader.py index 6069d81..731eb86 100644 --- a/bluepyefe/nwbreader.py +++ b/bluepyefe/nwbreader.py @@ -5,18 +5,20 @@ class NWBReader: - def __init__(self, content, target_protocols, repetition=None): + def __init__(self, content, target_protocols, repetition=None, v_file=None): """ Init Args: content (h5.File): NWB file target_protocols (list of str): list of the protocols to be read and returned repetition (list of int): id of the repetition(s) to be read and returned + v_file (str): name of original file that can be retrieved in sweep's description """ self.content = content self.target_protocols = target_protocols self.repetition = repetition + self.v_file = v_file def read(self): """ Read the content of the NWB file @@ -162,8 +164,21 @@ def read(self): for ecode in self.target_protocols: for cell_id in self.content["data_organization"].keys(): if ecode not in self.content["data_organization"][cell_id]: - logger.debug(f"No eCode {ecode} in nwb.") - continue + new_ecode = next( + iter( + ec + for ec in self.content["data_organization"][cell_id] + if ec.lower() == ecode.lower() + ) + ) + if new_ecode: + logger.debug( + f"Could not find {ecode} in nwb file, will use {new_ecode} instead" + ) + ecode = new_ecode + else: + logger.debug(f"No eCode {ecode} in nwb.") + continue ecode_content = self.content["data_organization"][cell_id][ecode] @@ -185,11 +200,20 @@ def read(self): logger.debug(f"Ignoring {key_current} not" " present in the stimulus presentation") continue + if trace_name not in self.content["acquisition"]: logger.debug(f"Ignoring {trace_name} not" " present in the acquisition") continue + # if we have v_file, check that trace comes from this original file + if self.v_file is not None: + attrs = self.content["acquisition"][trace_name].attrs + v_file_end = "/" + "/".join(self.v_file.split("/")[-2:]) + if v_file_end != attrs.get("description", ""): + logger.debug(f"Ignoring {trace_name} not matching v_file") + continue + data.append(self._format_nwb_trace( voltage=self.content["acquisition"][trace_name]["data"], current=self.content["stimulus"]["presentation"][key_current][ diff --git a/bluepyefe/reader.py b/bluepyefe/reader.py index 44c8524..2c34234 100644 --- a/bluepyefe/reader.py +++ b/bluepyefe/reader.py @@ -191,7 +191,12 @@ def nwb_reader(in_data): with h5py.File(in_data["filepath"], "r") as content: if "data_organization" in content: - reader = BBPNWBReader(content, target_protocols, in_data.get("repetition", None)) + reader = BBPNWBReader( + content, + target_protocols, + in_data.get("repetition", None), + in_data.get("v_file", None) + ) elif "timeseries" in content["acquisition"].keys(): reader = AIBSNWBReader(content, target_protocols) else: From e314c2b7ab1590b61066049074c0151fffb5a88b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaquier=20Aur=C3=A9lien=20Tristan?= Date: Thu, 21 Mar 2024 11:20:08 +0100 Subject: [PATCH 2/5] use file name in description, not file path --- bluepyefe/nwbreader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bluepyefe/nwbreader.py b/bluepyefe/nwbreader.py index 731eb86..c332a46 100644 --- a/bluepyefe/nwbreader.py +++ b/bluepyefe/nwbreader.py @@ -209,8 +209,8 @@ def read(self): # if we have v_file, check that trace comes from this original file if self.v_file is not None: attrs = self.content["acquisition"][trace_name].attrs - v_file_end = "/" + "/".join(self.v_file.split("/")[-2:]) - if v_file_end != attrs.get("description", ""): + v_file_end = self.v_file.split("/")[-1] + if v_file_end != attrs.get("description", "").split("/")[-1]: logger.debug(f"Ignoring {trace_name} not matching v_file") continue From f37d9b64ba3ed62b09dc118d04a27d8090f5d398 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaquier=20Aur=C3=A9lien=20Tristan?= Date: Thu, 21 Mar 2024 11:33:53 +0100 Subject: [PATCH 3/5] adding warning if we can not find any description --- bluepyefe/nwbreader.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/bluepyefe/nwbreader.py b/bluepyefe/nwbreader.py index c332a46..86c0101 100644 --- a/bluepyefe/nwbreader.py +++ b/bluepyefe/nwbreader.py @@ -209,6 +209,12 @@ def read(self): # if we have v_file, check that trace comes from this original file if self.v_file is not None: attrs = self.content["acquisition"][trace_name].attrs + if not "description" in attrs: + logger.warning( + "Ignoring %s because no description could be found.", + trace_name + ) + continue v_file_end = self.v_file.split("/")[-1] if v_file_end != attrs.get("description", "").split("/")[-1]: logger.debug(f"Ignoring {trace_name} not matching v_file") From 7f9e3a44489bbd8f691f44f4aade5259faff4276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaquier=20Aur=C3=A9lien=20Tristan?= Date: Thu, 21 Mar 2024 11:42:49 +0100 Subject: [PATCH 4/5] check protocol name in a case-insensitive way --- bluepyefe/nwbreader.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bluepyefe/nwbreader.py b/bluepyefe/nwbreader.py index 86c0101..da192ae 100644 --- a/bluepyefe/nwbreader.py +++ b/bluepyefe/nwbreader.py @@ -86,7 +86,10 @@ def read(self): if not isinstance(protocol_name, str): protocol_name = protocol_name.decode('UTF-8') - if self.target_protocols and protocol_name not in self.target_protocols: + if ( + self.target_protocols and + protocol_name.lower() not in [prot.lower() for prot in self.target_protocols] + ): continue data.append(self._format_nwb_trace( @@ -113,7 +116,10 @@ def read(self): key_current = sweep.replace('Series', 'StimulusSeries') protocol_name = "Step" - if self.target_protocols and protocol_name not in self.target_protocols: + if ( + self.target_protocols and + protocol_name.lower() not in [prot.lower() for prot in self.target_protocols] + ): continue if key_current not in self.content['stimulus']['presentation']: From c740a44e782f5bcfcc83be39d496bb010236a0c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaquier=20Aur=C3=A9lien=20Tristan?= Date: Thu, 21 Mar 2024 11:45:20 +0100 Subject: [PATCH 5/5] lint fix --- bluepyefe/nwbreader.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bluepyefe/nwbreader.py b/bluepyefe/nwbreader.py index da192ae..51d4361 100644 --- a/bluepyefe/nwbreader.py +++ b/bluepyefe/nwbreader.py @@ -215,7 +215,7 @@ def read(self): # if we have v_file, check that trace comes from this original file if self.v_file is not None: attrs = self.content["acquisition"][trace_name].attrs - if not "description" in attrs: + if "description" not in attrs: logger.warning( "Ignoring %s because no description could be found.", trace_name