~ubuntu-branches/ubuntu/saucy/sphinxtrain/saucy

« back to all changes in this revision

Viewing changes to python/cmusphinx/s3gaucnt.py

  • Committer: Package Import Robot
  • Author(s): Samuel Thibault
  • Date: 2013-01-02 04:10:21 UTC
  • Revision ID: package-import@ubuntu.com-20130102041021-ynsizmz33fx02hea
Tags: upstream-1.0.8
ImportĀ upstreamĀ versionĀ 1.0.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2006 Carnegie Mellon University
 
2
#
 
3
# You may copy and modify this freely under the same terms as
 
4
# Sphinx-III
 
5
 
 
6
"""Read/write Sphinx-III Gaussian parameter count files.
 
7
 
 
8
This module reads and writes the expected Gaussian mixture occupancy
 
9
count files created by SphinxTrain's implementation of the
 
10
Forward-Backward algorithm for training (semi-)continuous HMMs.
 
11
"""
 
12
 
 
13
__author__ = "David Huggins-Daines <dhuggins@cs.cmu.edu>"
 
14
__version__ = "$Revision: 8994 $"
 
15
 
 
16
from struct import unpack, pack
 
17
from numpy import array, reshape, shape, fromstring
 
18
from s3file import S3File
 
19
import os
 
20
 
 
21
def open(filename, mode="rb", attr={"version":1.0}):
 
22
    if mode in ("r", "rb"):
 
23
        return S3GauCntFile(filename, mode)
 
24
    else:
 
25
        raise Exception, "mode must be 'r' or 'rb'"
 
26
 
 
27
def accumdirs(accumdirs):
 
28
    "Read and accumulate counts from several directories"
 
29
    gauden = None
 
30
    for d in accumdirs:
 
31
        try:
 
32
            subgau = S3GauCntFile(os.path.join(d, "gauden_counts"), "rb")
 
33
        except:
 
34
            subgau = None
 
35
            continue
 
36
        if gauden == None:
 
37
            gauden = subgau
 
38
        else:
 
39
            for m, mgau in enumerate(gauden.mean):
 
40
                for f, feat in enumerate(mgau):
 
41
                    gauden.mean[m][f] += subgau.mean[m][f]
 
42
                    gauden.var[m][f] += subgau.var[m][f]
 
43
                    gauden.dnom[m][f] += subgau.dnom[m][f]
 
44
    return gauden
 
45
 
 
46
def accumdirs_full(accumdirs):
 
47
    "Read and accumulate full-covariance counts from several directories"
 
48
    gauden = None
 
49
    for d in accumdirs:
 
50
        try:
 
51
            subgau = S3FullGauCntFile(os.path.join(d, "gauden_counts"), "rb")
 
52
        except:
 
53
            subgau = None
 
54
            continue
 
55
        if gauden == None:
 
56
            gauden = subgau
 
57
        else:
 
58
            for m, mgau in enumerate(gauden.mean):
 
59
                for f, feat in enumerate(mgau):
 
60
                    gauden.mean[m][f] += subgau.mean[m][f]
 
61
                    gauden.var[m][f] += subgau.var[m][f]
 
62
                    gauden.dnom[m][f] += subgau.dnom[m][f]
 
63
    return gauden
 
64
 
 
65
def open_full(filename, mode="rb", attr={"version":1.0}):
 
66
    if mode in ("r", "rb"):
 
67
        return S3FullGauCntFile(filename, mode)
 
68
    else:
 
69
        raise Exception, "mode must be 'r', 'rb'"
 
70
 
 
71
class S3GauCntFile(S3File):
 
72
    "Read Sphinx-III format Gaussian count files"
 
73
    def __init__(self, file, mode):
 
74
        S3File.__init__(self, file, mode)
 
75
        self._load()
 
76
 
 
77
    def readgauheader(self):
 
78
        if self.fileattr["version"] != "1.0":
 
79
            raise Exception("Version mismatch: must be 1.0 but is "
 
80
                            + self.fileattr["version"])
 
