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