def processLogin(self): subject = self.subject print 'SUBJECT['+ subject+']' self.mySubjectDir = j.checkSubjDir(subject) j.dirStructure(subject) # verify/create subject's directory structure (visits, etc.) self.jsonpath = os.path.join(self.mySubjectDir, "%s_experiment_info.json" % subject) if os.path.exists(self.jsonpath): self.json = lib.load_json(self.jsonpath) self.json['flotscript'] = '' if 'flotscript_header' in self.json: del self.json['flotscript_header'] else: lib.set_node(self.json, subject, j.SUBJID) ## get a fresh json_template ## find the next incomplete visit (if study complete, display final visit) for v in range(j.NUM_VISITS): self.setTab(v) if not lib.get_node(self.json, self.vNodePath + j.VCOMPLETE): break visit = v # handle subject's group assignment and create visit/session dir based on group, if needed. group = lib.get_node(self.json, j.GROUP) if not group == "": ### create & populate session dir self.visitDir, correctVisit = j.checkVisitDir(subject, visit, group, self.json) if not correctVisit == visit: self.subjectMoved("<b>Cannot move on to next visit without ROI masks!</b>", "false") self.setTab(correctVisit) return self.renderAndSave() # saves the json, and renders the page else: return self.modalthing() # render modal to assign group -> call setgroup() -> save json & render normally
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)
def setgroup(self, group=None): ## Responds to result of modalthing's form submission. ## Uses group value to create session dir. ## Note: group might not be assigned if "Cancel" is pressed if group: lib.set_node(self.json, group, j.GROUP) self.visitDir = j.checkVisitDir(self.subject, self.TabID, group, self.json) ### create & populate session dir return self.renderAndSave()
def setTab(self,tab=0): ## NB: Clicking on a tab in the web-interface updates the json properly, but ## the mako template (subreg.html) is not re-rendered, so "what you get" is NOT ## "what you see". You must either cause the form to be submitted (click a button) ## or logout and login again for the website to catch up to the json's reality. self.TabID = int(tab) self.visitDir = os.path.join(self.mySubjectDir, "session%d"%self.TabID) self.vNodePath = j.FULLSTUDY + ":%d:"%self.TabID lib.set_node(self.json,self.TabID,j.TAB) return self.renderAndSave()
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)
def doMakoLogin(self,subject=None,visit=None): self.subject = subject ## keep this accessible to other methods self.mySubjectDir = j.checkSubjDir(subject) self.jsonpath = os.path.join(self.mySubjectDir, "%s_experiment_info.json"%subject) if os.path.exists(self.jsonpath): self.json = lib.load_json(self.jsonpath) else: lib.set_node(self.json,subject,j.SUBJID) ## get a fresh json_template visit = lib.get_node(self.json,j.TAB) self.setTab(visit) # activates the tab # handle subject's group assignment and create visit/session dir based on group, if needed. group = lib.get_node(self.json, j.GROUP) if not group == "": self.visitDir = j.checkVisitDir(subject,visit,group, self.json) ### create & populate session dir return self.renderAndSave() # saves the json, and renders the page else: return self.modalthing() # render modal to assign group -> call setgroup() -> save json & render normally
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
def setProgress(bid,visitNode): lib.set_node(visitNode, bid, jlib.VPROGRESS) return