-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAddSpinLinksFromUpls.py
More file actions
executable file
·157 lines (130 loc) · 5.95 KB
/
AddSpinLinksFromUpls.py
File metadata and controls
executable file
·157 lines (130 loc) · 5.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/nmr/programs/python/bin/python2.5
"""
AddSpinLinksFromUpls.py reads in a CARA repository and a UPL list, and generates spin links in the repository based on the UPL list.
Use AddSpinLinksFromUpls.py -h or AddSpinLinksFromUpls.py --help to learn more about inputs.
WARNING: This script ABSOLUTELY REQUIRES that your system numbers match
your residue numbers. You must first use the script:
NumberCaraSystemsByAssignment.py
"""
### Import some libraries #################################################
from optparse import OptionParser # for parsing commandline input
from sys import stdout # for output to screen instead of to file
import xml.etree.ElementTree as ET # for parsing XML
from os.path import exists # for making sure not to overwrite files
### Helper functions ######################################################
def getProject(projectName,projects):
"""This function, getProject, is only used if the user specifies a project
name from the command line, rather than simply allowing the script to
select the first (and likely only) project in a repository."""
for project in projects:
if project.get('name') == projectName:
return project
# if that doesn't work, raise an error:
raise NameError,"There is no project named \"%s\"."%projectName
### Main body of the script ###############################################
def main():
parser = OptionParser() # creates an instance of the parser
parser.usage = "%prog -i input.cara -u uplfile.upl [-o output.cara] [-p project-name]"
parser.description = "%prog reads in a CARA repository and a UPL list, and generates spin links in the repository based on the UPL list."
parser.epilog = ""
parser.add_option("-i", "--input", dest="infile",type="string",default=None,
help="name of original CARA repository, required.", metavar="FILE")
parser.add_option("-o", "--output", dest="outfile",type="string",default=None,
help="name of new CARA repository, defaults to stdout.", metavar="FILE")
parser.add_option("-p", "--project", metavar="NAME", dest="project", default=None,type="string",
help="name of project to alter, if there is more than one project in the repository, defaults to the first project.")
parser.add_option("-u", "--upl", dest="uplfile",type="string",default=None,
help="name of upl file, required.", metavar="FILE")
# Now parse the command-line options
(options, args) = parser.parse_args()
infile = options.infile
outfile = options.outfile
projectName = options.project
uplfile = options.uplfile
if infile == None:
parser.print_help()
parser.error("Please specify an input cara file.")
if uplfile == None:
parser.print_help()
parser.error("Please specify an input upl file.")
if outfile == None:
outfile = stdout
elif exists(outfile):
print '\nOutput file \'%s\' exists. Choose a new name to avoid overwriting.\n'%outfile
return
# Now that we have an input file and we know where to send the output, we parse the xml.
tree = ET.parse(infile)
root = tree.getroot() #retrieves the whole repository
projects = root.findall('project') #retrieves every project in the repository
# Select a project according to command-line input, defaulting to the first project
if projectName:
project = getProject(projectName,projects)
if not project:
print 'No project found with name \"%s\".'%projectName
return
else:
project = projects[0]
if not project:
print 'No project found.'
return
spinbase = project.find('spinbase')
spins = spinbase.findall('spin')
pairs = spinbase.findall('pair')
spindict = {}
getSpinID = {}
pairList = []
for spin in spins:
atom = spin.get('atom')
offset = spin.get('off')
if atom == 'H1':
spinid = spin.get('id')
try:
system = int(spin.get('sys'))
tag = spin.get('tag')
spindict[spinid] = {'tag': tag, 'sys': system}
getSpinID[(system,tag)]=spinid
except Exception, e:
print "Orphan spin: ",e
# Lists of pairs:
for pair in pairs:
lhs = pair.get('lhs')
rhs = pair.get('rhs')
if int(lhs) < int(rhs):
pairList.append((lhs,rhs))
else:
pairList.append((rhs,lhs))
# Read UPLs
openfile= open(uplfile,'r')
upllines = openfile.readlines()
openfile.close()
for line in upllines:
if line[0] != '#':
try:
columns = line.split()
leftsys = int(columns[0])
lefttag = columns[2]
rightsys = int(columns[3])
righttag = columns[5]
if leftsys != rightsys:
lhs = getSpinID[(leftsys,lefttag)]
rhs = getSpinID[(rightsys,righttag)]
if int(lhs) < int(rhs) and (lhs,rhs) not in pairList:
newpair = ET.Element("pair")
newpair.attrib['lhs']=lhs
newpair.attrib['rhs']=rhs
pairList.append((lhs,rhs))
spinbase.append(newpair)
#spinbase.append(Element("pair",'lhs'=lhs,'rhs'=rhs)
elif int(rhs) < int(lhs) and (rhs,lhs) not in pairList:
newpair = ET.Element("pair")
newpair.attrib['lhs']=rhs
newpair.attrib['rhs']=lhs
spinbase.append(newpair)
#spinbase.append(Element("pair",'lhs'=rhs,'rhs'=lhs))
pairList.append((rhs,lhs))
except Exception, e:
print "Bad upl line: ",line
tree.write(outfile)
# for string in printstrings:
# print string
main()