PKCNPH i@ eyelinkparser/_events.py# -*- coding: utf-8 -*- """ This file is part of eyelinkparser. eyelinkparser is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. eyelinkparser is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with datamatrix. If not, see . """ import warnings import numbers from datamatrix.py3compat import * import numpy as np class Event(object): def assert_numeric(self, l, indices): for i in indices: if not isinstance(l[i], numbers.Number) or l[i] <= 0: raise TypeError() class Fixation(Event): """ desc: Format (short): EFIX R 1651574 1654007 2434 653.3 557.8 4710 EFIX R 299705 299872 168 509.0 341.1 2024 Format (long): TODO """ def __init__(self, l): if len(l) != 8 or l[0] != "EFIX": raise TypeError() self.assert_numeric(l, range(2,8)) self.x = l[5] self.y = l[6] self.pupil_size = l[7] self.st = l[2] self.et = l[3] self.duration = self.et - self.st class Sample(Event): """ desc: # Normal: [Timestamp] [x] [y] [pupil size] ... 4815155 168.2 406.5 2141.0 ... # During blinks: 661781 . . 0.0 ... # Elaborate format: 548367 514.0 354.5 1340.0 ... -619.0 -161.0 88.9 ...CFT..R.BLR """ def __init__(self, l): if len(l) not in (5, 9) or isinstance(l[0], basestring): raise TypeError() self.assert_numeric(l, [0]) self.t = l[0] if l[1] == '.': self.x = np.nan else: self.x = l[1] if l[2] == '.': self.y = np.nan else: self.y = l[2] if l[3] in (0, '.'): self.pupil_size = np.nan else: self.pupil_size = l[3] class Saccade(Event): """ desc: Format: ESACC R 3216221 3216233 13 515.2 381.6 531.2 390.7 0.51 58 Format (long) TODO """ def __init__(self, l): if len(l) not in (11, 15) or l[0] != u'ESACC': raise TypeError() if len(l) == 11: self.assert_numeric(l, [2,3,5,6,7,8]) self.sx = l[5] self.sy = l[6] self.ex = l[7] self.ey = l[8] else: self.assert_numeric(l, [2,3,9,10,11,12]) self.sx = l[9] self.sy = l[10] self.ex = l[11] self.ey = l[12] self.size = np.sqrt((self.sx-self.ex)**2 + (self.sy-self.ey)**2) self.st = l[2] self.et = l[3] self.duration = self.et - self.st def event(l, cls): try: return cls(l) except TypeError: pass except Exception as e: warnings.warn( u'Unexpected exception during parsing of %s' % safe_decode(e)) def sample(l): return event(l, Sample) def fixation(l): return event(l, Fixation) def saccade(l): return event(l, Saccade) PK9~]H=sk**eyelinkparser/_eyelinkparser.py# -*- coding: utf-8 -*- """ This file is part of eyelinkparser. eyelinkparser is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. eyelinkparser is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with datamatrix. If not, see . """ import math import sys import shlex import os from datamatrix import DataMatrix, SeriesColumn, operations from datamatrix.py3compat import * from eyelinkparser import sample import numpy as np import numbers import warnings class EyeLinkParser(object): def __init__(self, folder=u'data', ext=u'.asc'): self.dm = DataMatrix() for fname in sorted(os.listdir(folder)): if not fname.endswith(ext): continue path = os.path.join(folder, fname) self.dm <<= self.parse_file(path) operations.auto_type(self.dm) # Helper functions that can be overridden def on_start_file(self): pass def on_end_file(self): pass def on_start_trial(self): pass def on_end_trial(self): pass def parse_line(self, l): pass # Internal functions def print_(self, s): sys.stdout.write(s) sys.stdout.flush() def parse_file(self, path): self.filedm = DataMatrix() self.print_(u'Parsing %s ' % path) self.path = path self.on_start_file() ntrial = 0 with open(path) as f: for line in f: l = self.split(line) if self.is_start_trial(l): ntrial += 1 self.print_(u'.') self.filedm <<= self.parse_trial(f) self.on_end_file() self.print_(u' (%d trials)\n' % ntrial) return self.filedm def parse_trial(self, f): self.trialdm = DataMatrix(length=1) self.trialdm.path = self.path self.trialdm.trialid = self.trialid self.on_start_trial() for line in f: l = self.split(line) if self.is_end_trial(l): break self.parse_variable(l) self.parse_phase(l) self.parse_line(l) if self.current_phase is not None: warnings.warn( u'Trial ended while phase "%s" was still ongoing' \ % self.current_phase) self.end_phase() self.on_end_trial() return self.trialdm def parse_variable(self, l): # MSG 6740629 var rt 805 if len(l) == 5 and l[0] == u'MSG' and l[2] == u'var': var = l[3] val = l[4] if var in self.trialdm: warnings.warn(u'Variable "%s" defined twice in one trial' % var) self.trialdm[var] = val def start_phase(self, l): if self.current_phase is not None: warnings.warn( u'Phase "%s" started while phase "%s" was still ongoing' \ % (l[3], self.current_phase)) self.end_phase() self.current_phase = l[3] assert(self.current_phase not in self.trialdm) self.ptrace = [] self.xtrace = [] self.ytrace = [] def end_phase(self): for prefix, trace in [ (u'ptrace_', self.ptrace), (u'xtrace_', self.xtrace), (u'ytrace_', self.ytrace), ]: colname = prefix + self.current_phase self.trialdm[colname] = SeriesColumn( len(trace), defaultnan=True) self.trialdm[colname][0] = trace self.current_phase = None def parse_phase(self, l): # MSG [timestamp] start_phase [name] if len(l) == 4 and l[0] == u'MSG' \ and l[2] in (u'start_phase', u'phase'): self.start_phase(l) return # MSG [timestamp] end_phase [name] if len(l) == 4 and l[0] == u'MSG' \ and l[2] in (u'end_phase', u'stop_phase'): assert(self.current_phase == l[3]) self.end_phase() return if self.current_phase is None: return s = sample(l) if s is None: return self.ptrace.append(s.pupil_size) self.xtrace.append(s.x) self.ytrace.append(s.y) def is_start_trial(self, l): # MSG 6735155 start_trial 1 if len(l) == 4 and l[0] == u'MSG' and l[2] == u'start_trial': self.trialid = l[3] self.current_phase = None return True return False def is_end_trial(self, l): # MSG 6740629 end_trial if len(l) == 3 and l[0] == u'MSG' \ and l[2] in (u'end_trial', u'stop_trial'): self.trialid = None return True return False def split(self, line): l = [] for s in shlex.split(line): try: l.append(int(s)) except: try: # Make sure we don't convert 'inf' and 'nan' strings to # float assert(not math.isinf(float(s))) assert(not math.isnan(float(s))) l.append(float(s)) except: l.append(s) return l PKuh.HsReyelinkparser/__init__.py# -*- coding: utf-8 -*- """ This file is part of eyelinkparser. eyelinkparser is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. eyelinkparser is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with datamatrix. If not, see . """ from datamatrix import cached from datamatrix.py3compat import * from eyelinkparser._events import sample, fixation, saccade from eyelinkparser._eyelinkparser import EyeLinkParser @cached def parse(parser=EyeLinkParser, **kwdict): return parser(**kwdict).dm PKdH^- 4python_eyelinkparser-0.2.0.dist-info/DESCRIPTION.rstUNKNOWN PKdH@AF2python_eyelinkparser-0.2.0.dist-info/metadata.json{"classifiers": ["Development Status :: 4 - Beta", "Intended Audience :: Science/Research", "Topic :: Scientific/Engineering", "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3"], "extensions": {"python.details": {"contacts": [{"email": "s.mathot@cogsci.nl", "name": "Sebastiaan Mathot", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/smathot/python-eyelinkparser"}}}, "generator": "bdist_wheel (0.26.0)", "license": "GNU GPL Version 3", "metadata_version": "2.0", "name": "python-eyelinkparser", "summary": "An extensible parser for EyeLink data files (EDF)", "version": "0.2.0"}PKdHs\2python_eyelinkparser-0.2.0.dist-info/top_level.txteyelinkparser PKdHndnn*python_eyelinkparser-0.2.0.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PKdH7A__-python_eyelinkparser-0.2.0.dist-info/METADATAMetadata-Version: 2.0 Name: python-eyelinkparser Version: 0.2.0 Summary: An extensible parser for EyeLink data files (EDF) Home-page: https://github.com/smathot/python-eyelinkparser Author: Sebastiaan Mathot Author-email: s.mathot@cogsci.nl License: GNU GPL Version 3 Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Science/Research Classifier: Topic :: Scientific/Engineering Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3) Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 3 UNKNOWN PKdHuo66+python_eyelinkparser-0.2.0.dist-info/RECORDeyelinkparser/__init__.py,sha256=djNmVPp8Q-7ydF7F8Ug52T9MYj1qokQowAIXWLULoTE,944 eyelinkparser/_events.py,sha256=wAYa4fDZVims5_vOrq1M1xbBjxcOyo4Kij_UvcjBxjY,2965 eyelinkparser/_eyelinkparser.py,sha256=x62MTg2YaV6ohII8hAcstMSxkQEXxniRYGStkvE2yRs,4650 python_eyelinkparser-0.2.0.dist-info/DESCRIPTION.rst,sha256=OCTuuN6LcWulhHS3d5rfjdsQtW22n7HENFRh6jC6ego,10 python_eyelinkparser-0.2.0.dist-info/METADATA,sha256=DfXpRu7ltfh9fs1LDimQUi97sT6tBoomyUmNR8DJmpE,607 python_eyelinkparser-0.2.0.dist-info/RECORD,, python_eyelinkparser-0.2.0.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 python_eyelinkparser-0.2.0.dist-info/metadata.json,sha256=X2Ivz_YJjz0lCQVJDZGHos3ueoQ8Ns4pRulMYe6VFoI,746 python_eyelinkparser-0.2.0.dist-info/top_level.txt,sha256=WIn8YTa8x6AGcis32VFfFLf8ZumyipZtXc-itPxRL7o,14 PKCNPH i@ eyelinkparser/_events.pyPK9~]H=sk** eyelinkparser/_eyelinkparser.pyPKuh.HsR2eyelinkparser/__init__.pyPKdH^- 4"python_eyelinkparser-0.2.0.dist-info/DESCRIPTION.rstPKdH@AF2u"python_eyelinkparser-0.2.0.dist-info/metadata.jsonPKdHs\2%python_eyelinkparser-0.2.0.dist-info/top_level.txtPKdHndnn* &python_eyelinkparser-0.2.0.dist-info/WHEELPKdH7A__-&python_eyelinkparser-0.2.0.dist-info/METADATAPKdHuo66+m)python_eyelinkparser-0.2.0.dist-info/RECORDPK ,