Package lib :: Package software :: Module grace
[hide private]
[frames] | no frames]

Source Code for Module lib.software.grace

  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 interfacing with Grace (also known as Xmgrace, Xmgr, and ace).""" 
 24   
 25  # Python module imports. 
 26  from math import ceil, sqrt 
 27   
 28  # relax module imports. 
 29  import pipe_control 
 30  from pipe_control import pipes 
 31  import specific_analyses 
 32   
 33   
34 -def write_xy_data(data, file=None, graph_type=None, norm=None):
35 """Write the data into the Grace xy-scatter plot. 36 37 The numerical data should be supplied as a 4 dimensional list or array object. The first dimension corresponds to the graphs, Gx. The second corresponds the sets of each graph, Sx. 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 (either dx or dy dependent upon the graph_type arg), and the forth is the optional dy error when graph_type is xydxdy (the third position is then dx). 38 39 40 @param data: The 4D structure of numerical data to graph (see docstring). 41 @type data: list of lists of lists of float 42 @keyword file: The file object to write the data to. 43 @type file: file object 44 @keyword graph_type: The graph type which can be one of xy, xydy, xydx, or xydxdy. 45 @type graph_type: str 46 @keyword norm: The normalisation flag which if set to True will cause all graphs to be normalised to 1. The first dimension is the graph. 47 @type norm: None or list of bool 48 """ 49 50 # Graph number. 51 graph_num = len(data) 52 53 # Defaults. 54 if not norm: 55 norm = [] 56 for gi in range(graph_num): 57 norm.append(False) 58 59 # Comment columns. 60 comment_col = 2 61 if graph_type in ['xydx', 'xydy']: 62 comment_col = 3 63 elif graph_type == 'xydxdy': 64 comment_col = 4 65 66 # Loop over the graphs. 67 for gi in range(graph_num): 68 # Loop over the data sets of the graph. 69 for si in range(len(data[gi])): 70 # The target and type. 71 file.write("@target G%s.S%s\n" % (gi, si)) 72 file.write("@type %s\n" % graph_type) 73 74 # Normalisation (to the first data point y value!). 75 norm_fact = 1.0 76 if norm[gi]: 77 norm_fact = data[gi][si][0][1] 78 79 # Loop over the data points. 80 for point in data[gi][si]: 81 # Bad data. 82 if point[0] == None or point[1] == None: 83 continue 84 85 # X and Y data. 86 file.write("%-30s %-30.15f" % (point[0], point[1]/norm_fact)) 87 88 # The dx and dy errors. 89 if graph_type in ['xydx', 'xydy', 'xydxdy']: 90 # Catch x or y-axis errors of None. 91 error = point[2] 92 if error == None: 93 error = 0.0 94 95 # Write the error. 96 file.write(" %-30.15f" % (error/norm_fact)) 97 98 # The dy errors of xydxdy. 99 if graph_type == 'xydxdy': 100 # Catch y-axis errors of None. 101 error = point[3] 102 if error == None: 103 error = 0.0 104 105 # Write the error. 106 file.write(" %-30.15f" % (error/norm_fact)) 107 108 # The comment if given. 109 try: 110 file.write("%30s \"# %s\"" % ('', point[comment_col])) 111 except IndexError: 112 pass 113 114 # End the point. 115 file.write("\n") 116 117 # End of the data set i. 118 file.write("&\n") 119 120 # Autoscaling of all graphs to avoid user confusion. 121 for i in range(graph_num): 122 file.write("@with g%i\n" % i) 123 file.write("@autoscale\n") 124 125 # Auto-arrange the graphs if multiple are present. 126 if len(data) > 1: 127 row_num = int(round(sqrt(len(data)))) 128 col_num = int(ceil(sqrt(len(data)))) 129 file.write("@arrange(%i, %i, .1, .1, .1, OFF, OFF, OFF)\n" % (row_num, col_num))
130 131
132 -def write_xy_header(file=None, paper_size='A4', title=None, subtitle=None, view=None, graph_num=1, sets=None, set_names=None, set_colours=None, x_axis_type_zero=None, y_axis_type_zero=None, symbols=None, symbol_sizes=None, symbol_fill=None, linestyle=None, linetype=None, linewidth=None, data_type=None, seq_type=None, axis_labels=None, legend_pos=None, legend=None, norm=None):
133 """Write the grace header for xy-scatter plots. 134 135 Many of these keyword arguments should be supplied in a [X, Y] list format, where the first element corresponds to the X data, and the second the Y data. Defaults will be used for any non-supplied args (or lists with elements set to None). 136 137 138 @keyword file: The file object to write the data to. 139 @type file: file object 140 @keyword paper_size: The paper size, i.e. 'A4'. If set to None, this will default to letter size. 141 @type paper_size: str 142 @keyword title: The title of the graph. 143 @type title: None or str 144 @keyword subtitle: The sub-title of the graph. 145 @type subtitle: None or str 146 @keyword view: List of 4 coordinates defining the graph view port. 147 @type view: None or list of float 148 @keyword graph_num: The total number of graphs. 149 @type graph_num: int 150 @keyword sets: The number of data sets in each graph. 151 @type sets: list of int 152 @keyword set_names: The names associated with each graph data set Gx.Sy. For example this can be a list of spin identification strings. The first dimension is the graph, the second is the set. 153 @type set_names: None or list of list of str 154 @keyword set_colours: The colours for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 155 @type set_colours: None or list of list of int 156 @keyword x_axis_type_zero: The flags specifying if the X-axis should be placed at zero. 157 @type x_axis_type_zero: None or list of lists of bool 158 @keyword y_axis_type_zero: The flags specifying if the Y-axis should be placed at zero. 159 @type y_axis_type_zero: None or list of lists of bool 160 @keyword symbols: The symbol style for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 161 @type symbols: None or list of list of int 162 @keyword symbol_sizes: The symbol size for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 163 @type symbol_sizes: None or list of list of int 164 @keyword symbol_fill: The symbol file style for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 165 @type symbol_fill: None or list of list of int 166 @keyword linestyle: The line style for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 167 @type linestyle: None or list of list of int 168 @keyword linetype: The line type for each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 169 @type linetype: None or list of list of int 170 @keyword linewidth: The line width for all elements of each graph data set Gx.Sy. The first dimension is the graph, the second is the set. 171 @type linewidth: None or list of float 172 @keyword data_type: The axis data category (in the [X, Y] list format). 173 @type data_type: None or list of list of str 174 @keyword seq_type: The sequence data type (in the [X, Y] list format). This is for molecular sequence specific data and can be one of 'res', 'spin', or 'mixed'. 175 @type seq_type: None or list of list of str 176 @keyword axis_labels: The labels for the axes (in the [X, Y] list format). The first dimension is the graph. 177 @type axis_labels: None or list of list of str 178 @keyword legend_pos: The position of the legend, e.g. [0.3, 0.8]. The first dimension is the graph. 179 @type legend_pos: None or list of list of float 180 @keyword legend: If True, the legend will be visible. The first dimension is the graph. 181 @type legend: list of bool 182 @keyword norm: The normalisation flag which if set to True will cause all graphs to be normalised to 1. The first dimension is the graph. 183 @type norm: list of bool 184 """ 185 186 # Defaults. 187 if sets == None: 188 sets = [] 189 for gi in range(graph_num): 190 sets.append(1) 191 if x_axis_type_zero == None: 192 x_axis_type_zero = [] 193 for gi in range(graph_num): 194 x_axis_type_zero.append(False) 195 if y_axis_type_zero == None: 196 y_axis_type_zero = [] 197 for gi in range(graph_num): 198 y_axis_type_zero.append(False) 199 if linewidth == None: 200 linewidth = [] 201 for gi in range(graph_num): 202 linewidth.append(0.5) 203 if norm == None: 204 norm = [] 205 for gi in range(graph_num): 206 norm.append(False) 207 208 # Set the None args to lists as needed. 209 if not data_type: 210 data_type = [None, None] 211 if not seq_type: 212 seq_type = [None, None] 213 if not axis_labels: 214 axis_labels = [] 215 for gi in range(graph_num): 216 axis_labels.append([None, None]) 217 218 # Set the Grace version number of the header's formatting for compatibility. 219 file.write("@version 50121\n") 220 221 # The paper size. 222 if paper_size == 'A4': 223 file.write("@page size 842, 595\n") 224 225 # Loop over each graph. 226 for gi in range(graph_num): 227 # Graph Gi. 228 file.write("@with g%i\n" % gi) 229 230 # The view port. 231 if not view: 232 view = [0.15, 0.15, 1.28, 0.85] 233 file.write("@ view %s, %s, %s, %s\n" % (view[0], view[1], view[2], view[3])) 234 235 # The title and subtitle. 236 if title: 237 file.write("@ title \"%s\"\n" % title) 238 if subtitle: 239 file.write("@ subtitle \"%s\"\n" % subtitle) 240 241 # Axis at zero. 242 if x_axis_type_zero[gi]: 243 file.write("@ xaxis type zero true\n") 244 if y_axis_type_zero[gi]: 245 file.write("@ yaxis type zero true\n") 246 247 # Axis specific settings. 248 axes = ['x', 'y'] 249 for i in range(2): 250 # Analysis specific methods for making labels. 251 analysis_spec = False 252 if pipes.cdp_name(): 253 # Flag for making labels. 254 analysis_spec = True 255 256 # Specific value and error, conversion factor, and units returning functions. 257 return_units = specific_analyses.setup.get_specific_fn('return_units', pipes.get_type()) 258 return_grace_string = specific_analyses.setup.get_specific_fn('return_grace_string', pipes.get_type()) 259 260 # Test if the axis data type is a minimisation statistic. 261 if data_type[i] and data_type[i] != 'spin' and pipe_control.minimise.return_data_name(data_type[i]): 262 return_units = pipe_control.minimise.return_units 263 return_grace_string = pipe_control.minimise.return_grace_string 264 265 # Some axis default values for spin data. 266 if data_type[i] == 'spin': 267 # Residue only data. 268 if seq_type[i] == 'res': 269 # X-axis label. 270 if not axis_labels[gi][i]: 271 axis_labels[gi][i] = "Residue number" 272 273 # Spin only data. 274 if seq_type[i] == 'spin': 275 # X-axis label. 276 if not axis_labels[gi][i]: 277 axis_labels[gi][i] = "Spin number" 278 279 # Mixed data. 280 if seq_type[i] == 'mixed': 281 # X-axis label. 282 if not axis_labels[gi][i]: 283 axis_labels[gi][i] = "Spin identification string" 284 285 # Some axis default values for other data types. 286 else: 287 # Label. 288 if analysis_spec and (not axis_labels or not axis_labels[gi][i]): 289 # Get the units. 290 units = return_units(data_type[i]) 291 292 # Set the label. 293 axis_labels[gi][i] = return_grace_string(data_type[i]) 294 295 # Add units. 296 if units: 297 axis_labels[gi][i] = axis_labels[gi][i] + "\\N (" + units + ")" 298 299 # Normalised data. 300 if norm and norm[gi] and axes[i] == 'y': 301 axis_labels[gi][i] = axis_labels[gi][i] + " \\N\\q(normalised)\\Q" 302 303 # Write out the data. 304 if axis_labels[gi][i]: 305 file.write("@ %saxis label \"%s\"\n" % (axes[i], axis_labels[gi][i])) 306 file.write("@ %saxis label char size 1.00\n" % axes[i]) 307 file.write("@ %saxis tick major size 0.50\n" % axes[i]) 308 file.write("@ %saxis tick major linewidth %s\n" % (axes[i], linewidth[gi])) 309 file.write("@ %saxis tick minor linewidth %s\n" % (axes[i], linewidth[gi])) 310 file.write("@ %saxis tick minor size 0.25\n" % axes[i]) 311 file.write("@ %saxis ticklabel char size 0.70\n" % axes[i]) 312 313 # Legend box. 314 if legend != None and legend[gi]: 315 file.write("@ legend on\n") 316 else: 317 file.write("@ legend off\n") 318 if legend_pos != None: 319 file.write("@ legend %s, %s\n" % (legend_pos[gi][0], legend_pos[gi][1])) 320 321 # Frame. 322 file.write("@ frame linewidth %s\n" % linewidth[gi]) 323 324 # Loop over each graph set. 325 for i in range(sets[gi]): 326 # Symbol style (default to all different symbols). 327 if symbols: 328 file.write("@ s%i symbol %i\n" % (i, symbols[gi][i])) 329 else: 330 # The symbol number (cycle between 1 and 10). 331 num = i % 10 + 1 332 333 # Write out. 334 file.write("@ s%i symbol %i\n" % (i, num)) 335 336 # Symbol sizes (default to a small size). 337 if symbol_sizes: 338 file.write("@ s%i symbol size %s\n" % (i, symbol_sizes[gi][i])) 339 else: 340 file.write("@ s%i symbol size 0.45\n" % i) 341 342 # The symbol fill. 343 if symbol_fill: 344 file.write("@ s%i symbol fill pattern %i\n" % (i, symbol_fill[gi][i])) 345 346 # The symbol line width. 347 file.write("@ s%i symbol linewidth %s\n" % (i, linewidth[gi])) 348 349 # Symbol colour (default to nothing). 350 if set_colours: 351 file.write("@ s%i symbol color %s\n" % (i, set_colours[gi][i])) 352 file.write("@ s%i symbol fill color %s\n" % (i, set_colours[gi][i])) 353 354 # Error bars. 355 file.write("@ s%i errorbar size 0.5\n" % i) 356 file.write("@ s%i errorbar linewidth %s\n" % (i, linewidth[gi])) 357 file.write("@ s%i errorbar riser linewidth %s\n" % (i, linewidth[gi])) 358 359 # Line linestyle (default to nothing). 360 if linestyle: 361 file.write("@ s%i line linestyle %s\n" % (i, linestyle[gi][i])) 362 363 # Line linetype (default to nothing). 364 if linetype: 365 file.write("@ s%i line type %s\n" % (i, linetype[gi][i])) 366 367 # Line and all other colours (default to nothing). 368 if set_colours: 369 file.write("@ s%i line color %s\n" % (i, set_colours[gi][i])) 370 file.write("@ s%i fill color %s\n" % (i, set_colours[gi][i])) 371 file.write("@ s%i avalue color %s\n" % (i, set_colours[gi][i])) 372 file.write("@ s%i errorbar color %s\n" % (i, set_colours[gi][i])) 373 374 # Legend. 375 if set_names and len(set_names) and len(set_names[gi]) and set_names[gi][i]: 376 file.write("@ s%i legend \"%s\"\n" % (i, set_names[gi][i]))
377