#!/usr/bin/python
#######################################################################
# convert SHIFTX 1.0 output into SHIFTX+ output format
# to enable the use of SHIFTX 1.0 in SHIFTX2
# author: Yifeng Liu
# date: august 18th, 2010
#######################################################################
import sys, re

# amino acid name dictionary
aa_name_dict = {
    'A' : 'ALA',     'C' : 'CYS',    'D' : 'ASP',    'E' : 'GLU',
    'F' : 'PHE',     'G' : 'GLY',    'H' : 'HIS',    'I' : 'ILE',
    'K' : 'LYS',     'L' : 'LEU',    'M' : 'MET',    'N' : 'ASN',
    'P' : 'PRO',     'Q' : 'GLN',    'R' : 'ARG',    'S' : 'SER',
    'T' : 'THR',     'V' : 'VAL',    'W' : 'TRP',    'Y' : 'TYR'
}

#            2    3     4    5    6      7
backbone_header = ['NUM', 'RES', 'HA', 'H', 'N', 'CA', 'CB', 'C']
#                   0       1      2     3     4     5      6      7      8      9       10      11    12     13    14      15       16     17     18    19     20      21      22    23      24
sidechain_header = ['NUM', 'RES', 'H', 'HA', 'HB', 'HB2', 'HB3', 'HD1', 'HD2', 'HD21', 'HD22', 'HD3', 'HE', 'HE1', 'HE2', 'HE21', 'HE22', 'HE3', 'HG', 'HG1', 'HG12', 'HG13', 'HG2', 'HG3', 'HZ']

# SHIFTX 1.0 OUTPUT FORMAT
#   NUM RES   HA     H       N        CA      CB       C
# --- --- ------ ------ -------- ------- ------- --------
#  1     S  4.4936 8.1776 116.7852 57.9721 64.8573 175.0875
#  2     D  4.2141 8.1221 120.3899 54.7598 39.3950 175.4580
#  3     K  4.4371 8.6280 118.9586 56.0155 33.5996 176.5779
#  4     I  4.4771 7.1672 121.1627 59.8501 38.2802 175.7995
#  5     I  3.8416 8.5077 128.9524 61.5196 38.2056 174.7097
#  6     H  4.8054 8.7645 128.0765 55.4195 29.8713 174.5060
#  7     L  4.7755 8.3999 126.4800 53.6087 43.3963 175.9637
#  
# SHIFTX+ OUTPUT FORMAT
# NUM RES IUPAC ATOM  PRED_CS
# 1,SER,S,H,8.4504
# 1,SER,S,HA,4.3157
# 1,SER,S,C,174.9460

def convert_section(lines, sectiontype):
    ''' convert the backbone into csv output '''
    outlines = []
    start_index = 2
    if sectiontype != "backbone":
        start_index = 4
        
    for line in lines:
        if line.strip()=="" or line.startswith('*'):
            continue # skip blank lines and inaccurate shiftx predictions (identified by *)

        tmplist = re.split("\\s+", line.strip())

        resnum = tmplist[0]
        restype = tmplist[1]
        resname = aa_name_dict[tmplist[1]]

        for i in range(start_index, len(tmplist)):
            atomname = ""
            if sectiontype == "backbone":
                atomname = backbone_header[i]
            else:
                atomname = sidechain_header[i]

            cs = tmplist[i]
            if float(tmplist[i])>0: # skip 0.0000 shifts
                outstr = resnum + "," + resname + "," + restype + "," + atomname + "," + cs
                outlines.append(outstr)
    
    return "\n".join(outlines)
           
def separate_sections(lines):
    ''' separate the backbone and sidechain lines'''
    backbone_lines = []
    sidechain_lines = []
    INBACKBONE = True

    for line in lines:
        if line.strip() == "":
            INBACKBONE = False
        if line.strip().startswith('NUM') or ('---' in line):
            continue # skip the header and --- line

        if INBACKBONE:
            backbone_lines.append(line)
        else:
            sidechain_lines.append(line)

    return (backbone_lines, sidechain_lines)

##############################################################################
# main program
##############################################################################
if __name__ == '__main__':
    if len(sys.argv)<2:
        print "Usage: python shiftx2shiftxp.py [shiftx1.output] [output.out]"
        sys.exit(-1)

    infile = sys.argv[1]
    outfile = sys.argv[2]
    
    input = open(infile, 'r')
    lines = input.readlines()
    input.close()
    
    (backbone_lines, sidechain_lines) = separate_sections(lines)
    backbone = convert_section(backbone_lines, "backbone")
    sidechain = convert_section(sidechain_lines, "sidechain")    

    output = open(outfile, 'w')
    print >>output, "NUM RES IUPAC ATOM  PRED_CS"
    print >>output, backbone
    print >>output 
    print >>output, sidechain
    output.close()

    

    
