def get(self):
        from riglib.experiment import generate
        from json_param import Parameters

        if hasattr(self, 'generator') and self.generator.static: # If the generator is static, (NOTE: the generator being static is different from the *sequence* being static)
            if len(self.sequence) > 0:
                return generate.runseq, dict(seq=cPickle.loads(str(self.sequence)))
            else:
                return generate.runseq, dict(seq=self.generator.get()(**Parameters(self.params).params))            
        else:
            return self.generator.get(), Parameters(self.params).params
 def get(self, feats=()):
     from json_param import Parameters
     from riglib import experiment
     Exp = experiment.make(self.task.get(), tuple(f.get() for f in self.feats.all())+feats)
     params = Parameters(self.params)
     params.trait_norm(Exp.class_traits())
     if issubclass(Exp, experiment.Sequence):
         gen, gp = self.sequence.get()
         seq = gen(Exp, **gp)
         exp = Exp(seq, **params.params)
     else:
         exp = Exp(**params.params)
     exp.event_log = json.loads(self.report)
     return exp
    def task_params(self):
        from json_param import Parameters
        data = Parameters(self.params).params

        if 'bmi' in data:
            data['decoder'] = data['bmi']
        ##    del data['bmi']
        return data
 def to_json(self):
     from json_param import Parameters
     state = 'saved' if self.pk is not None else "new"
     js = dict(name=self.name, state=state)
     js['static'] = len(self.sequence) > 0
     js['params'] = self.generator.to_json(Parameters(self.params).params)['params']
     js['generator'] = self.generator.id, self.generator.name
     return js
    def from_json(cls, js):
        '''
        Construct a models.Sequence instance from JSON data (e.g., generated by the web interface for starting experiments)
        '''
        from json_param import Parameters

        # Error handling when input argument 'js' actually specifies the primary key of a Sequence object already in the database
        try:
            seq = Sequence.objects.get(pk=int(js))
            print "retreiving sequence from POSTed ID"
            return seq
        except:
            pass
        
        # Make sure 'js' is a python dictionary
        if not isinstance(js, dict):
            js = json.loads(js)

        # Determine the ID of the "generator" used to make this sequence
        genid = js['generator']
        if isinstance(genid, (tuple, list)):
            genid = genid[0]
        
        # Construct the database record for the new Sequence object
        seq = cls(generator_id=int(genid), name=js['name'])

        # Link the generator instantiation parameters to the sequence record
        # Parameters are stored in JSON format in the database
        seq.params = Parameters.from_html(js['params']).to_json()

        # If the sequence is to be static, 
        if js['static']:
            print "db.tracker.models.Sequence.from_json: storing static sequence data to database"
            generator_params = Parameters(seq.params).params
            seq_data = seq.generator.get()(**generator_params)
            seq.sequence = cPickle.dumps(seq_data)
        return seq
Esempio n. 6
0
    def __init__(self, subj, task_rec, feats, params, seq=None, seq_params=None, saveid=None):
        '''
        Parameters
        ----------
        subj : tracker.models.Subject instance
            Database record for subject performing the task
        task_rec : tracker.models.Task instance
            Database record for base task being run (without features)
        feats : list 
            List of features to enable for the task
        params : json_param.Parameters, or string representation of JSON object
            user input on configurable task parameters
        seq : models.Sequence instance, or tuple
            Database record of Sequence parameters/static target sequence
            If passed in as a tuple, then it's the result of calling 'seq.get' on the models.Sequence instance
        seq_params: params from seq (see above)

        saveid : int, optional
            ID number of db.tracker.models.TaskEntry associated with this task
            if None specified, then the data saved will not be linked to the
            database entry and will be lost after the program exits
        '''
        self.saveid = saveid
        self.taskname = task_rec.name
        self.subj = subj
        if isinstance(params, Parameters):
            self.params = params
        elif isinstance(params, (string, str)):
            self.params = Parameters(params)
        
        base_class = task_rec.get()

        if None in feats:
            raise Exception("Features not found properly in database!")
        else:
            Task = experiment.make(base_class, feats=feats)

        # Run commands which must be executed before the experiment class can be instantiated (e.g., starting neural recording)
        Task.pre_init(saveid=saveid)

        self.params.trait_norm(Task.class_traits())
        if issubclass(Task, experiment.Sequence):
            # retreive the sequence data from the db, or from the input argument if the input arg was a tuple
            if isinstance(seq, tuple):
                gen_constructor, gen_params = seq
            elif isinstance(seq, models.Sequence):
                gen_constructor, gen_params = seq.get()
                # Typically, 'gen_constructor' is the experiment.generate.runseq function (not an element of namelist.generators)
            else:
                raise ValueError("Unrecognized type for seq")

            gen = gen_constructor(Task, **gen_params)
            self.params.params['seq_params'] = seq_params
            
            # 'gen' is now a true python generator usable by experiment.Sequence
            self.task = Task(gen, **self.params.params)

            with open(log_filename, 'a') as f:
                f.write("instantiating task with a generator\n")

        else:
            self.task = Task(**self.params.params)
        self.task.start()
