Package specific_analyses :: Package relax_disp :: Module cpmgfit
[hide private]
[frames] | no frames]

Source Code for Module specific_analyses.relax_disp.cpmgfit

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2013-2014 Edward d'Auvergne                                   # 
  4  # Copyright (C) 2014 Troels E. Linnet                                         # 
  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  """Functions for interfacing with Art Palmer's CPMGFit program.""" 
 25   
 26  # Dependencies. 
 27  import dep_check 
 28   
 29  # Python module imports. 
 30  from math import pi 
 31  from os import F_OK, access, chmod, sep 
 32  from stat import S_IRGRP, S_IROTH, S_IRWXU 
 33  PIPE, Popen = None, None 
 34  if dep_check.subprocess_module: 
 35      from subprocess import PIPE, Popen 
 36  import sys 
 37   
 38  # relax module imports. 
 39  from lib.errors import RelaxError, RelaxDirError, RelaxFileError, RelaxNoSequenceError 
 40  from lib.io import mkdir_nofail, open_write_file, test_binary 
 41  from lib.periodic_table import periodic_table 
 42  from pipe_control.pipes import check_pipe 
 43  from pipe_control.spectrometer import get_frequencies 
 44  from pipe_control.mol_res_spin import exists_mol_res_spin_data, spin_loop 
 45  from specific_analyses.relax_disp.data import loop_exp_frq_offset_point, return_param_key_from_data 
 46   
 47   
