1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module for the manipulation of J coupling data."""
24
25
26 import sys
27 from warnings import warn
28
29
30 from lib.check_types import is_float
31 from lib.errors import RelaxError, RelaxNoJError, RelaxNoSequenceError
32 from lib.io import extract_data, open_write_file, strip, write_data
33 from lib.warnings import RelaxWarning
34 from pipe_control import pipes
35 from pipe_control.interatomic import consistent_interatomic_data, create_interatom, interatomic_loop, return_interatom
36 from pipe_control.mol_res_spin import exists_mol_res_spin_data, return_spin
37
38
76
77
78 -def copy(pipe_from=None, pipe_to=None):
79 """Copy the J coupling data from one data pipe to another.
80
81 @keyword pipe_from: The data pipe to copy the J coupling data from. This defaults to the current data pipe.
82 @type pipe_from: str
83 @keyword pipe_to: The data pipe to copy the J coupling data to. This defaults to the current data pipe.
84 @type pipe_to: str
85 """
86
87
88 if pipe_from == None and pipe_to == None:
89 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.")
90 elif pipe_from == None:
91 pipe_from = pipes.cdp_name()
92 elif pipe_to == None:
93 pipe_to = pipes.cdp_name()
94
95
96 check_pipe_setup(pipe=pipe_from, sequence=True, j=True)
97 check_pipe_setup(pipe=pipe_to, sequence=True)
98
99
100 dp_from = pipes.get_pipe(pipe_from)
101 dp_to = pipes.get_pipe(pipe_to)
102
103
104 consistent_interatomic_data(pipe1=pipe_to, pipe2=pipe_from)
105
106
107 for i in range(len(dp_from.interatomic)):
108
109 interatom_from = dp_from.interatomic[i]
110 interatom_to = dp_to.interatomic[i]
111
112
113 if not hasattr(interatom_from, 'j_coupling') or not hasattr(interatom_from, 'j_coupling_err'):
114 continue
115
116
117 if hasattr(interatom_from, 'j_coupling'):
118 interatom_to.j_coupling = interatom_from.j_coupling
119 if hasattr(interatom_from, 'j_coupling_err'):
120 interatom_to.j_coupling_err = interatom_from.j_coupling_err
121
122
138
139
148
149
150 -def read(file=None, dir=None, file_data=None, spin_id1_col=None, spin_id2_col=None, data_col=None, error_col=None, sign_col=None, sep=None):
151 """Read the J coupling data from file.
152
153 @keyword file: The name of the file to open.
154 @type file: str
155 @keyword dir: The directory containing the file (defaults to the current directory if None).
156 @type dir: str or None
157 @keyword file_data: An alternative to opening a file, if the data already exists in the correct format. The format is a list of lists where the first index corresponds to the row and the second the column.
158 @type file_data: list of lists
159 @keyword spin_id1_col: The column containing the spin ID strings of the first spin.
160 @type spin_id1_col: int
161 @keyword spin_id2_col: The column containing the spin ID strings of the second spin.
162 @type spin_id2_col: int
163 @keyword data_col: The column containing the J coupling data in Hz.
164 @type data_col: int or None
165 @keyword error_col: The column containing the J coupling errors.
166 @type error_col: int or None
167 @keyword sign_col: The optional column containing the sign of the J coupling.
168 @type sign_col: int or None
169 @keyword sep: The column separator which, if None, defaults to whitespace.
170 @type sep: str or None
171 """
172
173
174 check_pipe_setup(sequence=True)
175
176
177 if data_col == None and error_col == None:
178 raise RelaxError("One of either the data or error column must be supplied.")
179
180
181 file_data = extract_data(file, dir, sep=sep)
182 file_data = strip(file_data, comments=True)
183
184
185 data = []
186 for line in file_data:
187
188 if spin_id1_col > len(line):
189 warn(RelaxWarning("The data %s is invalid, no first spin ID column can be found." % line))
190 continue
191 if spin_id2_col > len(line):
192 warn(RelaxWarning("The data %s is invalid, no second spin ID column can be found." % line))
193 continue
194 if data_col and data_col > len(line):
195 warn(RelaxWarning("The data %s is invalid, no data column can be found." % line))
196 continue
197 if error_col and error_col > len(line):
198 warn(RelaxWarning("The data %s is invalid, no error column can be found." % line))
199 continue
200 if sign_col and sign_col > len(line):
201 warn(RelaxWarning("The data %s is invalid, no sign column can be found." % line))
202 continue
203
204
205 spin_id1 = line[spin_id1_col-1]
206 spin_id2 = line[spin_id2_col-1]
207 value = None
208 if data_col:
209 value = line[data_col-1]
210 error = None
211 if error_col:
212 error = line[error_col-1]
213 sign = None
214 if sign_col:
215 sign = line[sign_col-1]
216
217
218 if spin_id1[0] in ["\"", "\'"]:
219 spin_id1 = eval(spin_id1)
220 if spin_id2[0] in ["\"", "\'"]:
221 spin_id2 = eval(spin_id2)
222
223
224 if value == 'None':
225 value = None
226 if value != None:
227 try:
228 value = float(value)
229 except ValueError:
230 warn(RelaxWarning("The J coupling value of the line %s is invalid." % line))
231 continue
232
233
234 if sign == 'None':
235 sign = None
236 if sign != None:
237 try:
238 sign = float(sign)
239 except ValueError:
240 warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line))
241 continue
242 if sign not in [1.0, -1.0]:
243 warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line))
244 continue
245
246
247 if error == 'None':
248 error = None
249 if error != None:
250 try:
251 error = float(error)
252 except ValueError:
253 warn(RelaxWarning("The error value of the line %s is invalid." % line))
254 continue
255
256
257 spin1 = return_spin(spin_id1)
258 spin2 = return_spin(spin_id2)
259
260
261 if not spin1:
262 warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id1, line)))
263 continue
264 if not spin2:
265 warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id2, line)))
266 continue
267
268
269 if error == 0.0:
270 raise RelaxError("An invalid error value of zero has been encountered.")
271
272
273 interatom = return_interatom(spin_id1, spin_id2)
274
275
276 if interatom == None:
277 interatom = create_interatom(spin_id1=spin_id1, spin_id2=spin_id2)
278
279
280 if data_col:
281
282 if sign != None:
283 value = value * sign
284
285
286 interatom.j_coupling = value
287
288
289 if error_col:
290 interatom.j_coupling_err = error
291
292
293 data.append([spin_id1, spin_id2])
294 if is_float(value):
295 data[-1].append("%20.15f" % value)
296 else:
297 data[-1].append("%20s" % value)
298 if is_float(error):
299 data[-1].append("%20.15f" % error)
300 else:
301 data[-1].append("%20s" % error)
302
303
304 if not len(data):
305 raise RelaxError("No J coupling data could be extracted.")
306
307
308 print("The following J coupling have been loaded into the relax data store:\n")
309 write_data(out=sys.stdout, headings=["Spin_ID1", "Spin_ID2", "Value", "Error"], data=data)
310
311
312 -def write(file=None, dir=None, force=False):
313 """Write the J coupling data to file.
314
315 @keyword file: The file name or object to write to.
316 @type file: str or file object
317 @keyword dir: The name of the directory to place the file into (defaults to the current directory).
318 @type dir: str
319 @keyword force: A flag which if True will cause any pre-existing file to be overwritten.
320 @type force: bool
321 """
322
323
324 check_pipe_setup(sequence=True, j=True)
325
326
327 file = open_write_file(file, dir, force)
328
329
330 data = []
331 for interatom in interatomic_loop():
332
333 if not interatom.select:
334 continue
335
336
337 if not hasattr(interatom, 'j_coupling'):
338 continue
339
340
341 data.append([])
342 data[-1].append(interatom.spin_id1)
343 data[-1].append(interatom.spin_id2)
344
345
346 data[-1].append(repr(interatom.j_coupling))
347
348
349 if hasattr(interatom, 'j_coupling_err'):
350 data[-1].append(repr(interatom.j_coupling_err))
351 else:
352 data[-1].append(repr(None))
353
354
355 write_data(out=file, headings=["Spin_ID1", "Spin_ID2", "J coupling", "J coupling"], data=data)
356