Esempio n. 7
0
class TaskWrapper(object):
    '''
    Wrapper for Experiment classes launched from the web interface
    '''
    def __init__(self, subj, task_rec, feats, params, seq=None, seq_params=None, saveid=None):
        '''
        Parameters
        ----------
        subj : tracker.models.Subject instance
            Database record for subject performing the task
        task_rec : tracker.models.Task instance
            Database record for base task being run (without features)
        feats : list 
            List of features to enable for the task
        params : json_param.Parameters, or string representation of JSON object
            user input on configurable task parameters
        seq : models.Sequence instance, or tuple
            Database record of Sequence parameters/static target sequence
            If passed in as a tuple, then it's the result of calling 'seq.get' on the models.Sequence instance
        seq_params: params from seq (see above)

        saveid : int, optional
            ID number of db.tracker.models.TaskEntry associated with this task
            if None specified, then the data saved will not be linked to the
            database entry and will be lost after the program exits
        '''
        self.saveid = saveid
        self.taskname = task_rec.name
        self.subj = subj
        if isinstance(params, Parameters):
            self.params = params
        elif isinstance(params, (string, str)):
            self.params = Parameters(params)
        
        base_class = task_rec.get()

        if None in feats:
            raise Exception("Features not found properly in database!")
        else:
            Task = experiment.make(base_class, feats=feats)

        # Run commands which must be executed before the experiment class can be instantiated (e.g., starting neural recording)
        Task.pre_init(saveid=saveid)

        self.params.trait_norm(Task.class_traits())
        if issubclass(Task, experiment.Sequence):
            # retreive the sequence data from the db, or from the input argument if the input arg was a tuple
            if isinstance(seq, tuple):
                gen_constructor, gen_params = seq
            elif isinstance(seq, models.Sequence):
                gen_constructor, gen_params = seq.get()
                # Typically, 'gen_constructor' is the experiment.generate.runseq function (not an element of namelist.generators)
            else:
                raise ValueError("Unrecognized type for seq")

            gen = gen_constructor(Task, **gen_params)
            self.params.params['seq_params'] = seq_params
            
            # 'gen' is now a true python generator usable by experiment.Sequence
            self.task = Task(gen, **self.params.params)

            with open(log_filename, 'a') as f:
                f.write("instantiating task with a generator\n")

        else:
            self.task = Task(**self.params.params)
        self.task.start()

    def report(self):
        return experiment.report(self.task)
    
    def pause(self):
        self.task.pause = not self.task.pause
        return "pause" if self.task.pause else "running"
    
    def end_task(self):
        self.task.end_task()

    def enable_clda(self):
        self.task.enable_clda()

    def disable_clda(self):
        self.task.disable_clda()
    
    def get_state(self):
        return self.task.state

    def __getattr__(self, attr):
        # This function is only defined because __getattr__ is not defined 
        # for children of 'object' by default, but the TaskObjProxy always calles '__getattr__'
        # when trying to remotely retreive an attribute. Might be avoidable if TaskObjProxy were
        # to use '__getattribute__' instead
        return getattr(self, attr)

    def set_task_attr(self, attr, value):
        setattr(self.task, attr, value)

    def cleanup(self):
        self.task.join()
        print("Calling saveout/task cleanup code")
        
        if self.saveid is not None:
            # get object representing function calls to the remote database
            # returns the result of tracker.dbq.rpc_handler
            database = xmlrpc.client.ServerProxy("http://localhost:8000/RPC2/", allow_none=True)

            cleanup_successful = self.task.cleanup(database, self.saveid, subject=self.subj)
            
            # if not self.task._task_init_complete:
            #     from tracker import dbq
            #     dbq.hide_task_entry(self.saveid)
            #     print 'hiding task entry!'
            # else:
            #     print 'not hiding task entry!'
        else:
            cleanup_successful = True

        self.task.terminate()
        return cleanup_successful
 def get(self):
     from json_param import Parameters
     return getattr(calibrations, self.name)(**Parameters(self.params).params)
    def __init__(self, subj, task_rec, feats, params, seq=None, seq_params=None, saveid=None):
        '''
        Parameters
        ----------
        subj : tracker.models.Subject instance
            Database record for subject performing the task
        task_rec : tracker.models.Task instance
            Database record for base task being run (without features)
        feats : list 
            List of features to enable for the task
        params : json_param.Parameters, or string representation of JSON object
            user input on configurable task parameters
        seq : models.Sequence instance, or tuple
            Database record of Sequence parameters/static target sequence
            If passed in as a tuple, then it's the result of calling 'seq.get' on the models.Sequence instance
        seq_params: params from seq (see above)

        saveid : int, optional
            ID number of db.tracker.models.TaskEntry associated with this task
            if None specified, then the data saved will not be linked to the
            database entry and will be lost after the program exits
        '''
        self.saveid = saveid
        self.taskname = task_rec.name
        self.subj = subj
        if isinstance(params, Parameters):
            self.params = params
        elif isinstance(params, (string, unicode)):
            self.params = Parameters(params)
        
        base_class = task_rec.get()

        if None in feats:
            raise Exception("Features not found properly in database!")
        else:
            Task = experiment.make(base_class, feats=feats)

        # Run commands which must be executed before the experiment class can be instantiated (e.g., starting neural recording)
        Task.pre_init(saveid=saveid)

        self.params.trait_norm(Task.class_traits())
        if issubclass(Task, experiment.Sequence):
            # retreive the sequence data from the db, or from the input argument if the input arg was a tuple
            if isinstance(seq, tuple):
                gen_constructor, gen_params = seq
            elif isinstance(seq, models.Sequence):
                gen_constructor, gen_params = seq.get()
                # Typically, 'gen_constructor' is the experiment.generate.runseq function (not an element of namelist.generators)
            else:
                raise ValueError("Unrecognized type for seq")

            gen = gen_constructor(Task, **gen_params)
            self.params.params['seq_params'] = seq_params
            
            # 'gen' is now a true python generator usable by experiment.Sequence
            self.task = Task(gen, **self.params.params)

            with open(log_filename, 'a') as f:
                f.write("instantiating task with a generator\n")

        else:
            self.task = Task(**self.params.params)
        self.task.start()
