Module praatio.dataio

Code for reading, writing, and representing less complicated praat data files

see examples/get_vowel_points.py

Expand source code
'''
Code for reading, writing, and representing less complicated praat data files

see **examples/get_vowel_points.py**
'''

import io

POINT = "PointProcess"
PITCH = "PitchTier"
DURATION = "DurationTier"


class PointObject(object):
    
    def __init__(self, pointList, objectClass, minTime=0, maxTime=None):
        
        # Sanitize input
        pointList = [tuple(row) for row in pointList]
        
        self.pointList = pointList
        self.objectClass = objectClass
        self.minTime = minTime if minTime > 0 else 0
        self.maxTime = maxTime
    
    def __eq__(self, other):
        isEqual = True
        isEqual &= self.objectClass == other.objectClass
        isEqual &= self.minTime == other.minTime
        isEqual &= self.maxTime == other.maxTime
        isEqual &= len(self.pointList) == len(other.pointList)
        
        if isEqual:
            for selfEntry, otherEntry in zip(self.pointList, other.pointList):
                isEqual &= selfEntry == otherEntry
        
        return isEqual
    
    def save(self, fn):
        header = ('File type = "ooTextFile"\n'
                  'Object class = "%s"\n'
                  '\n%s\n%s\n%d')
        header %= (self.objectClass, repr(self.minTime), repr(self.maxTime),
                   len(self.pointList))
        
        tmp = [repr(val) for entry in self.pointList for val in entry]
        strPoints = "\n".join(tmp)
        
        outputStr = u"%s\n%s\n" % (header, strPoints)
        
        with io.open(fn, "w", encoding="utf-8") as fd:
            fd.write(outputStr)
    
    def getPointsInInterval(self, start, stop, startIndex=0):
    
        returnPointList = []
        for entry in self.pointList[startIndex:]:
            time = entry[0]
            if time >= start:
                if time <= stop:
                    returnPointList.append(time)
                else:
                    break
        
        return returnPointList


class PointObject1D(PointObject):
    '''Points that only carry temporal information'''

    def __init__(self, pointList, objectClass, minTime=0, maxTime=None):

        assert(objectClass != PITCH)
        assert(objectClass != DURATION)
    
        if maxTime is None:
            maxTime = max(pointList)
        
        super(PointObject1D, self).__init__(pointList, objectClass,
                                            minTime, maxTime)


class PointObject2D(PointObject):
    '''Points that carry a temporal value and some other value'''

    def __init__(self, pointList, objectClass, minTime=0, maxTime=None):

        assert(objectClass != POINT)
        
        if maxTime is None:
            maxTime = max([timeV for timeV, _ in pointList])
        
        super(PointObject2D, self).__init__(pointList, objectClass,
                                            minTime, maxTime)


def open1DPointObject(fn):
    with io.open(fn, "r", encoding='utf-8') as fd:
        data = fd.read()
    if "xmin" in data[:100]:  # Kindof lazy
        data, objectType, minT, maxT = _parseNormalHeader(fn)
        
        start = 0
        dataList = []
        while True:
            try:
                start = data.index('=', start)
            except ValueError:
                break
            
            pointVal, start = _getNextValue(data, start)
            dataList.append([float(pointVal), ])
        
        po = PointObject1D(dataList, objectType, minT, maxT)

    else:
        data, objectType, minT, maxT = _parseShortHeader(fn)
        dataList = data.split('\n')
        dataList = [[float(val), ] for val in dataList if val.strip() != '']
        po = PointObject1D(dataList, objectType, minT, maxT)
    
    return po


def open2DPointObject(fn):
    with io.open(fn, "r", encoding='utf-8') as fd:
        data = fd.read()
    if "xmin" in data[:100]:  # Kindof lazy
        data, objectType, minT, maxT = _parseNormalHeader(fn)
        
        start = 0
        dataList = []
        while True:
            try:
                start = data.index('=', start)
            except ValueError:
                break
            
            timeVal, start = _getNextValue(data, start)
            
            try:
                start = data.index('=', start)
            except ValueError:
                break
            
            pointVal, start = _getNextValue(data, start)
            dataList.append([float(timeVal), float(pointVal), ])
        
        po = PointObject2D(dataList, objectType, minT, maxT)
        
    else:
        data, objectType, minT, maxT = _parseShortHeader(fn)
        dataList = data.split('\n')
        dataList = [(float(dataList[i]), float(dataList[i + 1]))
                    for i in range(0, len(dataList), 2)
                    if dataList[i].strip() != '']
        po = PointObject2D(dataList, objectType, minT, maxT)
    
    return po


def _parseNormalHeader(fn):
    with io.open(fn, "r", encoding='utf-8') as fd:
        data = fd.read()
    
    chunkedData = data.split("\n", 7)
    
    objectType = chunkedData[1].split("=")[-1]
    objectType = objectType.replace('"', "").strip()
    
    data = chunkedData[-1]
    maxT = chunkedData[-4].split("=")[-1].strip()
    minT = chunkedData[-5].split("=")[-1].strip()
    minT, maxT = float(minT), float(maxT)
    
    return data, objectType, minT, maxT


def _getNextValue(data, start):
    end = data.index('\n', start)
    value = data[start + 1:end]
    return value, end


def _parseShortHeader(fn):
    with io.open(fn, "r", encoding='utf-8') as fd:
        data = fd.read()
    
    chunkedData = data.split("\n", 6)
    
    objectType = chunkedData[1].split("=")[-1]
    objectType = objectType.replace('"', "").strip()
    
    data = chunkedData[-1]
    maxT = chunkedData[-3]
    minT = chunkedData[-4]
    
    minT, maxT = float(minT), float(maxT)
    
    return data, objectType, minT, maxT

