def __finishTrial__(self, trialDict): """ Perform some finalization after we we have parsed a trial Arguments: trialDict -- a trial dictionary """ nPhase = len(self.traceDict) i = 1 if self.traceImg or self.tracePlot: plt.clf() plt.close() plt.figure(figsize=(12,12)) plt.subplots_adjust(hspace=.5, wspace=.5) for phase, trace in self.traceDict.iteritems(): a = np.array(trace, dtype=float) if len(a) == 0: continue origA = a.copy() if self.blinkReconstruct: a[:,2] = TraceKit.blinkReconstruct(a[:,2]) if self.traceSmoothParams != None: a[:,0] = TraceKit.smooth(a[:,0], **self.traceSmoothParams) a[:,1] = TraceKit.smooth(a[:,1], **self.traceSmoothParams) a[:,2] = TraceKit.smooth(a[:,2], **self.traceSmoothParams) self.traceDict[phase] = a path = os.path.join(self.traceFolder, '%s-%.5d-%s.npy' \ % (trialDict['file'], trialDict['trialId'], phase)) if not os.path.exists(self.traceFolder): print('Creating traceFolder: %s' % self.traceFolder) os.makedirs(self.traceFolder) np.save(path, a) trialDict['__trace_%s__' % phase] = path if self.traceImg or self.tracePlot: plt.subplot(nPhase, 3, i) i += 1 plt.title('X(%s)' % phase) plt.plot(a[:,0]) if self.traceSmoothParams != None: plt.plot(origA[:,0]) plt.subplot(nPhase, 3, i) i += 1 plt.title('Y(%s)' % phase) plt.plot(a[:,1]) if self.traceSmoothParams != None: plt.plot(origA[:,1]) plt.subplot(nPhase, 3, i) i += 1 plt.title('Pupil(%s)' % phase) plt.plot(a[:,2]) if self.traceSmoothParams != None or self.blinkReconstruct: plt.plot(origA[:,2]) if self.traceImg or self.tracePlot: plt.suptitle(path) if self.traceImg: path = os.path.join(self.traceFolder, 'png', '%s-%.5d-%s.png' \ % (trialDict['file'], trialDict['trialId'], phase)) if not os.path.exists(os.path.join(self.traceFolder, 'png')): print('Creating traceImgFolder: %s' % os.path.join( \ self.traceFolder, 'png')) if not os.path.exists(os.path.join(self.traceFolder, 'png')): os.makedirs(os.path.join(self.traceFolder, 'png')) plt.savefig(path) if self.tracePlot: plt.show()
def parseLine(self, trialDict, l): """ desc: Parses a single line from the EyeLink .asc file. arguments: trialDict: desc: Trial information. type: dict l: desc: A white-space-splitted line. type: list """ trialDict['subject_nr'] = int(trialDict['file'][2:4]) # The active period is the moment from the first round until the winner # is announced. This way we don't count the extra time taken by the # preview and end animation. if 'start_round' in l and l[3] == 0: self.active = True self.startTime = l[1] if 'status=winner' in l: self.active = False self.endTime = l[1] # Check for check fixation during the active period. if self.active: fix = self.toFixation(l) if fix != None: fixErr = np.sqrt( (fix['x']-xc)**2 + (fix['y']-yc)**2 ) trialDict['maxFixErr'] = max(trialDict['maxFixErr'], fixErr) self.fixList.append( (fix['x'], fix['y']) ) if 'fixation_lost' in l: trialDict['nFixLost'] += 1 # Get target coordinates # MSG 18895724 item id="B" status=init likelihood=1 ecc=375 # angle=0.785398163397 size=99 brightness=-1 color=green opacity=0.5 # x=265.165042945 y=265.16504 if 'target' in trialDict and ('id="%s"' % trialDict['target']) in l: if 'targetX' not in trialDict: # The x and y coordinates are sometimes chopped off, because the # logging string is too long. Therefore, we recalculate them # from the radius and eccentricity. for i in l: if type(i) != str: continue if 'ecc' in i: r = float(i[4:]) if 'angle' in i: a = float(i[6:]) x = np.cos(a) * r y = np.sin(a) * r # If possible, doubcheck the coordinates for strings that have # not been chopped off. try: _x = float(l[-2][2:]) _y = float(l[-1][2:]) assert(int(_x) == int(x)) assert(int(_y) == int(y)) except: print 'Failed to verify' trialDict['targetX'] = x trialDict['targetY'] = y # For Exp 1: # MSG 7093294 var correct 1 # For Exp 2+: # MSG 7093294 var correct_selection 1 if ('correct' in l or 'correct_selection' in l) and l[4] in (0, 1): self.correct = l[4] # Collect pupil trace # MSG 18625682 start_round 0 if 'start_round' in l: self.tracePhase = 'dummy' self.startRoundTime = l[1] # Determine whether the target is bright or dark if self.tracePhase != None and 'item' in l: if 'id="%s"' % trialDict['target'] in l: if 'brightness=1.0' in l: self.phaseType = 'bright' elif 'brightness=-1.0' in l: self.phaseType = 'dark' else: raise Exception('Incorrect brightness!') if 'end_invert' in l: self.endInvertTime.append(l[1] - self.startRoundTime) if 'end_adaptation' in l: self.endAdaptationTime.append(l[1] - self.startRoundTime) if 'end_collection' in l: self.endCollectionTime.append(l[1] - self.startRoundTime) if 'end_round' in l: if 'dummy' in self.traceDict: a = np.array(self.traceDict['dummy'], dtype=float) a[:,2] = tk.blinkReconstruct(a[:,2]) global rnd path = 'traces/subject%0d-%04d-%s.npy' % \ (trialDict['subject_nr'], rnd, self.phaseType) rnd += 1 print(path) np.save(path, a) del self.traceDict['dummy'] else: print('Warning: No trace collected!') self.tracePhase = None self.endRoundTime.append(l[1] - self.startRoundTime) self.roundId += 1 # Collect item information and likelihood ratios # MSG 1806804 item id="B" status=init likelihood=1 ecc=310 # angle=-0.785398163397 size=64 brightness=1 color=green opacity=0.5 # x=219.203102168 if self.tracePhase != None: # Process item if len(l) > 2 and l[2] == 'item': _dict = {} for s in l[3:]: _l = s.split('=') if len(_l) != 2: continue _dict[_l[0]] = _l[1].strip('"') if _dict['id'] == trialDict['target']: _id = 'target' else: _id = _dict['id'] if _id not in self.likelihoodTraces: self.likelihoodTraces[_id] = [] self.likelihoodTraces[_id].append(_dict['likelihood'])