Package specific_fns :: Module jw_mapping
[hide private]
[frames] | no frames]

Source Code for Module specific_fns.jw_mapping

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2004-2012 Edward d'Auvergne                                   # 
  4  #                                                                             # 
  5  # This file is part of the program relax.                                     # 
  6  #                                                                             # 
  7  # relax 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 2 of the License, or           # 
 10  # (at your option) any later version.                                         # 
 11  #                                                                             # 
 12  # relax 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 relax; if not, write to the Free Software                        # 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   # 
 20  #                                                                             # 
 21  ############################################################################### 
 22   
 23  # Python module imports. 
 24  from re import search 
 25  from warnings import warn 
 26   
 27  # relax module imports. 
 28  from api_base import API_base 
 29  from api_common import API_common 
 30  from generic_fns.mol_res_spin import exists_mol_res_spin_data, return_spin, spin_loop 
 31  from generic_fns import pipes 
 32  from maths_fns.jw_mapping import Mapping 
 33  from physical_constants import N15_CSA, NH_BOND_LENGTH, h_bar, mu0, return_gyromagnetic_ratio 
 34  from relax_errors import RelaxError, RelaxFuncSetupError, RelaxNoSequenceError, RelaxNoValueError, RelaxProtonTypeError, RelaxSpinTypeError 
 35  from relax_warnings import RelaxDeselectWarning 
 36  import specific_fns 
 37  from user_functions.data import Uf_tables; uf_tables = Uf_tables() 
 38  from user_functions.objects import Desc_container 
 39   
 40   
