PK CNPH 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)
PK 9~]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
PK uh.HsR eyelinkparser/__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
PK dH^-
4 python_eyelinkparser-0.2.0.dist-info/DESCRIPTION.rstUNKNOWN
PK dH@AF 2 python_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"}PK dHs\ 2 python_eyelinkparser-0.2.0.dist-info/top_level.txteyelinkparser
PK dHndn n * 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
PK dH7A_ _ - 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
PK dHuo6 6 + 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
PK CNPH i@ eyelinkparser/_events.pyPK 9~]H=sk* * eyelinkparser/_eyelinkparser.pyPK uh.HsR 2 eyelinkparser/__init__.pyPK dH^-
4 " python_eyelinkparser-0.2.0.dist-info/DESCRIPTION.rstPK dH@AF 2 u" python_eyelinkparser-0.2.0.dist-info/metadata.jsonPK dHs\ 2 % python_eyelinkparser-0.2.0.dist-info/top_level.txtPK dHndn n *
&