Beispiel #1
0
 def makoDoServ(self,btn_value,node):
     murfNode = bt.sib_node(node['id'], self.json, 0)
     servLog = bt.nameLogfile(node, self.subject, murfNode)
     self.run = murfNode['run']  # in case of accidental logout
     self.servProc, self.servOUT, h = lib.doServ(self.subject, self.TabID, self.run, servLog)
     lib.set_here(node,'disabled', True)
     return
Beispiel #2
0
def enableOnly(j, tab, only=None):
    """
    only: 'first', None
    """
    vBids = visitBids(tab, j)
    if only == 'first':
        lib.set_here(btn_node(vBids.pop(0),j),'disabled', False)
    [lib.set_here(btn_node(bid,j), 'disabled', True) for bid in vBids]
    return
Beispiel #3
0
def enableNext(bid,j):
    [v,s,p] = bid.split(".")
    try:
        nextBtn = btn_node("%s.%s.%d"%(v,s,int(p)+1), j)
    except LookupError:  ## done with this step
        try:
            nextBtn = btn_node("%s.%d.%d"%(v,int(s)+1,0), j)
        except LookupError:  ## done with this visit
            vNode = get_visit(bid,j)
            lib.set_node(vNode,True, jlib.VCOMPLETE)
            return int(v)+1
    lib.set_here(nextBtn,'disabled', False)
    return int(v)
Beispiel #4
0
 def makoRealtimeStim(self, btn_value, node):
     murfNode = bt.sib_node(node['id'], self.json, 0)
     stimLog = bt.nameLogfile(node, self.subject, murfNode)
     self.run = murfNode['run']   ## in case of accidental logout
     self.flotJavascript()
     # based on group, use proper stimulus file
     group = lib.get_node(self.json, j.GROUP)
     if group == "high":
         psychofile = j.HIFILE
     elif group == "low":
         psychofile = j.LOFILE
     lib.set_here(node, 'file', psychofile)  # record which stimulus file was used
     # ready to launch!
     self.stimProc, h = lib.doStim(self.subject, self.TabID, self.run, stimLog, psychofile,self.json["study_info"]["group"])
     lib.set_here(node,'disabled', True)  # this button only launches. 'End Murfi' cleans up
     return
Beispiel #5
0
def rtDone(j, bid):
    # Purpose: When an RT run completes, this advances the "progress" key
    #   to the last part of the RT step, so that enableNext can enable the
    #   next step or next visit.
    # This is a helper function for handling an "End Murfi" buttonpress. Nothing 
    #   else should call it.
    # Inputs:
    # j (dict) = full json the subject
    # bid (str) = "x.y.z", as above

    node = btn_node(bid, j)
    lib.set_here(node, 'done', True)
    # disable all sibling parts
    parent = parent_node(bid, j)
    for p in range(0, len(parent)):
        lib.set_here(parent[p], 'disabled', True)
    # progress is set to button ID of the last part of this step.    
    lastID = lib.get_node(parent, ['-1', 'id'])
    setProgress(lastID, get_visit(bid, j))
Beispiel #6
0
def enableNext(bid, j):
    [v, s, p] = bid.split(".")
    try:
        nextBtn = btn_node("%s.%s.%d" % (v, s, int(p) + 1), j)
    except LookupError:  ## done with this step
        try:
            nextBtn = btn_node("%s.%d.%d" % (v, int(s) + 1, 0), j)
        except LookupError:  ## done with this visit
            vNode = get_visit(bid, j)
            lib.set_node(vNode, True, jlib.VCOMPLETE)
            return int(v) + 1
    ## we have the next valid button: enable it!
    ## ... unless we're in redo-mode: skip completed steps until we've resumed
    resume = lib.get_node(j, jlib.RESUME)
    if resume:  # redo-mode!
        if compareBids(resume, nextBtn["id"]):  # we've caught up to the resume point
            lib.set_node(j, None, jlib.RESUME)  # end redo-mode
            lib.set_here(nextBtn, "disabled", False)  # enable as normal
        else:  # stay in redo-mode
            if lib.get_node(nextBtn, "time") == "":  # not stamped yet, so enable
                lib.set_here(nextBtn, "disabled", False)
            else:  # timestamped; this was complete before redo began.
                # don't enable; rather, advance progress & skip to next-next
                nextID = lib.get_node(nextBtn, "id")
                setProgress(nextID, get_visit(bid, j))
                return enableNext(nextID, j)
    else:  # no redo occurring, normal enable
        lib.set_here(nextBtn, "disabled", False)
    return int(v)