41 -class Jw_mapping(API_base, API_common):
42 """Class containing functions specific to reduced spectral density mapping.""" 43
44 - def __init__(self):
45 """Initialise the class by placing API_common methods into the API.""" 46 47 # Execute the base class __init__ method. 48 super(Jw_mapping, self).__init__() 49 50 # Place methods into the API. 51 self.base_data_loop = self._base_data_loop_spin 52 self.create_mc_data = self._create_mc_relax_data 53 self.model_loop = self._model_loop_spin 54 self.return_conversion_factor = self._return_no_conversion_factor 55 self.return_error = self._return_error_relax_data 56 self.return_value = self._return_value_general 57 self.set_param_values = self._set_param_values_spin 58 self.set_selected_sim = self._set_selected_sim_spin 59 self.sim_pack_data = self._sim_pack_relax_data 60 61 # Set up the spin parameters. 62 self.PARAMS.add('j0', scope='spin', string='J(0)', desc='Spectral density value at 0 MHz', py_type=float, set='params', grace_string='\\qJ(0)\\Q', err=True, sim=True) 63 self.PARAMS.add('jwx', scope='spin', string='J(wX)', desc='Spectral density value at the frequency of the heteronucleus', py_type=float, set='params', grace_string='\\qJ(\\xw\\f{}\\sX\\N)\\Q', err=True, sim=True) 64 self.PARAMS.add('jwh', scope='spin', string='J(wH)', desc='Spectral density value at the frequency of the proton', py_type=float, set='params', grace_string='\\qJ(\\xw\\f{}\\sH\\N)\\Q', err=True, sim=True) 65 self.PARAMS.add('r', scope='spin', default=NH_BOND_LENGTH, units='Angstrom', desc='Bond length', py_type=float, grace_string='Bond length') 66 self.PARAMS.add('csa', scope='spin', default=N15_CSA, units='ppm', desc='CSA value', py_type=float, grace_string='\\qCSA\\Q') 67 self.PARAMS.add('heteronuc_type', scope='spin', default='15N', desc='The heteronucleus type', py_type=str) 68 self.PARAMS.add('proton_type', scope='spin', default='1H', desc='The proton type', py_type=str)
69 70
71 - def _set_frq(self, frq=None):
72 """Function for selecting which relaxation data to use in the J(w) mapping.""" 73 74 # Test if the current pipe exists. 75 pipes.test() 76 77 # Test if the pipe type is set to 'jw'. 78 function_type = cdp.pipe_type 79 if function_type != 'jw': 80 raise RelaxFuncSetupError(specific_fns.setup.get_string(function_type)) 81 82 # Test if the frequency has been set. 83 if hasattr(cdp, 'jw_frq'): 84 raise RelaxError("The frequency has already been set.") 85 86 # Create the data structure if it doesn't exist. 87 if not hasattr(cdp, 'jw_frq'): 88 cdp.jw_frq = {} 89 90 # Set the frequency. 91 cdp.jw_frq = frq
92 93
94 - def calculate(self, spin_id=None, verbosity=1, sim_index=None):
95 """Calculation of the spectral density values. 96 97 @keyword spin_id: The spin identification string. 98 @type spin_id: None or str 99 @keyword verbosity: The amount of information to print. The higher the value, the greater the verbosity. 100 @type verbosity: int 101 @keyword sim_index: The optional MC simulation index. 102 @type sim_index: None or int 103 """ 104 105 # Test if the frequency has been set. 106 if not hasattr(cdp, 'jw_frq') or not isinstance(cdp.jw_frq, float): 107 raise RelaxError("The frequency has not been set up.") 108 109 # Test if the sequence data is loaded. 110 if not exists_mol_res_spin_data(): 111 raise RelaxNoSequenceError 112 113 # Test if the CSA and bond length values have been set. 114 for spin in spin_loop(spin_id): 115 # Skip deselected spins. 116 if not spin.select: 117 continue 118 119 # Test if the CSA value has been set. 120 if not hasattr(spin, 'csa') or spin.csa == None: 121 raise RelaxNoValueError("CSA") 122 123 # Test if the bond length has been set. 124 if not hasattr(spin, 'r') or spin.r == None: 125 raise RelaxNoValueError("bond length") 126 127 # Test if the spin type has been set. 128 if not hasattr(spin, 'heteronuc_type'): 129 raise RelaxSpinTypeError 130 131 # Test if the type attached proton has been set. 132 if not hasattr(spin, 'proton_type'): 133 raise RelaxProtonTypeError 134 135 # Frequency index. 136 if cdp.jw_frq not in cdp.frq.values(): 137 raise RelaxError("No relaxation data corresponding to the frequency " + repr(cdp.jw_frq) + " has been loaded.") 138 139 # Reduced spectral density mapping. 140 for spin in spin_loop(spin_id): 141 # Skip deselected spins. 142 if not spin.select: 143 continue 144 145 # Set the r1, r2, and NOE to None. 146 r1 = None 147 r2 = None 148 noe = None 149 150 # Get the R1, R2, and NOE values corresponding to the set frequency. 151 for ri_id in cdp.ri_ids: 152 # The frequency does not match. 153 if cdp.frq[ri_id] != cdp.jw_frq: 154 continue 155 156 # R1. 157 if cdp.ri_type[ri_id] == 'R1': 158 if sim_index == None: 159 r1 = spin.ri_data[ri_id] 160 else: 161 r1 = spin.ri_data_sim[ri_id][sim_index] 162 163 # R2. 164 if cdp.ri_type[ri_id] == 'R2': 165 if sim_index == None: 166 r2 = spin.ri_data[ri_id] 167 else: 168 r2 = spin.ri_data_sim[ri_id][sim_index] 169 170 # NOE. 171 if cdp.ri_type[ri_id] == 'NOE': 172 if sim_index == None: 173 noe = spin.ri_data[ri_id] 174 else: 175 noe = spin.ri_data_sim[ri_id][sim_index] 176 177 # Skip the spin if not all of the three value exist. 178 if r1 == None or r2 == None or noe == None: 179 continue 180 181 # Initialise the function to calculate. 182 self.jw = Mapping(frq=cdp.jw_frq, gx=return_gyromagnetic_ratio(spin.heteronuc_type), gh=return_gyromagnetic_ratio(spin.proton_type), mu0=mu0, h_bar=h_bar) 183 184 # Calculate the spectral density values. 185 j0, jwx, jwh = self.jw.func(r=spin.r, csa=spin.csa, r1=r1, r2=r2, noe=noe) 186 187 # Reduced spectral density values. 188 if sim_index == None: 189 spin.j0 = j0 190 spin.jwx = jwx 191 spin.jwh = jwh 192 193 # Monte Carlo simulated reduced spectral density values. 194 else: 195 # Initialise the simulation data structures. 196 self.data_init(spin, sim=1) 197 if spin.j0_sim == None: 198 spin.j0_sim = [] 199 spin.jwx_sim = [] 200 spin.jwh_sim = [] 201 202 # Reduced spectral density values. 203 spin.j0_sim.append(j0) 204 spin.jwx_sim.append(jwx) 205 spin.jwh_sim.append(jwh)
206 207
208 - def data_init(self, data_cont, sim=False):
209 """Initialise the data structures. 210 211 @param data_cont: The data container. 212 @type data_cont: instance 213 @keyword sim: The Monte Carlo simulation flag, which if true will initialise the simulation data structure. 214 @type sim: bool 215 """ 216 217 # Get the data names. 218 data_names = self.data_names() 219 220 # Loop over the data structure names. 221 for name in data_names: 222 # Simulation data structures. 223 if sim: 224 # Add '_sim' to the names. 225 name = name + '_sim' 226 227 # If the name is not in 'data_cont', add it. 228 if not hasattr(data_cont, name): 229 # Set the attribute. 230 setattr(data_cont, name, None)
231 232 233 default_value_doc = Desc_container("Reduced spectral density mapping default values") 234 default_value_doc.add_paragraph("These default values are found in the file 'physical_constants.py'.") 235 _table = uf_tables.add_table(label="table: J(w) default values", caption="Reduced spectral density mapping default values.") 236 _table.add_headings(["Data type", "Object name", "Value"]) 237 _table.add_row(["Bond length", "'r'", "1.02 * 1e-10"]) 238 _table.add_row(["CSA", "'csa'", "-172 * 1e-6"]) 239 _table.add_row(["Heteronucleus type", "'heteronuc_type'", "'15N'"]) 240 _table.add_row(["Proton type", "'proton_type'", "'1H'"]) 241 default_value_doc.add_table(_table.label) 242 243
244 - def overfit_deselect(self):
245 """Deselect spins which _have insufficient data to support calculation.""" 246 247 # Print out. 248 print("\n\nOver-fit spin deselection.\n") 249 250 # Test the sequence data exists. 251 if not exists_mol_res_spin_data(): 252 raise RelaxNoSequenceError 253 254 # Loop over spin data. 255 for spin, spin_id in spin_loop(return_id=True): 256 # Skip deselected spins. 257 if not spin.select: 258 continue 259 260 # Check if data exists. 261 if not hasattr(spin, 'ri_data'): 262 warn(RelaxDeselectWarning(spin_id, 'missing relaxation data')) 263 spin.select = False 264 265 # Require 3 or more data points. 266 else: 267 # Count the points. 268 data_points = 0 269 for id in cdp.ri_ids: 270 if spin.ri_data.has_key(id) and spin.ri_data[id] != None: 271 data_points += 1 272 273 # Not enough. 274 if data_points < 3: 275 warn(RelaxDeselectWarning(spin_id, 'insufficient relaxation data, 3 or more data points are required')) 276 spin.select = False
277 278 279 return_data_name_doc = Desc_container("Reduced spectral density mapping data type string matching patterns") 280 _table = uf_tables.add_table(label="table: J(w) data types", caption="Reduced spectral density mapping data type string matching patterns.") 281 _table.add_headings(["Data type", "Object name"]) 282 _table.add_row(["J(0)", "'j0'"]) 283 _table.add_row(["J(wX)", "'jwx'"]) 284 _table.add_row(["J(wH)", "'jwh'"]) 285 _table.add_row(["Bond length", "'r'"]) 286 _table.add_row(["CSA", "'csa'"]) 287 _table.add_row(["Heteronucleus type", "'heteronuc_type'"]) 288 _table.add_row(["Proton type", "'proton_type'"]) 289 return_data_name_doc.add_table(_table.label) 290 291 292 set_doc = Desc_container("Reduced spectral density mapping set details") 293 set_doc.add_paragraph("In reduced spectral density mapping, three values must be set prior to the calculation of spectral density values: the bond length, CSA, and heteronucleus type.") 294 295
296 - def set_error(self, model_info, index, error):
297 """Set the parameter errors. 298 299 @param model_info: The spin container originating from model_loop(). 300 @type model_info: SpinContainer instance 301 @param index: The index of the parameter to set the errors for. 302 @type index: int 303 @param error: The error value. 304 @type error: float 305 """ 306 307 # Alias. 308 spin = model_info 309 310 # Return J(0) sim data. 311 if index == 0: 312 spin.j0_err = error 313 314 # Return J(wX) sim data. 315 if index == 1: 316 spin.jwx_err = error 317 318 # Return J(wH) sim data. 319 if index == 2: 320 spin.jwh_err = error
321 322
323 - def sim_return_param(self, model_info, index):
324 """Return the array of simulation parameter values. 325 326 @param model_info: The spin container originating from model_loop(). 327 @type model_info: SpinContainer instance 328 @param index: The index of the parameter to return the array of values for. 329 @type index: int 330 @return: The array of simulation parameter values. 331 @rtype: list of float 332 """ 333 334 # Alias. 335 spin = model_info 336 337 # Skip deselected spins. 338 if not spin.select: 339 return 340 341 # Return J(0) sim data. 342 if index == 0: 343 return spin.j0_sim 344 345 # Return J(wX) sim data. 346 if index == 1: 347 return spin.jwx_sim 348 349 # Return J(wH) sim data. 350 if index == 2: 351 return spin.jwh_sim
352 353
354 - def sim_return_selected(self, model_info):
355 """Return the array of selected simulation flags. 356 357 @param model_info: The spin container originating from model_loop(). 358 @type model_info: SpinContainer instance 359 @return: The array of selected simulation flags. 360 @rtype: list of int 361 """ 362 363 # Alias. 364 spin = model_info 365 366 # Multiple spins. 367 return spin.select_sim
368