class TaskWrapper(object):
    '''
    Wrapper for Experiment classes launched from the web interface
    '''
    def __init__(self, subj, task_rec, feats, params, seq=None, seq_params=None, saveid=None):
        '''
        Parameters
        ----------
        subj : tracker.models.Subject instance
            Database record for subject performing the task
        task_rec : tracker.models.Task instance
            Database record for base task being run (without features)
        feats : list 
            List of features to enable for the task
        params : json_param.Parameters, or string representation of JSON object
            user input on configurable task parameters
        seq : models.Sequence instance, or tuple
            Database record of Sequence parameters/static target sequence
            If passed in as a tuple, then it's the result of calling 'seq.get' on the models.Sequence instance
        seq_params: params from seq (see above)

        saveid : int, optional
            ID number of db.tracker.models.TaskEntry associated with this task
            if None specified, then the data saved will not be linked to the
            database entry and will be lost after the program exits
        '''
        self.saveid = saveid
        self.taskname = task_rec.name
        self.subj = subj
        if isinstance(params, Parameters):
            self.params = params
        elif isinstance(params, (string, unicode)):
            self.params = Parameters(params)
        
        base_class = task_rec.get()

        if None in feats:
            raise Exception("Features not found properly in database!")
        else:
            Task = experiment.make(base_class, feats=feats)

        # Run commands which must be executed before the experiment class can be instantiated (e.g., starting neural recording)
        Task.pre_init(saveid=saveid)

        self.params.trait_norm(Task.class_traits())
        if issubclass(Task, experiment.Sequence):
            # retreive the sequence data from the db, or from the input argument if the input arg was a tuple
            if isinstance(seq, tuple):
                gen_constructor, gen_params = seq
            elif isinstance(seq, models.Sequence):
                gen_constructor, gen_params = seq.get()
                # Typically, 'gen_constructor' is the experiment.generate.runseq function (not an element of namelist.generators)
            else:
                raise ValueError("Unrecognized type for seq")

            gen = gen_constructor(Task, **gen_params)
            self.params.params['seq_params'] = seq_params
            
            # 'gen' is now a true python generator usable by experiment.Sequence
            self.task = Task(gen, **self.params.params)

            with open(log_filename, 'a') as f:
                f.write("instantiating task with a generator\n")

        else:
            self.task = Task(**self.params.params)
        self.task.start()

    def report(self):
        return experiment.report(self.task)
    
    def pause(self):
        self.task.pause = not self.task.pause
        return "pause" if self.task.pause else "running"
    
    def end_task(self):
        self.task.end_task()

    def enable_clda(self):
        self.task.enable_clda()

    def disable_clda(self):
        self.task.disable_clda()
    
    def get_state(self):
        return self.task.state

    def __getattr__(self, attr):
        # This function is only defined because __getattr__ is not defined 
        # for children of 'object' by default, but the TaskObjProxy always calles '__getattr__'
        # when trying to remotely retreive an attribute. Might be avoidable if TaskObjProxy were
        # to use '__getattribute__' instead
        return getattr(self, attr)

    def set_task_attr(self, attr, value):
        setattr(self.task, attr, value)

    def cleanup(self):
        self.task.join()
        print "Calling saveout/task cleanup code"
        
        if self.saveid is not None:
            # get object representing function calls to the remote database
            # returns the result of tracker.dbq.rpc_handler
            database = xmlrpclib.ServerProxy("http://localhost:8000/RPC2/", allow_none=True)

            cleanup_successful = self.task.cleanup(database, self.saveid, subject=self.subj)
            
            # if not self.task._task_init_complete:
            #     from tracker import dbq
            #     dbq.hide_task_entry(self.saveid)
            #     print 'hiding task entry!'
            # else:
            #     print 'not hiding task entry!'
        else:
            cleanup_successful = True

        self.task.terminate()
        return cleanup_successful
