Calculate conservation levels at each consensus position.

    Return a dict of {position: float conservation}

def get_conservation(block):
    """Calculate conservation levels at each consensus position.

    Return a dict of {position: float conservation}
    """
    consensus = block['sequences'][0]['seq']
    assert all(c.isupper() for c in consensus), \
            "So-called consensus contains indels!"
    # remove all non-consensus positions -- now alignment is easy
    cleaned = [[c for c in s['seq'] if not c.islower()]
               for s in block['sequences'][1:]]
    height = float(len(cleaned))
    # validation
    for row in cleaned:
        if len(row) != len(consensus):
            raise ValueError("Aligned sequence length (%s) doesn't match "
                             "consensus (%s)"
                             % (len(row), len(consensus)))
    # transpose & go
    columns = zip(*cleaned)
    return dict((idx + 1, columns[idx].count(cons_char) / height)
                for idx, cons_char in enumerate(consensus))