def sub_rates(stats, annots):
nucs = ['<STR_LIT:A>', '<STR_LIT:T>', '<STR_LIT>', '<STR_LIT:C>']<EOL>subs = {} <EOL>for cds in annots:<EOL><INDENT>locus, location, info = cds<EOL>subs[locus] = {}<EOL>start, end, strand = location<EOL>trans_table = info['<STR_LIT>'][<NUM_LIT:0>]<EOL>wrt_reference = {'<STR_LIT>':<NUM_LIT:0>, '<STR_LIT>':<NUM_LIT:0>, '<STR_LIT>':<NUM_LIT:0>, '<STR_LIT>':<NUM_LIT:0>}<EOL>wrt_consensus = {'<STR_LIT>':<NUM_LIT:0>, '<STR_LIT>':<NUM_LIT:0>, '<STR_LIT>':<NUM_LIT:0>, '<STR_LIT>':<NUM_LIT:0>} <EOL>for codon in parse_codons(stats, start, end, strand):<EOL><INDENT>ref_codon = [i['<STR_LIT>'] for i in codon]<EOL>con_codon = [i['<STR_LIT>'][<NUM_LIT:0>] for i in codon]<EOL>ref_aa = codon2aa(ref_codon, trans_table)<EOL>con_aa = codon2aa(con_codon, trans_table)<EOL>wrt_reference =count_mutations(ref_codon, ref_aa, codon, wrt_reference, nucs, trans_table) <EOL>wrt_consensus =count_mutations(con_codon, con_aa, codon, wrt_consensus, nucs, trans_table)<EOL><DEDENT>subs[locus]['<STR_LIT>']       = calc_PnPs(wrt_reference)<EOL>subs[locus]['<STR_LIT>'] = calc_PnPs(wrt_consensus)<EOL>locus_length = end - start + <NUM_LIT:1><EOL>subs[locus]['<STR_LIT>']= float(wrt_reference['<STR_LIT>'] + wrt_reference['<STR_LIT>']) / locus_length<EOL>subs[locus]['<STR_LIT>']= float(wrt_consensus['<STR_LIT>'] + wrt_consensus['<STR_LIT>']) / locus_length<EOL>subs[locus]['<STR_LIT>'] = calc_coverage(stats, start, end, locus_length, nucs)<EOL>info['<STR_LIT>'] = locus_length<EOL>info['<STR_LIT>'] = ((start, end), strand)<EOL>subs[locus]['<STR_LIT:info>'] = info<EOL><DEDENT>return subs<EOL>
calculate syn and non-syn sub. rates for each locus/gene