Functions

def open1DPointObject(fn)
Expand source code
def open1DPointObject(fn):
    with io.open(fn, "r", encoding='utf-8') as fd:
        data = fd.read()
    if "xmin" in data[:100]:  # Kindof lazy
        data, objectType, minT, maxT = _parseNormalHeader(fn)
        
        start = 0
        dataList = []
        while True:
            try:
                start = data.index('=', start)
            except ValueError:
                break
            
            pointVal, start = _getNextValue(data, start)
            dataList.append([float(pointVal), ])
        
        po = PointObject1D(dataList, objectType, minT, maxT)

    else:
        data, objectType, minT, maxT = _parseShortHeader(fn)
        dataList = data.split('\n')
        dataList = [[float(val), ] for val in dataList if val.strip() != '']
        po = PointObject1D(dataList, objectType, minT, maxT)
    
    return po
def open2DPointObject(fn)
Expand source code
def open2DPointObject(fn):
    with io.open(fn, "r", encoding='utf-8') as fd:
        data = fd.read()
    if "xmin" in data[:100]:  # Kindof lazy
        data, objectType, minT, maxT = _parseNormalHeader(fn)
        
        start = 0
        dataList = []
        while True:
            try:
                start = data.index('=', start)
            except ValueError:
                break
            
            timeVal, start = _getNextValue(data, start)
            
            try:
                start = data.index('=', start)
            except ValueError:
                break
            
            pointVal, start = _getNextValue(data, start)
            dataList.append([float(timeVal), float(pointVal), ])
        
        po = PointObject2D(dataList, objectType, minT, maxT)
        
    else:
        data, objectType, minT, maxT = _parseShortHeader(fn)
        dataList = data.split('\n')
        dataList = [(float(dataList[i]), float(dataList[i + 1]))
                    for i in range(0, len(dataList), 2)
                    if dataList[i].strip() != '']
        po = PointObject2D(dataList, objectType, minT, maxT)
    
    return po

Classes

class PointObject (pointList, objectClass, minTime=0, maxTime=None)
Expand source code
class PointObject(object):
    
    def __init__(self, pointList, objectClass, minTime=0, maxTime=None):
        
        # Sanitize input
        pointList = [tuple(row) for row in pointList]
        
        self.pointList = pointList
        self.objectClass = objectClass
        self.minTime = minTime if minTime > 0 else 0
        self.maxTime = maxTime
    
    def __eq__(self, other):
        isEqual = True
        isEqual &= self.objectClass == other.objectClass
        isEqual &= self.minTime == other.minTime
        isEqual &= self.maxTime == other.maxTime
        isEqual &= len(self.pointList) == len(other.pointList)
        
        if isEqual:
            for selfEntry, otherEntry in zip(self.pointList, other.pointList):
                isEqual &= selfEntry == otherEntry
        
        return isEqual
    
    def save(self, fn):
        header = ('File type = "ooTextFile"\n'
                  'Object class = "%s"\n'
                  '\n%s\n%s\n%d')
        header %= (self.objectClass, repr(self.minTime), repr(self.maxTime),
                   len(self.pointList))
        
        tmp = [repr(val) for entry in self.pointList for val in entry]
        strPoints = "\n".join(tmp)
        
        outputStr = u"%s\n%s\n" % (header, strPoints)
        
        with io.open(fn, "w", encoding="utf-8") as fd:
            fd.write(outputStr)
    
    def getPointsInInterval(self, start, stop, startIndex=0):
    
        returnPointList = []
        for entry in self.pointList[startIndex:]:
            time = entry[0]
            if time >= start:
                if time <= stop:
                    returnPointList.append(time)
                else:
                    break
        
        return returnPointList

Subclasses

Methods

def getPointsInInterval(self, start, stop, startIndex=0)
Expand source code
def getPointsInInterval(self, start, stop, startIndex=0):

    returnPointList = []
    for entry in self.pointList[startIndex:]:
        time = entry[0]
        if time >= start:
            if time <= stop:
                returnPointList.append(time)
            else:
                break
    
    return returnPointList
def save(self, fn)
Expand source code
def save(self, fn):
    header = ('File type = "ooTextFile"\n'
              'Object class = "%s"\n'
              '\n%s\n%s\n%d')
    header %= (self.objectClass, repr(self.minTime), repr(self.maxTime),
               len(self.pointList))
    
    tmp = [repr(val) for entry in self.pointList for val in entry]
    strPoints = "\n".join(tmp)
    
    outputStr = u"%s\n%s\n" % (header, strPoints)
    
    with io.open(fn, "w", encoding="utf-8") as fd:
        fd.write(outputStr)
class PointObject1D (pointList, objectClass, minTime=0, maxTime=None)

Points that only carry temporal information

Expand source code
class PointObject1D(PointObject):
    '''Points that only carry temporal information'''

    def __init__(self, pointList, objectClass, minTime=0, maxTime=None):

        assert(objectClass != PITCH)
        assert(objectClass != DURATION)
    
        if maxTime is None:
            maxTime = max(pointList)
        
        super(PointObject1D, self).__init__(pointList, objectClass,
                                            minTime, maxTime)

Ancestors

class PointObject2D (pointList, objectClass, minTime=0, maxTime=None)

Points that carry a temporal value and some other value

Expand source code
class PointObject2D(PointObject):
    '''Points that carry a temporal value and some other value'''

    def __init__(self, pointList, objectClass, minTime=0, maxTime=None):

        assert(objectClass != POINT)
        
        if maxTime is None:
            maxTime = max([timeV for timeV, _ in pointList])
        
        super(PointObject2D, self).__init__(pointList, objectClass,
                                            minTime, maxTime)

Ancestors