Package pipe_control :: Module j_coupling
[hide private]
[frames] | no frames]

Source Code for Module pipe_control.j_coupling

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2013 Edward d'Auvergne                                   # 
  4  # Copyright (C) 2006 Chris MacRaild                                           # 
  5  #                                                                             # 
  6  # This file is part of the program relax (http://www.nmr-relax.com).          # 
  7  #                                                                             # 
  8  # This program is free software: you can redistribute it and/or modify        # 
  9  # it under the terms of the GNU General Public License as published by        # 
 10  # the Free Software Foundation, either version 3 of the License, or           # 
 11  # (at your option) any later version.                                         # 
 12  #                                                                             # 
 13  # This program is distributed in the hope that it will be useful,             # 
 14  # but WITHOUT ANY WARRANTY; without even the implied warranty of              # 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               # 
 16  # GNU General Public License for more details.                                # 
 17  #                                                                             # 
 18  # You should have received a copy of the GNU General Public License           # 
 19  # along with this program.  If not, see <http://www.gnu.org/licenses/>.       # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Module docstring. 
 24  """Module for the manipulation of J coupling data.""" 
 25   
 26  # Python module imports. 
 27  import sys 
 28  from warnings import warn 
 29   
 30  # relax module imports. 
 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   
41 -def check_pipe_setup(pipe=None, sequence=False, j=False):
42 """Check that the current data pipe has been setup sufficiently. 43 44 @keyword pipe: The data pipe to check, defaulting to the current pipe. 45 @type pipe: None or str 46 @keyword sequence: A flag which when True will invoke the sequence data check. 47 @type sequence: bool 48 @keyword j: A flag which if True will check that J couplings exist. 49 @type j: bool 50 """ 51 52 # The data pipe. 53 if pipe == None: 54 pipe = pipes.cdp_name() 55 56 # Get the data pipe. 57 dp = pipes.get_pipe(pipe) 58 59 # Test if the current data pipe exists. 60 check_pipe(pipe) 61 62 # Test if sequence data exists. 63 if sequence and not exists_mol_res_spin_data(pipe): 64 raise RelaxNoSequenceError(pipe) 65 66 # Test if J coupling data exists. 67 if j: 68 # Search for interatomic data. 69 data = False 70 for interatom in interatomic_loop(): 71 if hasattr(interatom, 'j_coupling'): 72 data = True 73 break 74 75 # No data. 76 if not data: 77 raise RelaxNoJError()
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 # Defaults. 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 # Check the pipe setup. 98 check_pipe_setup(pipe=pipe_from, sequence=True, j=True) 99 check_pipe_setup(pipe=pipe_to, sequence=True) 100 101 # Get the data pipes. 102 dp_from = pipes.get_pipe(pipe_from) 103 dp_to = pipes.get_pipe(pipe_to) 104 105 # Test that the interatomic data is consistent between the two data pipe. 106 consistent_interatomic_data(pipe1=pipe_to, pipe2=pipe_from) 107 108 # Loop over the interatomic data. 109 for i in range(len(dp_from.interatomic)): 110 # Alias the containers. 111 interatom_from = dp_from.interatomic[i] 112 interatom_to = dp_to.interatomic[i] 113 114 # No data or errors. 115 if not hasattr(interatom_from, 'j_coupling') or not hasattr(interatom_from, 'j_coupling_err'): 116 continue 117 118 # Copy the value and error from pipe_from. 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
125 -def delete():
126 """Delete all J coupling data.""" 127 128 # Check the pipe setup. 129 check_pipe_setup(sequence=True, j=True) 130 131 # The interatomic data. 132 for interatom in interatomic_loop(): 133 # The data. 134 if hasattr(interatom, 'j_coupling'): 135 del interatom.j_coupling 136 137 # The error. 138 if hasattr(interatom, 'j_coupling_err'): 139 del interatom.j_coupling_err
140 141
142 -def display():
143 """Display the J coupling data.""" 144 145 # Check the pipe setup. 146 check_pipe_setup(sequence=True, j=True) 147 148 # Call the write method with sys.stdout as the file. 149 write(file=sys.stdout)
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 # Check the pipe setup. 176 check_pipe_setup(sequence=True) 177 178 # Either the data or error column must be supplied. 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 # Extract the data from the file, and remove comments and blank lines. 183 file_data = extract_data(file, dir, sep=sep) 184 file_data = strip(file_data, comments=True) 185 186 # Loop over the J coupling data. 187 data = [] 188 for line in file_data: 189 # Invalid columns. 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 # Unpack. 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 # Convert the spin IDs. 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 # Convert and check the value. 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 # The sign data. 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 # Convert and check the error. 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 # Get the spins. 259 spin1 = return_spin(spin_id=spin_id1) 260 spin2 = return_spin(spin_id=spin_id2) 261 262 # Check the spin IDs. 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 # Test the error value (cannot be 0.0). 271 if error == 0.0: 272 raise RelaxError("An invalid error value of zero has been encountered.") 273 274 # Get the interatomic data container. 275 interatom = return_interatom(spin_hash1=spin1._hash, spin_hash2=spin2._hash) 276 277 # Create the container if needed. 278 if interatom == None: 279 interatom = create_interatom(spin_id1=spin_id1, spin_id2=spin_id2) 280 281 # Add the data. 282 if data_col: 283 # Sign conversion. 284 if sign != None: 285 value = value * sign 286 287 # Add the value. 288 interatom.j_coupling = value 289 290 # Add the error. 291 if error_col: 292 interatom.j_coupling_err = error 293 294 # Append the data for printout. 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 # No data, so fail hard! 306 if not len(data): 307 raise RelaxError("No J coupling data could be extracted.") 308 309 # Print out. 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 # Check the pipe setup. 326 check_pipe_setup(sequence=True, j=True) 327 328 # Open the file for writing. 329 file = open_write_file(file, dir, force) 330 331 # Loop over the interatomic data containers and collect the data. 332 data = [] 333 for interatom in interatomic_loop(): 334 # Skip deselected containers. 335 if not interatom.select: 336 continue 337 338 # Skip containers with no J coupling. 339 if not hasattr(interatom, 'j_coupling'): 340 continue 341 342 # Append the spin data. 343 data.append([]) 344 data[-1].append(interatom.spin_id1) 345 data[-1].append(interatom.spin_id2) 346 347 # The value. 348 data[-1].append(repr(interatom.j_coupling)) 349 350 # The error. 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 # Write out. 357 write_data(out=file, headings=["Spin_ID1", "Spin_ID2", "J coupling", "J coupling"], data=data)
358