Esempio n. 11
0
def start_experiment(request, save=True):
    '''
    Handles presses of the 'Start Experiment' and 'Test' buttons in the browser 
    interface
    '''
    #make sure we don't have an already-running experiment
    if exp_tracker.status.value != '':
        http_request_queue.append((request, save))
        return _respond(dict(status="running", msg="Already running task, queuelen=%d!" % len(http_request_queue)))

    # Try to start the task, and if there are any errors, send them to the browser interface
    try:
        data = json.loads(request.POST['data'])

        task =  Task.objects.get(pk=data['task'])
        Exp = task.get(feats=data['feats'].keys())

        entry = TaskEntry(subject_id=data['subject'], task=task)
        params = Parameters.from_html(data['params'])
        entry.params = params.to_json()
        kwargs = dict(subj=entry.subject, task_rec=task, feats=Feature.getall(data['feats'].keys()),
                      params=params)

        # Save the target sequence to the database and link to the task entry, if the task type uses target sequences
        if issubclass(Exp, experiment.Sequence):
            print "creating seq"
            print "data['sequence'] POST data"
            print data['sequence']
            seq = Sequence.from_json(data['sequence'])
            seq.task = task
            if save:
                seq.save()
            entry.sequence = seq
            kwargs['seq'] = seq
        else:
            entry.sequence_id = -1
        
        response = dict(status="testing", subj=entry.subject.name, 
                        task=entry.task.name)

        if save:
            # Save the task entry to database
            entry.save()

            # Link the features used to the task entry
            for feat in data['feats'].keys():
                f = Feature.objects.get(pk=feat)
                entry.feats.add(f.pk)

            response['date'] = entry.date.strftime("%h %d, %Y %I:%M %p")
            response['status'] = "running"
            response['idx'] = entry.id

            # Give the entry ID to the runtask as a kwarg so that files can be linked after the task is done
            kwargs['saveid'] = entry.id
        
        # Start the task FSM and exp_tracker
        exp_tracker.runtask(**kwargs)

        # Return the JSON response
        return _respond(response)

    except Exception as e:
        # Generate an HTML response with the traceback of any exceptions thrown
        import cStringIO
        import traceback
        err = cStringIO.StringIO()
        traceback.print_exc(None, err)
        err.seek(0)
        return _respond(dict(status="error", msg=err.read()))