81
        self.fh.seek(self.data_start, 0)
 
82
        self.has_mean = unpack(self.swap + "I", self.fh.read(4))[0]
 
83
        self.has_var = unpack(self.swap + "I", self.fh.read(4))[0]
 
84
        self.pass2var = unpack(self.swap + "I", self.fh.read(4))[0]
 
85
        self.n_mgau = unpack(self.swap + "I", self.fh.read(4))[0]
 
86
        self.density = unpack(self.swap + "I", self.fh.read(4))[0]
 
87
        self.n_feat = unpack(self.swap + "I", self.fh.read(4))[0]
 
88
        self.veclen = unpack(self.swap + "I" * self.n_feat,
 
89
                             self.fh.read(4 * self.n_feat))
 
90
        self.blk = sum(self.veclen)
 
91
 
 
92
    def _load(self):
 
93
        self.readgauheader()
 
94
        if self.has_mean:
 
95
            self.mean = self._loadgau()
 
96
        if self.has_var:
 
97
            self.var = self._loadgau()
 
98
        self.dnom = self.read3d()
 
99
 
 
100
    def _loadgau(self):
 
101
        self._nfloats = unpack(self.swap + "I", self.fh.read(4))[0]
 
102
        if self._nfloats != self.n_mgau * self.density * self.blk:
 
103
            raise Exception(("Number of data points %d doesn't match "
 
104
                             + "total %d = %d*%d*%d")
 
105
                            %
 
106
                            (self._nfloats,
 
107
                             self.n_mgau * self.density * self.blk,
 
108
                             self.n_mgau, self.density, self.blk))
 
109
        spam = self.fh.read(self._nfloats * 4)
 
110
        data = fromstring(spam, 'f')
 
111
        if self.otherend:
 
112
            data = data.byteswap()
 
113
        params = []
 
114
        r = 0
 
115
        for i in range(0, self.n_mgau):
 
116
            mgau = []
 
117
            params.append(mgau)
 
118
            for j in range(0, self.n_feat):
 
119
                rnext = r + self.density * self.veclen[j];
 
120
                gmm = reshape(data[r:rnext], (self.density, self.veclen[j]))
 
121
                mgau.append(gmm)
 
122
                r = rnext
 
123
        return params        
 
124
 
 
125
class S3FullGauCntFile(S3GauCntFile):
 
126
    "Read Sphinx-III format Gaussian full covariance matrix files"
 
127
    def _load(self):
 
128
        self.readgauheader()
 
129
        if self.has_mean:
 
130
            self.mean = self._loadgau()
 
131
        if self.has_var:
 
132
            self.var = self._loadfullgau()
 
133
        self.dnom = self.read3d()
 
134
 
 
135
    def _loadfullgau(self):
 
136
        self._nfloats = unpack(self.swap + "I", self.fh.read(4))[0]
 
137
        if self._nfloats != self.n_mgau * self.density * self.blk * self.blk:
 
138
            raise Exception(("Number of data points %d doesn't match "
 
139
                             + "total %d = %d*%d*%d*%d")
 
140
                            %
 
141
                            (self._nfloats,
 
142
                             self.n_mgau * self.density * self.blk * self.blk,
 
143
                             self.n_mgau, self.density, self.blk, self.blk))
 
144
        spam = self.fh.read(self._nfloats * 4)
 
145
        data = fromstring(spam, 'f')
 
146
        if self.otherend:
 
147
            data = data.byteswap()
 
148
        params = []
 
149
        r = 0
 
150
        for i in range(0, self.n_mgau):
 
151
            mgau = []
 
152
            params.append(mgau)
 
153
            for j in range(0, self.n_feat):
 
154
                rnext = r + self.density * self.veclen[j] * self.veclen[j];
 
155
                gmm = reshape(data[r:rnext], (self.density,
 
156
                                              self.veclen[j],
 
157
                                              self.veclen[j]))
 
158
                mgau.append(gmm)
 
159
                r = rnext
 
160
        return params