Beispiel #7
0
 def makoMurfiHandler(self, btn_value, node):
     ## Handle "Start" & "End" differently
     if ('Start' in btn_value):
         murfLog = bt.nameLogfile(node, self.subject)
         try:
             self.murfProc, self.murfOUT, h = lib.doMurfi(self.subject, self.TabID, self.run, murfLog)
         except:
             self.murfProc.kill()
             self.murfOUT.close()
             raise
         lib.set_here(node,'text','End Murfi')  ## could do this better
         lib.set_here(bt.sib_node(node['id'], self.json, 1), "disabled", False)  ## activate psychopy
         #lib.set_here(bt.sib_node(node['id'], self.json, 2), "disabled", False)  ## activate servenii
     elif "End" in btn_value:
         ## End must also clean up after servenii & rt psychopy, if needed.
         lib.set_here(bt.sib_node(node['id'], self.json, 1), "disabled", True)  ## disable psychopy
         #lib.set_here(bt.sib_node(node['id'], self.json, 2), "disabled", True)  ## disable servenii
         ## close errant process handles
         if hasattr(self, 'murfProc'):
             lib.endMurfi(self.murfProc, self.subject, self.TabID, self.run, self.murfOUT)
         if hasattr(self, 'stimProc'):
             self.stimProc.kill()
         if hasattr(self, 'servProc'):
             lib.endServ(self.servProc, self.subject, self.TabID, self.run, self.servOUT)
         lib.set_here(node,'text','Start Murfi')
         ## check if RT run is done yet:
         ## -- 150ish TRs collected in results JSON? ==> done; update progress.
         ## -- otherwise, allow Murfi restart for this run.
         activeFile = os.path.join(self.visitDir,'data','run00%d_active.json'%self.run)
         if os.path.exists(activeFile):
             activeData = lib.load_json(activeFile)
             print "activeData's length is:", len(activeData['data'])
             if len(activeData['data']) > 150:
                 bt.rtDone(self.json, node['id'])  ## bt.updateProgress gets called in here.
             else:
                 lib.set_here(node, "disabled", False) ## ensure murfi can be restarted
     else:
         print "realtime_app: Can't handle this murfi button value:",btn_value
     return
Beispiel #8
0
def movementRedo(j, tab):
    ## Use this visit's progress to figure out what things to redo.
    ## Collaborate with enableNext() to use timestamps as a high-water mark.
    ##    j (dict) = full json for the subject
    ##    tab (int) = visit/session number
    vNode = get_visit(tab, j)
    vBids = visitBids(tab, j)  ## full, ordered list of all button ids for this visit
    progress = getProgress(vNode)
    currentBid = vBids[vBids.index(progress) + 1]  ## for current step (after progress)
    ## 1. build prereq button id list
    # 1.1 get base prereqs, plus prereqs based on current step's action keyword
    action = lib.get_node(btn_node(currentBid, j), "action")
    prereqs = []
    for btn in [btn_node(bid, j) for bid in visitBids(tab, j)]:
        if btn.has_key("prereqFor"):
            prfor = btn["prereqFor"].split(".")  # some prereqs are '.'-joined
            if ("all" in prfor) or (action in prfor):
                prereqs.append(btn["id"])
    # 1.2 get all siblings of the current step
    sibs = [lib.get_node(sib, "id") for sib in parent_node(currentBid, j)]
    prereqs.extend(sibs)
    # 2. prepare prereqs for redo: clear all tstamps, uncheck checkboxes.
    for prereq in prereqs:
        prNode = btn_node(prereq, j)
        clearTimeStamp(prNode)
        if lib.get_node(prNode, "action") == "":  # it's a checkbox
            lib.set_here(prNode, "checked", False)  # clear checkboxes
    # 3. save progress to study-wide resume pointer, unless we're restarting a redo.
    resume = lib.get_node(j, jlib.RESUME)
    if resume:
        pass  ## restarting redo-mode due to another movement
    else:  ## enter fresh redo-mode
        lib.set_node(j, progress, jlib.RESUME)
    # 4. reset progress so that the first prereq is the next thing to happen.
    vBids.insert(0, "")  # if 1st prereq is tab.0.0, then progress = "" (as expected)
    resetBid = vBids[vBids.index(prereqs[0]) - 1]
    setProgress(resetBid, vNode)
    return
Beispiel #9
0
 def makoDoStim(self,btn_value,node):
     print btn_value
     if ('RT' in btn_value):
         return self.makoRealtimeStim(btn_value,node)
     else:
         if ('Launch' in btn_value) or ('Test' in btn_value):
             psyFile = node['file']
             psyArgs = [self.subject, self.TabID, bt.getTimestamp(node)]
             log = os.path.join(self.visitDir, "%s.log"%btn_value[-1])
             print psyFile, psyArgs, log
             self.stimProc, h = lib.startPsycho(psyFile, psyArgs, log)
             if ('Launch' in btn_value):
                 lib.set_here(node, 'text', 'End '+ btn_value[-1])
             elif ('Test' in btn_value):
                 self.updateProgress(btn_value[0])
         elif ('End' in btn_value):
             ## decide whether to allow restart or to disable!
             if bt.checkPsychoDone(self.subject, node):
                 self.updateProgress(btn_value[0])
                 lib.set_here(node,'disabled',True)
             else:
                 lib.set_here(node, 'text', 'Launch '+ btn_value[-1])                    
     return
Beispiel #10
0
def clearTimeStamp(node):
    lib.set_here(node,'time',"")
    return
Beispiel #11
0
def timeStamp(node):  ## store time in epoch-secs + string
    tStamp = "%f"%time.time()  ## get time in seconds in the epoch
    timeReadable = time.strftime("%H:%M:%S--%m/%d/%Y",time.localtime(float(tStamp)))
    node['history'].append(tStamp)
    lib.set_here(node,'time',timeReadable)
    return  ### end timeStamp
Beispiel #12
0
 def makoCheckboxHandler(self,node):
     lib.set_here(node, 'checked', True)
     lib.set_here(node, 'disabled', True)
     self.updateProgress(node['id'])
     return
Beispiel #13
0
def clearTimeStamp(node):
    lib.set_here(node, "time", "")
    return