def _get_ephys_constructor(obj, **kwargs): """Return the class, argument, and kwargs to create an Ephys instance from any compatible Python object.""" if 'n_channels_dat' in kwargs: # pragma: no cover kwargs['n_channels'] = kwargs.pop('n_channels_dat') if isinstance(obj, mtscomp.Reader): return (MtscompEphysReader, obj, kwargs) elif isinstance(obj, (str, Path)): path = Path(obj) if not path.exists(): # pragma: no cover logger.warning("File %s does not exist.", path) return None, None, {} assert path.exists() ext = path.suffix # Mtscomp file if ext == '.cbin': reader = mtscomp.Reader(n_threads=mp.cpu_count() // 2) reader.open(path) return (MtscompEphysReader, reader, kwargs) # Flat binary file elif ext in EPHYS_RAW_EXTENSIONS: return (FlatEphysReader, path, kwargs) elif ext == '.npy': return (NpyEphysReader, obj, kwargs) # TODO: other standard binary formats else: # pragma: no cover raise IOError("Unknown file extension: %s.", ext) elif isinstance(obj, (tuple, list)): if obj: # Concatenate the main argument to the constructor. klass, arg, kwargs = _get_ephys_constructor(obj[0], **kwargs) arg = [_get_ephys_constructor(o)[1] for o in obj] return (klass, arg, kwargs) else: return (ArrayEphysReader, obj, kwargs)
def __init__(self, sglx_file): self.file_bin = Path(sglx_file) self.nbytes = self.file_bin.stat().st_size file_meta_data = Path(sglx_file).with_suffix('.meta') if not file_meta_data.exists(): self.file_meta_data = None self.meta = None self.channel_conversion_sample2v = 1 _logger.warning(str(sglx_file) + " : no metadata file found. Very limited support") return # normal case we continue reading and interpreting the metadata file self.file_meta_data = file_meta_data self.meta = read_meta_data(file_meta_data) self.channel_conversion_sample2v = _conversion_sample2v_from_meta(self.meta) # if we are not looking at a compressed file, use a memmap, otherwise instantiate mtscomp if self.is_mtscomp: self._raw = mtscomp.Reader() self._raw.open(self.file_bin, self.file_bin.with_suffix('.ch')) else: if self.nc * self.ns * 2 != self.nbytes: ftsec = self.file_bin.stat().st_size / 2 / self.nc / self.fs _logger.warning(f"{sglx_file} : meta data and filesize do not checkout\n" f"File size: expected {self.meta['fileSizeBytes']}," f" actual {self.file_bin.stat().st_size}\n" f"File duration: expected {self.meta['fileTimeSecs']}," f" actual {ftsec}\n" f"Will attempt to fudge the meta-data information.") self.meta['fileTimeSecs'] = ftsec self._raw = np.memmap(sglx_file, dtype='int16', mode='r', shape=(self.ns, self.nc))
def __init__(self, sglx_file): self.file_bin = Path(sglx_file) self.nbytes = self.file_bin.stat().st_size file_meta_data = Path(sglx_file).with_suffix('.meta') if not file_meta_data.exists(): self.file_meta_data = None self.meta = None self.channel_conversion_sample2v = 1 _logger.warning( str(sglx_file) + " : no metadata file found. Very limited support") return # normal case we continue reading and interpreting the metadata file self.file_meta_data = file_meta_data self.meta = read_meta_data(file_meta_data) self.channel_conversion_sample2v = _conversion_sample2v_from_meta( self.meta) # if we are not looking at a compressed file, use a memmap, otherwise instantiate mtscomp if self.is_mtscomp: self.data = mtscomp.Reader() self.data.open(self.file_bin, self.file_bin.with_suffix('.ch')) else: if self.nc * self.ns * 2 != self.nbytes: _logger.warning( str(sglx_file) + " : meta data and filesize do not checkout") self.data = np.memmap(sglx_file, dtype='int16', mode='r', shape=(self.ns, self.nc))
def __init__(self, file_path: str, x_pitch: int = 32, y_pitch: int = 20): RecordingExtractor.__init__(self) self._npxfile = Path(file_path) self._basepath = self._npxfile.parents[0] # Gets file type: 'imec0.ap', 'imec0.lf' or 'nidq' assert re.search(r'imec[0-9]*.(ap|lf){1}.bin$', self._npxfile.name) or 'nidq' in self._npxfile.name, \ "'file_path' can be an imec.ap, imec.lf, imec0.ap, imec0.lf, or nidq file" if 'ap.bin' in str(self._npxfile): rec_type = "ap" self.is_filtered = True elif 'lf.bin' in str(self._npxfile): rec_type = "lf" else: rec_type = "nidq" aux = self._npxfile.stem.split('.')[-1] if aux == 'nidq': self._ftype = aux else: self._ftype = self._npxfile.stem.split('.')[-2] + '.' + aux # Metafile self._metafile = self._basepath.joinpath(self._npxfile.stem + '.meta') if not self._metafile.exists(): raise Exception("'meta' file for '" + self._ftype + "' traces should be in the same folder.") # Read in metadata, returns a dictionary meta = readMeta(self._npxfile) self._meta = meta # Traces in 16-bit format if '.cbin' in self._npxfile.name: # compressed binary format used by IBL try: import mtscomp except: raise Exception(self.installation_mesg) self._raw = mtscomp.Reader() self._raw.open(self._npxfile, self._npxfile.with_suffix('.ch')) else: self._raw = makeMemMapRaw(self._npxfile, meta) # [chanList, firstSamp:lastSamp+1] # sampling rate and ap channels self._sampling_frequency = SampRate(meta) tot_chan, ap_chan, lfp_chan, locations, channel_ids, channel_names \ = _parse_spikeglx_metafile(self._metafile, x_pitch=x_pitch, y_pitch=y_pitch, rec_type=rec_type) if rec_type in ("ap", "lf"): self._channels = channel_ids # locations if len(locations) > 0: self.set_channel_locations(locations) if len(channel_names) > 0: if len(channel_names) == len(self._channels): for i, ch in enumerate(self._channels): self.set_channel_property(ch, "channel_name", channel_names[i]) if rec_type == "ap": if ap_chan < tot_chan: self._timeseries = self._raw[0:ap_chan, :] elif rec_type == "lf": if lfp_chan < tot_chan: self._timeseries = self._raw[0:lfp_chan, :] else: # nidq self._channels = list(range(int(tot_chan))) self._timeseries = self._raw # get gains if meta['typeThis'] == 'imec': gains = GainCorrectIM(self._timeseries, self._channels, meta) elif meta['typeThis'] == 'nidq': gains = GainCorrectNI(self._timeseries, self._channels, meta) # set gains - convert from int16 to uVolt self.set_channel_gains(gains=gains * 1e6, channel_ids=self._channels) self._kwargs = { 'file_path': str(Path(file_path).absolute()), 'x_pitch': x_pitch, 'y_pitch': y_pitch }
def __init__(self, file_path: str, dtype: str = 'int16'): RecordingExtractor.__init__(self) self._npxfile = Path(file_path) self._basepath = self._npxfile.parents[0] assert dtype in ['int16', 'float'], "'dtype' can be either 'int16' or 'float'" self._dtype = dtype # Gets file type: 'imec0.ap', 'imec0.lf' or 'nidq' assert 'imec0.ap' in self._npxfile.name or 'imec0.lf' in self._npxfile.name or 'nidq' in self._npxfile.name, \ "'file_path' can be an imec0.ap, imec.lf, or nidq file" assert 'bin' in self._npxfile.name, "The 'npx_file should be either the 'ap' or the 'lf' bin file." if 'imec0.ap' in str(self._npxfile): lfp = False ap = True self.is_filtered = True elif 'imec0.lf' in str(self._npxfile): lfp = True ap = False else: lfp = False ap = False aux = self._npxfile.stem.split('.')[-1] if aux == 'nidq': self._ftype = aux else: self._ftype = self._npxfile.stem.split('.')[-2] + '.' + aux # Metafile self._metafile = self._basepath.joinpath(self._npxfile.stem + '.meta') if not self._metafile.exists(): raise Exception("'meta' file for '" + self._ftype + "' traces should be in the same folder.") # Read in metadata, returns a dictionary meta = readMeta(self._npxfile) self._meta = meta # Traces in 16-bit format if '.cbin' in self._npxfile.name: # compressed binary format used by IBL try: import mtscomp except: raise Exception(self.installation_mesg) self._raw = mtscomp.Reader() self._raw.open(self._npxfile, self._npxfile.with_suffix('.ch')) else: self._raw = makeMemMapRaw(self._npxfile, meta) # [chanList, firstSamp:lastSamp+1] # sampling rate and ap channels self._sampling_frequency = SampRate(meta) tot_chan, ap_chan, lfp_chan, locations = _parse_spikeglx_metafile( self._metafile) if ap: if ap_chan < tot_chan: self._channels = list(range(int(ap_chan))) self._timeseries = self._raw[0:ap_chan, :] else: self._channels = list(range( int(tot_chan))) # OriginalChans(meta).tolist() elif lfp: if lfp_chan < tot_chan: self._channels = list(range(int(lfp_chan))) self._timeseries = self._raw[0:lfp_chan, :] else: self._channels = list(range(int(tot_chan))) else: # nidq self._channels = list(range(int(tot_chan))) self._timeseries = self._raw # locations if len(locations) > 0: self.set_channel_locations(locations) # get gains if meta['typeThis'] == 'imec': gains = GainCorrectIM(self._timeseries, self._channels, meta) elif meta['typeThis'] == 'nidq': gains = GainCorrectNI(self._timeseries, self._channels, meta) # set gains - convert from int16 to uVolt self.set_channel_gains(self._channels, gains * 1e6) self._kwargs = { 'file_path': str(Path(file_path).absolute()), 'dtype': dtype }