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 move_atoms_to_maximum(atoms, volume, max_steps = 100, ijk_step_size_min = 0.01, ijk_step_size_max = 0.5, optimize_translation = True, optimize_rotation = True, move_whole_molecules = True, request_stop_cb = None): points = atom_coordinates(atoms) point_weights = None # Each atom give equal weight in fit. metric = 'sum product' move_tf, stats = motion_to_maximum(points, point_weights, volume, max_steps, ijk_step_size_min, ijk_step_size_max, optimize_translation, optimize_rotation, metric, request_stop_cb) stats['data region'] = volume stats['molecules'] = list(set([a.molecule for a in atoms])) import move move.move_models_and_atoms(move_tf, [], atoms, move_whole_molecules, volume) from Matrix import chimera_xform poc, clevel = points_outside_contour(points, chimera_xform(move_tf), volume) stats['atoms outside contour'] = poc stats['contour level'] = clevel return stats
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 align_best(reference, probe, transform=True, sanitize=True, ignore_warnings=False, maxIters=50, reflect=False, **kwargs): rdk_reference = _chimera_to_rdkit(reference, sanitize=sanitize) rdk_probe = _chimera_to_rdkit(probe, sanitize=sanitize) matches = rdk_reference.GetSubstructMatches(rdk_probe, uniquify=False) if not matches: raise chimera.UserError('Could not find any alignment.') if not ignore_warnings and len(matches) > 1e6: raise chimera.UserError( "Too many possible alignments found! This can be " "slow! Use `ignore_warnings true` to try.") maps = [list(enumerate(match)) for match in matches] best_rmsd, best_xform = 1000., None for atom_map in maps: rmsd, xform = GetAlignmentTransform(rdk_probe, rdk_reference, atomMap=atom_map, maxIters=maxIters, reflect=reflect) if rmsd < best_rmsd: best_rmsd = rmsd best_xform = xform if transform and best_xform is not None: _transform_molecule(probe, chimera_xform(best_xform[:3])) return best_rmsd
def shift_and_angle(tf, center): from Matrix import chimera_xform, apply_matrix moved_center = apply_matrix(tf, center) shift_vector = map(lambda a, b: a - b, moved_center, center) shift = norm(shift_vector) axis, angle = chimera_xform(tf).getRotation() return shift, angle
def fit_map_in_map(map1_path, map2_path, xformName, initial_map1_transform = None, map1_threshold = None, ijk_step_size_min = 0.01, # Grid index units ijk_step_size_max = 0.5, # Grid index units max_steps = 5000, optimize_translation = True, optimize_rotation = True): # Files have to have file suffix indicating volume format. from VolumeViewer import open_volume_file map1 = open_volume_file(map1_path)[0] # Assume files contain just one array map2 = open_volume_file(map2_path)[0] if initial_map1_transform: from Matrix import chimera_xform xf = chimera_xform(initial_map1_transform) map1.surface_model().openState.globalXform(xf) use_threshold = (map1_threshold != None) from FitMap.fitmap import map_points_and_weights, motion_to_maximum points, point_weights = map_points_and_weights(map1, use_threshold) if len(points) == 0: if use_threshold: print 'No grid points above map threshold.' else: print 'Map has no non-zero values.' return move_tf, stats = motion_to_maximum(points, point_weights, map2, max_steps, ijk_step_size_min, ijk_step_size_max, optimize_translation, optimize_rotation) import Matrix if initial_map1_transform: move_tf = Matrix.multiply_matrices(move_tf, initial_map1_transform) header = ('\nFit map %s in map %s using %d points\n' % (map1.name, map2.name, stats['points']) + ' correlation = %.4g, overlap = %.4g\n' % (stats['correlation'], stats['overlap']) + ' steps = %d, shift = %.3g, angle = %.3g degrees\n' % (stats['steps'], stats['shift'], stats['angle'])) print header f = open(xformName,'w') for i in range(4): for j in range(3): # print move_tf[j][i] f.write('{:f}'.format(move_tf[j][i])) f.write("\n") f.close() print move_tf tfs = Matrix.transformation_description(move_tf) print tfs
def create_symmetry_copies(mol, csys, tflist, cdist, rdist, exclude_identity=True): if exclude_identity: from Matrix import is_identity_matrix tflist = [tf for tf in tflist if not is_identity_matrix(tf)] close_contacts = not cdist is None close_centers = not rdist is None if not close_contacts and not close_centers: transforms = tflist # Use all transforms elif close_contacts and not close_centers: transforms = contacting_transforms(mol, csys, tflist, cdist) elif close_centers and not close_contacts: transforms = close_center_transforms(mol, csys, tflist, rdist) else: transforms = unique( contacting_transforms(mol, csys, tflist, cdist) + close_center_transforms(mol, csys, tflist, rdist)) if hasattr(mol, 'symmetry_copies'): remove_symmetry_copies(mol) copies = [] from chimera import openModels, replyobj from PDBmatrices import copy_molecule from Matrix import chimera_xform for tf in transforms: copy = copy_molecule(mol) copy.symmetry_xform = chimera_xform(tf) copies.append(copy) replyobj.status('Created symmetry copy %d of %d' % (len(copies), len(transforms))) if len(copies) == 0: return copies openModels.add(copies) replyobj.status('') mol.symmetry_copies = copies mol.symmetry_reference_model = csys # TODO: Set xform before opening so that code that detects open sees # the correct position. Currently not possible. Bug 4486. update_symmetry_positions(mol) return copies
def fit_map_in_map( map1_path, map2_path, initial_map1_transform=None, map1_threshold=None, ijk_step_size_min=0.01, # Grid index units ijk_step_size_max=0.5, # Grid index units max_steps=2000, optimize_translation=True, optimize_rotation=True, metric='sum product' ): # 'sum product' > overlap; other options are 'correlation' and 'correlation about mean' # Files have to have file suffix indicating volume format. map1 = open_volume_file(map1_path)[ 0] # Assume files contain just one array map2 = open_volume_file(map2_path)[0] if initial_map1_transform: from Matrix import chimera_xform xf = chimera_xform(initial_map1_transform) map1.surface_model().openState.globalXform(xf) use_threshold = (map1_threshold != None) points, point_weights = map_points_and_weights(map1, use_threshold) if len(points) == 0: if use_threshold: print 'No grid points above map threshold.' else: print 'Map has no non-zero values.' return move_tf, stats = motion_to_maximum(points, point_weights, map2, max_steps, ijk_step_size_min, ijk_step_size_max, optimize_translation, optimize_rotation, metric) if initial_map1_transform: move_tf = Matrix.multiply_matrices(move_tf, initial_map1_transform) header = ('\nFit map %s in map %s using %d points\n' % (map1.name, map2.name, stats['points']) + ' correlation = %.4g, overlap = %.4g\n' % (stats['correlation'], stats['overlap']) + ' steps = %d, shift = %.3g, angle = %.3g degrees\n' % (stats['steps'], stats['shift'], stats['angle'])) print header tfs = Matrix.transformation_description(move_tf) print tfs
def align(reference, probe, transform=True, sanitize=True, maxIters=50, reflect=False, **kwargs): rdk_reference = _chimera_to_rdkit(reference, sanitize=sanitize) rdk_probe = _chimera_to_rdkit(probe, sanitize=sanitize) rmsd, xform = GetAlignmentTransform(rdk_probe, rdk_reference, maxIters=maxIters, reflect=reflect) if transform: _transform_molecule(probe, chimera_xform(xform[:3])) return rmsd
def create_symmetry_copies(mol, csys, tflist, cdist, rdist, exclude_identity = True): if exclude_identity: from Matrix import is_identity_matrix tflist = [tf for tf in tflist if not is_identity_matrix(tf)] close_contacts = not cdist is None close_centers = not rdist is None if not close_contacts and not close_centers: transforms = tflist # Use all transforms elif close_contacts and not close_centers: transforms = contacting_transforms(mol, csys, tflist, cdist) elif close_centers and not close_contacts: transforms = close_center_transforms(mol, csys, tflist, rdist) else: transforms = unique(contacting_transforms(mol, csys, tflist, cdist) + close_center_transforms(mol, csys, tflist, rdist)) if hasattr(mol, 'symmetry_copies'): remove_symmetry_copies(mol) copies = [] from chimera import openModels, replyobj from PDBmatrices import copy_molecule from Matrix import chimera_xform for tf in transforms: copy = copy_molecule(mol) copy.symmetry_xform = chimera_xform(tf) copies.append(copy) replyobj.status('Created symmetry copy %d of %d' % (len(copies), len(transforms))) if len(copies) == 0: return copies openModels.add(copies) replyobj.status('') mol.symmetry_copies = copies mol.symmetry_reference_model = csys # TODO: Set xform before opening so that code that detects open sees # the correct position. Currently not possible. Bug 4486. update_symmetry_positions(mol) return copies
def make_asu_copies(m, asu_list, crystal): xflist = [] names = [] from Matrix import is_identity_matrix, chimera_xform for asu in asu_list: if is_identity_matrix(asu.transform): continue xflist.append(chimera_xform(asu.transform)) name = '%s %s' % (m.name, '%d %d %d' % asu.unit_cell_index) if len(crystal.smtry_matrices) > 1: name += ' sym %d' % asu.smtry_index if len(crystal.ncs_matrices) > 1: name += ' ncs %d' % asu.ncs_index names.append(name) cmodels = make_molecule_copies(m, xflist, names) return cmodels
def make_asu_copies(m, asu_list, crystal): xflist = [] names = [] from Matrix import is_identity_matrix, chimera_xform for asu in asu_list: if is_identity_matrix(asu.transform): continue xflist.append(chimera_xform(asu.transform)) name = '%s %s' % (m.name, '%d %d %d' % asu.unit_cell_index) if len(crystal.smtry_matrices) > 1: name += ' sym %d' % asu.smtry_index if len(crystal.ncs_matrices) > 1: name += ' ncs %d' % asu.ncs_index names.append(name) cmodels = make_molecule_copies(m, xflist, names) return cmodels
def axis_center_angle_shift(tf): from Matrix import chimera_xform axis, angle = chimera_xform(tf).getRotation() axis = axis.data() t = map(lambda r: r[3], tf) axt = cross_product(axis, t) axaxt = cross_product(axis, axt) from math import pi, cos, sin a2 = 0.5 * angle * pi / 180 # Half angle in radians try: ct2 = cos(a2) / sin(a2) except: ct2 = None # Identity rotation if ct2 == None: axis_point = (0, 0, 0) else: axis_point = tuple(map(lambda a, b: .5 * ct2 * a - .5 * b, axt, axaxt)) from numpy import dot as inner_product shift = inner_product(axis, t) return axis, axis_point, angle, shift
def move_atom_to_maximum(a, max_steps = 100, ijk_step_size_min = 0.001, ijk_step_size_max = 0.5): from VolumeViewer import active_volume dr = active_volume() if dr == None or dr.model_transform() == None: from chimera.replyobj import status status('No data shown by volume viewer dialog') return points = atom_coordinates([a]) point_weights = None move_tf, stats = motion_to_maximum(points, point_weights, dr, max_steps, ijk_step_size_min, ijk_step_size_max, optimize_translation = True, optimize_rotation = False) # Update atom position. from Matrix import chimera_xform xf = chimera_xform(move_tf) mxf = a.molecule.openState.xform p = mxf.inverse().apply(xf.apply(a.xformCoord())) a.setCoord(p)
def align_o3a(reference, probe, transform=True, sanitize=True, maxIters=50, reflect=False, **kwargs): rdk_reference = _chimera_to_rdkit(reference, sanitize=sanitize) rdk_probe = _chimera_to_rdkit(probe, sanitize=sanitize) FastFindRings(rdk_reference) FastFindRings(rdk_probe) reference_params = MMFFGetMoleculeProperties(rdk_reference) probe_params = MMFFGetMoleculeProperties(rdk_probe) o3a = GetO3A(rdk_probe, rdk_reference, prbPyMMFFMolProperties=probe_params, refPyMMFFMolProperties=reference_params, maxIters=maxIters, reflect=reflect) rmsd, xform = o3a.Trans() if transform: _transform_molecule(probe, chimera_xform(xform[:3])) return rmsd