def __init__(self, path, animal=None): self.level = 2 # level in the hierarchy self.treebuf = StringIO.StringIO() # string buffer to print tree hierarchy to self.path = path self.animal = animal if animal != None: # update parent animal's track dict, in case self wasn't loaded by its parent animal.tr[self.id] = self self.r = dictattr() # store recordings in a dictionary with attrib access
def __init__(self, path, animal=None): self.level = 2 # level in the hierarchy self.treebuf = StringIO() # string buffer to print tree hierarchy to self.path = path self.animal = animal if animal != None: # update parent animal's track dict, in case self wasn't loaded by its parent animal.tr[self.id] = self self.r = dictattr( ) # store recordings in a dictionary with attrib access
def build(self): """Build the sweep table. A Variable's dim value relative to the dim values of all the other Variables determines its order in the nested for loops that generate the combinations of values for each sweep: the Variable with the lowest dim value becomes the outermost for loop and changes least often; the Variable with the highest dim value becomes the innermost for loop and changes on every sweep. dim must be an integer. Variables with the same dim value are part of the same Dimension, are shuffled/randomized together, and must therefore be of the same length and have the same shuffle and random flags""" e = self.experiment # synonym # Build the dimensions self.builddimensions() # Build the dimension index table self.builddimitable() # Now use dimitable to build the sweep table self.data = dictattr( ) # holds the actual sweep table, a dict with attribute access for dim in self.dimensions: for var in dim.variables: # get the entire column of indices into the values of this dimension: dimi = self.dimitable[:, dim.dim] # convert to array to enable multiple value selection: vals = np.asarray(var.vals)[dimi] self.data[var.name] = vals # store it as an array # Check to make sure that all the variables in self.data have the same number of vals try: nvals = len(list(self.data.values())[0]) except IndexError: # there aren't any variables at all nvals = 0 for varname in self.data: if len(self.data[varname]) != nvals: raise ValueError( '%s length in sweep table does not match expected length %d' % (varname, nvals)) # For convenience the main stimulus loop, add non-varying dynamic params to self.data: nvals = max(nvals, 1) # make sure the sweep table has at least one entry for paramname, paramval in e.dynamic.items(): if paramname not in self.data: # paramval was already checked to be a scalar in Experiment.check(): self.data[paramname] = np.tile(paramval, nvals)
def build(self): """Build the sweep table. A Variable's dim value relative to the dim values of all the other Variables determines its order in the nested for loops that generate the combinations of values for each sweep: the Variable with the lowest dim value becomes the outermost for loop and changes least often; the Variable with the highest dim value becomes the innermost for loop and changes on every sweep. dim must be an integer. Variables with the same dim value are part of the same Dimension, are shuffled/randomized together, and must therefore be of the same length and have the same shuffle and random flags""" e = self.experiment # synonym # Build the dimensions self.builddimensions() # Build the dimension index table self.builddimitable() # Now use dimitable to build the sweep table self.data = dictattr() # holds the actual sweep table, a dict with attribute access for dim in self.dimensions: for var in dim.variables: dimi = self.dimitable[:, dim.dim] # get the entire column of indices into the values of this dimension vals = np.asarray(var.vals)[ dimi ] # convert to array so you can select multiple values with a sequence of indices self.data[var.name] = vals # store it as an array # Check to make sure that all the variables in self.data have the same number of vals try: nvals = len(self.data.values()[0]) except IndexError: # there aren't any variables at all nvals = 0 for varname in self.data: assert len(self.data[varname]) == nvals, "%s length in sweep table does not match expected length %d" % ( varname, nvals, ) # For convenience in the main stimulus loop, add the non-varying dynamic params to self.data nvals = max(nvals, 1) # make sure the sweep table has at least one entry for paramname, paramval in e.dynamic.iteritems(): if paramname not in self.data: self.data[paramname] = np.tile( paramval, nvals ) # paramval was already checked to be a scalar in Experiment.check()
get_ipython().user_ns['VARNAME'] """ # __future__ imports don't seem to work when executing this file in IPython, see main.py: # from __future__ import division # from __future__ import print_function import os from core import mergeuniquedictvals, dictattr DATAROOTPATH = os.path.expanduser("~/data") LABPATHNAME = "slab" # LABPATHNAME = 'blab' DATAPATH = os.path.join(DATAROOTPATH, LABPATHNAME) MOVIEPATH = os.path.join(DATAPATH, "mov") MOVIES = dictattr() # for each recording, load all Sorts, or just the most recent one? LOADALLSORTS = False """Mean spike rate that delineates normal vs "quiet" neurons. 0.1 Hz seems reasonable if you plot mean spike rate distributions for all the neurons in a given track. But, if you want a reasonable looking DJS histogram without a lot of missing netstates, you need to exclude more low firing rate cells, 0.5 works better""" MINRATE = 0.05 # Hz """Calculate a TrackNeuron's meanrate according to its trange (period between its first and last spike), or according to its track's entire duration. Need to reload the track or call Track.calc_meanrates() after changing this on the fly""" TRACKNEURONPERIOD = "track" # 'trange' or 'track' # ditto for recordings: RECNEURONPERIOD = "recording" # 'trange' or 'recording'
def __init__(self, path): self.level = 1 # level in the hierarchy self.treebuf = StringIO.StringIO() # string buffer to print tree hierarchy to self.path = path self.tr = dictattr() # store tracks in a dictionary with attrib access
def load_din(self): self.din = np.fromfile(self.path, dtype=np.int64).reshape(-1, 2) # reshape to 2 cols # look for a .textheader: try: txthdrpath = rstrip(self.path, '.din') + '.textheader' f = open(txthdrpath, 'rU') # use universal newline support self.textheader = f.read() # read it all in f.close() except IOError: print("WARNING: couldn't load text header associated with '%s'" % self.name) self.textheader = '' # set to empty if self.textheader != '': # comment out all lines starting with "from dimstim" self.textheader = self.textheader.replace('from dimstim', '#from dimstim') # execute any remaining 'import' lines first, so that any modules imported # aren't artefactually detected as having been added to the namespace: for line in self.textheader.splitlines(): if line.startswith('import'): exec(line) thns = {} # textheader namespace # compiling to code and then executing it is supposed to be faster than directly # executing a string, according to # http://lucumr.pocoo.org/2011/2/1/exec-in-python/, but doesn't seem to make # a difference here: code = compile(self.textheader, "<string>", "exec") # don't exec in current namespace, load name:val pairs into thns instead: exec(code, None, thns) try: # dimstim up to ptc15 didn't have a version, neither did NVS display self.__version__ = thns['__version__'] # a string except KeyError: self.__version__ = '0.0' if float(self.__version__ ) >= 0.16: # after major refactoring of dimstim for name, val in thns.items(): # bind each variable in the textheader as an attrib of self self.__setattr__(name, val) # this doesn't work for textheaders generated by dimstim 0.16, since # xorigDeg and yorigDeg were accidentally omitted from all the experiment # scripts and hence the textheaders too: ''' self.e.xorig = deg2pix(self.e.static.xorigDeg, self.I) + self.I.SCREENWIDTH / 2 self.e.yorig = deg2pix(self.e.static.yorigDeg, self.I) + self.I.SCREENHEIGHT / 2 ''' self.REFRESHTIME = intround(1 / float(self.I.REFRESHRATE) * 1000000) # us # prevent replication of movie frame data in memory if type(self.e) == Movie: fname = os.path.split( self.e.static.fname)[-1] # pathless fname uns = get_ipython().user_ns if fname not in uns['MOVIES']: # add movie experiment, indexed according to movie data file name, # to prevent from ever loading its frames more than once uns['MOVIES'][fname] = self.e else: self.oldparams = dictattr() for name, val in thns.items(): # bind each variable in the textheader to oldparams self.oldparams[name] = val self.loadptc15exp() else: # use the time difference between the first two din instead self.REFRESHTIME = self.din[1, 0] - self.din[0, 0] # add an extra refresh time after last din, that's when screen actually turns off self.trange = (self.din[0, 0], self.din[-1, 0] + self.REFRESHTIME)
def loadptc15exp(self): ## TODO: - fake a .e dimstim.Experiment object, to replace what used to be the ## .stims object for movie experiments ''' - self.movie = self.experiment.stims[0] - need to convert sweeptimeMsec to sweepSec - assert len(self.experiment.stims) == 1 - self.movie = self.experiment.stims[0] - self.movie.load() # ensure the movie's data is loaded if self.movie.oname == 'mseq32': frameis = frameis[frameis != 65535] # remove all occurences of 65535 elif self.movie.oname == 'mseq16': frameis = frameis[frameis != 16383] # remove all occurences of 16383 ''' # Add .static and .dynamic params to fake dimstim experiment self.e = dictattr() self.I = dictattr() # fake InternalParams object self.e.static = dictattr() # fake StaticParams object self.e.dynamic = dictattr() # fake DynamicParams object # maps ptc15 param names to dimstim 0.16 param types and names, wherever possible ## TODO: fill in params for experiment types other than Movie?? _15to16 = { 'EYE': ('I', 'EYE'), 'PIXPERCM': ('I', 'PIXPERCM'), 'REFRESHRATE': ('I', 'REFRESHRATE'), 'SCREENDISTANCECM': ('I', 'SCREENDISTANCECM'), 'SCREENHEIGHT': ('I', 'SCREENHEIGHT'), 'SCREENHEIGHTCM': ('I', 'SCREENHEIGHTCM'), 'SCREENWIDTH': ('I', 'SCREENWIDTH'), 'SCREENWIDTHCM': ('I', 'SCREENWIDTHCM'), 'fname': ('static', 'fname'), 'preexpSec': ('static', 'preexpSec'), 'postexpSec': ('static', 'postexpSec'), 'orioff': ('static', 'orioff'), 'regionwidthDeg': ('static', 'widthDeg'), 'regionheightDeg': ('static', 'heightDeg'), 'mask': ('static', 'mask'), 'diameterDeg': ('static', 'diameterDeg'), 'GAMMA': ('static', 'gamma'), 'framei': ('dynamic', 'framei'), 'ori': ('dynamic', 'ori'), 'polarity': ('dynamic', 'invert'), 'bgbrightness': ('dynamic', 'bgbrightness'), 'sweeptimeMsec': ('dynamic', 'sweepSec'), 'postsweepMsec': ('dynamic', 'postsweepSec'), } # collect any ptc15 movie attribs and add them to self.oldparams try: # can't really handle more than 1 movie, since dimstim 0.16 doesn't assert len(np.unique(self.oldparams.playlist)) == 1 # bind it, movie was the only possible stim object anyway in ptc15 self.movie = self.oldparams.playlist[0] # returns dict of name:val pair attribs excluding __ and methods: movieparams = self.oldparams[self.movie.oname].__dict__ self.oldparams.update(movieparams) except AttributeError: # no playlist, no movies, and therefore no movie attribs to deal with pass # convert ptc15 params to dimstim 0.16 for oldname, val in self.oldparams.items(): if 'msec' in oldname.lower(): val = val / 1000. # convert to sec elif oldname == 'polarity': val = bool(val) # convert from 0/1 to boolean if oldname == 'origDeg': # split old origDeg into new separate xposDeg and yposDeg self.e.dynamic.xposDeg = val[0] self.e.dynamic.yposDeg = val[1] else: try: paramtype, newname = _15to16[oldname] if paramtype == 'I': # bind InternalParams directly to self, not to self.e: self.I[newname] = val self.e[paramtype][newname] = val except KeyError: # oldname doesn't have a newname equivalent pass try: m = self.movie except AttributeError: m = None if m: # make fake dimstim experiment a ptc15 Movie object, bind all of the attribs of # the existing fake dimstim experiment old_e = self.e self.e = m for name, val in old_e.__dict__.items(): # bind each variable in the textheader as an attrib of self self.e.__setattr__(name, val) # deal with movie filename: # didn't have a chance to pass this exp as the parent in the movie init, # so just set the attribute manually: m.e = self # if fname refers to a movie whose local name is different, rename it to match # the local movie name old2new = {'mseq16.m': 'MSEQ16', 'mseq32.m': 'MSEQ32'} try: m.fname = old2new[m.fname] except KeyError: pass # old name not in old2new, leave it be self.e.static.fname = m.fname # update fake dimstim experiment's fname too # extensionless fname, fname should've been defined in the textheader m.name = os.path.splitext(m.fname)[0] uns = get_ipython().user_ns if m.name not in uns['MOVIES']: # and it very well may not be, cuz the textheader inits movies with no args, # leaving fname==None at first, which prevents it from being added to # MOVIES uns['MOVIES'][m.name] = m # add m to MOVIES dictattr # Search self.e.moviepath string (from textheader) for 'Movies' word. Everything # after that is the relative path to your base movies folder. Eg, if # self.e.moviepath = 'C:\\Desktop\\Movies\\reliability\\e\\single\\', then set # self.e.relpath = '\\reliability\\e\\single\\' spath = self.oldparams.moviepath.split( '\\') # ptc15 has purely MS path separators matchi = spath.index('Movies') relpath = joinpath(spath[matchi + 1::]) MOVIEPATH = get_ipython().user_ns['MOVIEPATH'] path = os.path.join(MOVIEPATH, relpath) m.fname = os.path.join(path, m.fname) self.e.static.fname = m.fname # update try: self.REFRESHTIME = intround(1 / float(self.oldparams.REFRESHRATE) * 1000000) # us except AttributeError: pass
def load(self): f = open(self.path, 'rb') self.din = np.fromfile(f, dtype=np.int64).reshape(-1, 2) # reshape to nrows x 2 cols f.close() try: txthdrpath = rstrip(self.path, '.din') + '.textheader' f = open(txthdrpath, 'rU') # use universal newline support self.textheader = f.read() # read it all in f.close() except IOError: warn("couldn't load text header associated with '%s'" % self.name) self.textheader = '' # set to empty treestr = self.level*TAB + self.name + '/' # print string to tree hierarchy and screen self.writetree(treestr + '\n') print(treestr) if self.textheader != '': # comment out all lines starting with "from dimstim" self.textheader = self.textheader.replace('from dimstim', '#from dimstim') names1 = locals().copy() # namespace before execing the textheader exec(self.textheader) names2 = locals().copy() # namespace after # names that were added to the namespace, excluding the 'names1' name itself: newnames = [ n2 for n2 in names2 if n2 not in names1 and n2 != 'names1' ] try: # dimstim up to Cat 15 didn't have a version, neither did NVS display self.__version__ = eval('__version__') except NameError: self.__version__ = 0.0 if self.__version__ >= 0.16: # after major refactoring of dimstim for newname in newnames: # bind each variable in the textheader as an attrib of self self.__setattr__(newname, eval(newname)) self.sweeptable = SweepTable(experiment=self.e) # build the sweep table self.st = self.sweeptable.data # synonym, used a lot by experiment subclasses # this doesn't work for textheaders generated by dimstim 0.16, since # xorigDeg and yorigDeg were accidentally omitted from all the experiment # scripts and hence the textheaders too: ''' self.e.xorig = deg2pix(self.e.static.xorigDeg, self.I) + self.I.SCREENWIDTH / 2 self.e.yorig = deg2pix(self.e.static.yorigDeg, self.I) + self.I.SCREENHEIGHT / 2 ''' self.REFRESHTIME = intround(1 / float(self.I.REFRESHRATE) * 1000000) # us # prevent replication of movie frame data in memory if type(self.e) == Movie: fname = os.path.split(self.e.static.fname)[-1] # pathless fname if fname not in _MOVIES: # add movie experiment, indexed according to movie data file name, # to prevent from ever loading its frames more than once _MOVIES[fname] = e else: self.oldparams = dictattr() for newname in newnames: # bind each variable in the textheader to oldparams self.oldparams[newname] = eval(newname) self.loadCat15exp() else: # use the time difference between the first two din instead self.REFRESHTIME = self.din[1, 0] - self.din[0, 0] # add an extra refresh time after last din, that's when screen actually turns off self.trange = (self.din[0, 0], self.din[-1, 0] + self.REFRESHTIME)
def loadCat15exp(self): ## TODO: - fake a .e dimstim.Experiment object, to replace what used to be the ## .stims object for movie experiments ''' - self.movie = self.experiment.stims[0] - need to convert sweeptimeMsec to sweepSec - assert len(self.experiment.stims) == 1 - self.movie = self.experiment.stims[0] - self.movie.load() # ensure the movie's data is loaded if self.movie.oname == 'mseq32': frameis = frameis[frameis != 65535] # remove all occurences of 65535 elif self.movie.oname == 'mseq16': frameis = frameis[frameis != 16383] # remove all occurences of 16383 ''' # Add .static and .dynamic params to fake dimstim experiment self.e = dictattr() self.I = dictattr() # fake InternalParams object self.e.static = dictattr() # fake StaticParams object self.e.dynamic = dictattr() # fake DynamicParams object # maps Cat 15 param names to dimstim 0.16 param types and names, wherever possible ## TODO: fill in params for experiment types other than Movie?? _15to16 = {'EYE': ('I', 'EYE'), 'PIXPERCM': ('I', 'PIXPERCM'), 'REFRESHRATE': ('I', 'REFRESHRATE'), 'SCREENDISTANCECM': ('I', 'SCREENDISTANCECM'), 'SCREENHEIGHT': ('I', 'SCREENHEIGHT'), 'SCREENHEIGHTCM': ('I', 'SCREENHEIGHTCM'), 'SCREENWIDTH': ('I', 'SCREENWIDTH'), 'SCREENWIDTHCM': ('I', 'SCREENWIDTHCM'), 'fname': ('static', 'fname'), 'preexpSec': ('static', 'preexpSec'), 'postexpSec': ('static', 'postexpSec'), 'orioff': ('static', 'orioff'), 'regionwidthDeg': ('static', 'widthDeg'), 'regionheightDeg': ('static', 'heightDeg'), 'mask': ('static', 'mask'), 'diameterDeg': ('static', 'diameterDeg'), 'GAMMA': ('static', 'gamma'), 'framei': ('dynamic', 'framei'), 'ori': ('dynamic', 'ori'), 'polarity': ('dynamic', 'invert'), 'bgbrightness': ('dynamic', 'bgbrightness'), 'sweeptimeMsec': ('dynamic', 'sweepSec'), 'postsweepMsec': ('dynamic', 'postsweepSec'), } # collect any Cat 15 movie attribs and add them to self.oldparams try: # can't really handle more than 1 movie, since dimstim 0.16 doesn't assert len(np.unique(self.oldparams.playlist)) == 1 # bind it, movie was the only possible stim object anyway in Cat 15 self.movie = self.oldparams.playlist[0] # returns dict of name:val pair attribs excluding __ and methods: movieparams = self.oldparams[self.movie.oname].__dict__ self.oldparams.update(movieparams) except AttributeError: # no playlist, no movies, and therefore no movie attribs to deal with pass # convert Cat 15 params to dimstim 0.16 for oldname, val in self.oldparams.items(): if 'msec' in oldname.lower(): val = val / 1000. # convert to sec elif oldname == 'polarity': val = bool(val) # convert from 0/1 to boolean if oldname == 'origDeg': # split old origDeg into new separate xposDeg and yposDeg self.e.dynamic.xposDeg = val[0] self.e.dynamic.yposDeg = val[1] else: try: paramtype, newname = _15to16[oldname] if paramtype == 'I': # bind InternalParams directly to self, not to self.e: self.I[newname] = val self.e[paramtype][newname] = val except KeyError: # oldname doesn't have a newname equivalent pass try: m = self.movie except AttributeError: m = None if m: # make fake dimstim experiment a Cat15Movie object, bind all of the attribs of # the existing fake dimstim experiment old_e = self.e self.e = m for name, val in old_e.__dict__.items(): # bind each variable in the textheader as an attrib of self self.e.__setattr__(name, val) # deal with movie filename: # didn't have a chance to pass this exp as the parent in the movie init, # so just set the attribute manually: m.e = self # if fname refers to a movie whose local name is different, rename it to match # the local movie name _old2new = {'mseq16.m': MSEQ16, 'mseq32.m': MSEQ32} try: m.fname = _old2new[m.fname] except KeyError: pass # old name not in _old2new, leave it be self.e.static.fname = m.fname # update fake dimstim experiment's fname too # extensionless fname, fname should've been defined in the textheader m.name = os.path.splitext(m.fname)[0] if m.name not in _MOVIES: # and it very well may not be, cuz the textheader inits movies with no args, # leaving fname==None at first, which prevents it from being added to # _MOVIES _MOVIES[m.name] = m # add m to _MOVIES dictattr # Search self.e.moviepath string (from textheader) for 'Movies' word. Everything # after that is the relative path to your base movies folder. Eg, if # self.e.moviepath = 'C:\\Desktop\\Movies\\reliability\\e\\single\\', then set # self.e.relpath = '\\reliability\\e\\single\\' spath = self.oldparams.moviepath.split('\\') # Cat15 has purely windows seperators matchi = spath.index('Movies') relpath = joinpath(spath[matchi+1 ::]) MOVIEPATH = get_ipython().user_ns['MOVIEPATH'] path = os.path.join(MOVIEPATH, relpath) m.fname = os.path.join(path, m.fname) self.e.static.fname = m.fname # update # Generate the sweeptable: # dict of lists, ie sweeptable={'ori':[0,45,90], 'sfreq':[1,1,1]}, so you index # into it with self.sweeptable['var'][sweepi] #self.sweeptable = {[]} #vars = self.sweeptable.keys() # need to check if varlist exists, if so use it (we're dealing with Cat 15), # if not, use revamped dimstim.SweepTable class varvals = {} # init a dictionary that will contain variable values for var in m.varlist: # generate dict with var:val entries, to pass to buildSweepTable varvals[var] = eval('m.' + var) # pass varlist by reference, dim indices end up being modified: m.sweepTable = self.buildCat15SweepTable(m.varlist, varvals, m.nruns, m.shuffleRuns, m.blankSweep, m.shuffleBlankSweeps, makeSweepTableText=0)[0] else: # this is a simple stim (not object oriented movie) varvals = {} # init a dictionary that will contain variable values for var in self.oldparams.varlist: # generate dict with var:val entries, to pass to buildSweepTable varvals[var] = eval('self.oldparams.' + var) # pass varlist by reference, dim indices end up being modified: self.sweepTable = self.buildCat15SweepTable(self.oldparams.varlist, varvals, self.oldparams.nruns, self.oldparams.shuffleRuns, self.oldparams.blankSweep, self.oldparams.shuffleBlankSweeps, makeSweepTableText=0)[0] try: self.REFRESHTIME = intround(1 / float(self.oldparams.REFRESHRATE) * 1000000) # us except AttributeError: pass
def __init__(self, path): self.level = 1 # level in the hierarchy self.treebuf = StringIO() # string buffer to print tree hierarchy to self.path = path self.tr = dictattr() # store tracks in a dictionary with attrib access
def load(self): f = open(self.path, 'rb') self.din = np.fromfile(f, dtype=np.int64).reshape(-1, 2) # reshape to 2 cols f.close() try: txthdrpath = rstrip(self.path, '.din') + '.textheader' f = open(txthdrpath, 'rU') # use universal newline support self.textheader = f.read() # read it all in f.close() except IOError: print("WARNING: couldn't load text header associated with '%s'" % self.name) self.textheader = '' # set to empty treestr = self.level*TAB + self.name + '/' # print string to tree hierarchy and screen self.writetree(treestr + '\n') print(treestr) if self.textheader != '': # comment out all lines starting with "from dimstim" self.textheader = self.textheader.replace('from dimstim', '#from dimstim') # execute any remaining 'import' lines first, so that any modules imported # aren't artefactually detected as having been added to the namespace: for line in self.textheader.splitlines(): if line.startswith('import'): exec(line) thns = {} # textheader namespace # compiling to code and then executing that is supposed to be faster than directly # executing a string, according to # http://lucumr.pocoo.org/2011/2/1/exec-in-python/, but doesn't seem to make # a difference here: code = compile(self.textheader, "<string>", "exec") # don't exec in current namespace, load name:val pairs into thns instead: exec(code, None, thns) try: # dimstim up to ptc15 didn't have a version, neither did NVS display self.__version__ = thns['__version__'] except KeyError: self.__version__ = 0.0 if self.__version__ >= 0.16: # after major refactoring of dimstim for name, val in thns.items(): # bind each variable in the textheader as an attrib of self self.__setattr__(name, val) # this doesn't work for textheaders generated by dimstim 0.16, since # xorigDeg and yorigDeg were accidentally omitted from all the experiment # scripts and hence the textheaders too: ''' self.e.xorig = deg2pix(self.e.static.xorigDeg, self.I) + self.I.SCREENWIDTH / 2 self.e.yorig = deg2pix(self.e.static.yorigDeg, self.I) + self.I.SCREENHEIGHT / 2 ''' self.REFRESHTIME = intround(1 / float(self.I.REFRESHRATE) * 1000000) # us # prevent replication of movie frame data in memory if type(self.e) == Movie: fname = os.path.split(self.e.static.fname)[-1] # pathless fname uns = get_ipython().user_ns if fname not in uns['MOVIES']: # add movie experiment, indexed according to movie data file name, # to prevent from ever loading its frames more than once uns['MOVIES'][fname] = self.e else: self.oldparams = dictattr() for name, val in thns.items(): # bind each variable in the textheader to oldparams self.oldparams[name] = val self.loadptc15exp() else: # use the time difference between the first two din instead self.REFRESHTIME = self.din[1, 0] - self.din[0, 0] # add an extra refresh time after last din, that's when screen actually turns off self.trange = (self.din[0, 0], self.din[-1, 0] + self.REFRESHTIME) # these are static, no need for properties: self.dt = self.trange[1] - self.trange[0] # duration (us) self.dtsec = self.dt / 1e6 self.dtmin = self.dtsec / 60 self.dthour = self.dtmin / 60
"""Global variables that can be modified by the user at the IPython command line. Access programatically using: get_ipython().user_ns['VARNAME'] """ import os from core import mergeuniquedictvals, dictattr import colour as clr DATAPATH = os.path.expanduser('~/data') #BLABPATH = os.path.join(DATAPATH, 'blab') # Busse Lab BLABPATH = os.path.join(DATAPATH, 'blab', 'natstate') # Busse Lab SLABPATH = os.path.join(DATAPATH, 'slab') # Swindale Lab MOVIEPATH = os.path.join(SLABPATH, 'mov') MOVIES = dictattr() # for each recording, load all Sorts, or just the most recent one? LOADALLSORTS = False """Mean spike rate that delineates normal vs "quiet" neurons. 0.1 Hz seems reasonable if you plot mean spike rate distributions for all the neurons in a given track. But, if you want a reasonable looking DJS histogram without a lot of missing netstates, you need to exclude more low firing rate cells, 0.5 works better""" MINRATE = 0.05 # Hz """Calculate a TrackNeuron's meanrate according to its trange (period between its first and last spike), or according to its track's entire duration. Need to reload the track or call Track.calc_meanrates() after changing this on the fly""" TRACKNEURONPERIOD = 'track' # 'trange' or 'track' # ditto for recordings: RECNEURONPERIOD = 'recording' # 'trange' or 'recording' """NeuronCode (Ising matrix) and network state parameters""" CODEKIND = 'binary'