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-2014 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  from pipe_control.pipes import check_pipe 
 38   
 39   
40 -def check_pipe_setup(pipe=None, sequence=False, j=False):
41 """Check that the current data pipe has been setup sufficiently. 42 43 @keyword pipe: The data pipe to check, defaulting to the current pipe. 44 @type pipe: None or str 45 @keyword sequence: A flag which when True will invoke the sequence data check. 46 @type sequence: bool 47 @keyword j: A flag which if True will check that J couplings exist. 48 @type j: bool 49 """ 50 51 # The data pipe. 52 if pipe == None: 53 pipe = pipes.cdp_name() 54 55 # Get the data pipe. 56 dp = pipes.get_pipe(pipe) 57 58 # Test if the current data pipe exists. 59 check_pipe(pipe) 60 61 # Test if sequence data exists. 62 if sequence and not exists_mol_res_spin_data(pipe): 63 raise RelaxNoSequenceError(pipe) 64 65 # Test if J coupling data exists. 66 if j: 67 # Search for interatomic data. 68 data = False 69 for interatom in interatomic_loop(): 70 if hasattr(interatom, 'j_coupling'): 71 data = True 72 break 73 74 # No data. 75 if not data: 76 raise RelaxNoJError()
77 78
79 -def copy(pipe_from=None, pipe_to=None):
80 """Copy the J coupling data from one data pipe to another. 81 82 @keyword pipe_from: The data pipe to copy the J coupling data from. This defaults to the current data pipe. 83 @type pipe_from: str 84 @keyword pipe_to: The data pipe to copy the J coupling data to. This defaults to the current data pipe. 85 @type pipe_to: str 86 """ 87 88 # Defaults. 89 if pipe_from == None and pipe_to == None: 90 raise RelaxError("The pipe_from and pipe_to arguments cannot both be set to None.") 91 elif pipe_from == None: 92 pipe_from = pipes.cdp_name() 93 elif pipe_to == None: 94 pipe_to = pipes.cdp_name() 95 96 # Check the pipe setup. 97 check_pipe_setup(pipe=pipe_from, sequence=True, j=True) 98 check_pipe_setup(pipe=pipe_to, sequence=True) 99 100 # Get the data pipes. 101 dp_from = pipes.get_pipe(pipe_from) 102 dp_to = pipes.get_pipe(pipe_to) 103 104 # Test that the interatomic data is consistent between the two data pipe. 105 consistent_interatomic_data(pipe1=pipe_to, pipe2=pipe_from) 106 107 # Loop over the interatomic data. 108 for i in range(len(dp_from.interatomic)): 109 # Alias the containers. 110 interatom_from = dp_from.interatomic[i] 111 interatom_to = dp_to.interatomic[i] 112 113 # No data or errors. 114 if not hasattr(interatom_from, 'j_coupling') or not hasattr(interatom_from, 'j_coupling_err'): 115 continue 116 117 # Copy the value and error from pipe_from. 118 if hasattr(interatom_from, 'j_coupling'): 119 interatom_to.j_coupling = interatom_from.j_coupling 120 if hasattr(interatom_from, 'j_coupling_err'): 121 interatom_to.j_coupling_err = interatom_from.j_coupling_err
122 123
124 -def delete():
125 """Delete all J coupling data.""" 126 127 # Check the pipe setup. 128 check_pipe_setup(sequence=True, j=True) 129 130 # The interatomic data. 131 for interatom in interatomic_loop(): 132 # The data. 133 if hasattr(interatom, 'j_coupling'): 134 del interatom.j_coupling 135 136 # The error. 137 if hasattr(interatom, 'j_coupling_err'): 138 del interatom.j_coupling_err
139 140
141 -def display():
142 """Display the J coupling data.""" 143 144 # Check the pipe setup. 145 check_pipe_setup(sequence=True, j=True) 146 147 # Call the write method with sys.stdout as the file. 148 write(file=sys.stdout)
149 150
151 -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):
152 """Read the J coupling data from file. 153 154 @keyword file: The name of the file to open. 155 @type file: str 156 @keyword dir: The directory containing the file (defaults to the current directory if None). 157 @type dir: str or None 158 @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. 159 @type file_data: list of lists 160 @keyword spin_id1_col: The column containing the spin ID strings of the first spin. 161 @type spin_id1_col: int 162 @keyword spin_id2_col: The column containing the spin ID strings of the second spin. 163 @type spin_id2_col: int 164 @keyword data_col: The column containing the J coupling data in Hz. 165 @type data_col: int or None 166 @keyword error_col: The column containing the J coupling errors. 167 @type error_col: int or None 168 @keyword sign_col: The optional column containing the sign of the J coupling. 169 @type sign_col: int or None 170 @keyword sep: The column separator which, if None, defaults to whitespace. 171 @type sep: str or None 172 """ 173 174 # Check the pipe setup. 175 check_pipe_setup(sequence=True) 176 177 # Either the data or error column must be supplied. 178 if data_col == None and error_col == None: 179 raise RelaxError("One of either the data or error column must be supplied.") 180 181 # Extract the data from the file, and remove comments and blank lines. 182 file_data = extract_data(file, dir, sep=sep) 183 file_data = strip(file_data, comments=True) 184 185 # Loop over the J coupling data. 186 data = [] 187 for line in file_data: 188 # Invalid columns. 189 if spin_id1_col > len(line): 190 warn(RelaxWarning("The data %s is invalid, no first spin ID column can be found." % line)) 191 continue 192 if spin_id2_col > len(line): 193 warn(RelaxWarning("The data %s is invalid, no second spin ID column can be found." % line)) 194 continue 195 if data_col and data_col > len(line): 196 warn(RelaxWarning("The data %s is invalid, no data column can be found." % line)) 197 continue 198 if error_col and error_col > len(line): 199 warn(RelaxWarning("The data %s is invalid, no error column can be found." % line)) 200 continue 201 if sign_col and sign_col > len(line): 202 warn(RelaxWarning("The data %s is invalid, no sign column can be found." % line)) 203 continue 204 205 # Unpack. 206 spin_id1 = line[spin_id1_col-1] 207 spin_id2 = line[spin_id2_col-1] 208 value = None 209 if data_col: 210 value = line[data_col-1] 211 error = None 212 if error_col: 213 error = line[error_col-1] 214 sign = None 215 if sign_col: 216 sign = line[sign_col-1] 217 218 # Convert the spin IDs. 219 if spin_id1[0] in ["\"", "\'"]: 220 spin_id1 = eval(spin_id1) 221 if spin_id2[0] in ["\"", "\'"]: 222 spin_id2 = eval(spin_id2) 223 224 # Convert and check the value. 225 if value == 'None': 226 value = None 227 if value != None: 228 try: 229 value = float(value) 230 except ValueError: 231 warn(RelaxWarning("The J coupling value of the line %s is invalid." % line)) 232 continue 233 234 # The sign data. 235 if sign == 'None': 236 sign = None 237 if sign != None: 238 try: 239 sign = float(sign) 240 except ValueError: 241 warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line)) 242 continue 243 if sign not in [1.0, -1.0]: 244 warn(RelaxWarning("The J coupling sign of the line %s is invalid." % line)) 245 continue 246 247 # Convert and check the error. 248 if error == 'None': 249 error = None 250 if error != None: 251 try: 252 error = float(error) 253 except ValueError: 254 warn(RelaxWarning("The error value of the line %s is invalid." % line)) 255 continue 256 257 # Get the spins. 258 spin1 = return_spin(spin_id1) 259 spin2 = return_spin(spin_id2) 260 261 # Check the spin IDs. 262 if not spin1: 263 warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id1, line))) 264 continue 265 if not spin2: 266 warn(RelaxWarning("The spin ID '%s' cannot be found in the current data pipe, skipping the data %s." % (spin_id2, line))) 267 continue 268 269 # Test the error value (cannot be 0.0). 270 if error == 0.0: 271 raise RelaxError("An invalid error value of zero has been encountered.") 272 273 # Get the interatomic data container. 274 interatom = return_interatom(spin_id1, spin_id2) 275 276 # Create the container if needed. 277 if interatom == None: 278 interatom = create_interatom(spin_id1=spin_id1, spin_id2=spin_id2) 279 280 # Add the data. 281 if data_col: 282 # Sign conversion. 283 if sign != None: 284 value = value * sign 285 286 # Add the value. 287 interatom.j_coupling = value 288 289 # Add the error. 290 if error_col: 291 interatom.j_coupling_err = error 292 293 # Append the data for printout. 294 data.append([spin_id1, spin_id2]) 295 if is_float(value): 296 data[-1].append("%20.15f" % value) 297 else: 298 data[-1].append("%20s" % value) 299 if is_float(error): 300 data[-1].append("%20.15f" % error) 301 else: 302 data[-1].append("%20s" % error) 303 304 # No data, so fail hard! 305 if not len(data): 306 raise RelaxError("No J coupling data could be extracted.") 307 308 # Print out. 309 print("The following J coupling have been loaded into the relax data store:\n") 310 write_data(out=sys.stdout, headings=["Spin_ID1", "Spin_ID2", "Value", "Error"], data=data)
311 312
313 -def write(file=None, dir=None, force=False):
314 """Write the J coupling data to file. 315 316 @keyword file: The file name or object to write to. 317 @type file: str or file object 318 @keyword dir: The name of the directory to place the file into (defaults to the current directory). 319 @type dir: str 320 @keyword force: A flag which if True will cause any pre-existing file to be overwritten. 321 @type force: bool 322 """ 323 324 # Check the pipe setup. 325 check_pipe_setup(sequence=True, j=True) 326 327 # Open the file for writing. 328 file = open_write_file(file, dir, force) 329 330 # Loop over the interatomic data containers and collect the data. 331 data = [] 332 for interatom in interatomic_loop(): 333 # Skip deselected containers. 334 if not interatom.select: 335 continue 336 337 # Skip containers with no J coupling. 338 if not hasattr(interatom, 'j_coupling'): 339 continue 340 341 # Append the spin data. 342 data.append([]) 343 data[-1].append(interatom.spin_id1) 344 data[-1].append(interatom.spin_id2) 345 346 # The value. 347 data[-1].append(repr(interatom.j_coupling)) 348 349 # The error. 350 if hasattr(interatom, 'j_coupling_err'): 351 data[-1].append(repr(interatom.j_coupling_err)) 352 else: 353 data[-1].append(repr(None)) 354 355 # Write out. 356 write_data(out=file, headings=["Spin_ID1", "Spin_ID2", "J coupling", "J coupling"], data=data)
357