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

Source Code for Module specific_fns.model_free.macro_base

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-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  # Module docstring. 
 24  """The module containing the base class for the model-free macros.""" 
 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 generic_fns.mol_res_spin import spin_loop 
 33  from relax_errors import RelaxFault, RelaxStyleError, RelaxUnknownDataTypeError 
 34   
 35   
 36   
37 -class Macro:
38 """The base class for the model-free analysis Molmol and PyMOL macro creation.""" 39 40 classic_style_doc = ["Model-free classic style", """ 41 Creator: Edward d'Auvergne 42 43 Argument string: "classic" 44 45 Description: The classic style draws the backbone of a protein in a cylindrical bond style. Rather than colouring the amino acids to which the NH bond belongs, the three covalent bonds of the peptide bond from Ca to Ca in which the NH bond is located are coloured. Deselected residues are shown as black lines. 46 47 Supported data types: 48 ____________________________________________________________________________________________ 49 | | | | 50 | Data type | String | Description | 51 |________________|_____________|___________________________________________________________| 52 | | | | 53 | S2. | 's2' | The standard model-free order parameter, equal to S2f.S2s | 54 | | | for the two timescale models. The default colour | 55 | | | gradient starts at 'yellow' and ends at 'red'. | 56 | | | | 57 | S2f. | 's2f' | The order parameter of the faster of two internal | 58 | | | motions. Residues which are described by model-free | 59 | | | models m1 to m4, the single timescale models, are | 60 | | | illustrated as white neon bonds. The default colour | 61 | | | gradient is the same as that for the S2 data type. | 62 | | | | 63 | S2s. | 's2s' | The order parameter of the slower of two internal | 64 | | | motions. This functions exactly as S2f except that S2s | 65 | | | is plotted instead. | 66 | | | | 67 | Amplitude of | 'amp_fast' | Model independent display of the amplite of fast motions. | 68 | fast motions. | | For residues described by model-free models m5 to m8, the | 69 | | | value plotted is that of S2f. However, for residues | 70 | | | described by models m1 to m4, what is shown is dependent | 71 | | | on the timescale of the motions. This is because these | 72 | | | single timescale models can, at times, be perfect | 73 | | | approximations to the more complex two timescale models. | 74 | | | Hence if te is less than 200 ps, S2 is plotted. Otherwise | 75 | | | the peptide bond is coloured white. The default colour | 76 | | | gradient is the same as that for S2. | 77 | | | | 78 | Amplitude of | 'amp_slow' | Model independent display of the amplite of slow motions, | 79 | slow motions. | | arbitrarily defined as motions slower than 200 ps. For | 80 | | | residues described by model-free models m5 to m8, the | 81 | | | order parameter S2 is plotted if ts > 200 ps. For models | 82 | | | m1 to m4, S2 is plotted if te > 200 ps. The default | 83 | | | colour gradient is the same as that for S2. | 84 | | | | 85 | te. | 'te' | The correlation time, te. The default colour gradient | 86 | | | starts at 'turquoise' and ends at 'blue'. | 87 | | | | 88 | tf. | 'tf' | The correlation time, tf. The default colour gradient is | 89 | | | the same as that of te. | 90 | | | | 91 | ts. | 'ts' | The correlation time, ts. The default colour gradient | 92 | | | starts at 'blue' and ends at 'black'. | 93 | | | | 94 | Timescale of | 'time_fast' | Model independent display of the timescale of fast | 95 | fast motions | | motions. For models m5 to m8, only the parameter tf is | 96 | | | plotted. For models m2 and m4, the parameter te is | 97 | | | plotted only if it is less than 200 ps. All other | 98 | | | residues are assumed to have a correlation time of zero. | 99 | | | The default colour gradient is the same as that of te. | 100 | | | | 101 | Timescale of | 'time_slow' | Model independent display of the timescale of slow | 102 | slow motions | | motions. For models m5 to m8, only the parameter ts is | 103 | | | plotted. For models m2 and m4, the parameter te is | 104 | | | plotted only if it is greater than 200 ps. All other | 105 | | | residues are coloured white. The default colour gradient | 106 | | | is the same as that of ts. | 107 | | | | 108 | Chemical | 'rex' | The chemical exchange, Rex. Residues which experience no | 109 | exchange | | chemical exchange are coloured white. The default colour | 110 | | | gradient starts at 'yellow' and finishes at 'red'. | 111 |________________|_____________|___________________________________________________________| 112 """] 113
114 - def classic_style(self, data_type=None, colour_start=None, colour_end=None, colour_list=None, spin_id=None):
115 """The classic macro style. 116 117 @keyword data_type: The parameter name or data type. 118 @type data_type: str 119 @keyword colour_start: The starting colour (must be a MOLMOL or X11 name). 120 @type colour_start: str 121 @keyword colour_end: The ending colour (must be a MOLMOL or X11 name). 122 @type colour_end: str 123 @keyword colour_list: The colour list used, either 'molmol' or 'x11'. 124 @type colour_list: str 125 @keyword spin_id: The spin identification string. 126 @type spin_id: str 127 """ 128 129 # Test the validity of the data (only a single spin per residue). 130 ################################################################# 131 132 # Init some variables. 133 prev_res_num = None 134 num = 0 135 136 # Loop over the spins. 137 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 138 # More than one spin. 139 if prev_res_num == res_num: 140 raise RelaxError("Only a single spin per residue is allowed for the classic macro style.") 141 142 # Update the previous residue number. 143 prev_res_num = res_num 144 145 146 # Generate the macro header. 147 ############################ 148 149 self.classic_header() 150 151 152 # S2. 153 ##### 154 155 if data_type == 's2': 156 # Loop over the spins. 157 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 158 # Skip deselected spins. 159 if not spin.select: 160 continue 161 162 # Skip spins which don't have an S2 value. 163 if not hasattr(spin, 's2') or spin.s2 == None: 164 continue 165 166 # S2 width and colour. 167 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 168 169 170 # S2f. 171 ###### 172 173 elif data_type == 's2f': 174 # Loop over the spins. 175 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 176 # Skip deselected spins. 177 if not spin.select: 178 continue 179 180 # Colour residues which don't have an S2f value white. 181 if not hasattr(spin, 's2f') or spin.s2f == None: 182 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 183 184 # S2f width and colour. 185 else: 186 self.classic_order_param(res_num, spin.s2f, colour_start, colour_end, colour_list) 187 188 189 # S2s. 190 ###### 191 192 elif data_type == 's2s': 193 # Loop over the spins. 194 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 195 # Skip deselected spins. 196 if not spin.select: 197 continue 198 199 # Colour residues which don't have an S2s value white. 200 if not hasattr(spin, 's2s') or spin.s2s == None: 201 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 202 203 # S2s width and colour. 204 else: 205 self.classic_order_param(res_num, spin.s2s, colour_start, colour_end, colour_list) 206 207 208 # Amplitude of fast motions. 209 ############################ 210 211 elif data_type == 'amp_fast': 212 # Loop over the spins. 213 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 214 # Skip deselected spins. 215 if not spin.select: 216 continue 217 218 # The model. 219 if search('tm[0-9]', spin.model): 220 model = spin.model[1:] 221 else: 222 model = spin.model 223 224 # S2f width and colour (for models m5 to m8). 225 if hasattr(spin, 's2f') and spin.s2f != None: 226 self.classic_order_param(res_num, spin.s2f, colour_start, colour_end, colour_list) 227 228 # S2 width and colour (for models m1 and m3). 229 elif model == 'm1' or model == 'm3': 230 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 231 232 # S2 width and colour (for models m2 and m4 when te <= 200 ps). 233 elif (model == 'm2' or model == 'm4') and spin.te <= 200e-12: 234 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 235 236 # White bonds (for models m2 and m4 when te > 200 ps). 237 elif (model == 'm2' or model == 'm4') and spin.te > 200e-12: 238 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 239 240 # Catch errors. 241 else: 242 raise RelaxFault 243 244 245 # Amplitude of slow motions. 246 ############################ 247 248 elif data_type == 'amp_slow': 249 # Loop over the spins. 250 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 251 # Skip deselected spins. 252 if not spin.select: 253 continue 254 255 # The model. 256 if search('tm[0-9]', spin.model): 257 model = spin.model[1:] 258 else: 259 model = spin.model 260 261 # S2 width and colour (for models m5 to m8). 262 if hasattr(spin, 'ts') and spin.ts != None: 263 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 264 265 # S2 width and colour (for models m2 and m4 when te > 200 ps). 266 elif (model == 'm2' or model == 'm4') and spin.te > 200 * 1e-12: 267 self.classic_order_param(res_num, spin.s2, colour_start, colour_end, colour_list) 268 269 # White bonds for fast motions. 270 else: 271 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 272 273 # te. 274 ##### 275 276 elif data_type == 'te': 277 # Loop over the spins. 278 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 279 # Skip deselected spins. 280 if not spin.select: 281 continue 282 283 # Skip spins which don't have a te value. 284 if not hasattr(spin, 'te') or spin.te == None: 285 continue 286 287 # te width and colour. 288 self.classic_correlation_time(res_num, spin.te, colour_start, colour_end, colour_list) 289 290 291 # tf. 292 ##### 293 294 elif data_type == 'tf': 295 # Loop over the spins. 296 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 297 # Skip deselected spins. 298 if not spin.select: 299 continue 300 301 # Skip spins which don't have a tf value. 302 if not hasattr(spin, 'tf') or spin.tf == None: 303 continue 304 305 # tf width and colour. 306 self.classic_correlation_time(res_num, spin.tf, colour_start, colour_end, colour_list) 307 308 309 # ts. 310 ##### 311 312 elif data_type == 'ts': 313 # Loop over the spins. 314 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 315 # Skip deselected spins. 316 if not spin.select: 317 continue 318 319 # Skip spins which don't have a ts value. 320 if not hasattr(spin, 'ts') or spin.ts == None: 321 continue 322 323 # The default start and end colours. 324 if colour_start == None: 325 colour_start = 'blue' 326 if colour_end == None: 327 colour_end = 'black' 328 329 # ts width and colour. 330 self.classic_correlation_time(res_num, spin.ts / 10.0, colour_start, colour_end, colour_list) 331 332 333 # Timescale of fast motions. 334 ############################ 335 336 elif data_type == 'time_fast': 337 # Loop over the spins. 338 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 339 # Skip deselected spins. 340 if not spin.select: 341 continue 342 343 # The model. 344 if search('tm[0-9]', spin.model): 345 model = spin.model[1:] 346 else: 347 model = spin.model 348 349 # tf width and colour (for models m5 to m8). 350 if hasattr(spin, 'tf') and spin.tf != None: 351 self.classic_correlation_time(res_num, spin.tf, colour_start, colour_end, colour_list) 352 353 # te width and colour (for models m2 and m4 when te <= 200 ps). 354 elif (model == 'm2' or model == 'm4') and spin.te <= 200e-12: 355 self.classic_correlation_time(res_num, spin.te, colour_start, colour_end, colour_list) 356 357 # All other residues are assumed to have a fast correlation time of zero (statistically zero, not real zero!). 358 # Colour these bonds white. 359 else: 360 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 361 362 363 # Timescale of slow motions. 364 ############################ 365 366 elif data_type == 'time_slow': 367 # Loop over the spins. 368 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 369 # Skip deselected spins. 370 if not spin.select: 371 continue 372 373 # The model. 374 if search('tm[0-9]', spin.model): 375 model = spin.model[1:] 376 else: 377 model = spin.model 378 379 # The default start and end colours. 380 if colour_start == None: 381 colour_start = 'blue' 382 if colour_end == None: 383 colour_end = 'black' 384 385 # ts width and colour (for models m5 to m8). 386 if hasattr(spin, 'ts') and spin.ts != None: 387 self.classic_correlation_time(res_num, spin.ts / 10.0, colour_start, colour_end, colour_list) 388 389 # te width and colour (for models m2 and m4 when te > 200 ps). 390 elif (model == 'm2' or model == 'm4') and spin.te > 200e-12: 391 self.classic_correlation_time(res_num, spin.te / 10.0, colour_start, colour_end, colour_list) 392 393 # White bonds for the rest. 394 else: 395 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 396 397 398 # Rex. 399 ###### 400 401 elif data_type == 'rex': 402 # Loop over the spins. 403 for spin, mol_name, res_num, res_name in spin_loop(spin_id, full_info=True): 404 # Skip deselected spins. 405 if not spin.select: 406 continue 407 408 # Residues which chemical exchange. 409 if hasattr(spin, 'rex') and spin.rex != None: 410 self.classic_rex(res_num, spin.rex, colour_start, colour_end, colour_list) 411 412 # White bonds for the rest. 413 else: 414 self.classic_colour(res_num=res_num, width=0.3, rgb_array=[1, 1, 1]) 415 416 417 # Unknown data type. 418 #################### 419 420 else: 421 raise RelaxUnknownDataTypeError(data_type)
422 423
424 - def classic_correlation_time(self, res_num, te, colour_start, colour_end, colour_list):
425 """Function for generating the bond width and colours for correlation times.""" 426 427 # The te value in picoseconds. 428 te = te * 1e12 429 430 # The bond width (aiming for a width range of 2 to 0 for te values of 0 to 10 ns). 431 width = 2.0 - 200.0 / (te + 100.0) 432 433 # Catch invalid widths. 434 if width <= 0.0: 435 width = 0.001 436 437 # Colour value (hyperbolic). 438 colour_value = 1.0 / (te / 100.0 + 1.0) 439 440 # Catch invalid colours. 441 if colour_value < 0.0: 442 colour_value = 0.0 443 elif colour_value > 1.0: 444 colour_value = 1.0 445 446 # Default colours. 447 if colour_start == None: 448 colour_start = 'turquoise' 449 if colour_end == None: 450 colour_end = 'blue' 451 452 # Get the RGB colour array (swap the colours because of the inverted hyperbolic colour value). 453 rgb_array = linear_gradient(colour_value, colour_end, colour_start, colour_list) 454 455 # Colour the peptide bond. 456 self.classic_colour(res_num, width, rgb_array)
457 458
459 - def classic_order_param(self, res_num, s2, colour_start, colour_end, colour_list):
460 """Function for generating the bond width and colours for order parameters.""" 461 462 # The bond width (aiming for a width range of 2 to 0 for S2 values of 0.0 to 1.0). 463 if s2 <= 0.0: 464 width = 2.0 465 else: 466 width = 2.0 * (1.0 - s2**2) 467 468 # Catch invalid widths. 469 if width <= 0.0: 470 width = 0.001 471 472 # Colour value (quartic). 473 colour_value = s2 ** 4 474 475 # Catch invalid colours. 476 if colour_value < 0.0: 477 colour_value = 0.0 478 elif colour_value > 1.0: 479 colour_value = 1.0 480 481 # Default colours. 482 if colour_start == None: 483 colour_start = 'red' 484 if colour_end == None: 485 colour_end = 'yellow' 486 487 # Get the RGB colour array. 488 rgb_array = linear_gradient(colour_value, colour_start, colour_end, colour_list) 489 490 # Colour the peptide bond. 491 self.classic_colour(res_num, width, rgb_array)
492 493
494 - def classic_rex(self, res_num, rex, colour_start, colour_end, colour_list):
495 """Function for generating the bond width and colours for correlation times.""" 496 497 # The Rex value at the first field strength. 498 rex = rex * (2.0 * pi * cdp.frq[cdp.ri_ids[0]])**2 499 500 # The bond width (aiming for a width range of 2 to 0 for Rex values of 0 to 25 s^-1). 501 width = 2.0 - 2.0 / (rex/5.0 + 1.0) 502 503 # Catch invalid widths. 504 if width <= 0.0: 505 width = 0.001 506 507 # Colour value (hyperbolic). 508 colour_value = 1.0 / (rex + 1.0) 509 510 # Catch invalid colours. 511 if colour_value < 0.0: 512 colour_value = 0.0 513 elif colour_value > 1.0: 514 colour_value = 1.0 515 516 # Default colours. 517 if colour_start == None: 518 colour_start = 'yellow' 519 if colour_end == None: 520 colour_end = 'red' 521 522 # Get the RGB colour array (swap the colours because of the inverted hyperbolic colour value). 523 rgb_array = linear_gradient(colour_value, colour_end, colour_start, colour_list) 524 525 # Colour the peptide bond. 526 self.classic_colour(res_num, width, rgb_array)
527 528
529 - def create_macro(self, data_type, style=None, colour_start=None, colour_end=None, colour_list=None, spin_id=None):
530 """Create and return an array of macros of the model-free parameters. 531 532 @param data_type: The parameter name or data type. 533 @type data_type: str 534 @keyword style: The Molmol style. 535 @type style: None or str 536 @keyword colour_start: The starting colour (must be a MOLMOL or X11 name). 537 @type colour_start: str 538 @keyword colour_end: The ending colour (must be a MOLMOL or X11 name). 539 @type colour_end: str 540 @keyword colour_list: The colour list used, either 'molmol' or 'x11'. 541 @type colour_list: str 542 @keyword spin_id: The spin identification string. 543 @type spin_id: str 544 """ 545 546 # Initialise. 547 self.commands = [] 548 549 # The classic style. 550 if style == 'classic': 551 self.classic_style(data_type, colour_start, colour_end, colour_list, spin_id) 552 553 # Unknown style. 554 else: 555 raise RelaxStyleError(style) 556 557 # Return the command array. 558 return self.commands
559