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