Package csb :: Package bio :: Package io :: Module cs
[frames] | no frames]

Source Code for Module csb.bio.io.cs

  1  """ 
  2  Simple NMR STAR chemical shift readers. 
  3  """ 
  4   
  5  from csb.bio.nmr import ChemShiftInfo 
6 7 8 -class ChemShiftFormatError(ValueError):
9 pass
10
11 12 -class ChemShiftReader(object):
13 """ 14 Simple NMR STAR v2 chemical shift reader. 15 16 @note: This is not a full-fledged, semantic NMR STAR parser. It handles 17 only the chemical shift table. 18 """ 19 20 FRAME = 'save_assigned_chemical_shifts' 21 22 RANK = '_Residue_seq_code' 23 RESIDUE = '_Residue_label' 24 ATOM = '_Atom_name' 25 ELEMENT = '_Atom_type' 26 SHIFT = '_Chem_shift_value' 27 28 @staticmethod
29 - def create(frame=FRAME, version=2):
30 """ 31 Parser factory: create a new parser, given a saveframe name 32 and format verison. 33 34 @param frame: name of the saveframe to read 35 @type frame: str 36 @param version: NMR STAR format version 37 @type version: int 38 39 @return: an instance of any L{ChemShiftReader} class 40 @rtype: L{ChemShiftReader} 41 """ 42 43 if version == 3: 44 return ChemShift3Reader(frame=frame) 45 elif version == 2: 46 return ChemShiftReader(frame=frame) 47 else: 48 raise ValueError('Unknown NMR-STAR version')
49 50 @staticmethod
51 - def guess(file, frame=FRAME):
52 """ 53 Parser factory: try to guess the correct NMR STAR version from a given 54 file and create an appropriate parser. 55 56 @param file: NMR STAR path and file name 57 @type file: str 58 @param frame: name of the saveframe to read 59 @type frame: str 60 61 @return: an instance of any L{ChemShiftReader} class 62 @rtype: L{ChemShiftReader} 63 64 @raise ChemShiftFormatError: on failure to determine the NMR STAR version 65 """ 66 67 with open(file) as cs: 68 content = cs.read() 69 70 if not content.strip(): 71 return ChemShiftReader.create() 72 elif ChemShift3Reader.SHIFT3 in content: 73 return ChemShiftReader.create(frame, version=3) 74 elif ChemShiftReader.SHIFT in content: 75 return ChemShiftReader.create(frame, version=2) 76 else: 77 raise ChemShiftFormatError("Can't guess NMR-STAR version")
78
79 - def __init__(self, frame=FRAME):
80 self._frame = frame
81
82 - def read_file(self, filename):
83 """ 84 Parse the specified file. 85 86 @param filename: file path and name 87 @type filename: str 88 89 @rtype: tuple of L{ChemShiftInfo} 90 """ 91 with open(filename) as input: 92 return self.read_shifts(input.read())
93
94 - def read_shifts(self, star_table):
95 """ 96 Parse a given NMR STAR chemical shift table. 97 98 @param star_table: NMR STAR chemical shift table 99 @type star_table: str 100 101 @rtype: tuple of L{ChemShiftInfo} 102 @raise ChemShiftFormatError: on parse error 103 """ 104 105 shifts = [] 106 107 init = False 108 in_shifts = False 109 fields = [] 110 lines = iter(star_table.splitlines()) 111 112 if self._frame in star_table: 113 self._scroll(lines, self._frame) 114 115 116 for l in lines: 117 ls = l.strip() 118 119 if not in_shifts: 120 121 if ls == 'loop_': 122 assert in_shifts is False and not fields and init is False 123 init = True 124 continue 125 126 elif init and ls.startswith('_'): 127 assert in_shifts is False 128 fields.append(l.strip()) 129 continue 130 131 elif init and not ls: 132 if len(fields) < 1: 133 raise ChemShiftFormatError("No fields found in the CS table") 134 in_shifts = True 135 continue 136 137 else: 138 139 if ls == 'stop_': 140 break 141 142 elif ls.startswith('#'): 143 continue 144 145 elif ls: 146 values = l.split() 147 if len(values) < len(fields): 148 raise ChemShiftFormatError("Insufficient number of values: {0}".format(l)) 149 data = dict(zip(fields, values)) 150 151 shifts.append(self._create_shift(data)) 152 153 return tuple(shifts)
154
155 - def _scroll(self, iterator, field):
156 157 for line in iterator: 158 if line.lstrip().startswith(field): 159 break
160
161 - def _create_shift(self, data):
162 163 try: 164 position = int(data[ChemShiftReader.RANK]) 165 residue = data[ChemShiftReader.RESIDUE] 166 name = data[ChemShiftReader.ATOM] 167 element = data[ChemShiftReader.ELEMENT] 168 shift = float(data[ChemShiftReader.SHIFT]) 169 170 except KeyError as ke: 171 raise ChemShiftFormatError("Required field {0} not found".format(str(ke))) 172 except ValueError as ve: 173 raise ChemShiftFormatError("Can't parse value: {0}".format(str(ve))) 174 175 return ChemShiftInfo(position, residue, name, element, shift)
176
177 178 -class ChemShift3Reader(ChemShiftReader):
179 """ 180 Simple NMR STAR v3 chemical shift reader. 181 182 @note: This is not a full-fledged, semantic NMR STAR parser. It handles 183 only the chemical shift table. 184 """ 185 186 RANK3 = '_Atom_chem_shift.Seq_ID' 187 RESIDUE3 = '_Atom_chem_shift.Comp_ID' 188 ATOM3 = '_Atom_chem_shift.Atom_ID' 189 ELEMENT3 = '_Atom_chem_shift.Atom_type' 190 SHIFT3 = '_Atom_chem_shift.Val' 191
192 - def _create_shift(self, data):
193 194 try: 195 position = data[ChemShift3Reader.RANK3] 196 residue = data[ChemShift3Reader.RESIDUE3] 197 name = data[ChemShift3Reader.ATOM3] 198 element = data[ChemShift3Reader.ELEMENT3] 199 shift = data[ChemShift3Reader.SHIFT3] 200 201 except KeyError as ke: 202 raise ChemShiftFormatError("Required field {0} not found".format(str(ke))) 203 except ValueError as ve: 204 raise ChemShiftFormatError("Can't parse value: {0}".format(str(ve))) 205 206 return ChemShiftInfo(position, residue, name, element, shift)
207