from fishbook.backend.database import Cells, Datasets, CellDatasetMap, Subjects, SubjectProperties, SubjectDatasetMap, Stimuli, Repros from .util import safe_get_val, results_check import nixio as nix import os import numpy as np from IPython import embed class Cell: def __init__(self, cell_id=None, tuple=None): if tuple: self.__tuple = tuple elif cell_id: pattern = "cell_id like '{0:s}'".format(cell_id) cells = (Cells & pattern) results_check(cells, cell_id, "Cell ID") self.__tuple = cells.fetch(as_dict=True)[0] else: print("Empty Cell, not linked to any database entry!") @property def id(self): return self.__tuple["cell_id"] if "cell_id" in self.__tuple.keys() else "" @property def type(self): return self.__tuple["cell_type"] if "cell_type" in self.__tuple.keys() else "" @property def firing_rate(self): return self.__tuple["firing_rate"] if "firing_rate" in self.__tuple.keys() else 0.0 @property def location(self): keys = ["structure", "region", "subregion", "depth", "lateral_pos", "transversal_section"] loc = {} for k in keys: if k in self.__tuple.keys(): loc[k] = self.__tuple[k] else: loc[k] = "" return loc @property def subject(self): return Subject(tuple=(Subjects & {"subject_id": self.__tuple["subject_id"]}).fetch(limit=1, as_dict=True)[0]) @property def datasets(self): return [Dataset(tuple=d) for d in (Datasets & (CellDatasetMap & {"cell_id": self.id})).fetch(as_dict=True)] @property def repro_runs(self): repros = (Repros & "cell_id = '%s'" % self.id) return [RePro(tuple=r) for r in repros] @staticmethod def unique_cell_types(): return np.unique(Cells.fetch("cell_type")) @staticmethod def find(cell_type=None, species=None, quality="good"): cs = Cells * CellDatasetMap * Datasets * Subjects if cell_type: cs = cs & "cell_type like '{0:s}'".format(cell_type) if species: cs = cs & "species like '%{0:s}%'".format(species) if quality: cs = cs & "quality like '{0:s}'".format(quality) return [Cell(tuple=c) for c in cs] def __str__(self): str = "" str += "Cell: %s \t type: %s\n"%(self.id, self.type) return str @property def _tuple(self): return self.__tuple.copy() class Dataset: """[summary] """ def __init__(self, dataset_id=None, tuple=None): """[summary] Args: dataset_id ([type], optional): [description]. Defaults to None. tuple ([type], optional): [description]. Defaults to None. """ self.__samplerate = 0.0 if tuple: self.__tuple = tuple elif dataset_id: pattern = "dataset_id like '{0:s}'".format(dataset_id) dsets = (Datasets & pattern) results_check(dsets, dataset_id, "Dataset ID") self.__tuple = dsets.fetch(limit=1, as_dict=True)[0] else: print("Empty dataset, not linked to any database entry!") if len(self.__tuple.keys()) > 0: self.__find_samplerate() @property def id(self): """The id of the dataset. Returns: str: the id """ return self.__tuple["dataset_id"] @property def experimenter(self): """The person who recording the dataset. Returns: str: The experimenter """ return self.__tuple["experimenter"] @property def recording_date(self): return self.__tuple["recording_date"] @property def recording_duration(self): return self.__tuple["duration"] @property def quality(self): return self.__tuple["quality"] @property def has_nix(self): return self.__tuple["has_nix"] @property def comment(self): return self.__tuple["comment"] @property def data_source(self): return self.__tuple["data_source"] @property def setup(self): return self.__tuple["setup"] @property def cells(self): cell_list = (Cells * (CellDatasetMap & self.__tuple)) return [Cell(tuple=c) for c in cell_list] @property def subjects(self): subject_list = (Subjects * (SubjectDatasetMap & self.__tuple)) return [Subject(tuple=s) for s in subject_list] @property def samplerate(self): return self.__samplerate @staticmethod def find(min_duration=None, experimenter=None, quality=None): dataset_list = Datasets if min_duration: dataset_list = dataset_list & "duration > %.2f" % min_duration if experimenter: dataset_list = dataset_list & "experimenter like '%{0:s}%'".format(experimenter) if quality: dataset_list = dataset_list & "quality like '{0:s}'".format(quality) return [Dataset(tuple=d) for d in dataset_list] def __find_samplerate(self, trace_name="V-1"): if self.has_nix and os.path.exists(os.path.join(self.data_source, self.id, '.nix')): f = nix.File.open(os.path.join(self.data_source, self.id, '.nix'), nix.FileMode.ReadOnly) b = f.blocks[0] if trace_name in b.data_arrays: trace = b.data_arrays[trace_name] if trace.dimensions[0].dimension_type == nix.DimensionType.Sample: self.__samplerate = 1./trace.dimensions[0].sampling_interval else: print("Requested trace %s has no sampled dimension!" % trace_name) else: print("Requested trace %s was not found!" % trace_name) f.close() else: stimulus_file = os.path.join(self.data_source , 'stimuli.dat') if not os.path.exists(stimulus_file): return lines = None with open(stimulus_file, 'r') as f: lines = f.readlines() for l in lines: if "sample interval1" in l: si = l.strip().split(":")[-1][:-2] break self.__samplerate = 1000. / float(si) @property def _tuple(self): return self.__tuple.copy() class RePro: def __init__(self, repro_id=None, tuple=None): if tuple: self.__tuple = tuple elif repro_id: repros = (RePro & "repro_id like '{0:s}'".format(repro_id)) results_check(repros, repro_id, "RePro ID") self.__tuple = repros.fetch(limit=1, as_dict=True)[0] else: self.__tuple = {} print("Empty RePro, not linked to any database entry!") @property def id(self): return safe_get_val(self.__tuple, "repro_id", "") @property def run(self): return safe_get_val(self.__tuple, "run", -1) @property def cell_id(self): return safe_get_val(self.__tuple, "cell_id", "") @property def cell(self): return Cell(self.cell_id) @property def dataset(self): datasets = (Cells & "cell_id = '%s'" % self.cell_id) * CellDatasetMap * Datasets d = datasets.proj('dataset_id', 'data_source', 'experimenter', 'setup', 'recording_date', 'quality', 'comment', 'duration', 'has_nix').fetch(limit=1, as_dict=True)[0] del d["cell_id"] return Dataset(tuple=d) @property def name(self): return safe_get_val(self.__tuple, "repro_name", "") @property def settings(self): return safe_get_val(self.__tuple, "settings", "") @property def start(self): return safe_get_val(self.__tuple, "start", 0.0) @property def duration(self): return safe_get_val(self.__tuple, "duration", 0.0) @property def stimuli(self): stims = Stimuli & "repro_id = '%s'" % self.id & "cell_id = '%s'" % self.cell_id return [Stimulus(tuple=s) for s in stims] @staticmethod def find(name=None, cell_id=None, cell_type=None, species=None, settings=None, quality=None): """ Cell type, quality, and species are ignored, if cell_id is provided :param repro_name: :param cell_id: :param cell_type: :param species: :param settings: :param quality: :return: """ repros = Repros & True if name: repros = repros & "repro_name like '%{0:s}%'".format(name) if settings: repros = repros & "settings like '%{0:s}%'".format(settings) if cell_id: repros = repros & "cell_id = '{0:s}'".format(cell_id) if not cell_id and (cell_type or species or quality): cells = (Cells * CellDatasetMap * Datasets) * Subjects if cell_type: cells = cells & "cell_type like '%{0:s}%'".format(cell_type) if species: cells = cells & "species like '%{0:s}%'".format(species) if quality: cells = cells & "quality like '{0:s}'".format(quality) p = cells.proj("quality", "experimenter") repros = repros & p return [RePro(tuple=r) for r in repros] @property def _tuple(self): return self.__tuple.copy() class Stimulus: """The stimulus class represents a Stimulus that was presented. A Stimulus has several properties such as the start time, the duarion """ def __init__(self, stimulus_id=None, tuple=None): if tuple: self.__tuple = tuple elif stimulus_id: stimuli = Stimuli & "stimulus_id = '%s'" %stimulus_id results_check(stimuli, stimulus_id, "Stimulus ID") self.__tuple = stimuli.fetch(limit=1, as_dict=True)[0] else: print("Empty RePro, not linked to any database entry!") def __str__(self): str = "Stimulus %s: " % safe_get_val(self.__tuple, "stimulus_id", "") str += "\nStart time/index: %0.4f/%i, duration: %.3f" % (safe_get_val(self.__tuple, "start_time", 0.0), safe_get_val(self.__tuple, "start_index", -1), safe_get_val(self.__tuple, "duration", 0.0)) return str @property def id(self): return self.__tuple["stimulus_id"] @property def name(self): return self.__tuple["stimulus_name"] @property def cell(self): return Cells & "cell_id = %s" % self.__tuple["cell_id"] @property def repro(self): return Repros & "repro_id = %s" % self.__tuple["repro_id"] @property def start_time(self): return self.__tuple["start_time"] @property def start_index(self): return self.__tuple["start_index"] @property def duration(self): return self.__tuple["duration"] @property def multi_tag_id(self): return self.__tuple["mtag_id"] @property def run(self): return self.__tuple["run"] @property def index(self): return self.__tuple["stimulus_index"] @property def settings(self): return safe_get_val(self.__tuple, "settings", "") @property def _tuple(self): return self.__tuple.copy() @staticmethod def find(cell_id=None, repro_id=None, settings=None): """Find stimulus presentations that match in certain properties. Examples: Args: cell_id (str, optional): [description]. Defaults to None. repro_id (str, optional): [description]. Defaults to None. settings (str, optional): [description]. Defaults to None. Returns: List: of matching Stimulus presentations """ stimuli = Stimuli & True if cell_id: stimuli = stimuli & "cell_id = '{0:s}'".format(cell_id) if repro_id: stimuli = stimuli & "repro_id = '{0:s}'".format(repro_id) if settings: stimuli = stimuli & "settings like '%{0:s}%'".format(settings) return [Stimulus(tuple=s) for s in stimuli] class Subject: def __init__(self, subject_id=None, tuple=None): if tuple: self.__tuple = tuple elif subject_id: subjects = Subjects & "subject_id like '{0:s}'".format(subject_id) results_check(subjects, subject_id, "Subject ID") self.__tuple = subjects.fetch()[0] else: self.__tuple = {} print("Empty Subject, not linked to any database entry!") @property def id(self): return self.__tuple["subject_id"] @property def species(self): return self.__tuple["species"] @property def cells(self): cs = Cells & self.__tuple return [Cell(tuple=c) for c in cs] @property def properties(self): return (SubjectProperties & self.__tuple).fetch(as_dict=True) @property def _tuple(self): return self.__tuple.copy() @staticmethod def find(species=None): subjs = Subjects & True if species: subjs = (Subjects & "species like '%{0:s}%'".format(species)) return [Subject(tuple=s) for s in subjs] @staticmethod def unique_species(): all_species = (Subjects & True).fetch("species") return np.unique(all_species) if __name__ == "__main__": from IPython import embed cell = Cell("2010-04-16-ak") embed()