# utility file for reading distance matrices stored in basic PHYLIP format

def parse(filename):
    """Read matrix of distances form Phylip-formatted file.

    Return list of names and dictionary structure such that
    d[a][b] is the distance between names[a] and names[b].
    """
    try:
        with open(filename) as src:
            lines = [line.strip() for line in src if line.strip()]

        try:
            n = int(lines[0])
        except ValueError:
            raise ValueError('First line of file should contain number of samples')

        if n < 2:
            raise ValueError('N must be 2 or more')

        if len(lines) < 1+n:
            raise ValueError('Not enough lines of data')

        names = [line.split()[0] for line in lines[1:1+n]]
        dist = []
        for k in range(n):
            pieces = lines[1+k].split()[1:]
            try:
                vals = [float(v) for v in pieces]
            except ValueError:
                raise ValueError('invalid distance on line ' + str(2+k))

            if len(vals) != n:
                raise ValueError('line %d should have %d entries' % (2+k,n))

            dist.append( { j : vals[j] for j in range(n) } )
    except IOError:
        print('Unable to open file:',filename)
        raise

    return names,dist
