Package specific_analyses :: Package model_free :: Module macro_base
[hide private]
[frames] | no frames]

Source Code for Module specific_analyses.model_free.macro_base

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2002-2009,2011-2013 Edward d'Auvergne                         # 
  4  # Copyright (C) 2006 Chris MacRaild                                           # 
  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  """The Molmol and Pymol base macro methods of the specific API for model-free analysis.""" 
 25   
 26  # Python module imports. 
 27  from math import pi 
 28  from re import search 
 29   
 30  # relax module imports. 
 31  from colour import linear_gradient 
 32  from lib.errors import RelaxError, RelaxStyleError, RelaxUnknownDataTypeError 
 33  from pipe_control.mol_res_spin import spin_loop 
 34   
 35   
 36   
37 -class Macro:
38 """The base class for the model-free analysis Molmol and PyMOL macro creation.""" 39
40 - def classic_style(self, data_type=None, colour_start=None, colour_end=None, colour_list=None, spin_id=None):
41 """The classic macro style. 42 43 @keyword data_type: The parameter name or data type. 44 @type data_type: str 45 @keyword colour_start: The starting colour (must be a MOLMOL or X11 name). 46 @type colour_start: str 47 @keyword colour_end: The ending colour (must be a MOLMOL or X11 name). 48 @type colour_end: str 49 @keyword colour_list: The colour list used, either 'molmol' or 'x11'. 50 @type colour_list: str 51 @keyword spin_id: The spin identification string. 52 @type spin_id: str 53 """ 54 55 # Generate the macro header. 56 ############################ 57 58 self.classic_header() 59 60 61 # S2. 62 ##### 63 64 if data_type == 's2': 65 # Loop over the spins. 66 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 67 # Skip deselected spins or spins with no model information set. 68 if not spin.select or not hasattr(spin, 'model'): 69 continue 70 71 # Skip spins which don't have an S2 value. 72 if not hasattr(spin, 's2') or spin.s2 == None: 73 continue 74 75 # S2 width and colour for the backbone NH. 76 if spin.name == 'N': 77 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 78 79 80 # S2f. 81 ###### 82 83 elif data_type == 's2f': 84 # Loop over the spins. 85 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 86 # Skip deselected spins or spins with no model information set. 87 if not spin.select or not hasattr(spin, 'model'): 88 continue 89 90 # The backbone NH. 91 if spin.name == 'N': 92 # Colour residues which don't have an S2f value white. 93 if not hasattr(spin, 's2f') or spin.s2f == None: 94 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 95 96 # S2f width and colour. 97 else: 98 self.classic_order_param(res_num, spin.s2f, colour_start, colour_end, colour_list) 99 100 101 # S2s. 102 ###### 103 104 elif data_type == 's2s': 105 # Loop over the spins. 106 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 107 # Skip deselected spins or spins with no model information set. 108 if not spin.select or not hasattr(spin, 'model'): 109 continue 110 111 # The backbone NH. 112 if spin.name == 'N': 113 # Colour residues which don't have an S2s value white. 114 if not hasattr(spin, 's2s') or spin.s2s == None: 115 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 116 117 # S2s width and colour. 118 else: 119 self.classic_order_param(res_num, spin.s2s, colour_start, colour_end, colour_list) 120 121 122 # Amplitude of fast motions. 123 ############################ 124 125 elif data_type == 'amp_fast': 126 # Loop over the spins. 127 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 128 # Skip deselected spins or spins with no model information set. 129 if not spin.select or not hasattr(spin, 'model'): 130 continue 131 132 # The model. 133 if search('tm[0-9]', spin.model): 134 model = spin.model[1:] 135 else: 136 model = spin.model 137 138 # The backbone NH. 139 if spin.name == 'N': 140 # S2f width and colour (for models m5 to m8). 141 if hasattr(spin, 's2f') and spin.s2f != None: 142 self.classic_order_param(res_num, spin.s2f, colour_start, colour_end, colour_list) 143 144 # S2 width and colour (for models m1 and m3). 145 elif model == 'm1' or model == 'm3': 146 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 147 148 # S2 width and colour (for models m2 and m4 when te <= 200 ps). 149 elif (model == 'm2' or model == 'm4') and spin.te <= 200e-12: 150 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 151 152 # White bonds (for models m2 and m4 when te > 200 ps). 153 elif (model == 'm2' or model == 'm4') and spin.te > 200e-12: 154 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 155 156 157 # Amplitude of slow motions. 158 ############################ 159 160 elif data_type == 'amp_slow': 161 # Loop over the spins. 162 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 163 # Skip deselected spins or spins with no model information set. 164 if not spin.select or not hasattr(spin, 'model'): 165 continue 166 167 # The model. 168 if search('tm[0-9]', spin.model): 169 model = spin.model[1:] 170 else: 171 model = spin.model 172 173 # The backbone NH. 174 if spin.name == 'N': 175 # S2 width and colour (for models m5 to m8). 176 if hasattr(spin, 'ts') and spin.ts != None: 177 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 178 179 # S2 width and colour (for models m2 and m4 when te > 200 ps). 180 elif (model == 'm2' or model == 'm4') and spin.te > 200 * 1e-12: 181 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 182 183 # White bonds for fast motions. 184 else: 185 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 186 187 # te. 188 ##### 189 190 elif data_type == 'te': 191 # Loop over the spins. 192 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 193 # Skip deselected spins or spins with no model information set. 194 if not spin.select or not hasattr(spin, 'model'): 195 continue 196 197 # Skip spins which don't have a te value. 198 if not hasattr(spin, 'te') or spin.te == None: 199 continue 200 201 # te width and colour (backbone NH). 202 if spin.name == 'N': 203 self.classic_correlation_time(res_num, spin.te, colour_start, colour_end, colour_list) 204 205 206 # tf. 207 ##### 208 209 elif data_type == 'tf': 210 # Loop over the spins. 211 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 212 # Skip deselected spins or spins with no model information set. 213 if not spin.select or not hasattr(spin, 'model'): 214 continue 215 216 # Skip spins which don't have a tf value. 217 if not hasattr(spin, 'tf') or spin.tf == None: 218 continue 219 220 # tf width and colour (backbone NH). 221 if spin.name == 'N': 222 self.classic_correlation_time(res_num, spin.tf, colour_start, colour_end, colour_list) 223 224 225 # ts. 226 ##### 227 228 elif data_type == 'ts': 229 # Loop over the spins. 230 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 231 # Skip deselected spins or spins with no model information set. 232 if not spin.select or not hasattr(spin, 'model'): 233 continue 234 235 # Skip spins which don't have a ts value. 236 if not hasattr(spin, 'ts') or spin.ts == None: 237 continue 238 239 # The default start and end colours. 240 if colour_start == None: 241 colour_start = 'blue' 242 if colour_end == None: 243 colour_end = 'black' 244 245 # ts width and colour (backbone NH). 246 if spin.name == 'N': 247 self.classic_correlation_time(res_num, spin.ts / 10.0, colour_start, colour_end, colour_list) 248 249 250 # Timescale of fast motions. 251 ############################ 252 253 elif data_type == 'time_fast': 254 # Loop over the spins. 255 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 256 # Skip deselected spins or spins with no model information set. 257 if not spin.select or not hasattr(spin, 'model'): 258 continue 259 260 # The model. 261 if search('tm[0-9]', spin.model): 262 model = spin.model[1:] 263 else: 264 model = spin.model 265 266 # The backbone NH. 267 if spin.name == 'N': 268 # tf width and colour (for models m5 to m8). 269 if hasattr(spin, 'tf') and spin.tf != None: 270 self.classic_correlation_time(res_num, spin.tf, colour_start, colour_end, colour_list) 271 272 # te width and colour (for models m2 and m4 when te <= 200 ps). 273 elif (model == 'm2' or model == 'm4') and spin.te <= 200e-12: 274 self.classic_correlation_time(res_num, spin.te, colour_start, colour_end, colour_list) 275 276 # All other residues are assumed to have a fast correlation time of zero (statistically zero, not real zero!). 277 # Colour these bonds white. 278 else: 279 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 280 281 282 # Timescale of slow motions. 283 ############################ 284 285 elif data_type == 'time_slow': 286 # Loop over the spins. 287 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 288 # Skip deselected spins or spins with no model information set. 289 if not spin.select or not hasattr(spin, 'model'): 290 continue 291 292 # The model. 293 if search('tm[0-9]', spin.model): 294 model = spin.model[1:] 295 else: 296 model = spin.model 297 298 # The default start and end colours. 299 if colour_start == None: 300 colour_start = 'blue' 301 if colour_end == None: 302 colour_end = 'black' 303 304 # The backbone NH. 305 if spin.name == 'N': 306 # ts width and colour (for models m5 to m8). 307 if hasattr(spin, 'ts') and spin.ts != None: 308 self.classic_correlation_time(res_num, spin.ts / 10.0, colour_start, colour_end, colour_list) 309 310 # te width and colour (for models m2 and m4 when te > 200 ps). 311 elif (model == 'm2' or model == 'm4') and spin.te > 200e-12: 312 self.classic_correlation_time(res_num, spin.te / 10.0, colour_start, colour_end, colour_list) 313 314 # White bonds for the rest. 315 else: 316 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 317 318 319 # Rex. 320 ###### 321 322 elif data_type == 'rex': 323 # Loop over the spins. 324 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 325 # Skip deselected spins or spins with no model information set. 326 if not spin.select or not hasattr(spin, 'model'): 327 continue 328 329 # The backbone NH. 330 if spin.name == 'N': 331 # Residues which chemical exchange. 332 if hasattr(spin, 'rex') and spin.rex != None: 333 self.classic_rex(res_num, spin.rex, colour_start, colour_end, colour_list) 334 335 # White bonds for the rest. 336 else: 337 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 338 339 340 # Unknown data type. 341 #################### 342 343 else: 344 raise RelaxUnknownDataTypeError(data_type)
345 346
347 - def classic_correlation_time(self, res_num, te, colour_start, colour_end, colour_list):
348 """Function for generating the bond width and colours for correlation times.""" 349 350 # The te value in picoseconds. 351 te = te * 1e12 352 353 # The bond width (aiming for a width range of 2 to 0 for te values of 0 to 10 ns). 354 width = 2.0 - 200.0 / (te + 100.0) 355 356 # Catch invalid widths. 357 if width <= 0.0: 358 width = 0.001 359 360 # Colour value (hyperbolic). 361 colour_value = 1.0 / (te / 100.0 + 1.0) 362 363 # Catch invalid colours. 364 if colour_value < 0.0: 365 colour_value = 0.0 366 elif colour_value > 1.0: 367 colour_value = 1.0 368 369 # Default colours. 370 if colour_start == None: 371 colour_start = 'turquoise' 372 if colour_end == None: 373 colour_end = 'blue' 374 375 # Get the RGB colour array (swap the colours because of the inverted hyperbolic colour value). 376 rgb_array = linear_gradient(colour_value, colour_end, colour_start, colour_list) 377 378 # Colour the peptide bond. 379 self.classic_colour(res_num, width, rgb_array)
380 381
382 - def classic_order_param(self, res_num, s2, colour_start, colour_end, colour_list):
383 """Function for generating the bond width and colours for order parameters.""" 384 385 # The bond width (aiming for a width range of 2 to 0 for S2 values of 0.0 to 1.0). 386 if s2 <= 0.0: 387 width = 2.0 388 else: 389 width = 2.0 * (1.0 - s2**2) 390 391 # Catch invalid widths. 392 if width <= 0.0: 393 width = 0.001 394 395 # Colour value (quartic). 396 colour_value = s2 ** 4 397 398 # Catch invalid colours. 399 if colour_value < 0.0: 400 colour_value = 0.0 401 elif colour_value > 1.0: 402 colour_value = 1.0 403 404 # Default colours. 405 if colour_start == None: 406 colour_start = 'red' 407 if colour_end == None: 408 colour_end = 'yellow' 409 410 # Get the RGB colour array. 411 rgb_array = linear_gradient(colour_value, colour_start, colour_end, colour_list) 412 413 # Colour the peptide bond. 414 self.classic_colour(res_num, width, rgb_array)
415 416
417 - def classic_rex(self, res_num, rex, colour_start, colour_end, colour_list):
418 """Function for generating the bond width and colours for correlation times.""" 419 420 # The 1st spectrometer frequency. 421 if not hasattr(cdp, 'spectrometer_frq'): 422 raise RelaxError("No spectrometer frequency information is present in the current data pipe.") 423 if hasattr(cdp, 'ri_ids'): 424 frq = cdp.spectrometer_frq[cdp.ri_ids[0]] 425 else: # Take the highest frequency, if all else fails. 426 frqs = sorted(cdp.spectrometer_frq.values()) 427 frq = frqs[-1] 428 429 # The Rex value. 430 rex = rex * (2.0 * pi * frq)**2 431 432 # The bond width (aiming for a width range of 2 to 0 for Rex values of 0 to 25 s^-1). 433 width = 2.0 - 2.0 / (rex/5.0 + 1.0) 434 435 # Catch invalid widths. 436 if width <= 0.0: 437 width = 0.001 438 439 # Colour value (hyperbolic). 440 colour_value = 1.0 / (rex + 1.0) 441 442 # Catch invalid colours. 443 if colour_value < 0.0: 444 colour_value = 0.0 445 elif colour_value > 1.0: 446 colour_value = 1.0 447 448 # Default colours. 449 if colour_start == None: 450 colour_start = 'yellow' 451 if colour_end == None: 452 colour_end = 'red' 453 454 # Get the RGB colour array (swap the colours because of the inverted hyperbolic colour value). 455 rgb_array = linear_gradient(colour_value, colour_end, colour_start, colour_list) 456 457 # Colour the peptide bond. 458 self.classic_colour(res_num, width, rgb_array)
459 460
461 - def create_macro(self, data_type, style=None, colour_start=None, colour_end=None, colour_list=None, spin_id=None):
462 """Create and return an array of macros of the model-free parameters. 463 464 @param data_type: The parameter name or data type. 465 @type data_type: str 466 @keyword style: The Molmol style. 467 @type style: None or str 468 @keyword colour_start: The starting colour (must be a MOLMOL or X11 name). 469 @type colour_start: str 470 @keyword colour_end: The ending colour (must be a MOLMOL or X11 name). 471 @type colour_end: str 472 @keyword colour_list: The colour list used, either 'molmol' or 'x11'. 473 @type colour_list: str 474 @keyword spin_id: The spin identification string. 475 @type spin_id: str 476 """ 477 478 # Initialise. 479 self.commands = [] 480 481 # The classic style. 482 if style == 'classic': 483 self.classic_style(data_type, colour_start, colour_end, colour_list, spin_id) 484 485 # Unknown style. 486 else: 487 raise RelaxStyleError(style) 488 489 # Return the command array. 490 return self.commands
491