Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
 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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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()
Ejemplo n.º 5
0
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'
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
 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
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
"""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'