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