def restore_state(self): import SurfaceColor for surface_id_subid, (color_state, caps_only) in self.coloring_table.items(): from SimpleSession import modelMap from _surface import SurfaceModel slist = [ s for s in modelMap.get(surface_id_subid, []) if isinstance(s, SurfaceModel) ] if len(slist) > 0: surface = slist[0] color_source = color_state.create_color_source() SurfaceColor.color_surface(surface, color_source, caps_only, auto_update=True) else: from chimera import replyobj replyobj.info( 'Warning: Could not restore surface color on surface model\n\twith id %d.%d because that surface was not restored.\n' % surface_id_subid) # Update gui to show settings from restored session. if self.version >= 2: if self.coloring_table: if self.is_visible: from gui import surface_color_dialog d = surface_color_dialog(create=True) if self.geometry: from SessionUtil import set_window_position set_window_position(d.toplevel_widget, self.geometry) d.surface_menu_cb() d.enter()
def Apply(self): selectedResidues = chimera.selection.currentResidues() if not selectedResidues: self.enter() raise UserError("No residues selected") if len(selectedResidues) > 10: from chimera.baseDialog import AskYesNoDialog numSel = len(selectedResidues) if AskYesNoDialog("You have %d residues selected which" " could bring up %d rotamer dialogs.\n" "Continue?" % (numSel, numSel)).run( chimera.tkgui.app) == "no": self.enter() return resType = self.resType.get() lib = self.rotLib.get() from Rotamers import NoResidueRotamersError try: for sr in selectedResidues: RotamerDialog(sr, resType, lib) except NoResidueRotamersError: from SwapRes import swap for sr in selectedResidues: replyobj.info("Swapping %s to %s\n" % (sr, resType)) swap(sr, resType, bfactor=None) replyobj.status("Swapped %d residue(s)\n" % len(selectedResidues))
def restore_state(self): from ColorZone import color_zone from SessionUtil import string_to_array, float32 czt = self.color_zone_table for surface_id_subid, (points, colors, distance) in czt.items(): from SimpleSession import modelMap from _surface import SurfaceModel surfaces = [s for s in modelMap.get(surface_id_subid, []) if isinstance(s, SurfaceModel)] if surfaces: # TODO: If more than one surface may get wrong one. surface = surfaces[0] if self.version >= 2: npoints = string_to_array(points, float32, 3) ncolors = string_to_array(colors, float32, 4) else: from numpy import array, single as floatc npoints = array(points, floatc) ncolors = array(colors, floatc) color_zone(surface, npoints, ncolors, distance, auto_update = True) else: from chimera import replyobj replyobj.info('Warning: Could not restore color zone on surface model\n\twith id %d.%d because that surface was not restored.\n' % surface_id_subid)
def report_atom_fit(self, stats): mlist = stats['molecules'] mnames = map(lambda m: '%s (%s)' % (m.name, m.oslIdent()), mlist) mnames = ', '.join(mnames) if len(mlist) > 1: plural = 's' else: plural = '' vname = stats['data region'].name natom = stats['points'] aoc = stats['atoms outside contour'] clevel = stats['contour level'] ave = stats['average map value'] steps = stats['steps'] shift = stats['shift'] angle = stats['angle'] message = ('Fit molecule%s %s to map %s using %d atoms\n' % (plural, mnames, vname, natom) + ' average map value = %.4g, steps = %d\n' % (ave, steps) + ' shifted from previous position = %.3g\n' % (shift,) + ' rotated from previous position = %.3g degrees\n' % (angle,)) if (not clevel is None) and (not aoc is None): message += (' atoms outside contour = %d, contour level = %.5g\n' % (aoc, clevel)) from chimera import replyobj replyobj.info(message) self.report_average(ave) self.report_correlation(None) if not aoc is None: status_message = '%d of %d atoms outside contour' % (aoc, natom) self.message(status_message)
def select_atoms_outside_map(): from chimera.replyobj import status, info from VolumeViewer import active_volume dr = active_volume() if dr is None: status('No density map opened.') return if dr.surface_model() == None or not dr.surface_model().display: status('No surface shown for map.') return levels = dr.surface_levels if len(levels) == 0: status('No surface shown for map.') return contour_level = min(levels) from chimera import selection atoms = selection.currentAtoms() aolist = atoms_outside_map(atoms, dr, contour_level) msg = ('%d of %d selected atoms outside %s at level %.5g' % (len(aolist), len(atoms), dr.name, contour_level)) status(msg) info(msg + '\n') selection.setCurrent(aolist)
def color_and_measure(self, window_x, window_y): from VolumeViewer import slice xyz_in, xyz_out = slice.clip_plane_points(window_x, window_y) import PickBlobs smlist = PickBlobs.surface_models() p, vlist, tlist = PickBlobs.picked_surface_component( smlist, xyz_in, xyz_out) if p is None: self.message('No intercept with surface.') return PickBlobs.color_blob(p, vlist, self.blob_color.rgba) # Report enclosed volume and area from MeasureVolume import enclosed_volume, surface_area varray, tarray = PickBlobs.blob_geometry(p, vlist, tlist) v, h = enclosed_volume(varray, tarray) if v == None: vstr = 'undefined (non-oriented surface)' else: vstr = '%.5g' % v if h > 0: vstr += ' (%d holes)' % h area = surface_area(varray, tarray) s = p.model msg = ('Surface %s (%s) piece: volume = %s, area = %.5g' % (s.name, s.oslIdent(), vstr, area)) self.message(msg) from chimera.replyobj import info, status info(msg + '\n') status(msg)
def report_surface_areas(self, compareas): mname = self.molecule.name cname = self.category ncomp = len(compareas) lines = \ ['', 'Surface %s, category %s, probe radius %.4g, vertex density %.4g' % (mname, cname, self.probeRadius, self.density), ' %d connected surface components' % ncomp, ' Total solvent excluded surface area = %.6g' % self.areaSES] if ncomp > 1: careas = [(sesa, sasa) for sesa, sasa in compareas] careas.sort() careas.reverse() eareas = ', '.join(['%.6g' % sesa for sesa, sasa in careas]) aareas = ', '.join(['%.6g' % sasa for sesa, sasa in careas]) lines.append(' component areas = %s' % eareas) lines.append(' Total solvent accessible surface area = %.6g' % self.areaSAS) if ncomp > 1: lines.append(' component areas = %s' % aareas) msg = '\n'.join(lines) + '\n' from chimera.replyobj import info, status info(msg) smsg = ('Surface %s, category %s has %d components' % (mname, cname, ncomp)) status(smsg)
def restore_state(self): from ColorZone import color_zone from SessionUtil import string_to_array, float32 czt = self.color_zone_table for surface_id_subid, (points, colors, distance) in czt.items(): from SimpleSession import modelMap from _surface import SurfaceModel surfaces = [ s for s in modelMap.get(surface_id_subid, []) if isinstance(s, SurfaceModel) ] if surfaces: # TODO: If more than one surface may get wrong one. surface = surfaces[0] if self.version >= 2: npoints = string_to_array(points, float32, 3) ncolors = string_to_array(colors, float32, 4) else: from numpy import array, single as floatc npoints = array(points, floatc) ncolors = array(colors, floatc) color_zone(surface, npoints, ncolors, distance, auto_update=True) else: from chimera import replyobj replyobj.info( 'Warning: Could not restore color zone on surface model\n\twith id %d.%d because that surface was not restored.\n' % surface_id_subid)
def createPlane(self, name, atoms, number=None, radius=None, radiusOffset=0.0, color=None, sourceModel=None, thickness=defaults[PLANE_THICKNESS]): if len(atoms) < 3: raise ValueError("Need at least 3 atoms to define plane") numbers = dict([(pl.number, pl) for pl in self.planes]) if number == None: if numbers: number = max(numbers.keys()) + 1 else: number = 1 elif number in numbers: self.removePlanes([numbers[number]]) if color == None: from StructMeasure import matchStructureColor color = matchStructureColor(atoms) if sourceModel == None: sourceModel = self._getSourceModel(atoms) import StructMeasure if radius == None: plane, proj, radius = StructMeasure.plane( chimera.numpyArrayFromAtoms(atoms), findBounds=True) radius += radiusOffset else: plane = StructMeasure.plane( chimera.numpyArrayFromAtoms(atoms), findBounds=False) replyobj.info("%s has radius %g\n" % (name, radius)) self.planeOrdinal += 1 return self._instantiatePlane(number, name, self.planeOrdinal, color, radius, thickness, sourceModel, atoms, plane)
def report_correlations_with_rotation(v1, v2, aboveThreshold, axis, center, angleRange, plot): from chimera import Vector, Point, replyobj # Convert axis and center to v1 local coordinates so transformation # is still valid if user rotates entire scene. xf = v1.openState.xform.inverse() axis = xf.apply(Vector(*axis)).data() center = xf.apply(Point(*center)).data() import FitMap, Matrix replyobj.info('Correlation between %s and %s\n' % (v1.name, v2.name) + 'Rotation\tCorrelation\n') a0, a1, astep = angleRange angle = a0 clist = [] from Matrix import multiply_matrices, xform_matrix, rotation_transform, chimera_xform while angle < a1: tf = multiply_matrices(xform_matrix(v1.openState.xform), rotation_transform(axis, angle, center), xform_matrix(v1.openState.xform.inverse())) xf = chimera_xform(tf) olap, cor = FitMap.map_overlap_and_correlation(v1, v2, aboveThreshold, xf) replyobj.status('angle = %.4g, correlation = %.4g\n' % (angle, cor)) replyobj.info('%.4g\t%.4g\n' % (angle, cor)) clist.append((angle, cor)) angle += astep if plot: angles = [a for a, c in clist] corr = [c for a, c in clist] plot_correlation(angles, corr, v1, v2, axis, center)
def report_atom_fit(self, stats): mlist = stats['molecules'] mnames = map(lambda m: '%s (%s)' % (m.name, m.oslIdent()), mlist) mnames = ', '.join(mnames) if len(mlist) > 1: plural = 's' else: plural = '' vname = stats['data region'].name natom = stats['points'] aoc = stats['atoms outside contour'] clevel = stats['contour level'] ave = stats['average map value'] steps = stats['steps'] shift = stats['shift'] angle = stats['angle'] message = ('Fit molecule%s %s to map %s using %d atoms\n' % (plural, mnames, vname, natom) + ' average map value = %.4g, steps = %d\n' % (ave, steps) + ' shifted from previous position = %.3g\n' % (shift, ) + ' rotated from previous position = %.3g degrees\n' % (angle, )) if (not clevel is None) and (not aoc is None): message += ( ' atoms outside contour = %d, contour level = %.5g\n' % (aoc, clevel)) from chimera import replyobj replyobj.info(message) self.report_average(ave) self.report_correlation(None) if not aoc is None: status_message = '%d of %d atoms outside contour' % (aoc, natom) self.message(status_message)
def create_object(self): if self.version >= 3: source_molecule = find_molecule_by_id(self.source_molecule_id) else: source_molecule = find_molecule_by_name(self.name) if source_molecule is None: from chimera.replyobj import info info('Multiscale session restore error, molecule "%s" missing.\n' % self.name) return None import MultiScale lm = MultiScale.LAN_Molecule(source_molecule) lm.dont_unload = self.dont_unload if self.molecule_id: m = find_molecule_by_id(self.molecule_id) if m: lm.associate_molecule(m, allow_close = not self.dont_unload) if self.chain_states != None: clist = map(lambda cs: cs.create_object(lm), self.chain_states) lm.chain_list = clist return lm
def _readHeader(self): # version string replyobj.info("%s\n" % self._readString()) realSize = self.xdr.unpack_uint() if realSize == 4: self.unpackFloatFunc = self.xdr.unpack_float replyobj.info("using floats\n") elif realSize == 8: self.unpackFloatFunc = self.xdr.unpack_double replyobj.info("using doubles\n") else: raise ValueError("Floating-point values in .tpr file" " are not the same as either single-precision" " or double-precision floating point on this" " machine") version = self.xdr.unpack_uint() if version >= 26: generation = self.xdr.unpack_uint() else: generation = 0 replyobj.info("version %d, generation %d\n" % (version, generation)) natoms = self.xdr.unpack_uint() replyobj.info("%d atoms\n" % natoms) if version >= 28: tempCouplingGroups = self.xdr.unpack_uint() curStep = self.xdr.unpack_uint() curTime = self.unpackFloatFunc() curLambda = self.unpackFloatFunc() hasInputRec = self.xdr.unpack_uint() hasTopology = self.xdr.unpack_uint() if not hasTopology: raise ValueError(".tpr file does not have topology section") hasCoord = self.xdr.unpack_uint() hasVelocities = self.xdr.unpack_uint() hasForces = self.xdr.unpack_uint() hasBbox = self.xdr.unpack_uint() if hasBbox: for i in range(9): self.unpackFloatFunc() if version >= 51: for i in range(9): self.unpackFloatFunc() if version >= 28: for i in range(9): self.unpackFloatFunc() if version < 56: for i in range(9): self.unpackFloatFunc() if version >= 28 and tempCouplingGroups > 0: for i in range(tempCouplingGroups): self.unpackFloatFunc() self.unpackFloatFunc() if version < 26 and hasInputRec: raise ValueError("Cannot read version 26 or earlier" " .tpr files") return version
def report_correlations_with_rotation(v1, v2, aboveThreshold, axis, center, angleRange, plot): from chimera import Vector, Point, replyobj # Convert axis and center to v1 local coordinates so transformation # is still valid if user rotates entire scene. xf = v1.openState.xform.inverse() axis = xf.apply(Vector(*axis)).data() center = xf.apply(Point(*center)).data() import FitMap, Matrix replyobj.info('Correlation between %s and %s\n' % (v1.name, v2.name) + 'Rotation\tCorrelation\n') a0, a1, astep = angleRange angle = a0 clist = [] from Matrix import multiply_matrices, xform_matrix, rotation_transform, chimera_xform while angle < a1: tf = multiply_matrices(xform_matrix(v1.openState.xform), rotation_transform(axis, angle, center), xform_matrix(v1.openState.xform.inverse())) xf = chimera_xform(tf) olap, cor = FitMap.map_overlap_and_correlation(v1, v2, aboveThreshold, xf) replyobj.status('angle = %.4g, correlation = %.4g\n' % (angle, cor)) replyobj.info('%.4g\t%.4g\n' % (angle, cor)) clist.append((angle,cor)) angle += astep if plot: angles = [a for a,c in clist] corr = [c for a,c in clist] plot_correlation(angles, corr, v1, v2, axis, center)
def create_object(self): if self.version >= 3: source_molecule = find_molecule_by_id(self.source_molecule_id) else: source_molecule = find_molecule_by_name(self.name) if source_molecule is None: from chimera.replyobj import info info('Multiscale session restore error, molecule "%s" missing.\n' % self.name) return None import MultiScale lm = MultiScale.LAN_Molecule(source_molecule) lm.dont_unload = self.dont_unload if self.molecule_id: m = find_molecule_by_id(self.molecule_id) if m: lm.associate_molecule(m, allow_close=not self.dont_unload) if self.chain_states != None: clist = map(lambda cs: cs.create_object(lm), self.chain_states) lm.chain_list = clist return lm
def spine(operation, regions, spacing=None, tipLength=None, color=None, showDiameter=False): sel = parse_object_specifier(regions, 'segmentation region') import Surface plist = Surface.selected_surface_pieces(sel, include_outline_boxes=False) from Segger.regions import Segmentation rlist = [ p.region for p in plist if (hasattr(p, 'region') and isinstance(p.model, Segmentation)) ] if len(rlist) == 0: raise CommandError('No segmentation regions specified: "%s"' % regions) if not (spacing is None or isinstance(spacing, (int, float)) and spacing > 0): raise CommandError('spacing must be positive numeric value') if not (tipLength is None or isinstance(tipLength, (int, float)) and tipLength > 0): raise CommandError('tipLength must be positive numeric value') if not color is None: from Commands import parse_color color = parse_color(color) if showDiameter: from _surface import SurfaceModel diam_model = SurfaceModel() diam_model.name = 'Diameters' from chimera import openModels openModels.add([diam_model], sameAs=rlist[0].segmentation) else: diam_model = None import spine from chimera import replyobj from PathLength import path_length for r in rlist: mset = spine.trace_spine(r, spacing, tipLength, color) slen = path_length([l.bond for l in mset.links()]) r.set_attribute('spine length', slen) msg = 'Spine length for region %d is %.4g' % (r.rid, slen) dmax, dmin = spine.measure_diameter(r, mset, diam_model) if not dmax is None: r.set_attribute('diameter1', dmax) r.set_attribute('diameter2', dmin) msg += ', diameters %.4g, %.4g' % (dmax, dmin) kave, kmin, kmax = spine.measure_curvature(mset) if not kmax is None: r.set_attribute('curvature average', kave) r.set_attribute('curvature minimum', kmin) r.set_attribute('curvature maximum', kmax) msg += ', curvature %.4g (ave), %.4g (max), %.4g (min)' % ( kave, kmax, kmin) replyobj.info(msg + '\n')
def show_saxs_profile(molecules, selected_only, epath, expath, dialog=None): if len(molecules) <= 2: name = ', '.join([m.name for m in molecules]) else: name = '%d models' % len(molecules) import tempfile, os fd, pdbpath = tempfile.mkstemp(suffix='.pdb') os.close(fd) import Midas Midas.write(molecules, molecules[0], pdbpath, selOnly=selected_only) if not epath: # Use web services if no executable is given if dialog is None: dialog = PlotDialog() ProfileOpalService(pdbpath, expath, name, dialog.figure) else: cmd = '%s %s %s' % (epath, pdbpath, expath) from chimera.replyobj import info, warning info('Executing command: %s\n' % cmd) status = os.system(cmd) if status != 0: warning('Error %d executing command "%s"' % (status, cmd)) return dialog if expath: from os.path import basename ppath = pdbpath[:-4] + '_' + basename(expath) p = read_profile(ppath, 3) else: ppath = pdbpath + '.dat' p = read_profile(ppath, 2) plot_profile(p, name, dialog.figure) return dialog
def _phosphorylate(mols, status, deletes): replyobj.info("Deleting 5' phosphates from: %s\n" % ", ".join([str(r) for r in deletes])) from chimera.molEdit import addAtom for r in deletes: r.amberName += "5" for p in r.atomsMap['P']: o = None for nb in p.neighbors: for nnb in nb.neighbors: if nnb == p: continue if nnb.element.number > 1: o = nb continue r.molecule.deleteAtom(nnb) if nb != o: r.molecule.deleteAtom(nb) v = p.coord() - o.coord() sn = getattr(p, "serialNumber", None) r.molecule.deleteAtom(p) v.length = 0.96 addAtom("H5T", chimera.Element('H'), r, o.coord() + v, serialNumber=sn, bondedTo=o)
def symmetry(operation, volume, minimumCorrelation=0.99, nMax=8, helix=None, points=10000, set=True): from VolumeViewer import Volume vlist = [m for m in volume if isinstance(m, Volume)] if len(vlist) == 0: raise CommandError('No volume specified') if not helix is None: rise, angle, n, optimize = parse_helix_option(helix) import symmetry as S for v in vlist: if helix: syms, msg = S.find_helix_symmetry(v, rise, angle, n, optimize, nMax, minimumCorrelation, points) else: syms, msg = S.find_point_symmetry(v, nMax, minimumCorrelation, points) if set and syms: v.data.symmetries = syms from chimera.replyobj import info, status status(msg) info(msg + '\n')
def normalize5BU(r): for a in r.atoms: if a.element.name == "Br": r.molecule.deleteAtom(a) break r.type = "U" replyobj.info("5BU residue %s changed to U\n" % str(r))
def restore_state(self): import SurfaceColor for surface_id_subid, (color_state, caps_only) in self.coloring_table.items(): from SimpleSession import modelMap from _surface import SurfaceModel slist = [s for s in modelMap.get(surface_id_subid, []) if isinstance(s, SurfaceModel)] if len(slist) > 0: surface = slist[0] color_source = color_state.create_color_source() SurfaceColor.color_surface(surface, color_source, caps_only, auto_update = True) else: from chimera import replyobj replyobj.info('Warning: Could not restore surface color on surface model\n\twith id %d.%d because that surface was not restored.\n' % surface_id_subid) # Update gui to show settings from restored session. if self.version >= 2: if self.coloring_table: if self.is_visible: from gui import surface_color_dialog d = surface_color_dialog(create = True) if self.geometry: from SessionUtil import set_window_position set_window_position(d.toplevel_widget, self.geometry) d.surface_menu_cb() d.enter()
def map_values(operation, volume, atoms, name=None, report=10): from VolumeViewer import Volume vlist = [v for v in volume if isinstance(v, Volume)] if len(vlist) != 1: raise CommandError('No volume model specified') v = vlist[0] import AtomDensity if name is None: name = 'value_' + v.name name = AtomDensity.replace_special_characters(name, '_') AtomDensity.set_atom_volume_values(atoms, v, name) if report: arep = atoms[:report] if isinstance(report, int) else atoms values = '\n'.join( ['%s %.5g' % (a.oslIdent(), getattr(a, name)) for a in arep]) n = len(atoms) t = '%s map values at %d atom positions\n%s\n' % (v.name, n, values) if n > len(arep): t += '...\n' if n == 1: s = '%s map value at atom %s = %.5g' % ( v.name, atoms[0].oslIdent(), getattr(a, name)) else: maxa = 3 values = ', '.join( ['%.5g' % getattr(a, name) for a in atoms[:maxa]]) if n > maxa: values += ', ...' s = '%s map values at %d atoms: %s' % (v.name, n, values) from chimera import replyobj replyobj.info(t) replyobj.status(s)
def show_saxs_profile(molecules, selected_only, epath, expath, dialog = None): if len(molecules) <= 2: name = ', '.join([m.name for m in molecules]) else: name = '%d models' % len(molecules) import tempfile, os fd, pdbpath = tempfile.mkstemp(suffix = '.pdb') os.close(fd) import Midas Midas.write(molecules, molecules[0], pdbpath, selOnly = selected_only) if not epath: # Use web services if no executable is given if dialog is None: dialog = PlotDialog() ProfileOpalService(pdbpath, expath, name, dialog.figure) else: cmd = '%s %s %s' % (epath, pdbpath, expath) from chimera.replyobj import info, warning info('Executing command: %s\n' % cmd) status = os.system(cmd) if status != 0: warning('Error %d executing command "%s"' % (status, cmd)) return dialog if expath: from os.path import basename ppath = pdbpath[:-4] + '_' + basename(expath) p = read_profile(ppath, 3) else: ppath = pdbpath + '.dat' p = read_profile(ppath, 2) plot_profile(p, name, dialog.figure) return dialog
def rotation_axis(operation, model1, model2, showAxis = True, showSlabs = False, color = None): os1 = set([m.openState for m in model1]) os2 = set([m.openState for m in model2]) if len(os1) != 1: raise CommandError, 'First model spec names %d models, require 1' % len(os1) if len(os2) != 1: raise CommandError, 'Second model spec names %d models, require 1' % len(os2) os1 = os1.pop() os2 = os2.pop() xf = os1.xform.inverse() xf.multiply(os2.xform) import Matrix tf = Matrix.xform_matrix(xf) message = ('Position of %s (%s) relative to %s (%s) coordinates:\n' % (model2[0].name, model2[0].oslIdent(), model1[0].name, model1[0].oslIdent())) message += Matrix.transformation_description(tf) from chimera import replyobj replyobj.info(message) from chimera import MaterialColor if isinstance(color, MaterialColor): color = color.rgba() elif not color is None: raise CommandError, 'Unknown color "%s"' % str(color) if showAxis: show_axis(tf, color, os1) if showSlabs: show_slabs(xf, color, os1)
def report_correlation(v1, v2, aboveThreshold): from chimera import replyobj import FitMap olap, cor = FitMap.map_overlap_and_correlation(v1, v2, aboveThreshold) replyobj.status('correlation = %.4g\n' % cor) replyobj.info('Correlation between %s and %s = %.4g\n' % (v1.name, v2.name, cor))
def no_feature(self, name=None): if name == None: name = '' msg = 'Feature %s not available!\n' % (name) self.status(msg, color='blue', blankAfter=3) replyobj.info(msg) return
def morph_apply(self): """morph_apply() - applies appropriate morphing Applies appropriate morphing after Apply button is specified. Checks values and passes a message if incorrect parameters. """ # check input data exists if self.data_item == None: name = '%s' % (self.data_panel.data_menu.variable.get()) msg = 'Input data %s not found!\n' % name self.status(msg, color='red', blankAfter=15) replyobj.error(msg) return # get input file path, name, and size in pixels infile_path = str(self.data_item.path) infile = str(self.data_item.name) infile_size = self.data_item.size # get morph models morph0, morph1 = self.get_morph_models() if (morph0 == None or morph1 == None): return # get morph parameters morph_type = self.morph_type.variable.get() if morph_type == self.morph_choices[0]: frac, thr, filt = self.get_simple_morph_param() # check and set output name self.output_item = None outfile = str(self.data_output.variable.get()) if (outfile == '') or (outfile == infile): first_part, last_part = self.name_and_dot_suffix(infile) outfile = '%s-m%s' % (first_part, last_part) msg = 'Using default output file %s\n'% outfile replyobj.info(msg) self.data_output.variable.set(outfile) # output out_dir = os.getcwd() out_files = [outfile] # run morph command seg_sucess = 0 if morph_type == self.morph_choices[0]: seg_success = self.morph_apply_simple(self.data_item, morph0, morph1, outfile, frac, thr, filt) # open output if seg_success: self.open_output_data_items(out_dir, out_files) self.enter() return
def doneCB(ur, ua, cb=cb, status=status, models=models): if status: status("Done adding charges\n") if models is None: models = chimera.openModels.list( modelTypes=[chimera.Molecule]) warnMsg = "" if ur: warnMsg += "Correct charges are unknown for %d"\ " non-standard residue types\n\n" % len(ur) replyobj.info("Non-standard residue types:\n") for t, rs in ur.items(): info = ", ".join([str(r) for r in rs[:3]]) if len(rs) > 3: info += " + %d others" % ( len(rs) - 3) replyobj.info("\t%s (%s)\n" % (t, info)) warnMsg = unchargedAtomsWarning(ua, warning=warnMsg) if warnMsg: warnMsg += "Charges of 0.0 were assigned to the" \ " unknown atoms\n\n" nonIntegral = [] from math import floor numNImodels = 0 def isNonIntegral(val): return abs(floor(val+0.5) - val) > 0.0005 for m in models: totCharge = 0.0 for r in m.residues: resCharge = 0.0 for a in r.atoms: resCharge += getattr(a, 'charge', 0.0) totCharge += resCharge if isNonIntegral(resCharge): nonIntegral.append((r, resCharge)) tChargeMsg = "Total charge for %s: %.4f\n" % (str(m), totCharge) replyobj.info(tChargeMsg) if status: status(tChargeMsg) if isNonIntegral(totCharge): numNImodels += 1 if nonIntegral: if numNImodels: warnMsg += "%d model(s) had non-integral total"\ " charge\n" % numNImodels replyobj.info("The following residues had non-integral" " charges:\n") for r, charge in nonIntegral: replyobj.info("\t%s %g\n" % (str(r), charge)) if warnMsg: warnMsg += "Details in reply log\n" replyobj.warning(warnMsg, help="ContributedSoftware/addcharge/addcharge.html#warnings") if cb: cb(ur, ua)
def status(self, msg, blankAfter=None, echoToMain=False, log=False, followWith="", followTime=20, color='black'): """Display a status message 'blankAfter' controls how long (in seconds) before the status area is automatically cleared. Use zero to disable auto-clearing this message. 'None' uses the user preference. 'echoToMain' and 'log' control sending an identical message to the main window status line and the reply log, respectively. 'followWith' is a message to follow the first one with. 'followTime' is how long until the followup message is cleared (ala blankAfter). Show the text in 'color' color. """ from chimera import replyobj if not self.provideStatus: raise ValueError("no status support in dialog") if self._statusBlankHandle: self.statusLine.after_cancel(self._statusBlankHandle) self._statusBlankHandle = None if echoToMain: replyobj.status(msg, blankAfter=blankAfter, color=color) if log: replyobj.info(msg) if followWith: if not msg.endswith("\n"): msg += "\n" msg += "[above message copied to Reply Log]" self.statusLine.configure(text=msg.strip(), fg=color) self.statusLine.update_idletasks() blankTime = blankAfter if blankAfter is None: import preferences from replyobj import REPLY_PREFERENCES, STATUS_CLEARING blankTime = preferences.get(REPLY_PREFERENCES, STATUS_CLEARING) if blankTime != 0: if followWith: nextMsg = followWith nextTime = followTime elif log: nextMsg = "Previous message also written" \ " to reply log" nextTime = 20 else: nextMsg = "" nextTime = 0 self._statusBlankHandle = self.statusLine.after( 1000 * blankTime, lambda: self.status(nextMsg, blankAfter=nextTime))
def doneCB(ur, ua, cb=cb, status=status, models=models): if status: status("Done adding charges\n") if models is None: models = chimera.openModels.list(modelTypes=[chimera.Molecule]) warnMsg = "" if ur: warnMsg += "Correct charges are unknown for %d"\ " non-standard residue types\n\n" % len(ur) replyobj.info("Non-standard residue types:\n") for t, rs in ur.items(): info = ", ".join([str(r) for r in rs[:3]]) if len(rs) > 3: info += " + %d others" % (len(rs) - 3) replyobj.info("\t%s (%s)\n" % (t, info)) warnMsg = unchargedAtomsWarning(ua, warning=warnMsg) if warnMsg: warnMsg += "Charges of 0.0 were assigned to the" \ " unknown atoms\n\n" nonIntegral = [] from math import floor numNImodels = 0 def isNonIntegral(val): return abs(floor(val + 0.5) - val) > 0.0005 for m in models: totCharge = 0.0 for r in m.residues: resCharge = 0.0 for a in r.atoms: resCharge += getattr(a, 'charge', 0.0) totCharge += resCharge if isNonIntegral(resCharge): nonIntegral.append((r, resCharge)) tChargeMsg = "Total charge for %s: %.4f\n" % (str(m), totCharge) replyobj.info(tChargeMsg) if status: status(tChargeMsg) if isNonIntegral(totCharge): numNImodels += 1 if nonIntegral: if numNImodels: warnMsg += "%d model(s) had non-integral total"\ " charge\n" % numNImodels replyobj.info("The following residues had non-integral" " charges:\n") for r, charge in nonIntegral: replyobj.info("\t%s %g\n" % (str(r), charge)) if warnMsg: warnMsg += "Details in reply log\n" replyobj.warning( warnMsg, help="ContributedSoftware/addcharge/addcharge.html#warnings") if cb: cb(ur, ua)
def show_correlation(self, mmap, fmap): about_mean = self.corr_about_mean.get() from FitMap import map_overlap_and_correlation as oc olap, cor, corm = oc(mmap, fmap, self.above_threshold.get()) self.report_correlation(cor, corm) msg = 'Correlation = %.4g, Correlation about mean = %.4g, Overlap = %.4g\n' % (cor, corm, olap) from chimera import replyobj replyobj.info(msg)
def _reportResidues(residues, attribute): from chimera import replyobj for r in residues: try: attrValue = attrString(r, attribute) except AttributeError: continue info = "residue id %s" % r.oslIdent() info += " %s %s" % (attribute, attrValue) info += '\n' replyobj.info(info)
def _reportAtoms(atoms, attribute): from chimera import replyobj for a in atoms: try: attrValue = attrString(a, attribute) except AttributeError: continue info = "atom id %s" % a.oslIdent() info += " %s %s" % (attribute, attrValue) info += '\n' replyobj.info(info)
def _reportChains(chains, attribute): from chimera import replyobj for seq in chains: try: attrValue = attrString(seq, attribute) except AttributeError: continue info = "chain id %s:.%s" % (seq.molecule.oslIdent(), seq.chain) info += " %s %s" % (attribute, attrValue) info += '\n' replyobj.info(info)
def show_correlation(self, mmap, fmap): about_mean = self.corr_about_mean.get() from FitMap import map_overlap_and_correlation as oc olap, cor, corm = oc(mmap, fmap, self.above_threshold.get()) self.report_correlation(cor, corm) msg = 'Correlation = %.4g, Correlation about mean = %.4g, Overlap = %.4g\n' % ( cor, corm, olap) from chimera import replyobj replyobj.info(msg)
def simpleAddHydrogens(models, unknownsInfo={}, hisScheme=None): """Add hydrogens to given models using simple geometric criteria Geometric info for atoms whose IDATM types don't themselves provide sufficient information can be passed via the 'unknownsInfo' dictionary. The keys are atoms and the values are dictionaries specifying the geometry and number of substituents (not only hydrogens) for the atom. The 'hisScheme' keyword determines how histidines are handled. If it is None then the residue name is expected to be HIE, HID, HIP, or HIS indicating the protonation state is epsilon, delta, both, or unspecified respectively. Otherwise the value is a dictionary: the keys are histidine residues and the values are HIE/HID/HIP/HIS indication of the protonation state. Histindines not in the dictionary will be protonated based on the nitrogens' atom types. the protonation is determined by the nitrogen atom type. This routine adds hydrogens immediately even if some atoms have unknown geometries. To allow the user to intervene to specify geometries, use the 'initiateAddHyd' function of the unknownsGUI module of this package. """ from simple import addHydrogens atomList, typeInfo4Atom, namingSchemas, idatmType, hydrogenTotals, \ hisNs, coordinations, fakeN, fakeC = \ _prepAdd(models, unknownsInfo, hisScheme) _makeSharedData() invertXforms = {} for atom in atomList: if not typeInfo4Atom.has_key(atom): continue bondingInfo = typeInfo4Atom[atom] try: invert = invertXforms[atom.molecule] except KeyError: try: invert = atom.molecule.openState.xform except ValueError: invert = chimera.Xform.identity() invert.invert() invertXforms[atom.molecule] = invert addHydrogens( atom, bondingInfo, (namingSchemas[atom.residue], namingSchemas[atom.molecule]), hydrogenTotals[atom], idatmType, invert, coordinations.get(atom, [])) postAdd(fakeN, fakeC) _deleteSharedData() replyobj.info("Hydrogens added\n")
def _reportModels(models, attribute): from chimera import replyobj for m in models: try: attrValue = attrString(m, attribute) except AttributeError: continue molType = m.__class__.__name__ info = "model id %s type %s" % (m.oslIdent(), molType) info += " %s %s" % (attribute, attrValue) info += '\n' replyobj.info(info)
def no_feature(self, name=None): """no_feature(name=None) - message for missing feature. Displays a message saying that feature='name' is not avaialable. """ if name == None: name = '' msg = 'Feature %s not available!\n' % (name) self.status(msg, color='blue', blankAfter=3) replyobj.info(msg) return
def restore_state(self): from numpy import array, single as floatc import dust for surface_id_subid, (method, limit) in self.dust_table.items(): from SimpleSession import modelMap if surface_id_subid in modelMap: surface = modelMap[surface_id_subid][0] dust.hide_dust(surface, method, limit, auto_update = True) else: from chimera import replyobj replyobj.info('Warning: Could not restore hide dust for surface model\n\twith id %d.%d because that surface was not restored.\n' % surface_id_subid)
def unchargedAtomsWarning(ua, warning=""): if ua: warning += "Correct charges are unknown for %d"\ " non-standard atom names in otherwise"\ " standard residues\n\n" % len(ua) replyobj.info("Non-standard atom names:\n") for k, atoms in ua.items(): t, n = k info = ", ".join([str(a) for a in atoms[:3]]) if len(atoms) > 3: info += " + %d others" % (len(atoms) - 3) replyobj.info("\t%s %s (%s)\n" % (t, n, info)) return warning
def run_mscalc(xyzr, probe_radius=1.4, vertex_density=2.0, all_components=True, fallback_to_single_component=True): from CGLutil.findExecutable import findExecutable mscalc_path = findExecutable('mscalc') if mscalc_path is None: raise Surface_Calculation_Error, 'No mscalc executable found' if all_components: allc = '1' else: allc = '0' args = (mscalc_path, '%f' % probe_radius, '%f' % vertex_density, allc) from numpy import array, intc xyzrs = array(len(xyzr), intc).tostring() + xyzr.tostring() cmd = ' '.join(args) from chimera.replyobj import info info(cmd + '\n') msout, mserr, status = run_shell_command(args, xyzrs) if status is None: raise Surface_Calculation_Error, 'Starting mscalc failed.' if mserr: info(mserr) try: if status != 0: raise Surface_Calculation_Error, 'Surface calculation failed, mscalc returned code %d' % status vfloat, vint, tri, atomareas, compareas = parse_mscalc_output(msout) if atomareas is None and len(xyzr) > 0: raise Surface_Calculation_Error, 'Surface calculation failed, produced empty surface.\n' except Surface_Calculation_Error: if fallback_to_single_component and all_components: from chimera.replyobj import warning warning( 'Calculation of some surface components failed.\nFalling back to single-component calculation.\n' ) return run_mscalc(xyzr, probe_radius, vertex_density, all_components=False) raise return vfloat, vint, tri, atomareas, compareas, all_components
def print_axes(axes, d2, m, center): from math import sqrt paxes = [ '\tv%d = %7.4f %7.4f %7.4f d%d = %7.3f' % (a + 1, axes[a][0], axes[a][1], axes[a][2], a + 1, sqrt(d2[a])) for a in range(3) ] from chimera.replyobj import info info('Inertia axes for %s\n%s\n' % (m.name, '\n'.join(paxes))) info('Centre of mass %7.4f %7.4f %7.4f\n ' % (center[0], center[1], center[2])) from Accelerators.standard_accelerators import show_reply_log show_reply_log()
def addDistance(atom1, atom2): b = _findDistance(atom1, atom2) if b is not None: from chimera import UserError raise UserError('Distance monitor already exists') b = distanceMonitor.newPseudoBond(atom1, atom2) from chimera import replyobj replyobj.info("Distance between %s and %s: %.*f\n" % (atom1, atom2, _pref['precision'], b.length())) b.drawMode = chimera.Bond.Wire updateDistance() if not distanceHandlers: _startHandlers() return b
def print_axes(axes, d2, elen, name, xform = None): if xform: import Matrix as m axes = m.apply_matrix_without_translation(m.xform_matrix(xform), axes) from math import sqrt paxes = ['\tv%d = %6.3f %6.3f %6.3f %s = %6.3f r%d = %6.3f' % (a+1, axes[a][0], axes[a][1], axes[a][2], ('a','b','c')[a], elen[a], a+1, sqrt(d2[a])) for a in range(3)] from chimera.replyobj import info info('Inertia axes for %s\n%s\n' % (name, '\n'.join(paxes))) from Accelerators.standard_accelerators import show_reply_log show_reply_log()
def center(operation, objects, level=None, mark=False, color=(.7, .7, .7, 1), radius=None, name=None, modelId=None): mlist = objects.models() from VolumeViewer import Volume vlist = [m for m in mlist if isinstance(m, Volume)] atoms = objects.atoms() if len(vlist) == 0 and len(atoms) == 0: raise CommandError('No volume or atoms specified') import Commands as CD rgba = CD.parse_color(color) model_id = None if modelId is None else CD.parse_model_id(modelId) import center as C from chimera import replyobj for v in vlist: ijk = C.volume_center_of_mass(v, level) xyz = v.data.ijk_to_xyz(ijk) msg = ('Center of mass grid index for %s = (%.2f, %.2f, %.2f)' % (v.name, ijk[0], ijk[1], ijk[2])) replyobj.info(msg + '\n') replyobj.status(msg) if mark: r = max(v.data.step) if radius is None else radius mname = v.name + ' center' if name is None else name C.place_marker(xyz, v, rgba, r, mname, model_id) if len(atoms) > 0: m0 = atoms[0].molecule cxf = m0.openState.xform xyz = C.atoms_center_of_mass(atoms, cxf) msg = ('Center of mass of %d atoms in %s (%s) coordinate system' ' = (%.2f, %.2f, %.2f)' % (len(atoms), m0.name, m0.oslIdent(), xyz[0], xyz[1], xyz[2])) replyobj.info(msg + '\n') smsg = ('Center for %d atoms = (%.2f, %.2f, %.2f)' % (len(atoms), xyz[0], xyz[1], xyz[2])) replyobj.status(smsg) if mark: r = atoms[0].radius if radius is None else radius mname = C.atoms_center_model_name(atoms) if name is None else name C.place_marker(xyz, m0, rgba, r, mname, model_id)
def unchargedAtomsWarning(ua, warning=""): if ua: warning += "Correct charges are unknown for %d"\ " non-standard atom names in otherwise"\ " standard residues\n\n" % len(ua) replyobj.info("Non-standard atom names:\n") for k, atoms in ua.items(): t, n = k info = ", ".join([str(a) for a in atoms[:3]]) if len(atoms) > 3: info += " + %d others" % ( len(atoms) - 3) replyobj.info("\t%s %s (%s)\n" % (t, n, info)) return warning
def normalizeMSE(r): S = chimera.Element("S") from BuildStructure import setBondLength for a in r.atoms: if a.element.name != "Se": continue a.element = S a.name = "SD" a.idatmType = "S3" for n, b in a.bondsMap.items(): if n.name == "CE": setBondLength(b, 1.78) elif n.name == "CG": setBondLength(b, 1.81) r.type = "MET" replyobj.info("MSE residue %s changed to MET\n" % str(r))
def listen(mode, what, prefix=None): from chimera import replyobj mode = findBestMatch(mode, ["start", "stop"]) what = findBestMatch(what, ["models", "selection"]) if what == "models": from chimera import openModels global modelHandler if mode == "start": if modelHandler is not None: msg = "already listening for models\n" else: if prefix is None: prefix = "ModelChanged" modelHandler = openModels.addAddHandler( _alertModel, prefix) msg = "listening for models\n" else: if modelHandler is None: msg = "not listening for models\n" else: openModels.deleteAddHandler(modelHandler) modelHandler = None msg = "stopped listening for models\n" replyobj.info(msg) elif what == "selection": import chimera global selectionHandler if mode == "start": if selectionHandler is not None: msg = "already listening for selection\n" else: if prefix is None: prefix = "SelectionChanged" selectionHandler = chimera.triggers.addHandler( "selection changed", _alertSelection, prefix) msg = "listening for selection\n" else: if selectionHandler is None: msg = "not listening for selection\n" else: chimera.triggers.deleteHandler( "selection changed", selectionHandler) selectionHandler = None msg = "stopped listening for selection\n" replyobj.info(msg)
def fetch_emdb_map(id, open_fit_pdbs = False, open_models = True): site = 'ftp.ebi.ac.uk' url_pattern = 'ftp://%s/pub/databases/emdb/structures/EMD-%s/map/%s' xml_url_pattern = 'ftp://%s/pub/databases/emdb/structures/EMD-%s/header/%s' from chimera.replyobj import status, info status('Fetching %s from %s...\n' % (id,site), blankAfter = False) # Fetch map. map_name = 'emd_%s.map' % id map_gz_name = map_name + '.gz' map_url = url_pattern % (site, id, map_gz_name) name = 'EMDB %s' % id minimum_map_size = 8192 # bytes from chimera import fetch map_path, headers = fetch.fetch_file(map_url, name, minimum_map_size, 'EMDB', map_name, uncompress = True) # Display map. status('Opening map %s...\n' % map_name, blankAfter = False) from VolumeViewer import open_volume_file models = open_volume_file(map_path, 'ccp4', map_name, 'surface', open_models = open_models) if open_fit_pdbs: # Find fit pdb ids. status('EMDB %s: looking for fits PDBs\n' % id) pdb_ids = fit_pdb_ids_from_web_service(id) msg = ('EMDB %s has %d fit PDB models: %s\n' % (id, len(pdb_ids), ','.join(pdb_ids))) status(msg) info(msg) if pdb_ids: mlist = [] from chimera import _openPDBIDModel, openModels for pdb_id in pdb_ids: status('Opening %s\n' % pdb_id) if open_models: m = openModels.open(pdb_id, 'PDBID') else: m = _openPDBIDModel(pdb_id) mlist.extend(m) models.extend(mlist) return models