48 -def cpmgfit_execute(dir=None, binary='cpmgfit', force=False):
49 """Execute CPMGFit for each spin input file. 50 51 @keyword dir: The directory where the input files are located. If None, this defaults to the dispersion model name in lowercase. 52 @type dir: str or None 53 @keyword binary: The name of the CPMGFit binary file. This can include the path to the binary. 54 @type binary: str 55 @keyword force: A flag which if True will cause any pre-existing files to be overwritten by CPMGFit. 56 @type force: bool 57 """ 58 59 # Test if the current pipe exists. 60 check_pipe() 61 62 # Test if sequence data is loaded. 63 if not exists_mol_res_spin_data(): 64 raise RelaxNoSequenceError 65 66 # Test if the experiment type has been set. 67 if not hasattr(cdp, 'exp_type'): 68 raise RelaxError("The relaxation dispersion experiment type has not been specified.") 69 70 # Test if the model has been set. 71 if not hasattr(cdp, 'model_type'): 72 raise RelaxError("The relaxation dispersion model has not been specified.") 73 74 # The directory. 75 if dir != None and not access(dir, F_OK): 76 raise RelaxDirError('CPMGFit', dir) 77 78 # Loop over each spin. 79 for spin, spin_id in spin_loop(return_id=True, skip_desel=True): 80 # Translate the model. 81 function = translate_model(spin.model) 82 83 # The spin input file name. 84 file_in = dir + sep + spin_file_name(spin_id=spin_id) 85 if not access(file_in, F_OK): 86 raise RelaxFileError("spin input", file_in) 87 88 # The spin output file name. 89 file_out = dir + sep + spin_file_name(spin_id=spin_id, output=True) 90 91 # Test the binary file string corresponds to a valid executable. 92 test_binary(binary) 93 94 # Execute CPMGFit. 95 cmd = "%s -grid -xmgr -f %s | tee %s\n" % (binary, file_in, file_out) 96 print("\n\n%s" % cmd) 97 pipe = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, close_fds=True) 98 99 # Write to stderr. 100 for line in pipe.stderr.readlines(): 101 # Decode Python 3 byte arrays. 102 if hasattr(line, 'decode'): 103 line = line.decode() 104 105 # Write. 106 sys.stderr.write(line) 107 108 # Write to stdout. 109 for line in pipe.stdout.readlines(): 110 # Decode Python 3 byte arrays. 111 if hasattr(line, 'decode'): 112 line = line.decode() 113 114 # Write. 115 sys.stdout.write(line)
116 117
118 -def cpmgfit_input(dir=None, binary='cpmgfit', spin_id=None, force=False):
119 """Create the CPMGFit input files. 120 121 @keyword dir: The optional directory to place the files into. If None, then the files will be placed into a directory named after the dispersion model. 122 @type dir: str or None 123 @keyword binary: The name of the CPMGFit binary file. This can include the path to the binary. 124 @type binary: str 125 @keyword spin_id: The spin ID string to restrict the file creation to. 126 @type spin_id: str 127 @keyword force: A flag which if True will cause all pre-existing files to be overwritten. 128 @type force: bool 129 """ 130 131 # Test if the current pipe exists. 132 check_pipe() 133 134 # Test if sequence data is loaded. 135 if not exists_mol_res_spin_data(): 136 raise RelaxNoSequenceError 137 138 # Test if the experiment type has been set. 139 if not hasattr(cdp, 'exp_type'): 140 raise RelaxError("The relaxation dispersion experiment type has not been specified.") 141 142 # Test if the model has been set. 143 if not hasattr(cdp, 'model_type'): 144 raise RelaxError("The relaxation dispersion model has not been specified.") 145 146 # Directory creation. 147 if dir != None: 148 mkdir_nofail(dir, verbosity=0) 149 150 # The 'run.sh' script. 151 batch = open_write_file('batch_run.sh', dir, force) 152 batch.write("#! /bin/sh\n\n") 153 154 # Generate the input files for each spin. 155 for spin, spin_id in spin_loop(return_id=True, skip_desel=True): 156 # Translate the model. 157 function = translate_model(spin.model) 158 159 # Create the input file. 160 file_in = create_spin_input(function=function, spin=spin, spin_id=spin_id, dir=dir) 161 162 # The output file name. 163 file_out = spin_file_name(spin_id=spin_id, output=True) 164 165 # Add the file to the batch script. 166 batch.write("%s -grid -xmgr -f %s | tee %s\n" % (binary, file_in, file_out)) 167 168 # Close the batch script, then make it executable. 169 batch.close() 170 if dir: 171 chmod(dir + sep + 'batch_run.sh', S_IRWXU|S_IRGRP|S_IROTH) 172 else: 173 chmod('batch_run.sh', S_IRWXU|S_IRGRP|S_IROTH)
174 175
176 -def create_spin_input(function=None, spin=None, spin_id=None, dir=None):
177 """Generate the CPMGFit file for the given spin. 178 179 @keyword function: The CPMGFit model or function name. 180 @type function: str 181 @keyword spin: The spin container to generate the input file for. 182 @type spin: SpinContainer instance 183 @keyword spin_id: The spin ID string corresponding to the spin container. 184 @type spin_id: str 185 @keyword dir: The directory to place the file into. 186 @type dir: str or None 187 @return: The name of the file created. 188 @rtype: str 189 """ 190 191 # The output file. 192 file_name = spin_file_name(spin_id=spin_id) 193 file = open_write_file(file_name=file_name, dir=dir, force=True) 194 195 # The title. 196 file.write("title %s\n" % spin_id) 197 198 # The proton frequencies. 199 frq = get_frequencies(units='T') 200 201 # The frequency info. 202 file.write("fields %s" % len(frq)) 203 for i in range(len(frq)): 204 file.write(" %.10f" % frq[i]) 205 file.write("\n") 206 207 # The function and parameters. 208 if function == 'CPMG': 209 # Function. 210 file.write("function CPMG\n") 211 212 # Parameters. 213 file.write("R2 1 10 20\n") 214 file.write("Rex 0 100.0 100\n") 215 file.write("Tau 0 10.0 100\n") 216 217 # The function and parameters. 218 elif function == 'Full_CPMG': 219 # Function. 220 file.write("function Full_CPMG\n") 221 222 # Parameters. 223 file.write("R2 1 10 20\n") 224 file.write("papb 0.01 0.49 20\n") 225 file.write("dw 0 10.0 100\n") 226 file.write("kex 0.1 1.0 100\n") 227 228 # The function and parameters. 229 elif function == "Ishima": 230 # Function. 231 file.write("function Ishima\n") 232 233 # Parameters. 234 file.write("R2 1 10 20\n") 235 file.write("Rex 0 100.0 50\n") 236 file.write("PaDw 2 10.0 50\n") 237 file.write("Tau 0.1 10.0 50\n") 238 239 # The function and parameters. 240 if function == '3-site_CPMG': 241 # Function. 242 file.write("function 3-site_CPMG\n") 243 244 # Parameters. 245 file.write("R2 1 10 20\n") 246 file.write("Rex1 0 100.0 20\n") 247 file.write("Tau1 0 10.0 20\n") 248 file.write("Rex2 0 100.0 20\n") 249 file.write("Tau2 0 10.0 20\n") 250 251 # The Grace setup. 252 file.write("xmgr\n") 253 file.write("@ xaxis label \"1/tcp (1/ms)\"\n") 254 file.write("@ yaxis label \"R2(tcp) (rad/s)\"\n") 255 file.write("@ xaxis ticklabel format decimal\n") 256 file.write("@ yaxis ticklabel format decimal\n") 257 file.write("@ xaxis ticklabel char size 0.8\n") 258 file.write("@ yaxis ticklabel char size 0.8\n") 259 file.write("@ world xmin 0.0\n") 260 261 # The data. 262 file.write("data\n") 263 for exp_type, frq, offset, point in loop_exp_frq_offset_point(): 264 # The parameter key. 265 param_key = return_param_key_from_data(exp_type=exp_type, frq=frq, offset=offset, point=point) 266 267 # No data. 268 if param_key not in spin.r2eff: 269 continue 270 271 # Tesla units. 272 B0 = frq * 2.0 * pi / periodic_table.gyromagnetic_ratio('1H') 273 274 # The X value of 1/tcp (or 1/tau_CPMG) in ms. This assumes Art's usage of the definition that nu_CPMG = 1 / (2 * tau_CPMG). 275 x = 2.0 * point / 1000.0 276 277 # Write out the data and error. 278 file.write("%-20f %-20f %-20f %-20f\n" % (x, spin.r2eff[param_key], spin.r2eff_err[param_key], B0)) 279 280 # Close the file and return its name. 281 file.close() 282 return file_name
283 284
285 -def spin_file_name(spin_id=None, output=False):
286 """Generate the unique file name for the given spin ID. 287 288 @keyword spin_id: The spin ID string. 289 @type spin_id: str 290 @keyword output: A flag which if True will cause the CPMGFit output rather than input name to be returned. 291 @return: The file name. 292 @rtype: str 293 """ 294 295 # Construct the name. 296 name = "spin%s." % spin_id.replace('#', '_').replace(':', '_').replace('@', '_') 297 if output: 298 name += "out" 299 else: 300 name += "in" 301 302 # Return the file name. 303 return name
304 305
306 -def translate_model(model):
307 """Translate the dispersion model from relax notation to CPMGFit notation. 308 309 @return: The CPMGFit model name. 310 @rtype: str 311 """ 312 313 # A translation table (relax to CPMGFit models). 314 translation = { 315 'LM63': 'CPMG', 316 'LM63 3-site': '3-site_CPMG', 317 'CR72': 'Full_CPMG', 318 'IT99': 'Ishima' 319 } 320 321 # No translation, so fail. 322 if model not in translation: 323 raise RelaxError("The conversion of the relax model '%s' to a CPMGFit model is not supported." % model) 324 325 # Printout. 326 print("Translating the relax '%s' model to the CPMGFit '%s' model." % (model, translation[model])) 327 328 # Return the translated name. 329 return translation[model]
330