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