Package generic_fns :: Module value
[hide private]
[frames] | no frames]

Source Code for Module generic_fns.value

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2003-2013 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  """Module for the manipulation of parameter and constant values.""" 
 24   
 25  # Python module imports. 
 26  from numpy import ndarray 
 27  import sys 
 28   
 29  # relax module imports. 
 30  from generic_fns import minimise, pipes 
 31  from generic_fns.mol_res_spin import exists_mol_res_spin_data, generate_spin_id_unique, return_spin, spin_loop 
 32  from generic_fns.result_files import add_result_file 
 33  from relax_errors import RelaxError, RelaxNoSequenceError, RelaxNoSpinError, RelaxParamSetError, RelaxValueError 
 34  from relax_io import get_file_path, open_write_file, read_spin_data, write_spin_data 
 35  import specific_fns 
 36  from status import Status; status = Status() 
 37   
 38   
39 -def copy(pipe_from=None, pipe_to=None, param=None):
40 """Copy spin specific data values from pipe_from to pipe_to. 41 42 @param pipe_from: The data pipe to copy the value from. This defaults to the current data 43 pipe. 44 @type pipe_from: str 45 @param pipe_to: The data pipe to copy the value to. This defaults to the current data pipe. 46 @type pipe_to: str 47 @param param: The name of the parameter to copy the values of. 48 @type param: str 49 """ 50 51 # The current data pipe. 52 if pipe_from == None: 53 pipe_from = pipes.cdp_name() 54 if pipe_to == None: 55 pipe_to = pipes.cdp_name() 56 57 # The second pipe does not exist. 58 pipes.test(pipe_to) 59 60 # Test if the sequence data for pipe_from is loaded. 61 if not exists_mol_res_spin_data(pipe_from): 62 raise RelaxNoSequenceError(pipe_from) 63 64 # Test if the sequence data for pipe_to is loaded. 65 if not exists_mol_res_spin_data(pipe_to): 66 raise RelaxNoSequenceError(pipe_to) 67 68 # Specific value and error returning function. 69 return_value = specific_fns.setup.get_specific_fn('return_value', pipes.get_type(pipe_from)) 70 71 # Test if the data exists for pipe_to. 72 for spin in spin_loop(pipe_to): 73 # Get the value and error for pipe_to. 74 value, error = return_value(spin, param) 75 76 # Data exists. 77 if value != None or error != None: 78 raise RelaxValueError(param, pipe_to) 79 80 # Copy the values. 81 for spin, spin_id in spin_loop(pipe_from, return_id=True): 82 # Get the value and error from pipe_from. 83 value, error = return_value(spin, param) 84 85 # Get the equivalent spin in pipe_to. 86 spin_to = return_spin(spin_id, pipe_to) 87 88 # Set the values of pipe_to. 89 set(spin_id=spin_to, value=value, error=error, param=param) 90 91 # Reset all minimisation statistics. 92 minimise.reset_min_stats(pipe_to)
93 94
95 -def display(param=None, scaling=1.0):
96 """Display spin specific data values. 97 98 @keyword param: The name of the parameter to display. 99 @type param: str 100 @keyword scaling: The value to scale the parameter by. 101 @type scaling: float 102 """ 103 104 # Test if the current pipe exists. 105 pipes.test() 106 107 # Test if the sequence data is loaded. 108 if not exists_mol_res_spin_data(): 109 raise RelaxNoSequenceError 110 111 # Print the data. 112 write_data(param=param, file=sys.stdout, scaling=scaling)
113 114
115 -def get_parameters():
116 """Return a list of the parameters associated with the current data pipe. 117 118 @return: The list of parameters. 119 @rtype: list of str 120 """ 121 122 # No data pipes. 123 if cdp == None: 124 return [] 125 126 # Get the specific functions. 127 data_names = specific_fns.setup.get_specific_fn('data_names', cdp.pipe_type, raise_error=False) 128 return_data_desc = specific_fns.setup.get_specific_fn('return_data_desc', cdp.pipe_type, raise_error=False) 129 130 # Loop over the parameters. 131 params = [] 132 for name in (data_names(set='params') + data_names(set='generic')): 133 # Get the description. 134 desc = return_data_desc(name) 135 136 # No description. 137 if not desc: 138 text = name 139 140 # The text. 141 else: 142 text = "'%s': %s" % (name, desc) 143 144 # Append the data as a list. 145 params.append((text, name)) 146 147 # Return the data. 148 return params
149 150
151 -def partition_params(val, param):
152 """Function for sorting and partitioning the parameters and their values. 153 154 The two major partitions are the tensor parameters and the spin specific parameters. 155 156 @param val: The parameter values. 157 @type val: None, number, or list of numbers 158 @param param: The parameter names. 159 @type param: None, str, or list of str 160 @return: A tuple, of length 4, of lists. The first and second elements are the lists of 161 spin specific parameters and values respectively. The third and forth elements 162 are the lists of all other parameters and their values. 163 @rtype: tuple of 4 lists 164 """ 165 166 # Specific functions. 167 is_spin_param = specific_fns.setup.get_specific_fn('is_spin_param', pipes.get_type()) 168 169 # Initialise. 170 spin_params = [] 171 spin_values = [] 172 other_params = [] 173 other_values = [] 174 175 # Single parameter. 176 if isinstance(param, str): 177 # Spin specific parameter. 178 if is_spin_param(param): 179 params = spin_params 180 values = spin_values 181 182 # Other parameters. 183 else: 184 params = other_params 185 values = other_values 186 187 # List of values. 188 if isinstance(val, list) or isinstance(val, ndarray): 189 # Parameter name. 190 for i in range(len(val)): 191 params.append(param) 192 193 # Parameter value. 194 values = val 195 196 # Single value. 197 else: 198 # Parameter name. 199 params.append(param) 200 201 # Parameter value. 202 values.append(val) 203 204 # Multiple parameters. 205 elif isinstance(param, list): 206 # Loop over all parameters. 207 for i in range(len(param)): 208 # Spin specific parameter. 209 if is_spin_param(param[i]): 210 params = spin_params 211 values = spin_values 212 213 # Other parameters. 214 else: 215 params = other_params 216 values = other_values 217 218 # Parameter name. 219 params.append(param[i]) 220 221 # Parameter value. 222 if isinstance(val, list) or isinstance(val, ndarray): 223 values.append(val[i]) 224 else: 225 values.append(val) 226 227 228 # Return the partitioned parameters and values. 229 return spin_params, spin_values, other_params, other_values
230 231
232 -def read(param=None, scaling=1.0, file=None, dir=None, file_data=None, spin_id_col=None, mol_name_col=None, res_num_col=None, res_name_col=None, spin_num_col=None, spin_name_col=None, data_col=None, error_col=None, sep=None, spin_id=None):
233 """Read spin specific data values from a file. 234 235 @keyword param: The name of the parameter to read. 236 @type param: str 237 @keyword scaling: A scaling factor by which all read values are multiplied by. 238 @type scaling: float 239 @keyword file: The name of the file to open. 240 @type file: str 241 @keyword dir: The directory containing the file (defaults to the current directory if None). 242 @type dir: str or None 243 @keyword file_data: An alternative to opening a file, if the data already exists in the correct format. The format is a list of lists where the first index corresponds to the row and the second the column. 244 @type file_data: list of lists 245 @keyword spin_id_col: The column containing the spin ID strings. If supplied, the mol_name_col, res_name_col, res_num_col, spin_name_col, and spin_num_col arguments must be none. 246 @type spin_id_col: int or None 247 @keyword mol_name_col: The column containing the molecule name information. If supplied, spin_id_col must be None. 248 @type mol_name_col: int or None 249 @keyword res_name_col: The column containing the residue name information. If supplied, spin_id_col must be None. 250 @type res_name_col: int or None 251 @keyword res_num_col: The column containing the residue number information. If supplied, spin_id_col must be None. 252 @type res_num_col: int or None 253 @keyword spin_name_col: The column containing the spin name information. If supplied, spin_id_col must be None. 254 @type spin_name_col: int or None 255 @keyword spin_num_col: The column containing the spin number information. If supplied, spin_id_col must be None. 256 @type spin_num_col: int or None 257 @keyword data_col: The column containing the RDC data in Hz. 258 @type data_col: int or None 259 @keyword error_col: The column containing the RDC errors. 260 @type error_col: int or None 261 @keyword sep: The column separator which, if None, defaults to whitespace. 262 @type sep: str or None 263 @keyword spin_id: The spin ID string. 264 @type spin_id: None or str 265 """ 266 267 # Test if the current pipe exists. 268 pipes.test() 269 270 # Test if sequence data is loaded. 271 if not exists_mol_res_spin_data(): 272 raise RelaxNoSequenceError 273 274 # Minimisation parameter. 275 if minimise.return_data_name(param): 276 # Minimisation statistic flag. 277 min_stat = True 278 279 # Specific value and error returning function. 280 return_value = minimise.return_value 281 282 # Specific set function. 283 set_fn = minimise.set 284 285 # Normal parameter. 286 else: 287 # Minimisation statistic flag. 288 min_stat = False 289 290 # Specific v 291 return_value = specific_fns.setup.get_specific_fn('return_value', pipes.get_type()) 292 293 # Specific set function. 294 set_fn = set 295 296 # Test data corresponding to param already exists. 297 for spin in spin_loop(): 298 # Skip deselected spins. 299 if not spin.select: 300 continue 301 302 # Get the value and error. 303 value, error = return_value(spin, param) 304 305 # Data exists. 306 if value != None or error != None: 307 raise RelaxValueError(param) 308 309 # Loop over the data. 310 mol_names = [] 311 res_nums = [] 312 res_names = [] 313 spin_nums = [] 314 spin_names = [] 315 values = [] 316 errors = [] 317 for data in read_spin_data(file=file, dir=dir, file_data=file_data, spin_id_col=spin_id_col, mol_name_col=mol_name_col, res_num_col=res_num_col, res_name_col=res_name_col, spin_num_col=spin_num_col, spin_name_col=spin_name_col, data_col=data_col, error_col=error_col, sep=sep, spin_id=spin_id): 318 # Unpack. 319 if data_col and error_col: 320 mol_name, res_num, res_name, spin_num, spin_name, value, error = data 321 elif data_col: 322 mol_name, res_num, res_name, spin_num, spin_name, value = data 323 error = None 324 else: 325 mol_name, res_num, res_name, spin_num, spin_name, error = data 326 value = None 327 328 # Set the value. 329 id = generate_spin_id_unique(mol_name=mol_name, res_num=res_num, res_name=res_name, spin_num=spin_num, spin_name=spin_name) 330 set_fn(val=value, error=error, param=param, spin_id=id) 331 332 # Append the data for printout. 333 mol_names.append(mol_name) 334 res_nums.append(res_num) 335 res_names.append(res_name) 336 spin_nums.append(spin_num) 337 spin_names.append(spin_name) 338 values.append(value) 339 errors.append(error) 340 341 # Print out. 342 write_spin_data(file=sys.stdout, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name=param, error=errors, error_name='%s_error'%param) 343 344 # Reset the minimisation statistics. 345 if not min_stat: 346 minimise.reset_min_stats()
347 348
349 -def set(val=None, param=None, error=None, pipe=None, spin_id=None, force=True, reset=True):
350 """Set global or spin specific data values. 351 352 @keyword val: The parameter values. 353 @type val: None or list 354 @keyword param: The parameter names. 355 @type param: None, str, or list of str 356 @keyword error: The parameter errors. 357 @type error: None, number, or list of numbers 358 @keyword pipe: The data pipe the values should be placed in. 359 @type pipe: None or str 360 @keyword spin_id: The spin identification string. 361 @type spin_id: str 362 @keyword force: A flag forcing the overwriting of current values. 363 @type force: bool 364 @keyword reset: A flag which if True will cause all minimisation statistics to be reset. 365 @type reset: bool 366 """ 367 368 # Switch to the data pipe, storing the original. 369 if pipe: 370 orig_pipe = pipes.cdp_name() 371 pipes.switch(pipe) 372 373 # Test if the current data pipe exists. 374 pipes.test() 375 376 # Specific functions. 377 default_value = specific_fns.setup.get_specific_fn('default_value', pipes.get_type()) 378 get_param_names = specific_fns.setup.get_specific_fn('get_param_names', pipes.get_type()) 379 return_data_name = specific_fns.setup.get_specific_fn('return_data_name', pipes.get_type()) 380 set_param_values = specific_fns.setup.get_specific_fn('set_param_values', pipes.get_type()) 381 382 # Convert numpy arrays to lists, if necessary. 383 if isinstance(val, ndarray): 384 val = val.tolist() 385 386 # Invalid combinations. 387 if (isinstance(val, float) or isinstance(val, int)) and param == None: 388 raise RelaxError("The combination of a single value '%s' without specifying the parameter name is invalid." % val) 389 if isinstance(val, list) and isinstance(param, str): 390 raise RelaxError("Invalid combination: When multiple values '%s' are specified, either no parameters or a list of parameters must by supplied rather than the single parameter '%s'." % (val, param)) 391 392 # Value array and parameter array of equal length. 393 if isinstance(val, list) and isinstance(param, list) and len(val) != len(param): 394 raise RelaxError("Both the value array and parameter array must be of equal length.") 395 396 # Get the parameter list if needed. 397 if param == None: 398 param = get_param_names() 399 400 # Convert the param to a list if needed. 401 if not isinstance(param, list): 402 param = [param] 403 404 # Convert the value to a list if needed. 405 if val != None and not isinstance(val, list): 406 val = [val] * len(param) 407 408 # Default values. 409 if val == None: 410 # Loop over the parameters, getting the default values. 411 val = [] 412 for i in range(len(param)): 413 val.append(default_value(return_data_name(param[i]))) 414 415 # Check that there is a default. 416 if val[-1] == None: 417 raise RelaxParamSetError(param[i]) 418 419 # Set the parameter values. 420 set_param_values(param=param, value=val, spin_id=spin_id, force=force) 421 422 # Reset all minimisation statistics. 423 if reset: 424 minimise.reset_min_stats() 425 426 # Switch back. 427 if pipe: 428 pipes.switch(orig_pipe)
429 430
431 -def write(param=None, file=None, dir=None, scaling=1.0, return_value=None, return_data_desc=None, comment=None, bc=False, force=False):
432 """Write data to a file. 433 434 @keyword param: The name of the parameter to write to file. 435 @type param: str 436 @keyword file: The file to write the data to. 437 @type file: str 438 @keyword dir: The name of the directory to place the file into (defaults to the current directory). 439 @type dir: str 440 @keyword scaling: The value to scale the parameter by. 441 @type scaling: float 442 @keyword return_value: An optional function which if supplied will override the default value returning function. 443 @type return_value: None or func 444 @keyword return_data_desc: An optional function which if supplied will override the default parameter description returning function. 445 @type return_data_desc: None or func 446 @keyword comment: Text which will be added to the start of the file as comments. All lines will be prefixed by '# '. 447 @type comment: str 448 @keyword bc: A flag which if True will cause the back calculated values to be written. 449 @type bc: bool 450 @keyword force: A flag which if True will cause any pre-existing file to be overwritten. 451 @type force: bool 452 """ 453 454 # Test if the current pipe exists. 455 pipes.test() 456 457 # Test if the sequence data is loaded. 458 if not exists_mol_res_spin_data(): 459 raise RelaxNoSequenceError 460 461 # Open the file for writing. 462 file_path = get_file_path(file, dir) 463 file = open_write_file(file, dir, force) 464 465 # Write the data. 466 write_data(param=param, file=file, scaling=scaling, return_value=return_value, return_data_desc=return_data_desc, comment=comment, bc=bc) 467 468 # Close the file. 469 file.close() 470 471 # Add the file to the results file list. 472 add_result_file(type='text', label='Text', file=file_path)
473 474
475 -def write_data(param=None, file=None, scaling=1.0, bc=False, return_value=None, return_data_desc=None, comment=None):
476 """The function which actually writes the data. 477 478 @keyword param: The parameter to write. 479 @type param: str 480 @keyword file: The file to write the data to. 481 @type file: str 482 @keyword scaling: The value to scale the parameter by. 483 @type scaling: float 484 @keyword bc: A flag which if True will cause the back calculated values to be written. 485 @type bc: bool 486 @keyword return_value: An optional function which if supplied will override the default value returning function. 487 @type return_value: None or func 488 @keyword return_data_desc: An optional function which if supplied will override the default parameter description returning function. 489 @type return_data_desc: None or func 490 @keyword comment: Text which will be added to the start of the file as comments. All lines will be prefixed by '# '. 491 @type comment: str 492 """ 493 494 # Get the value and error returning function parameter description function if required. 495 if not return_value: 496 return_value = specific_fns.setup.get_specific_fn('return_value', pipes.get_type()) 497 if not return_data_desc: 498 return_data_desc = specific_fns.setup.get_specific_fn('return_data_desc', pipes.get_type()) 499 500 # Format string. 501 format = "%-30s%-30s" 502 503 # Init the data. 504 mol_names = [] 505 res_nums = [] 506 res_names = [] 507 spin_nums = [] 508 spin_names = [] 509 values = [] 510 errors = [] 511 512 # Get the parameter description and add it to the file. 513 desc = return_data_desc(param) 514 if desc: 515 file.write("# Parameter description: %s.\n" % desc) 516 file.write("#\n") 517 518 # The comments. 519 if comment: 520 # Split up the lines. 521 lines = comment.splitlines() 522 523 # Write out. 524 for line in lines: 525 file.write("# %s\n" % line) 526 file.write("#\n") 527 528 # Loop over the sequence. 529 for spin, mol_name, res_num, res_name in spin_loop(full_info=True): 530 # Get the value and error. 531 value, error = return_value(spin, param, bc=bc) 532 533 # Append the spin data (scaled). 534 mol_names.append(mol_name) 535 res_nums.append(res_num) 536 res_names.append(res_name) 537 spin_nums.append(spin.num) 538 spin_names.append(spin.name) 539 540 # Append the scaled values and errors. 541 if value != None: 542 value *= scaling 543 if error != None: 544 error *= scaling 545 values.append(value) 546 errors.append(error) 547 548 # Write the data. 549 write_spin_data(file, mol_names=mol_names, res_nums=res_nums, res_names=res_names, spin_nums=spin_nums, spin_names=spin_names, data=values, data_name='value', error=errors, error_name='error')
550