def eval_color(v): try: if not v: v=eval(cmd.get('bg_rgb')) v=list(map(sum, list(zip(v,[-1,-1,-1])))) v=list(map(abs, v)) if v[0]==v[1]==v[2]==0.5: # grey v=[0,0,0] return v if isinstance(v, list): return v[0:3] if not isinstance(v, str): return v[0:3] if v.startswith('['): return cmd.safe_list_eval(v)[0:3] return list(cmd.get_color_tuple(v)) except: return [random.random(),random.random(),random.random()]
def ramp_levels(name, levels, quiet=1): ''' DESCRIPTION Changes the slot levels of a ramp. SEE ALSO ramp_new, isolevel ''' quiet = int(quiet) if cmd.is_string(levels): levels = cmd.safe_list_eval(levels) try: position = cmd.get_names('all').index(name) odata = cmd.get_session(name, 1, 1, 0, 0)['names'][0] if odata[4] != 8: raise TypeError('not a ramp') data = odata[5] except: print(' Error: Get session data for ramp "%s" failed' % (name)) raise CmdException if len(levels) != len(data[3]): print(' Error: number of levels must agree with existing object') raise CmdException map_name = data[6] colors = [data[4][i:i+3] for i in range(0, len(data[4]), 3)] cmd.ramp_new(name, map_name, levels, colors, quiet=quiet) # restore original position if position == 0: cmd.order(name, location='top') else: cmd.order(cmd.get_names('all')[position-1] + ' ' + name)
def get_coord(v): if not isinstance(v, str): try: return v[:3] except: return False if v.startswith('['): return cmd.safe_list_eval(v)[:3] try: if cmd.count_atoms(v)==1: # atom coordinates return cmd.get_atom_coords(v) else: # more than one atom --> use "center" # alt check! if cmd.count_atoms('(alt *) and not (alt "")')!=0: print "distancetoatom: warning! alternative coordinates found for origin, using center!" view_temp=cmd.get_view() cmd.zoom(v) v=cmd.get_position() cmd.set_view(view_temp) return v except: return False
def get_coord(v): if not isinstance(v, str): return v if v.startswith('['): return cmd.safe_list_eval(v) return cmd.get_atom_coords(v)
def volume_esp(name, map, stops=[0.1, 1.0], neg='red', pos='blue', opacity=0.2, quiet=1): ''' DESCRIPTION Create a volume object from a map object with default coloring for electrostatic potential (similar to positive and negative isosurface). ARGUMENTS name = string: name for the new volume object map = string: name of the map object to use stops = list of floats: 2 or 3 values in standard deviations for creating the volume ramp {default: [0.1, 1.0]} neg = string: color for negative volume {default: red} pos = string: color for positive volume {default: blue} opacity = float: maximum opacity in volume ramp {default: 0.2} SEE ALSO volume ''' from .setting import set_temporary opacity, quiet = float(opacity), int(quiet) if isinstance(stops, str): stops = cmd.safe_list_eval(stops) try: from pymol.colorramping import ColorRamp except ImportError: print(' Warning: volume_esp is deprecated') stdevD = cmd.get_volume_histogram(map, 0)[3] stops = [s * stdevD for s in stops] ramp = [ -stops[1], neg, opacity, -stops[0], neg, 0.0, stops[0], pos, 0.0, stops[1], pos, opacity, ] if len(stops) == 3: ramp = [-stops[2], neg, opacity] + ramp + [stops[2], pos, opacity] cmd.volume(name, map, ramp, quiet=quiet) return c_neg = cmd.get_color_tuple(neg) c_pos = cmd.get_color_tuple(pos) c_pos_0 = c_pos + (0.0,) c_pos_1 = c_pos + (opacity,) c_neg_0 = c_neg + (0.0,) c_neg_1 = c_neg + (opacity,) if len(stops) == 2: cstops = [(c_neg_1, -999), (c_neg_1, -stops[1]), (c_neg_0, -stops[0]), (c_pos_0, stops[0]), (c_pos_1, stops[1]), (c_pos_1, 999)] elif len(stops) == 3: cstops = [(c_neg_0, -999), (c_neg_0, -stops[2]), (c_neg_1, -stops[1]), (c_neg_0, -stops[0]), (c_pos_0, stops[0]), (c_pos_1, stops[1]), (c_pos_0, stops[2]), (c_pos_0, 999)] else: print(' Error: need 2 or 3 stops') raise CmdException cmd.volume(name, map, quiet=quiet) # get_volume_histogram returns zeros without refresh with set_temporary(suspend_updates='off'): cmd.refresh() minD, maxD, meanD, stdevD = cmd.get_volume_histogram(name)[:4] v_ramp = [] c_ramp = ColorRamp(360) for c, s in cstops: i = int(360 * ((s * stdevD) - minD) / (maxD - minD)) i = min(max(i, 0), 359) v_ramp.append(i) v_ramp.extend(c) c_ramp.addColor(i, c) cmd.set_volume_ramp(name, v_ramp) cmd.volume_color(name, c_ramp.getRamp()) cmd.recolor(name)
def pca_plot( aln_object, ref="all", state=0, maxlabels=20, size=20, invert="", which=(0, 1), alpha=0.75, filename=None, quiet=1, load_b=0, ): """ DESCRIPTION Principal Component Analysis on a set of superposed conformations, given by an alignment object. By default all states in all objects are considered. Generates a 2d-plot of the first two principal components. USAGE pca_plot aln_object [, ref [, state [, maxlabels ]]] ARGUMENTS aln_object = string: name of alignment object, defines the selection and the atom mapping between objects ref = string: object names for which to calculate PCA for {default: all} state = integer: if state=0 use all states {default: 0} maxlabels = integer: label dots in plot if maxlabels<0 or number of models not more than maxlabels {default: 20} size = float: size of plot points in px^2 {default: 20} invert = string: invert plotting axes x, y or xy {default: ''} which = (int,int): indices of principal components to plot {default: (0,1)} alpha = float: opacity of plotting points filename = string: if given, plot to file {default: None} EXAMPLE fetch 1ake 4ake 1dvr 1ak2, async=0 split_chains extra_fit (*_*) and name CA, reference=1ake_A, cycles=0, object=aln pca_plot aln, 1ake_* 4ake_* fetch 1ubq 2k39, async=0 align 2k39, 1ubq and guide, cycles=0, object=aln2 color blue, 1ubq color orange, 2k39 pca_plot aln2, filename=pca-ubq.pdf """ from numpy import array, dot from numpy.linalg import svd, LinAlgError from . import matplotlib_fix from matplotlib.pyplot import figure state, quiet = int(state), int(quiet) maxlabels = int(maxlabels) if cmd.is_string(which): which = cmd.safe_list_eval(which) if aln_object not in cmd.get_names_of_type("object:"): print(" Warning: first argument should be an alignment object") from .fitting import extra_fit selection = aln_object aln_object = cmd.get_unused_name("aln") extra_fit(selection, cycles=0, transform=0, object=aln_object) if state == 0: states = list(range(1, cmd.count_states() + 1)) elif state < 0: states = [cmd.get_state()] else: states = [state] models = cmd.get_object_list(aln_object) references = set(cmd.get_object_list("(" + ref + ")")).intersection(models) others = set(models).difference(references) aln = cmd.get_raw_alignment(aln_object) if not quiet: print(" PCA References:", ", ".join(references)) print(" PCA Others:", ", ".join(others)) if len(references) == 0: print(" PCA Error: No reference objects") raise CmdException model_count = len(models) coords = dict((model, []) for model in models) aln = [pos for pos in aln if len(pos) == model_count] for state in states: idx2xyz = dict() cmd.iterate_state(state, aln_object, "idx2xyz[model,index] = (x,y,z)", space={"idx2xyz": idx2xyz}) for pos in aln: for idx in pos: if idx not in idx2xyz: continue c = coords[idx[0]] if len(c) < state: c.append([]) c[-1].extend(idx2xyz[idx]) c_iter = lambda models: ((c, model, i + 1) for model in models for (i, c) in enumerate(coords[model])) X = array([i[0] for i in c_iter(references)]) Y = array([i[0] for i in c_iter(others)]) center = X.mean(0) X = X - center try: U, L, V = svd(X) except LinAlgError as e: print(" PCA Error: ", e) raise CmdException if int(load_b): cmd.alter("byobj " + aln_object, "b=-0.01") b_dict = {} i = which[0] b_array = (V[i].reshape((-1, 3)) ** 2).sum(1) ** 0.5 for pos, b in zip(aln, b_array): for idx in pos: b_dict[idx] = b cmd.alter(aln_object, "b=b_dict.get((model,index), -0.01)", space=locals()) cmd.color("yellow", "byobj " + aln_object) cmd.spectrum("b", "blue_red", aln_object + " and b > -0.01") X_labels = [i[1:3] for i in c_iter(references)] Y_labels = [i[1:3] for i in c_iter(others)] x_list = [] y_list = [] colors = [] text_list = [] def plot_pc_2d(X, labels): pca_12 = dot(X, V.T)[:, which] for (x, y), (model, state) in zip(pca_12, labels): x_list.append(x) y_list.append(y) colors.append(get_model_color(model)) if maxlabels < 0 or len(pca_12) <= maxlabels: text_list.append("%s(%d)" % (model, state)) else: text_list.append(None) plot_pc_2d(X, X_labels) if len(Y) > 0: Y = Y - center plot_pc_2d(Y, Y_labels) if "x" in invert: x_list = [-x for x in x_list] if "y" in invert: y_list = [-y for y in y_list] fig = figure() plt = fig.add_subplot(111, xlabel="PC %d" % (which[0] + 1), ylabel="PC %d" % (which[1] + 1)) plt.scatter(x_list, y_list, float(size), colors, linewidths=0, alpha=float(alpha)) for (x, y, text) in zip(x_list, y_list, text_list): if text is not None: plt.text(x, y, text, horizontalalignment="left") _showfigure(fig, filename, quiet)
def volume_esp(name, map, stops=[0.1, 1.0], neg='red', pos='blue', opacity=0.2, quiet=1): ''' DESCRIPTION Create a volume object from a map object with default coloring for electrostatic potential (similar to positive and negative isosurface). ARGUMENTS name = string: name for the new volume object map = string: name of the map object to use stops = list of floats: 2 or 3 values in standard deviations for creating the volume ramp {default: [0.1, 1.0]} neg = string: color for negative volume {default: red} pos = string: color for positive volume {default: blue} opacity = float: maximum opacity in volume ramp {default: 0.2} SEE ALSO volume ''' from .setting import set_temporary opacity, quiet = float(opacity), int(quiet) if isinstance(stops, str): stops = cmd.safe_list_eval(stops) try: from pymol.colorramping import ColorRamp except ImportError: print(' Warning: volume_esp is deprecated') stdevD = cmd.get_volume_histogram(map, 0)[3] stops = [s * stdevD for s in stops] ramp = [ -stops[1], neg, opacity, -stops[0], neg, 0.0, stops[0], pos, 0.0, stops[1], pos, opacity, ] if len(stops) == 3: ramp = [-stops[2], neg, opacity] + ramp + [stops[2], pos, opacity] cmd.volume(name, map, ramp, quiet=quiet) return c_neg = cmd.get_color_tuple(neg) c_pos = cmd.get_color_tuple(pos) c_pos_0 = c_pos + (0.0, ) c_pos_1 = c_pos + (opacity, ) c_neg_0 = c_neg + (0.0, ) c_neg_1 = c_neg + (opacity, ) if len(stops) == 2: cstops = [(c_neg_1, -999), (c_neg_1, -stops[1]), (c_neg_0, -stops[0]), (c_pos_0, stops[0]), (c_pos_1, stops[1]), (c_pos_1, 999)] elif len(stops) == 3: cstops = [(c_neg_0, -999), (c_neg_0, -stops[2]), (c_neg_1, -stops[1]), (c_neg_0, -stops[0]), (c_pos_0, stops[0]), (c_pos_1, stops[1]), (c_pos_0, stops[2]), (c_pos_0, 999)] else: print(' Error: need 2 or 3 stops') raise CmdException cmd.volume(name, map, quiet=quiet) # get_volume_histogram returns zeros without refresh with set_temporary(suspend_updates='off'): cmd.refresh() minD, maxD, meanD, stdevD = cmd.get_volume_histogram(name)[:4] v_ramp = [] c_ramp = ColorRamp(360) for c, s in cstops: i = int(360 * ((s * stdevD) - minD) / (maxD - minD)) i = min(max(i, 0), 359) v_ramp.append(i) v_ramp.extend(c) c_ramp.addColor(i, c) cmd.set_volume_ramp(name, v_ramp) cmd.volume_color(name, c_ramp.getRamp()) cmd.recolor(name)