def ion_dictionary(sequence):
    std_aa_mass = {
        'G': 57.02146,
        'A': 71.03711,
        'S': 87.03203,
        'P': 97.05276,
        'V': 99.06841,
        'T': 101.04768,
        'C': 103.00919,
        'L': 113.08406,
        'I': 113.08406,
        'N': 114.04293,
        'D': 115.02694,
        'Q': 128.05858,
        'K': 128.09496,
        'E': 129.04259,
        'M': 131.04049,
        'H': 137.05891,
        'F': 147.06841,
        'R': 156.10111,
        'Y': 163.06333,
        'W': 186.07931,
    }

    getmassresult = getmass(sequence)
    seq_nomod = getmassresult[0]
    moddict = getmassresult[1]
    seqlen = len(seq_nomod)

    def getmodmass(resn):
        return std_aa_mass[seq_nomod[resn-1]] + moddict[resn]

    iondict = {'a': [0], 'a+': [0], 'b': [0], 'y': [0], 'y-': [0], 'y--': [0], 'x': [0], 'x+': [0], 'c': [0], 'z': [0]}

    sum1 = 0
    sum2 = 0
    for i in range(1, len(seq_nomod)):

        sum1 += getmodmass(i)

        iondict['a'].append(sum1 - 27.9949)
        iondict['a+'].append(sum1 - 27.9949 + 1.007825)
        iondict['b'].append(sum1)
        iondict['c'].append(sum1 + 17.026549)

        i2 = seqlen - i +1
        sum2 += getmodmass(i2)

        iondict['x'].append(sum2 + 43.989830)
        iondict['x+'].append(sum2 + 43.989830 + 1.007825)
        iondict['y'].append(sum2 + 18.010565)
        iondict['y-'].append(sum2 + 18.010565 - 1.007825)
        iondict['y--'].append(sum2 + 18.010565 - 2 * 1.007825)
        iondict['z'].append(sum2 + + 17.002740 - 14.003074 - 1.007825)

    return iondict
def ion_dictionary(sequence, maxcharge):
    std_aa_mass = {
        'G': 57.02146,
        'A': 71.03711,
        'S': 87.03203,
        'P': 97.05276,
        'V': 99.06841,
        'T': 101.04768,
        'C': 103.00919,
        'L': 113.08406,
        'I': 113.08406,
        'N': 114.04293,
        'D': 115.02694,
        'Q': 128.05858,
        'K': 128.09496,
        'E': 129.04259,
        'M': 131.04049,
        'H': 137.05891,
        'F': 147.06841,
        'R': 156.10111,
        'Y': 163.06333,
        'W': 186.07931,
    }

    getmassresult = getmass(sequence)
    seq_nomod = getmassresult[0]
    moddict = getmassresult[1]
    seqlen = len(seq_nomod)

    def getmodmass(resn):
        return std_aa_mass[seq_nomod[resn-1]] + moddict[resn]

    iondict = {}

    for c in range(1, maxcharge+1):
        sum1 = 0
        for i in range(1, seqlen):
            sum1 += getmodmass(i)
            iondict[(sum1 - 27.994915 + (c * 1.007825)) / c] = [i, c]

    return iondict
def assign(sequence,raw_input):


    seqaa = getmass(sequence)[0]
    lenseq = len(seqaa)

    idict = ion_dictionary(sequence)
    pkd = peakdict(raw_input)

    intsbypos = {k:0 for k in range(1,lenseq+1)}

    nterm_types = [k for k in idict if k[0] in('a', 'b', 'c')]
    cterm_types = [k for k in idict if k[0] in('x', 'y', 'z')]


    for iontype in nterm_types:
        the_ions = idict[iontype]

        for ion in pkd:
            res = search(ion, the_ions, 10)
            if res > 0:
                intsbypos[res] += pkd[ion]

    for iontype in cterm_types:
        the_ions = idict[iontype]

        for ion in pkd:
            res = search(ion, the_ions, 10)
            if res > 0:
                intsbypos[lenseq - res + 1] += pkd[ion]

    dictrange = range(1,len(intsbypos)+1)


    outputformat =[]
    for thing in dictrange:
        outputformat.append(str(thing)+', '+str(intsbypos[thing]))

    return '<br>'.join(outputformat)
def result_table(filename, seq, maxc):
    themains = get_envelopes(filename, seq, maxc)
    seq_aa = getmass(seq)[0]

    a_ions = themains[0]  # a ions and position/charge
    discDist = themains[1]  # discovered distributions

    def maketd(text):
        return "<td>" + str(text) + "</td>"

    result = """<table border = "1"> <tr>
                <td>a.a.</td>
                <td>ion number</td>
                <td>charge state</td>
                <td>observed m/z</td>
                <td>[observed intensities]<br>[fitted intensities]</td>
                <td>(root square error)/(total signal)</td>
                <td>Relative contributions <br>[a-1, a, a+1, a+2]</td>
                <td> [a]/([a]+[a+1]) </td>
                </tr>"""

    for ion in discDist:
        optResult = getratio(ion * a_ions[ion][1], discDist[ion])
        if ((sqrt(optResult[1][1])) / sum(discDist[ion])) < 0.1:
            #optResult = getratio(ion * a_ions[ion][1], discDist[ion])
            result += "<tr>"
            result += maketd(seq_aa[a_ions[ion][0]-1])
            result += maketd(a_ions[ion][0])
            result += maketd(str(a_ions[ion][1]) + "+")
            result += maketd(ion)
            result += "<td>" + str([round(k,3) for k in discDist[ion]]) + "<br>" + str([round(k, 3) for k in optResult[1][0]]) + "</td>"
            result += maketd((sqrt(optResult[1][1])) / sum(discDist[ion]))
            result += maketd([round(k / sum(optResult[0]),3) for k in optResult[0]])
            result += maketd(float(optResult[0][1])/(optResult[0][1] + optResult[0][2]))
            result += "</tr>"

    return result