class MolecularMinimizer: def __init__(self, molecules, interaction_manager): self.molecules = molecules for molecule in self.molecules: molecule.r_array *= 1.85 self.v = QtViewer() self.renderers = {} for molecule in self.molecules: ar = self.v.add_renderer(BallAndStickRenderer, molecule.r_array, molecule.type_array, molecule.bonds) self.renderers[molecule] = ar self.best_response_value = 0 self.best_atom_coordinates = None self.twod_signal_manager = get_twod_signal_manager() self.interaction_manager = interaction_manager def update(self): for molecule in self.molecules: if len(molecule.bonds)>=2: i = random.randrange(len(molecule.bonds)) a = bond_bisect(molecule.bonds, molecule.bonds[i], True) r_old = np.copy(molecule.r_array) uf = a[1] point_a = np.copy(molecule.r_array[molecule.bonds[i][0]]) point_b = np.copy(molecule.r_array[molecule.bonds[i][1]]) M = rotation_matrix(np.pi/20, point_b-point_a)[:3, :3] molecule.r_array = np.array(molecule.export['vectors']) molecule.r_array -= point_a molecule.r_array[uf] = np.dot(molecule.r_array[uf], M.T) molecule.r_array += point_a self.set_vectors(molecule, molecule.r_array) new_response_value = calculate_response_value(molecule.r_array) if new_response_value < self.best_response_value: self.best_response_value = new_response_value else: molecule.r_array = r_old self.set_vectors(r_old) self.renderers[molecule].update_positions(molecule.r_array) self.v.widget.repaint() else: None def set_vectors(self, molecule, arr): for i,vec in enumerate(arr): molecule.export['vectors'][i][:] = vec def run(self): self.v.schedule(self.update) self.v.run()
import numpy as np v1 = np.array([1.0, 0.0, -1.0/np.sqrt(2)]) v2 = np.array([-1.0, 0.0, -1.0/np.sqrt(2)]) v3 = np.array([0.0, 1.0, 1.0/np.sqrt(2)]) v4 = np.array([0.0, -1.0, 1.0/np.sqrt(2)]) from chemlab.graphics import QtViewer from chemlab.graphics.renderers import PointRenderer from chemlab.graphics.colors import black, green, blue, red colors = [black, green, blue, red] v = QtViewer() v.add_renderer(PointRenderer, np.array([v1, v2, v3, v4]), colors) from chemlab.graphics.renderers import TriangleRenderer vertices = np.array([ v1, v4, v3, v3, v4, v2, v1, v3, v2, v2, v4, v1 ]) colors = [green] * 12 # Normals: cross-product for each face n1 = -np.cross(v4 - v1, v3 - v1) n1 /= np.linalg.norm(n1) n2 = -np.cross(v4 - v3, v2 - v3) n2 /= np.linalg.norm(n2)
from chemlab.db import CirDB from chemlab.graphics import QtViewer from chemlab.graphics.renderers import AtomRenderer from chemlab.graphics.postprocessing import FXAAEffect, SSAOEffect # A series of compounds to display compounds = ["methane", "ethane", "propane", "butane"] db = CirDB() # Prepare the viewer v = QtViewer() v.widget.initializeGL() v.add_post_processing(SSAOEffect, kernel_size=128, kernel_radius=1.0) v.add_post_processing(FXAAEffect) for compound in compounds: mol = db.get("molecule", compound) rend = v.add_renderer(AtomRenderer, mol.r_array, mol.type_array) v.widget.camera.autozoom(mol.r_array) # Give some extra zoom v.widget.camera.mouse_zoom(1.0) v.widget.toimage(300, 300).save(compound + '.png') # Cleanup v.remove_renderer(rend)
class ChemLabMinimiser: def __init__(self): self.interaction_manager = get_interaction_manager( *get_twod_signal_manager().get_interaction_data()) #TODO : REMOVE WEIRD POINTS for x in [[19, 6], [19, 7], [21, 6]]: print(self.interaction_manager.interaction_matrix[x]) self.interaction_manager.interaction_matrix[x[0]][x[1]] = 0 self.interaction_manager.interaction_matrix[x[1]][x[0]] = 0 self.interaction_matrix = self.interaction_manager.interaction_matrix self.interaction_matrix[self.interaction_matrix == 9] = 0 self.type_array = self.interaction_manager.type_array self.shift_data = self.interaction_manager.shift_data self.number_atoms = self.interaction_manager.number_atoms self.viewer = QtViewer() ac = np.random.rand(self.number_atoms, 3) * 3 self.coordinate_manager = CoordinateManager(ac, self.interaction_manager) self.renderer = self.viewer.add_renderer( BallAndStickRenderer, self.coordinate_manager.get_coordinates(), self.type_array, np.array([])) def main(self): self.viewer.schedule(self.iteration) self.viewer.run() def iteration(self): self.force_step() def force_step(self): atom_coordinates = self.coordinate_manager.get_coordinates() for index, atom in enumerate(atom_coordinates): atom_coordinates[index] += self.get_force_vector( index, atom, atom_coordinates) self.renderer.update_positions(atom_coordinates) self.coordinate_manager.update(atom_coordinates) def get_force_vector(self, index, atom, atom_coordinates): vec = np.zeros(3) for i2, atom2 in enumerate(atom_coordinates): distance = np.linalg.norm(atom2 - atom) if distance == 0 or atom is atom2: continue #input((atom,atom2)) subvec = 0.01 * (atom2 - atom) / distance minimum = minima[self.interaction_matrix[index][i2]] try: delta = abs(minimum - distance) except Exception as e: pass try: #print(delta, minimum, distance) subvec *= (delta * delta) vec += subvec except: pass return vec
class MolecularGraphics: def __init__(self, coordinates, interaction_manager): self.viewer = QtViewer() self.selected_atom = 0 self.active = True self.coordinates = None self.atoms = None self.bonds = None self.interaction_manager = interaction_manager self.viewer.widget.on_mouse.append(self.select) try: self.update(coordinates, interaction_manager) if len(coordinates) != len(self.atoms): raise Exception( "Atom List does not correspond to coordinate array") except Exception as e: self.disable(e) def select(self, mouse_vector): closest_index = None closest_dist = 100 for index, atom in enumerate(self.coordinates): dist = np.linalg.norm(mouse_vector[:2] - atom[:2]) if dist < closest_dist: closest_index = index closest_dist = dist mouse_vector[2] = 0 self.selected_atom = closest_index self.coordinates[0] = mouse_vector print(mouse_vector) self.update(self.coordinates, self.interaction_manager) """ def scroll_atom(self): self.selected_atom += 1 self.selected_atom %= len(self.interaction_manager.atoms) #print(self.selected_atom) self.update(self.coordinates, self.interaction_manager) """ def update_coordinates(self, coordinates): self.coordinates = coordinates if self.active: try: self.renderer.update_positions(scale * coordinates) self.viewer.widget.update() except Exception as e: self.disable(e) def disable(self, e): raise e input( "Exception occured in graphics handler. Graphics will henceforth be disabled:" ) self.active = False def run(self, iterfunction): if self.active: try: self.viewer.schedule(iterfunction) self.viewer.run() except Exception as e: self.disable(e) if not self.active: while True: iterfunction() def update(self, coordinates, interaction_manager): self.coordinates = coordinates self.interaction_manager = interaction_manager self.atoms = interaction_manager.atoms self.bonds = interaction_manager.bonds if self.active: try: bond_colors = np.array([ bond_colors_dict[bond.inferred_by] for bond in self.bonds ]) interactions = [] interaction_colors = [] for x in [1, 3, 6]: new_interaction_list = interaction_manager.get_all_interaction_atoms( x) new_interaction_indices = [[ y[0].index_value, y[1].index_value ] for y in new_interaction_list] interactions += new_interaction_indices interaction_colors += [interaction_colors_dict[x] ] * len(new_interaction_indices) self.viewer.clear() type_array = [ atom.atom_type for atom in interaction_manager.atoms ] atom_colors = [] for index, atom in enumerate(interaction_manager.atoms): if atom.get_free_valency( ) != 0 and atom.atom_type in atom_colors_dict and self.selected_atom != index: atom_colors.append(atom_colors_dict[atom.atom_type]) elif index == self.selected_atom: atom_colors.append([57, 255, 20, 255]) else: atom_colors.append(default_atom_map[atom.atom_type]) self.renderer = self.viewer.add_renderer( MyBallAndStickRenderer, scale * coordinates, np.array(type_array), np.array(atom_colors), np.array([bond.get_indices() for bond in self.bonds]), bond_colors, np.array(interactions), np.array(interaction_colors)) except Exception as e: self.disable(e)
import numpy as np v1 = np.array([1.0, 0.0, -1.0 / np.sqrt(2)]) v2 = np.array([-1.0, 0.0, -1.0 / np.sqrt(2)]) v3 = np.array([0.0, 1.0, 1.0 / np.sqrt(2)]) v4 = np.array([0.0, -1.0, 1.0 / np.sqrt(2)]) from chemlab.graphics import QtViewer from chemlab.graphics.renderers import PointRenderer from chemlab.graphics.colors import black, green, blue, red colors = [black, green, blue, red] v = QtViewer() v.add_renderer(PointRenderer, np.array([v1, v2, v3, v4]), colors) from chemlab.graphics.renderers import TriangleRenderer vertices = np.array([v1, v4, v3, v3, v4, v2, v1, v3, v2, v2, v4, v1]) colors = [green] * 12 # Normals: cross-product for each face n1 = -np.cross(v4 - v1, v3 - v1) n1 /= np.linalg.norm(n1) n2 = -np.cross(v4 - v3, v2 - v3) n2 /= np.linalg.norm(n2) n3 = -np.cross(v3 - v1, v2 - v1) n3 /= np.linalg.norm(n3)