Package Bio :: Package NMR :: Module xpktools
[hide private]
[frames] | no frames]

Source Code for Module Bio.NMR.xpktools

  1  # xpktools.py: A python module containing function definitions and classes 
  2  #          useful for manipulating data from nmrview .xpk peaklist files. 
  3  # 
  4  # ********** INDEX of functions and classes ********** 
  5  # 
  6  #    XpkEntry class: A class suited for handling single lines of 
  7  #        non-header data from an nmrview .xpk file.  This class 
  8  #        provides methods for extracting data by the field name 
  9  #        which is listed in the last line of the peaklist header. 
 10   
 11  from __future__ import print_function 
 12   
 13  import sys 
 14   
 15  # * * * * * INITIALIZATIONS * * * * * 
 16  HEADERLEN = 6 
 17  # * * * * * _______________ * * * * * 
 18   
 19   
20 -class XpkEntry(object):
21 # Usage: XpkEntry(xpkentry,xpkheadline) where xpkentry is the line 22 # from an nmrview .xpk file and xpkheadline is the line from 23 # the header file that gives the names of the entries 24 # which is typcially the sixth line of the header (counting fm 1) 25 # Variables are accessed by either their name in the header line as in 26 # self.field["H1.P"] will return the H1.P entry for example. 27 # self.field["entrynum"] returns the line number (1st field of line) 28
29 - def __init__(self, entry, headline):
30 self.fields = {} # Holds all fields from input line in a dictionary 31 # keys are data labels from the .xpk header 32 datlist = entry.split() 33 headlist = headline.split() 34 35 i = 0 36 for i in range(len(datlist) - 1): 37 self.fields[headlist[i]] = datlist[i+1] 38 i = i + 1 39 40 try: 41 self.fields["entrynum"] = datlist[0] 42 except IndexError as e: 43 pass
44 45
46 -class Peaklist(object):
47 # This class reads in an entire xpk file and returns 48 # Header file lines are available as attributes 49 # The data lines are available as a list
50 - def __init__(self, infn):
51 52 with open(infn, 'r') as infile: 53 54 # Read in the header lines 55 self.firstline = infile.readline().split("\012")[0] 56 self.axislabels = infile.readline().split("\012")[0] 57 self.dataset = infile.readline().split("\012")[0] 58 self.sw = infile.readline().split("\012")[0] 59 self.sf = infile.readline().split("\012")[0] 60 self.datalabels = infile.readline().split("\012")[0] 61 62 # Read in the data lines to a list 63 self.data = [line.split("\012")[0] for line in infile]
64
65 - def residue_dict(self, index):
66 # Generate a dictionary idexed by residue number or a nucleus 67 # The nucleus should be given as the input argument in the 68 # same form as it appears in the xpk label line (H1, 15N for example) 69 70 maxres = -1 71 minres = -1 72 73 # Cast the data lines into the xpentry class 74 self.dict = {} 75 for i in range(len(self.data)): 76 line = self.data[i] 77 ind = XpkEntry(line, self.datalabels).fields[index + ".L"] 78 key = ind.split(".")[0] 79 80 res = int(key) 81 82 if (maxres == -1): 83 maxres = res 84 if (minres == -1): 85 minres = res 86 87 maxres = max([maxres, res]) 88 minres = min([minres, res]) 89 90 if str(res) in self.dict: 91 # Append additional data to list under same key 92 templst = self.dict[str(res)] 93 templst.append(line) 94 self.dict[str(res)] = templst 95 96 else: 97 # This is a new residue, start a new list 98 self.dict[str(res)] = [line] # Use [] for list type 99 100 self.dict["maxres"] = maxres 101 self.dict["minres"] = minres 102 103 return self.dict
104
105 - def write_header(self, outfn):
106 with open(outfn, 'wb') as outfile: 107 outfile.write(self.firstline) 108 outfile.write("\012") 109 outfile.write(self.axislabels) 110 outfile.write("\012") 111 outfile.write(self.dataset) 112 outfile.write("\012") 113 outfile.write(self.sw) 114 outfile.write("\012") 115 outfile.write(self.sf) 116 outfile.write("\012") 117 outfile.write(self.datalabels) 118 outfile.write("\012")
119 120
121 -def replace_entry(line, fieldn, newentry):
122 # Replace an entry in a string by the field number 123 # No padding is implemented currently. Spacing will change if 124 # the original field entry and the new field entry are of 125 # different lengths. 126 # This method depends on xpktools._find_start_entry 127 128 start = _find_start_entry(line, fieldn) 129 leng = len(line[start:].split()[0]) 130 newline = line[:start] + str(newentry) + line[(start+leng):] 131 return newline
132 133
134 -def _find_start_entry(line, n):
135 # find the starting point character for the n'th entry in 136 # a space delimited line. n is counted starting with 1 137 # The n=1 field by definition begins at the first character 138 # This function is used by replace_entry 139 140 infield = 0 # A flag that indicates that the counter is in a field 141 142 if (n == 1): 143 return 0 # Special case 144 145 # Count the number of fields by counting spaces 146 c = 1 147 leng = len(line) 148 149 # Initialize variables according to whether the first character 150 # is a space or a character 151 if (line[0] == " "): 152 infield = 0 153 field = 0 154 else: 155 infield = 1 156 field = 1 157 158 while (c < leng and field < n): 159 if (infield): 160 if (line[c] == " " and not (line[c-1] == " ")): 161 infield = 0 162 else: 163 if (not line[c] == " "): 164 infield = 1 165 field = field + 1 166 167 c = c + 1 168 169 return c - 1
170 171
172 -def data_table(fn_list, datalabel, keyatom):
173 # Generate and generate a data table from a list of 174 # input xpk files <fn_list>. The data element reported is 175 # <datalabel> and the index for the data table is by the 176 # nucleus indicated by <keyatom>. 177 178 outlist = [] 179 180 [dict_list, label_line_list] = _read_dicts(fn_list, keyatom) 181 182 # Find global max and min residue numbers 183 minr = dict_list[0]["minres"] 184 maxr = dict_list[0]["maxres"] 185 186 for dictionary in dict_list: 187 if (maxr < dictionary["maxres"]): 188 maxr = dictionary["maxres"] 189 if (minr > dictionary["minres"]): 190 minr = dictionary["minres"] 191 192 res = minr 193 while res <= maxr: # s.t. res numbers 194 count = 0 195 line = str(res) 196 for dictionary in dict_list: # s.t. dictionaries 197 label = label_line_list[count] 198 if str(res) in dictionary: 199 line = line + "\t" + XpkEntry(dictionary[str(res)][0], label).fields[datalabel] 200 else: 201 line = line + "\t" + "*" 202 count = count + 1 203 line = line + "\n" 204 outlist.append(line) 205 res = res + 1 206 207 return outlist
208 209
210 -def _read_dicts(fn_list, keyatom):
211 # Read multiple files into a list of residue dictionaries 212 dict_list = [] 213 datalabel_list = [] 214 for fn in fn_list: 215 peaklist = Peaklist(fn) 216 dict = peaklist.residue_dict(keyatom) 217 dict_list.append(dict) 218 datalabel_list.append(peaklist.datalabels) 219 220 return [dict_list, datalabel_list]
221