Package pipe_control :: Module plotting
[hide private]
[frames] | no frames]

Source Code for Module pipe_control.plotting

  1  ############################################################################### 
  2  #                                                                             # 
  3  # Copyright (C) 2013,2015 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 plotting of data. 
 24   
 25  The numerical graph data handled in these functions consists of a 4 dimensional list or array object.  The first dimension corresponds to different graphs.  The second corresponds the different data sets within a single each graph.  The third corresponds to the data series (i.e. each data point).  The forth is a list of the information about each point, it is a list where the first element is the X value, the second is the Y value, the third is the optional dX or dY error, and the forth is the optional dY error when X errors are present (the third position is then dx). 
 26  """ 
 27   
 28  # Python module imports. 
 29  from warnings import warn 
 30   
 31  # relax module imports. 
 32  from lib.errors import RelaxError 
 33  from lib.io import get_file_path, open_write_file 
 34  from lib.plotting.api import write_xy_data, write_xy_header 
 35  from lib.warnings import RelaxWarning 
 36  from pipe_control.mol_res_spin import check_mol_res_spin_data, spin_loop 
 37  from pipe_control.pipes import cdp_name, check_pipe 
 38  from pipe_control.result_files import add_result_file 
 39  from specific_analyses.api import return_api 
 40   
 41   
42 -def assemble_data(spin_id=None, x_data_name=None, y_data_name=None, plot_data=None):
43 """Return all the xy data, along with the graph type and names for the graph sets. 44 45 @keyword spin_id: The spin ID string for restricting the graph to. 46 @type spin_id: str 47 @keyword x_data_name: The category of the X-axis data. 48 @type x_data_name: str 49 @keyword y_data_name: The category of the Y-axis data. 50 @type y_data_name: str 51 @keyword plot_data: The type of the plotted data, one of 'value', 'error', or 'sim'. 52 @type plot_data: str 53 @return: The 4D graph numerical data structure, the graph type (i.e. on of 'xy', 'xydy', or 'xydxdy'), and the labels for the graph sets. 54 @rtype: list of lists of lists of float, str, and list of str 55 """ 56 57 # Initialise the 4D data structure (Gx, Sx, data point, data point info), and graph set labels. 58 data_list = False 59 data_dict = False 60 61 # The data types. 62 x_type = get_data_type(data_name=x_data_name) 63 y_type = get_data_type(data_name=y_data_name) 64 65 # Determine the graph type. 66 graph_type = classify_graph_2D(x_data_name=x_data_name, y_data_name=y_data_name, x_type=x_type, y_type=y_type) 67 68 # Assemble the different graph data structures. 69 if graph_type == 'seq-value': 70 data, set_labels, x_err_flag, y_err_flag = assemble_data_seq_value(spin_id=spin_id, x_data_name=x_data_name, y_data_name=y_data_name, plot_data=plot_data) 71 elif graph_type == 'value-value': 72 data, set_labels, x_err_flag, y_err_flag = assemble_data_scatter(spin_id=spin_id, x_data_name=x_data_name, y_data_name=y_data_name, plot_data=plot_data) 73 elif graph_type == 'seq-series': 74 data, set_labels, x_err_flag, y_err_flag = assemble_data_seq_series(spin_id=spin_id, x_data_name=x_data_name, y_data_name=y_data_name, plot_data=plot_data, x_type=x_type, y_type=y_type) 75 elif graph_type == 'series-series': 76 data, set_labels, x_err_flag, y_err_flag = assemble_data_series_series(spin_id=spin_id, x_data_name=x_data_name, y_data_name=y_data_name, plot_data=plot_data, x_type=x_type, y_type=y_type) 77 else: 78 raise RelaxError("Unknown graph type '%s'." % graph_type) 79 80 # The graph type. 81 graph_type = 'X,Y' 82 if x_err_flag: 83 graph_type = graph_type + ',dX' 84 if y_err_flag: 85 graph_type = graph_type + ',dY' 86 87 # Return the data. 88 return data, set_labels, graph_type
89 90
91 -def assemble_data_scatter(spin_id=None, x_data_name=None, y_data_name=None, plot_data='value'):
92 """Assemble the graph data for scatter type data of one value verses another. 93 94 For such data, only a single graph and set will be produced. 95 96 97 @keyword spin_id: The spin ID string for restricting the graph to. 98 @type spin_id: str 99 @keyword x_data_name: The name of the X-data or variable to plot. 100 @type x_data_name: str 101 @keyword y_data_name: The name of the Y-data or variable to plot. 102 @type y_data_name: str 103 @keyword plot_data: The type of the plotted data, one of 'value', 'error', or 'sim'. 104 @type plot_data: str 105 @return: The graph data, set labels, and flags for errors in the X and Y dimensions. 106 @rtype: list of lists of lists of numbers, list of str, bool, bool 107 """ 108 109 # Default to the assemble_data_seq_value() function, as the graphs are currently not constructed differently. 110 return assemble_data_seq_value(x_data_name=x_data_name, y_data_name=y_data_name, plot_data=plot_data)
111 112
113 -def assemble_data_seq_series(spin_id=None, x_data_name=None, y_data_name=None, plot_data='value', x_type=None, y_type=None):
114 """Assemble the graph data for residue or spin sequence verses verses list or dictionary data. 115 116 For such data, one graph will be produced. There will be one data set in this graph per series. 117 118 119 @keyword spin_id: The spin ID string for restricting the graph to. 120 @type spin_id: str 121 @keyword x_data_name: The name of the X-data or variable to plot. 122 @type x_data_name: str 123 @keyword y_data_name: The name of the Y-data or variable to plot. 124 @type y_data_name: str 125 @keyword plot_data: The type of the plotted data, one of 'value', 'error', or 'sim'. 126 @type plot_data: str 127 @keyword x_type: The type of X-data to plot. 128 @type x_type: type object 129 @keyword y_type: The type of Y-data to plot. 130 @type y_type: type object 131 @return: The graph data, set labels, and flags for errors in the X and Y dimensions. 132 @rtype: list of lists of lists of numbers, list of str, bool, bool 133 """ 134 135 # Initialise some data structures. 136 data = [[]] 137 set_labels = [] 138 x_err_flag = False 139 y_err_flag = False 140 141 # The sequence and series axes. 142 if x_data_name in ['res_num', 'spin_num']: 143 seq_axis = 'x' 144 series_type = y_type 145 else: 146 seq_axis = 'y' 147 series_type = x_type 148 149 # Determine the number of sets. 150 for spin, mol_name, res_num, res_name, id in spin_loop(full_info=True, selection=spin_id, return_id=True, skip_desel=True): 151 # Fetch the series data (ignore simulations). 152 if seq_axis == 'x': 153 val, err = fetch_1D_data(plot_data=plot_data, data_name=y_data_name, spin=spin, res_num=res_num) 154 else: 155 val, err = fetch_1D_data(plot_data=plot_data, data_name=x_data_name, spin=spin, res_num=res_num) 156 157 # No data. 158 if val == None: 159 continue 160 161 # The keys. 162 if series_type == dict: 163 keys = sorted(val.keys()) 164 165 # Loop over the series data. 166 for j in range(len(val)): 167 # The index or key for the data. 168 if series_type == list: 169 elem = j 170 else: 171 elem = keys[j] 172 173 # Add the set info if new. 174 if elem not in set_labels: 175 data[0].append([]) 176 set_labels.append(elem) 177 178 # Sort the set labels. 179 set_labels.sort() 180 181 # Number of data points per spin. 182 if plot_data == 'sim': 183 points = cdp.sim_number 184 else: 185 points = 1 186 187 # Loop over the spins. 188 spin_index = 0 189 for spin, mol_name, res_num, res_name, id in spin_loop(full_info=True, selection=spin_id, return_id=True, skip_desel=True): 190 # Loop over the data points (for simulations). 191 for i in range(points): 192 # The X and Y data. 193 x_val, x_err = fetch_1D_data(plot_data=plot_data, data_name=x_data_name, spin=spin, res_num=res_num, sim_num=i) 194 y_val, y_err = fetch_1D_data(plot_data=plot_data, data_name=y_data_name, spin=spin, res_num=res_num, sim_num=i) 195 196 # Alias the data. 197 if seq_axis == 'x': 198 series_val = y_val 199 else: 200 series_val = x_val 201 202 # Go to the next spin if there is missing xy data. 203 if x_val == None or y_val == None: 204 continue 205 206 # The error flags. 207 if x_err != None: 208 x_err_flag = True 209 if y_err != None: 210 y_err_flag = True 211 212 # The keys. 213 if series_type == dict: 214 keys = sorted(series_val.keys()) 215 216 # Loop over the series data. 217 for j in range(len(series_val)): 218 # The index or key for the data. 219 if series_type == list: 220 index = set_labels.index(j) 221 elem = index 222 else: 223 index = set_labels.index(keys[j]) 224 elem = set_labels[set_labels.index(keys[j])] 225 226 # Append the data. 227 if seq_axis == 'x': 228 data[0][index].append([x_val, y_val[elem]]) 229 else: 230 data[0][index].append([x_val[elem], y_val]) 231 if x_err_flag: 232 data[0][index][-1].append(x_err[elem]) 233 if y_err_flag: 234 data[0][index][-1].append(y_err[elem]) 235 236 # Increment the spin index. 237 spin_index += 1 238 239 # Return the data. 240 return data, set_labels, x_err_flag, y_err_flag
241 242
243 -def assemble_data_seq_value(spin_id=None, x_data_name=None, y_data_name=None, plot_data='value'):
244 """Assemble the graph data for residue or spin sequence verses values. 245 246 For such data, only a single graph and set will be produced. 247 248 249 @keyword spin_id: The spin ID string for restricting the graph to. 250 @type spin_id: str 251 @keyword x_data_name: The name of the X-data or variable to plot. 252 @type x_data_name: str 253 @keyword y_data_name: The name of the Y-data or variable to plot. 254 @type y_data_name: str 255 @keyword plot_data: The type of the plotted data, one of 'value', 'error', or 'sim'. 256 @type plot_data: str 257 @return: The graph data, set labels, and flags for errors in the X and Y dimensions. 258 @rtype: list of lists of lists of numbers, list of str, bool, bool 259 """ 260 261 # Initialise some data structures. 262 data = [[[]]] 263 set_labels = [] 264 x_err_flag = False 265 y_err_flag = False 266 267 # Count the different spin types. 268 spin_names = [] 269 for spin, mol_name, res_num, res_name, id in spin_loop(full_info=True, selection=spin_id, return_id=True, skip_desel=True): 270 # A new spin name. 271 if spin.name not in spin_names: 272 spin_names.append(spin.name) 273 274 # The number of data sets. 275 set_count = len(spin_names) 276 277 # Expand the data structures for the number of sets. 278 if set_count > 1: 279 # Expand the data array. 280 for i in range(set_count-1): 281 data[0].append([]) 282 283 # Expand the set labels for all spin data. 284 for spin, mol_name, res_num, res_name, id in spin_loop(full_info=True, selection=spin_id, return_id=True, skip_desel=True): 285 label = "%s spins" % spin.name 286 if label not in set_labels: 287 set_labels.append(label) 288 289 # Number of data points per spin. 290 if plot_data == 'sim': 291 points = cdp.sim_number 292 else: 293 points = 1 294 295 # Loop over the spins. 296 for spin, mol_name, res_num, res_name, id in spin_loop(full_info=True, selection=spin_id, return_id=True, skip_desel=True): 297 # The set index. 298 set_index = spin_names.index(spin.name) 299 300 # Loop over the data points (for simulations). 301 for i in range(points): 302 # The X and Y data. 303 x_val, x_err = fetch_1D_data(plot_data=plot_data, data_name=x_data_name, spin=spin, res_num=res_num, sim_num=i) 304 y_val, y_err = fetch_1D_data(plot_data=plot_data, data_name=y_data_name, spin=spin, res_num=res_num, sim_num=i) 305 306 # Go to the next spin if there is missing xy data. 307 if x_val == None or y_val == None: 308 continue 309 310 # The error flags. 311 if x_err != None: 312 x_err_flag = True 313 if y_err != None: 314 y_err_flag = True 315 316 # Append the data. 317 data[0][set_index].append([x_val, y_val]) 318 if x_err_flag: 319 data[0][set_index][-1].append(x_err) 320 if y_err_flag: 321 data[0][set_index][-1].append(y_err) 322 323 # Return the data. 324 return data, set_labels, x_err_flag, y_err_flag
325 326
327 -def assemble_data_series_series(spin_id=None, x_data_name=None, y_data_name=None, plot_data='value', x_type=None, y_type=None):
328 """Assemble the graph data for curves of list or dictionary data verses list or dictionary data. 329 330 For such data, one graph will be produced. There will be one data set in this graph per spin. 331 332 333 @keyword spin_id: The spin ID string for restricting the graph to. 334 @type spin_id: str 335 @keyword x_data_name: The name of the X-data or variable to plot. 336 @type x_data_name: str 337 @keyword y_data_name: The name of the Y-data or variable to plot. 338 @type y_data_name: str 339 @keyword plot_data: The type of the plotted data, one of 'value', 'error', or 'sim'. 340 @type plot_data: str 341 @keyword x_type: The type of X-data to plot. 342 @type x_type: type object 343 @keyword y_type: The type of Y-data to plot. 344 @type y_type: type object 345 @return: The graph data, set labels, and flags for errors in the X and Y dimensions. 346 @rtype: list of lists of lists of numbers, list of str, bool, bool 347 """ 348 349 # Initialise some data structures. 350 data = [[]] 351 set_labels = [] 352 x_err_flag = False 353 y_err_flag = False 354 355 # Sanity check. 356 if x_type != y_type: 357 raise RelaxError("The X data type '%s' and Y data type '%s' do not match." % (x_type, y_type)) 358 359 # Check if the dictionary keys are the values to plot. 360 keys_for_values = None 361 base_values = [] 362 if x_type == dict: 363 for spin, mol_name, res_num, res_name, id in spin_loop(full_info=True, selection=spin_id, return_id=True, skip_desel=True): 364 # Fetch the series data (ignore simulations). 365 x_val, x_err = fetch_1D_data(plot_data=plot_data, data_name=x_data_name, spin=spin, res_num=res_num) 366 y_val, y_err = fetch_1D_data(plot_data=plot_data, data_name=y_data_name, spin=spin, res_num=res_num) 367 368 # Go to the next spin if there is missing xy data. 369 if x_val == None or y_val == None: 370 continue 371 372 # The keys. 373 x_keys = sorted(x_val.keys()) 374 y_keys = sorted(y_val.keys()) 375 376 # The keys do not match. 377 if x_keys[0] in y_keys: 378 continue 379 380 # Are the X keys in the Y values? 381 if x_keys[0] in list(y_val.values()): 382 keys_for_values = 'x' 383 for key in x_keys: 384 if key not in base_values: 385 base_values.append(key) 386 387 # Are the Y keys in the X values? 388 elif y_keys[0] in list(x_val.values()): 389 keys_for_values = 'y' 390 for key in y_keys: 391 if key not in base_values: 392 base_values.append(key) 393 394 # Number of data points per spin. 395 if plot_data == 'sim': 396 points = cdp.sim_number 397 else: 398 points = 1 399 400 # Loop over the spins. 401 spin_index = 0 402 for spin, mol_name, res_num, res_name, id in spin_loop(full_info=True, selection=spin_id, return_id=True, skip_desel=True): 403 # Append a new set structure and set the name to the spin ID. 404 data[0].append([]) 405 set_labels.append("Spin %s" % id) 406 407 # Loop over the data points (for simulations). 408 for i in range(points): 409 # The X and Y data. 410 x_val, x_err = fetch_1D_data(plot_data=plot_data, data_name=x_data_name, spin=spin, res_num=res_num, sim_num=i) 411 y_val, y_err = fetch_1D_data(plot_data=plot_data, data_name=y_data_name, spin=spin, res_num=res_num, sim_num=i) 412 413 # The base values to create the curve from. 414 if keys_for_values == None: 415 base_values = x_val 416 417 # Go to the next spin if there is missing xy data. 418 if x_val == None or y_val == None: 419 continue 420 421 # The error flags. 422 if x_err != None: 423 x_err_flag = True 424 if y_err != None: 425 y_err_flag = True 426 427 # Series sanity checks. 428 if keys_for_values == None and len(x_val) != len(y_val): 429 raise RelaxError("The series data %s does not have the same number of elements as %s." % (x_val, y_val)) 430 431 # The keys. 432 if x_type == dict: 433 keys = sorted(x_val.keys()) 434 435 # Loop over the list data. 436 for j in range(len(base_values)): 437 # The index or key for the data. 438 if x_type == list: 439 elem = j 440 else: 441 elem = keys[j] 442 443 # Append the data. 444 if keys_for_values == None: 445 data[0][spin_index].append([x_val[elem], y_val[elem]]) 446 if x_err_flag: 447 data[0][spin_index][-1].append(x_err[elem]) 448 if y_err_flag: 449 data[0][spin_index][-1].append(y_err[elem]) 450 451 # Append the data (X keys in the Y values). 452 elif keys_for_values == 'x': 453 data[0][spin_index].append([x_val[base_values[j]], base_values[j]]) 454 if x_err_flag: 455 data[0][spin_index][-1].append(x_err[base_values[j]]) 456 if y_err_flag: 457 raise RelaxError("Y errors are not possible when the Y values are keys.") 458 459 # Append the data (Y keys in the X values). 460 elif keys_for_values == 'y': 461 data[0][spin_index].append([base_values[j], y_val[base_values[j]]]) 462 if x_err_flag: 463 raise RelaxError("X errors are not possible when the X values are keys.") 464 if y_err_flag: 465 data[0][spin_index][-1].append(y_err[base_values[j]]) 466 467 # Sort the data for better looking curves. 468 data[0][spin_index].sort() 469 470 # Increment the spin index. 471 spin_index += 1 472 473 # Return the data. 474 return data, set_labels, x_err_flag, y_err_flag
475 476
477 -def axis_setup(data_type=None, norm=True):
478 """Determine the axis information for relax data store specific data. 479 480 @keyword data_type: The axis data category (in the [X, Y] list format). 481 @type data_type: list of str 482 @keyword norm: The normalisation flag which if set to True will cause all graphs to be normalised to a starting value of 1. 483 @type norm: bool 484 @return: The axis information. This includes the sequence type, the list of lower bounds, the list of upper bounds, and the axis labels. 485 @rtype: list of str or None, list of int or None, list of int or None, list of str or None 486 """ 487 488 # Axis specific settings. 489 axes = ['x', 'y'] 490 seq_type = [None, None] 491 axis_labels = [None, None] 492 for i in range(2): 493 # Determine the sequence data type. 494 if data_type[i] == 'res_num': 495 seq_type[i] = 'res' 496 497 # Analysis specific methods for making labels. 498 analysis_spec = False 499 if cdp_name(): 500 # Flag for making labels. 501 analysis_spec = True 502 503 # The specific analysis API object. 504 api = return_api() 505 506 # Some axis default values for spin data. 507 if data_type[i] == 'res_num': 508 # Residue only data. 509 if seq_type[i] == 'res': 510 # X-axis label. 511 if not axis_labels[i]: 512 axis_labels[i] = "Residue number" 513 514 # Spin only data. 515 if seq_type[i] == 'spin': 516 # X-axis label. 517 if not axis_labels[i]: 518 axis_labels[i] = "Spin number" 519 520 # Mixed data. 521 if seq_type[i] == 'mixed': 522 # X-axis label. 523 if not axis_labels[i]: 524 axis_labels[i] = "Spin identification string" 525 526 # Some axis default values for other data types. 527 else: 528 # Label. 529 if analysis_spec and not axis_labels[i]: 530 # Get the Grace units. 531 units = api.return_grace_units(data_type[i]) 532 533 # Set the label. 534 axis_labels[i] = api.return_grace_string(data_type[i]) 535 536 # Add units. 537 if units: 538 axis_labels[i] = axis_labels[i] + "\\N (" + units + ")" 539 540 # Normalised data. 541 if norm and axes[i] == 'y': 542 axis_labels[i] = axis_labels[i] + " \\N\\q(normalised)\\Q" 543 544 # Return the data. 545 return seq_type, axis_labels
546 547
548 -def classify_graph_2D(x_data_name=None, y_data_name=None, x_type=None, y_type=None):
549 """Determine the type of graph to produce. 550 551 The graph type can be one of: 552 553 - 'seq-value', the residue or spin sequence verses the parameter value. 554 - 'seq-series', the residue or spin sequence verses the parameter value. 555 - 'value-value', a scatter plot of one value verses another. 556 - 'value-series', a curve of one value verses a list or dictionary of data. 557 - 'series-series', curves of list or dictionary data verses list or dictionary data. 558 559 @keyword x_data_name: The name of the X-data or variable to plot. 560 @type x_data_name: str 561 @keyword y_data_name: The name of the Y-data or variable to plot. 562 @type y_data_name: str 563 @keyword x_type: The type of X-data to plot. 564 @type x_type: type object 565 @keyword y_type: The type of Y-data to plot. 566 @type y_type: type object 567 @return: The graph type. 568 @rtype: str 569 """ 570 571 # Disallow certain combinations. 572 if x_data_name == y_data_name == 'res_num': 573 raise RelaxError("The X and Y-axes can not both be based on residue numbers.") 574 if x_data_name == y_data_name == 'spin_num': 575 raise RelaxError("The X and Y-axes can not both be based on residue numbers.") 576 577 # Some data type flags. 578 x_series = False 579 y_series = False 580 if x_type == list or x_type == dict: 581 x_series = True 582 if y_type == list or y_type == dict: 583 y_series = True 584 585 # The different X and Y axis sequence types. 586 if x_data_name in ['res_num', 'spin_num'] and not y_series: 587 return 'seq-value' 588 if x_data_name in ['res_num', 'spin_num'] and y_series: 589 return 'seq-series' 590 if y_data_name in ['res_num', 'spin_num'] and not x_series: 591 return 'seq-value' 592 if y_data_name in ['res_num', 'spin_num'] and x_series: 593 return 'seq-series' 594 595 # Scatter plots. 596 if not x_series and not y_series: 597 return 'value-value' 598 599 # Series-series data. 600 if not x_series and y_series: 601 return 'value-series' 602 if x_series and not y_series: 603 return 'value-series' 604 605 # Series-series data. 606 if x_series and y_series: 607 return 'series-series' 608 609 # Unknown. 610 return 'unknown'
611 612
613 -def fetch_1D_data(plot_data=None, data_name=None, spin=None, res_num=None, sim_num=None):
614 """Return the value and error for the corresponding axis. 615 616 @keyword plot_data: The type of the plotted data, one of 'value', 'error', or 'sim'. 617 @type plot_data: str 618 @keyword data_name: The name of the data or variable to plot. 619 @type data_name: str 620 @keyword spin: The spin container to fetch the values from. 621 @type spin: SpinContainer instance 622 @keyword res_num: The residue number for the given spin. 623 @type res_num: int 624 @keyword sim_num: The simulation number if simulation data is to be returned. 625 @type sim_num: int 626 @return: The value and error when available. 627 @rtype: int or float, None or float 628 """ 629 630 # Specific x and y value returning functions. 631 return_value, return_conversion_factor = get_functions(data_name=data_name) 632 633 # The residue number data. 634 if data_name == 'res_num': 635 val, err = res_num, None 636 637 # The spin number data. 638 elif data_name == 'spin_num': 639 val, err = spin.num, None 640 641 # All other data types. 642 else: 643 # Get the data. 644 if plot_data == 'sim': 645 val, err = return_value(spin, data_name, sim=sim_num) 646 else: 647 val, err = return_value(spin, data_name) 648 649 # Convert to the correct scale. 650 if isinstance(val, list): 651 for i in range(len(val)): 652 val[i] = val[i] / return_conversion_factor(data_name) 653 if err != None: 654 err[i] = err[i] / return_conversion_factor(data_name) 655 elif isinstance(val, dict): 656 for key in val: 657 val[key] = val[key] / return_conversion_factor(data_name) 658 if err != None: 659 err[key] = err[key] / return_conversion_factor(data_name) 660 elif val != None and err != None: 661 val = val / return_conversion_factor(data_name) 662 err = err / return_conversion_factor(data_name) 663 elif val != None: 664 val = val / return_conversion_factor(data_name) 665 elif err != None: 666 err = err / return_conversion_factor(data_name) 667 668 # Convert the errors to values. 669 if data_name not in ['res_num', 'spin_num'] and plot_data == 'error': 670 val = err 671 err = None 672 673 # Simulation data, so turn off errors. 674 if plot_data == 'sim': 675 err = None 676 677 # Return the data. 678 return val, err
679 680
681 -def get_functions(data_name=None):
682 """Determine the specific functions for the given data type. 683 684 @keyword data_name: The name of the data or variable to plot. 685 @type data_name: str 686 @return: The analysis specific return_value, return_conversion_factor, and data_type methods. 687 @rtype: tuple of methods or None 688 """ 689 690 # Spin data. 691 if data_name in ['res_num', 'spin_num']: 692 return None, None 693 694 # Analysis specific value returning functions. 695 else: 696 api = return_api() 697 return api.return_value, api.return_conversion_factor
698 699
700 -def get_data_type(data_name=None):
701 """Determine the type for the given data. 702 703 @keyword data_name: The name of the data or variable to plot. 704 @type data_name: str 705 @return: The data type. 706 @rtype: Python type 707 """ 708 709 # Sequence data. 710 if data_name in ['res_num', 'spin_num']: 711 return int 712 713 # Analysis specific value returning functions. 714 api = return_api() 715 return api.data_type(data_name)
716 717
718 -def write_xy(format='grace', x_data_type='res_num', y_data_type=None, spin_id=None, plot_data='value', norm_type='first', file=None, dir=None, force=False, norm=True):
719 """Writing data to a file. 720 721 @keyword format: The specific backend to use. The currently support backends are 'grace'. 722 @type format: str 723 @keyword x_data_type: The category of the X-axis data. 724 @type x_data_type: str 725 @keyword y_data_type: The category of the Y-axis data. 726 @type y_data_type: str 727 @keyword spin_id: The spin identification string. 728 @type spin_id: str 729 @keyword plot_data: The type of the plotted data, one of 'value', 'error', or 'sim'. 730 @type plot_data: str 731 @keyword norm_type: The point to normalise to 1. This can be 'first' or 'last'. 732 @type norm_type: str 733 @keyword file: The name of the Grace file to create. 734 @type file: str 735 @keyword dir: The optional directory to place the file into. 736 @type dir: str 737 @param force: Boolean argument which if True causes the file to be overwritten if it already exists. 738 @type force: bool 739 @keyword norm: The normalisation flag which if set to True will cause all graphs to be normalised to a starting value of 1. 740 @type norm: bool 741 """ 742 743 # Checks. 744 check_pipe() 745 check_mol_res_spin_data() 746 747 # Test if the plot_data argument is one of 'value', 'error', or 'sim'. 748 if plot_data not in ['value', 'error', 'sim']: 749 raise RelaxError("The plot data argument " + repr(plot_data) + " must be set to either 'value', 'error', 'sim'.") 750 751 # Test if the simulations exist. 752 if plot_data == 'sim' and not hasattr(cdp, 'sim_number'): 753 raise RelaxNoSimError 754 755 # Open the file for writing. 756 file_path = get_file_path(file, dir) 757 file = open_write_file(file, dir, force) 758 759 # Get the data. 760 data, set_names, graph_type = assemble_data(spin_id, x_data_name=x_data_type, y_data_name=y_data_type, plot_data=plot_data) 761 762 # Convert the graph type. 763 if graph_type == 'X,Y': 764 graph_type = 'xy' 765 elif graph_type == 'X,Y,dX': 766 graph_type = 'xydx' 767 elif graph_type == 'X,Y,dY': 768 graph_type = 'xydy' 769 elif graph_type == 'X,Y,dX,dY': 770 graph_type = 'xydxdy' 771 772 # No data, so close the empty file and exit. 773 if not len(data) or not len(data[0]) or not len(data[0][0]): 774 warn(RelaxWarning("No data could be found, creating an empty file.")) 775 file.close() 776 return 777 778 # Get the axis information. 779 data_type = [x_data_type, y_data_type] 780 seq_type, axis_labels = axis_setup(data_type=data_type, norm=norm) 781 782 # Write the header. 783 write_xy_header(format=format, file=file, data_type=data_type, seq_type=seq_type, sets=[len(data[0])], set_names=[set_names], axis_labels=[axis_labels], norm=[norm]) 784 785 # Write the data. 786 write_xy_data(format=format, data=data, file=file, graph_type=graph_type, norm_type=norm_type, norm=[norm]) 787 788 # Close the file. 789 file.close() 790 791 # Add the file to the results file list. 792 label = None 793 if format == 'grace': 794 label = 'Grace' 795 add_result_file(type=format, label='Grace', file=file_path)
796