fishBook/fishbook/frontend/frontend_classes.py
2020-07-22 13:35:12 +02:00

442 lines
13 KiB
Python

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()