def get_pipeline_version(self): """ Returns the AI pipeline version number, stored in the metadata field 'generated_by'. If that field is missing, version 0.0 is returned. Borrowed from the AllenSDK Returns ------- int tuple: (major, minor) """ try: with h5py.File(self.nwb_file, 'r') as f: if 'generated_by' in f["general"]: info = f["general/generated_by"] # generated_by stores array of keys and values # keys are even numbered, corresponding values are in # odd indices for i in range(len(info)): if to_str(info[i]) == 'version': version = to_str(info[i+1]) break toks = version.split('.') if len(toks) >= 2: major = int(toks[0]) minor = int(toks[1]) except: # noqa: E722 minor = 0 major = 0 return major, minor
def get_unit_name(stim_attrs): if 'unit' in stim_attrs: unit = to_str(stim_attrs["unit"]) elif 'units' in stim_attrs: unit = to_str(stim_attrs["units"]) else: unit = None return unit
def get_value(self, name, sweep_num, default_val): """ looks for key in lab notebook and returns the value associated with the specified sweep, or the default value if no value is found (NaN and empty strings are considered to be non-values) name_number has 3 dimensions -- the first has shape (#fields * 9) and stores the key names. the second looks to store units for those keys. The third is numeric text but it's role isn't clear val_number has 3 dimensions -- the first has a shape of (#fields * 9). there are many hundreds of elements in this dimension. they look to represent the full array of values (for each field for each multipatch) for a given point in time, and thus given sweep Parameters ---------- name: str sweep_num: int default_val: dict Returns ------- values obtained from lab notebook """ numeric_fields = [to_str(c) for c in self.colname_number[0]] text_fields = [to_str(c) for c in self.colname_text[0]] if name in numeric_fields: sweep_idx = numeric_fields.index("SweepNum") enable_idx = None if name in self.enabled: enable_col = self.enabled[name] enable_idx = numeric_fields.index(enable_col) field_idx = numeric_fields.index(name) return self.get_numeric_value(name, field_idx, sweep_idx, enable_idx, sweep_num, default_val) elif name in text_fields: if "Sweep #" in text_fields: sweep_idx = text_fields.index("Sweep #") else: sweep_idx = text_fields.index("SweepNum") enable_idx = None if name in self.enabled: enable_col = self.enabled[name] enable_idx = text_fields.index(enable_col) field_idx = text_fields.index(name) return self.get_text_value(name, field_idx, sweep_idx, enable_idx, sweep_num, default_val) else: return default_val
def get_clamp_mode(self, sweep_num): attrs = self.nwb_data.get_sweep_attrs(sweep_num) try: ancestry = attrs["ancestry"] time_series_type = to_str(ancestry[-1]) if "CurrentClamp" in time_series_type: clamp_mode = self.CURRENT_CLAMP elif "VoltageClamp" in time_series_type: clamp_mode = self.VOLTAGE_CLAMP else: raise Exception( "Unable to determine clamp mode in {}".format(sweep_num)) return clamp_mode except: logging.debug("Error in reading stim from ancestry") try: if "CurrentClamp" in attrs['neurodata_type']: clamp_mode = self.CURRENT_CLAMP elif "VoltageClamp" in attrs['neurodata_type']: clamp_mode = self.VOLTAGE_CLAMP except: logging.debug("Error in reading stim from neurodata") return clamp_mode
def _select(cursor, query, parameters=None): if parameters is None: cursor.execute(query) else: pg8000.paramstyle = 'numeric' cursor.execute(query, parameters) columns = [to_str(d[0]) for d in cursor.description] return [dict(zip(columns, c)) for c in cursor.fetchall()]
def get_stimulus_code(self, sweep_num): stim_code = self._nwb_data.get_stim_code(sweep_num) if not stim_code: stim_code = self.notebook.get_value("Stim Wave Name", sweep_num, "") logging.debug("Reading stim_code from Labnotebook") if len(stim_code) == 0: raise Exception( "Could not read stimulus wave name from lab notebook") return to_str(stim_code)
def get_clamp_mode(self, sweep_num): attrs = self._nwb_data.get_sweep_attrs(sweep_num) ancestry = attrs["ancestry"] time_series_type = to_str(ancestry[-1]) if "CurrentClamp" in time_series_type: clamp_mode = self.CURRENT_CLAMP elif "VoltageClamp" in time_series_type: clamp_mode = self.VOLTAGE_CLAMP else: raise Exception("Unable to determine clamp mode in {}".format(sweep_num)) return clamp_mode
def get_value(self, name, sweep_num, default_val): # name_number has 3 dimensions -- the first has shape # (#fields * 9) and stores the key names. the second looks # to store units for those keys. The third is numeric text # but it's role isn't clear numeric_fields = [to_str(c) for c in self.colname_number[0]] text_fields = [to_str(c) for c in self.colname_text[0]] # val_number has 3 dimensions -- the first has a shape of # (#fields * 9). there are many hundreds of elements in this # dimension. they look to represent the full array of values # (for each field for each multipatch) for a given point in # time, and thus given sweep if name in numeric_fields: sweep_idx = numeric_fields.index("SweepNum") enable_idx = None if name in self.enabled: enable_col = self.enabled[name] enable_idx = numeric_fields.index(enable_col) field_idx = numeric_fields.index(name) return self.get_numeric_value(name, field_idx, sweep_idx, enable_idx, sweep_num, default_val) elif name in text_fields: # first check to see if file includes old version of column name if "Sweep #" in text_fields: sweep_idx = text_fields.index("Sweep #") else: sweep_idx = text_fields.index("SweepNum") enable_idx = None if name in self.enabled: enable_col = self.enabled[name] enable_idx = text_fields.index(enable_col) field_idx = text_fields.index(name) return self.get_text_value(name, field_idx, sweep_idx, enable_idx, sweep_num, default_val) else: return default_val
def get_stimulus_units(self, sweep_num): attrs = self.nwb_data.get_sweep_attrs(sweep_num) ancestry = attrs["ancestry"] # stim units are based on timeseries type time_series_type = to_str(ancestry[-1]) if "CurrentClamp" in time_series_type: units = 'pA' elif "VoltageClamp" in time_series_type: units = 'mV' else: raise Exception( "Unable to determine clamp mode in {}".format(sweep_num)) return units
def get_nwb_version(nwb_file): """ Return a dict with `major` and `full` NWB version as read from the NWB file. """ with h5py.File(nwb_file, 'r') as f: if "nwb_version" in f: # In version 0 and 1 this is a dataset nwb_version = get_scalar_value(f["nwb_version"][()]) nwb_version_str = to_str(nwb_version) if nwb_version is not None and re.match("^NWB-", nwb_version_str): return {"major": int(nwb_version_str[4]), "full": nwb_version_str} elif "nwb_version" in f.attrs: # but in version 2 this is an attribute nwb_version = f.attrs["nwb_version"] if nwb_version is not None and re.match("^2", nwb_version): return {"major": 2, "full": nwb_version} return {"major": None, "full": None}
def get_nwb_version(nwb_file: str) -> Dict[str, Any]: """ Find version of the nwb file Parameters ---------- nwb_file Returns ------- dict in the format: { `major`: str `full` str. } """ with h5py.File(nwb_file, 'r') as f: if "nwb_version" in f: # In version 0 and 1 this is a dataset nwb_version = get_scalar_value(f["nwb_version"][()]) nwb_version_str = py2to3.to_str(nwb_version) if nwb_version is not None and re.match("^NWB-", nwb_version_str): return { "major": int(nwb_version_str[4]), "full": nwb_version_str } elif "nwb_version" in f.attrs: # in version 2 this is an attribute nwb_version = f.attrs["nwb_version"] if nwb_version is not None and (re.match("^2", nwb_version) or re.match("^NWB-2", nwb_version)): return {"major": 2, "full": nwb_version} return {"major": None, "full": None}