def __init__(self, system): """Constructor. Parameters ---------- system : Sire.System.System, :class:`System <BioSimSpace._SireWrappers.System>`, \ Sire.Mol.Molecule, :class:`Molecule <BioSimSpace._SireWrappers.Molecule>`, \ [:class:`Molecule <BioSimSpace._SireWrappers.Molecule>`] A Sire or BioSimSpace System object, a Sire or BioSimSpace Molecule object, or a list of BioSimSpace molecule objects. """ # Check that the system is valid. # Convert tuple to a list. if type(system) is tuple: system = list(system) # A Sire System object. if type(system) is _SireSystem.System: self._sire_system = system.__deepcopy__() # Another BioSimSpace System object. elif type(system) is System: self._sire_system = system._sire_system.__deepcopy__() # A Sire Molecule object. elif type(system) is _SireMol.Molecule: self._sire_system = _SireSystem.System("BioSimSpace System.") self.addMolecules(_Molecule(system)) # A BioSimSpace Molecule object. elif type(system) is _Molecule: self._sire_system = _SireSystem.System("BioSimSpace System.") self.addMolecules(system) # A list of BioSimSpace Molecule objects. elif type(system) is list: if not all(isinstance(x, _Molecule) for x in system): raise TypeError("'system' must contain a list of 'BioSimSpace._SireWrappers.Molecule' types.") else: self._sire_system = _SireSystem.System("BioSimSpace System.") self.addMolecules(system) # Invalid type. else: raise TypeError("'system' must be of type 'Sire.System._System.System', 'BioSimSpace._SireWrappers.System', " " Sire.Mol._Mol.Molecule', 'BioSimSpace._SireWrappers.Molecule', " "or a list of 'BioSimSpace._SireWrappers.Molecule' types.")
def _createSireSystem(molecules): """Create a Sire system from a Molecules object or a list of Molecule objects. Parameters ---------- molecules : :class:`Molecules <BioSimSpace._SireWrappers.Molecules>` \ [:class:`Molecule <BioSimSpace._SireWrappers.Molecule>`] Returns ------- system : Sire.System.System A Sire system object. """ # Create an empty Sire System. system = _SireSystem.System("BioSimSpace System") # Create a new "all" molecule group. molgrp = _SireMol.MoleculeGroup("all") # Add the molecules to the group. if type(molecules) is _Molecules: molgrp.add(molecules._sire_object) else: for mol in molecules: molgrp.add(mol._sire_object) # Add the molecule group to the system. system.add(molgrp) return system
def addRDF(rdf, pdbfile, xscfile=None): """Add to the RDF 'rdf' the distances calculated using the coordinates from the PDB file 'pdbfile', using the xscfile 'xscfile' to get the dimensions of the periodic box. If 'xscfile' is None, then no periodic boundary conditions are used.""" #first get the space in which to calculate intermolecular distances space = Cartesian() if xscfile: lines = open(xscfile,"r").readlines() words = lines[0].split() mincoords = Vector( float(words[0]), float(words[1]), float(words[2]) ) maxcoords = Vector( float(words[3]), float(words[4]), float(words[5]) ) space = PeriodicBox(mincoords, maxcoords) #now load all of the molecules mols = PDB().read(pdbfile) #create a system to hold the molecules, and add them system = System() system.add( MoleculeGroup("molecules", mols) ) #give the space to the system system.add( InterCLJFF() ) # bug! need to add InterCLJFF so # that the system has a space property. This # is fixed in new version of Sire, but is broken # in your version system.setProperty("space", space) #add the RDF - this calculates the RDF for this PDB file and adds it to 'rdf' rdf.monitor(system)
def _createSireSystem(molecules): """Create a Sire system from a list of molecules. Parameters ---------- molecules : [:class:`Molecule <BioSimSpace._SireWrappers.Molecule>`] Returns ------- system : Sire.System.System A Sire system object. """ # Create an empty Sire System. system = _SireSystem.System("BioSimSpace System") # Create a new "all" molecule group. molgrp = _SireMol.MoleculeGroup("all") # Add the molecules to the group. for mol in molecules: molgrp.add(mol._sire_molecule) # Add the molecule group to the system. system.add(molgrp) return system
def _createSystem(molecules): moleculeNumbers = molecules.molNums() moleculeList = [] for moleculeNumber in moleculeNumbers: molecule = molecules.molecule(moleculeNumber)[0].molecule() moleculeList.append(molecule) molecules = MoleculeGroup("molecules") ions = MoleculeGroup("ions") for molecule in moleculeList: natoms = molecule.nAtoms() if natoms == 1: ions.add(molecule) else: molecules.add(molecule) all = MoleculeGroup("all") all.add(molecules) all.add(ions) # Add these groups to the System system = System() system.add(all) system.add(molecules) system.add(ions) return system
def createSystem(molecules): #print("Applying flexibility and zmatrix templates...") print("Creating the system...") moleculeNumbers = molecules.molNums() moleculeList = [] for moleculeNumber in moleculeNumbers: molecule = molecules.molecule(moleculeNumber)[0].molecule() moleculeList.append(molecule) molecules = MoleculeGroup("molecules") ions = MoleculeGroup("ions") for molecule in moleculeList: natoms = molecule.nAtoms() if natoms == 1: ions.add(molecule) else: molecules.add(molecule) all = MoleculeGroup("all") all.add(molecules) all.add(ions) # Add these groups to the System system = System() system.add(all) system.add(molecules) system.add(ions) return system
def buildSystem(forcefields): system = System() for forcefield in forcefields: system.add(forcefield) system.setProperty("space", space) system.setProperty("switchingFunction", HarmonicSwitchingFunction(8*angstrom, 7.5*angstrom)) system.setProperty("shiftDelta", VariantProperty(2.0)) system.setProperty("coulombPower", VariantProperty(0)) return system
def createSystem(top_file, crd_file, naming_scheme=NamingScheme()): """Create a new System from the molecules read in from the passed amber topology and coordinate files. This sorts the molecules into different molecule groups based on the passed naming scheme""" system = System(top_file) # Load all of the molecules and their parameters from # the topology and coordinate files amber = Amber() print("Loading the molecules from the Amber files \"%s\" and \"%s\"..." % \ (crd_file, top_file)) (molecules, space) = amber.readCrdTop(crd_file, top_file) return createSystemFrom(molecules, space, top_file, naming_scheme)
def molecule(self, index=0, gui=True): """View a specific molecule. Parameters ---------- index : int The molecule index. gui : bool Whether to display the gui. """ # Make sure we're running inside a Jupyter notebook. if not _is_notebook: return None # Check that the index is an integer. if type(index) is not int: raise TypeError("'index' must be of type 'int'") # Get the latest system from the process. if self._is_process: system = self._handle.getSystem()._getSireObject() # No system. if system is None: return else: system = self._handle # Extract the molecule numbers. molnums = system.molNums() # Make sure the index is valid. if index < 0 or index > len(molnums): raise ValueError("Molecule index is out of range!") # Create a new system and add a single molecule. s = _SireSystem.System("BioSimSpace System") m = _SireMol.MoleculeGroup("all") m.add(system[molnums[index]]) s.add(m) # Create and return the view. return self._create_view(s, gui=gui)
def test_fixed_center(verbose = False): ligand = Sire.Stream.load("../io/osel.s3") ligand = ligand.edit().setProperty("center", wrap(ligand.evaluate().center())).commit() old_center = ligand.property("center") intraff = InternalFF("intraff") intraff.add(ligand) intraclj = IntraCLJFF("intraclj") intraclj.add(ligand) system = System() system.add(intraff) system.add(intraclj) mols = MoleculeGroup("mols") mols.add(ligand) system.add(mols) intramove = InternalMove(mols) rbmove = RigidBodyMC(mols) rbmove.setMaximumTranslation(0*angstrom) moves = WeightedMoves() moves.add(intramove, 1) moves.add(rbmove, 1) for i in range(0,10): system = moves.move(system, 25, False) if verbose: print("Completed 25 moves...") ligand = system[ligand.number()].molecule() new_center = ligand.property("center") if verbose: print("Old center = %s" % old_center) print("New center = %s" % new_center) assert_almost_equal( old_center.x(), new_center.x(), 1 ) assert_almost_equal( old_center.y(), new_center.y(), 1 ) assert_almost_equal( old_center.z(), new_center.z(), 1 )
def __init__(self, system): """Constructor. Parameters ---------- system : Sire.System.System, :class:`System <BioSimSpace._SireWrappers.System>`, \ Sire.Mol._Mol.Molecule, :class:`Molecule <BioSimSpace._SireWrappers.Molecule>`, \ :class:`Molecules <BioSimSpace._SireWrappers.Molecules>` \ [:class:`Molecule <BioSimSpace._SireWrappers.Molecule>`] A Sire or BioSimSpace System object, a Sire or BioSimSpace Molecule object, a BioSimSpace Molecules object, or a list of BioSimSpace molecule objects. """ # Check that the system is valid. # Convert tuple to a list. if type(system) is tuple: system = list(system) # A Sire System object. if type(system) is _SireSystem.System: super().__init__(system) # Another BioSimSpace System object. elif type(system) is System: super().__init__(system._sire_object) # A Sire Molecule object. elif type(system) is _SireMol.Molecule: sire_object = _SireSystem.System("BioSimSpace System.") super().__init__(sire_object) self.addMolecules(_Molecule(system)) # A BioSimSpace Molecule object. elif type(system) is _Molecule: sire_object = _SireSystem.System("BioSimSpace System.") super().__init__(sire_object) self.addMolecules(system) # A BioSimSpace Molecules object. elif type(system) is _Molecules: sire_object = _SireSystem.System("BioSimSpace System.") super().__init__(sire_object) self.addMolecules(system) # A list of BioSimSpace Molecule objects. elif type(system) is list: if not all(isinstance(x, _Molecule) for x in system): raise TypeError("'system' must contain a list of 'BioSimSpace._SireWrappers.Molecule' types.") else: sire_object = _SireSystem.System("BioSimSpace System.") super().__init__(sire_object) self.addMolecules(system) # Invalid type. else: raise TypeError("'system' must be of type 'Sire.System.System', 'BioSimSpace._SireWrappers.System', " " Sire.Mol.Molecule', 'BioSimSpace._SireWrappers.Molecule', " "or a list of 'BioSimSpace._SireWrappers.Molecule' types.") # Flag that this object holds multiple atoms. self._is_multi_atom = True # Initalise dictionaries mapping MolNums to the number cumulative # number of atoms/residues in the system, up to that MolNum. self._atom_index_tally = {} self._residue_index_tally = {} # Initialise dictionary to map MolNum to MolIdx. self._molecule_index = {} # Store the molecule numbers. self._mol_nums = self._sire_object.molNums() # Intialise the iterator counter. self._iter_count = 0
def createSystem(): protomsdir = "%s/Work/ProtoMS" % os.getenv("HOME") protoms = ProtoMS("%s/protoms2" % protomsdir) protoms.addParameterFile("%s/parameter/amber99.ff" % protomsdir) protoms.addParameterFile("%s/parameter/solvents.ff" % protomsdir) protoms.addParameterFile("%s/parameter/gaff.ff" % protomsdir) protoms.addParameterFile(solute_params) solute = PDB().readMolecule(solute_file) solute = solute.edit().rename(solute_name).commit() solute = protoms.parameterise(solute, ProtoMS.SOLUTE) perturbation = solute.property("perturbations") lam = Symbol("lambda") lam_fwd = Symbol("lambda_{fwd}") lam_bwd = Symbol("lambda_{bwd}") initial = Perturbation.symbols().initial() final = Perturbation.symbols().final() solute = solute.edit().setProperty( "perturbations", perturbation.recreate((1 - lam) * initial + lam * final)).commit() solute_fwd = solute.edit().renumber().setProperty( "perturbations", perturbation.substitute(lam, lam_fwd)).commit() solute_bwd = solute.edit().renumber().setProperty( "perturbations", perturbation.substitute(lam, lam_bwd)).commit() solvent = PDB().read(solvent_file) tip4p = solvent.moleculeAt(0).molecule() tip4p = tip4p.edit().rename(solvent_name).commit() tip4p = protoms.parameterise(tip4p, ProtoMS.SOLVENT) tip4p_chgs = tip4p.property("charge") tip4p_ljs = tip4p.property("LJ") for i in range(0, solvent.nMolecules()): tip4p = solvent.moleculeAt(i).molecule() tip4p = tip4p.edit().rename(solvent_name) \ .setProperty("charge", tip4p_chgs) \ .setProperty("LJ", tip4p_ljs) \ .commit() solvent.update(tip4p) system = System() solutes = MoleculeGroup("solutes") solutes.add(solute) solutes.add(solute_fwd) solutes.add(solute_bwd) solvent = MoleculeGroup("solvent", solvent) all = MoleculeGroup("all") all.add(solutes) all.add(solvent) system.add(solutes) system.add(solvent) system.add(all) solventff = InterCLJFF("solvent:solvent") solventff.add(solvent) solute_intraff = InternalFF("solute_intraff") solute_intraff.add(solute) solute_fwd_intraff = InternalFF("solute_fwd_intraff") solute_fwd_intraff.add(solute_fwd) solute_bwd_intraff = InternalFF("solute_bwd_intraff") solute_bwd_intraff.add(solute_bwd) solute_intraclj = IntraCLJFF("solute_intraclj") solute_intraclj.add(solute) solute_fwd_intraclj = IntraCLJFF("solute_fwd_intraclj") solute_fwd_intraclj.add(solute_fwd) solute_bwd_intraclj = IntraCLJFF("solute_bwd_intraclj") solute_bwd_intraclj.add(solute_bwd) solute_solventff = InterGroupCLJFF("solute:solvent") solute_solventff.add(solute, MGIdx(0)) solute_solventff.add(solvent, MGIdx(1)) solute_fwd_solventff = InterGroupCLJFF("solute_fwd:solvent") solute_fwd_solventff.add(solute_fwd, MGIdx(0)) solute_fwd_solventff.add(solvent, MGIdx(1)) solute_bwd_solventff = InterGroupCLJFF("solute_bwd:solvent") solute_bwd_solventff.add(solute_bwd, MGIdx(0)) solute_bwd_solventff.add(solvent, MGIdx(1)) forcefields = [ solventff, solute_intraff, solute_intraclj, solute_solventff, solute_fwd_intraff, solute_fwd_intraclj, solute_fwd_solventff, solute_bwd_intraff, solute_bwd_intraclj, solute_bwd_solventff ] for forcefield in forcefields: system.add(forcefield) xsc_line = open(solvent_file, "r").readlines()[0] words = xsc_line.split() #HEADER box -12.5 -12.5 -12.5 12.5 12.5 12.5 space = PeriodicBox( Vector(float(words[2]), float(words[3]), float(words[4])), Vector(float(words[5]), float(words[6]), float(words[7]))) system.setProperty("space", space) system.setProperty( "switchingFunction", HarmonicSwitchingFunction(coulomb_cutoff, coulomb_feather, lj_cutoff, lj_feather)) system.setProperty("combiningRules", VariantProperty(combining_rules)) e_total = system.totalComponent() e_fwd = Symbol("E_{fwd}") e_bwd = Symbol("E_{bwd}") total_nrg = solventff.components().total() + \ solute_intraclj.components().total() + solute_intraff.components().total() + \ solute_solventff.components().total() fwd_nrg = solventff.components().total() + \ solute_fwd_intraclj.components().total() + solute_fwd_intraff.components().total() + \ solute_fwd_solventff.components().total() bwd_nrg = solventff.components().total() + \ solute_bwd_intraclj.components().total() + solute_bwd_intraff.components().total() + \ solute_bwd_solventff.components().total() system.setComponent(e_total, total_nrg) system.setComponent(e_fwd, fwd_nrg) system.setComponent(e_bwd, bwd_nrg) system.setConstant(lam, 0.0) system.setConstant(lam_fwd, 0.0) system.setConstant(lam_bwd, 0.0) system.add(SpaceWrapper(Vector(0, 0, 0), all)) system.add(PerturbationConstraint(solutes)) system.add(ComponentConstraint(lam_fwd, Min(lam + delta_lambda, 1))) system.add(ComponentConstraint(lam_bwd, Max(lam - delta_lambda, 0))) de_fwd = Symbol("de_fwd") de_bwd = Symbol("de_bwd") system.setComponent(de_fwd, fwd_nrg - total_nrg) system.setComponent(de_bwd, total_nrg - bwd_nrg) system.add("total_energy", MonitorComponent(e_total, Average())) system.add("de_fwd", MonitorComponent(de_fwd, FreeEnergyAverage(temperature))) system.add("de_bwd", MonitorComponent(de_bwd, FreeEnergyAverage(temperature))) system.setComponent(lam, 0.0) print "LAMBDA=0 : Energy = %f kcal mol-1" % system.energy().to( kcal_per_mol) print " (%f, %f)" % (system.energy(e_fwd).to(kcal_per_mol), system.energy(e_bwd).to(kcal_per_mol)) system.setComponent(lam, 0.5) print "LAMBDA=0.5 : Energy = %f kcal mol-1" % system.energy().to( kcal_per_mol) print " (%f, %f)" % (system.energy(e_fwd).to(kcal_per_mol), system.energy(e_bwd).to(kcal_per_mol)) system.setComponent(lam, 1.0) print "LAMBDA=1.0 : Energy = %f kcal mol-1" % system.energy().to( kcal_per_mol) print " (%f, %f)" % (system.energy(e_fwd).to(kcal_per_mol), system.energy(e_bwd).to(kcal_per_mol)) return system
def molecules(self, indices=None, gui=True): """View specific molecules. Parameters ---------- indices : [int], range A list of molecule indices. gui : bool Whether to display the gui. """ # Make sure we're running inside a Jupyter notebook. if not _is_notebook: return None # Return a view of the entire system. if indices is None: return self.system(gui=gui) # Convert single indices to a list. if isinstance(indices, range): indices = list(indices) elif type(indices) is not list: indices = [indices] # Check that the indices is a list of integers. if not all(isinstance(x, int) for x in indices): raise TypeError("'indices' must be a 'list' of type 'int'") # Get the latest system from the process. if self._is_process: system = self._handle.getSystem()._getSireObject() # No system. if system is None: return else: system = self._handle # Extract the molecule numbers. molnums = system.molNums() # Create a new system. s = _SireSystem.System("BioSimSpace System") m = _SireMol.MoleculeGroup("all") # Loop over all of the indices. for index in indices: if index < 0 or index > len(molnums): raise ValueError("Molecule index is out of range!") # Add the molecule. m.add(system[molnums[index]]) # Add all of the molecules to the system. s.add(m) # Create and return the view. return self._create_view(s, gui=gui)
def calculateEnergy(lamval): cljff01 = InterGroupCLJFF("cljff01") cljff02 = InterGroupCLJFF("cljff02") cljff01.add(water0, MGIdx(0)) cljff01.add(water1, MGIdx(1)) cljff02.add(water0, MGIdx(0)) cljff02.add(water2, MGIdx(1)) soft_cljff01 = InterGroupSoftCLJFF("soft_cljff01") soft_cljff02 = InterGroupSoftCLJFF("soft_cljff02") soft_cljff01.add(water0, MGIdx(0)) soft_cljff01.add(water1, MGIdx(1)) soft_cljff02.add(water0, MGIdx(0)) soft_cljff02.add(water2, MGIdx(1)) ref = MoleculeGroup("ref", water0) group_a = MoleculeGroup("group_a", water1) group_b = MoleculeGroup("group_b", water2) dlam = 0.001 lamval_f = lamval + dlam lam = Symbol("lambda") lam_f = Symbol("lambda_f") soft_nrg = (1 - lam) * soft_cljff01.components().total( 0) + lam * soft_cljff02.components().total(0) soft_nrg_f = (1 - lam_f) * soft_cljff01.components().total( 1) + lam_f * soft_cljff02.components().total(1) de_soft = soft_nrg_f - soft_nrg nrg = ((1 - lam) * cljff01.components().total()) + (lam * cljff02.components().total()) nrg_f = ((1 - lam_f) * cljff01.components().total()) + ( lam_f * cljff02.components().total()) de = nrg_f - nrg soft_cljff01.setProperty("alpha0", VariantProperty(lamval)) soft_cljff02.setProperty("alpha0", VariantProperty(1 - lamval)) soft_cljff01.setProperty("alpha1", VariantProperty(lamval_f)) soft_cljff02.setProperty("alpha1", VariantProperty(1 - lamval_f)) soft_cljff01.setProperty("coulombPower", VariantProperty(0)) soft_cljff01.setProperty("shiftDelta", VariantProperty(1.1)) soft_cljff02.setProperty("coulombPower", VariantProperty(0)) soft_cljff02.setProperty("shiftDelta", VariantProperty(1.1)) sys = System() sys.add(cljff01) sys.add(cljff02) sys.add(soft_cljff01) sys.add(soft_cljff02) sys.add(ref) sys.add(group_a) sys.add(group_b) sys.setComponent(lam, lamval) sys.setComponent(lam_f, lamval_f) sys.setComponent(sys.totalComponent(), nrg) sys.setComponent(Symbol("E_{total_f}"), nrg_f) sys.setComponent(Symbol("dE"), de) sys.setComponent(Symbol("E_soft_{total}"), soft_nrg) sys.setComponent(Symbol("E_soft_{total_f}"), soft_nrg_f) sys.setComponent(Symbol("dE_soft"), de_soft) nrgmon = FreeEnergyMonitor(ref, group_a, group_b) soft_nrgmon = FreeEnergyMonitor(ref, group_a, group_b) soft_nrgmon.setCoulombPower(0) soft_nrgmon.setShiftDelta(1.1) sys.add("nrgmon", nrgmon) sys.add("soft_nrgmon", soft_nrgmon) sys.collectStats() nrgmon = sys[MonitorName("nrgmon")] dg = nrgmon.freeEnergies()[0].average() soft_nrgmon = sys[MonitorName("soft_nrgmon")] soft_dg = soft_nrgmon.freeEnergies()[0].average() sys_dg = sys.energy(Symbol("dE")).value() sys_soft_dg = sys.energy(Symbol("dE_soft")).value() assert_almost_equal(dg, sys_dg, 5) assert_almost_equal(soft_dg, sys_soft_dg, 5)
from Sire.System import * from Sire.Vol import * from Sire.Base import * from Sire.FF import * sys = System() from Sire.Maths import * box0 = PeriodicBox(Vector(10.0, 10.0, 10.0)) box1 = PeriodicBox(Vector(20.0, 20.0, 20.0)) print(box0) print(box0.volume()) print(box1.volume()) from Sire.MM import * sys.add(InterCLJFF("cljff")) print(sys) print(sys.property("space")) print(sys.userProperties().propertyKeys()) print(sys.builtinProperties().propertyKeys()) sys.setProperty("space0", LinkToProperty("space", FFIdx(0))) print(sys.property("space0")) sys.setProperty("space0", box0) print(sys.property("space"))
def test_props(verbose=False): sys = System() box0 = PeriodicBox( Vector(10.0,10.0,10.0) ) box1 = PeriodicBox( Vector(20.0,20.0,20.0) ) if verbose: print(box0) print(box0.volume()) print(box1.volume()) assert(not sys.containsProperty("space")) sys.add( InterCLJFF("cljff") ) if verbose: print(sys) print(sys.property("space")) print(sys.userProperties().propertyKeys()) print(sys.builtinProperties().propertyKeys()) assert(sys.containsProperty("space")) assert_equal( sys.property("space"), Cartesian() ) sys.setProperty( "space0", LinkToProperty("space", FFIdx(0)) ) if verbose: print(sys.property("space0")) assert(sys.containsProperty("space0")) sys.setProperty("space0", box0) if verbose: print(sys.property("space")) assert_equal(sys.property("space0"), box0) sys.setProperty("space1", box1) sys.setProperty("combined_space", CombineSpaces("space0", "space1")) assert_equal(sys.property("space1"), box1) if verbose: print(sys.properties().propertyKeys()) print(sys.property("combined_space")) print(sys.property("combined_space").volume()) assert_almost_equal( sys.property("combined_space").volume().value(), sys.property("space0").volume().value() + sys.property("space1").volume().value(), 5 ) space3 = PeriodicBox( Vector(5,5,5) ) sys.setProperty("space0", space3) assert_equal( sys.property("space0"), space3 ) if verbose: print(sys.property("combined_space")) print(sys.property("combined_space").volume()) assert_almost_equal( sys.property("combined_space").volume().value(), sys.property("space0").volume().value() + sys.property("space1").volume().value(), 5 ) sys.removeProperty("space0") if verbose: print(sys.properties().propertyKeys()) assert( not sys.containsProperty("space0") )
def createSystemFrom(molecules, space, system_name, naming_scheme=NamingScheme()): """Create a new System from the passed molecules and space, sorting the molecules into different molecule groups based on the passed naming scheme""" system = System(system_name) # If requested, change the water model for all water molecules if water_model.val == "tip4p": molnums = molecules.molNums() new_molecules = Molecules() print("Forcing all water molecules to use the %s water model..." % water_model.val) print("Converting %d molecules..." % len(molnums)) i = 0 for molnum in molnums: molecule = molecules[molnum].molecule() if i % 100 == 0: print("%d" % i) sys.stdout.flush() elif i % 10 == 0: print(".", end=' ') sys.stdout.flush() i += 1 if molecule.nAtoms() == 3: # this could be a TIP3P water resname = str(molecule.residue().name().value()).lower() if resname == "wat" or resname == "t3p": new_molecule = convertTip3PtoTip4P(molecule) if new_molecule: molecule = new_molecule new_molecules.add(molecule) print("%d" % i) molecules = new_molecules nmols = molecules.nMolecules() print("Number of molecules == %s" % nmols) print("System space == %s" % space) if nmols == 0: return system print("Assigning molecules to molecule groups...") solute_group = MoleculeGroup(naming_scheme.solutesGroupName().value()) protein_group = MoleculeGroup(naming_scheme.proteinsGroupName().value()) solvent_group = MoleculeGroup(naming_scheme.solventsGroupName().value()) water_group = MoleculeGroup(naming_scheme.watersGroupName().value()) ion_group = MoleculeGroup(naming_scheme.ionsGroupName().value()) all_group = MoleculeGroup(naming_scheme.allMoleculesGroupName().value()) # The all molecules group has all of the molecules all_group.add(molecules) system.add(all_group) # Run through each molecule and decide what type it is... molnums = molecules.molNums() molnums.sort() central_molecule = None solutes = [] proteins = [] solvents = [] waters = [] ions = [] for molnum in molnums: molecule = molecules[molnum].molecule() resnams = getResidueNames(molecule) if naming_scheme.isSolute(resnams): solutes.append(molecule) elif naming_scheme.isProtein(resnams): proteins.append(molecule) elif naming_scheme.isWater(resnams): waters.append(molecule) elif naming_scheme.isIon(resnams): ions.append(molecule) elif molecule.nResidues() == 1: solvents.append(molecule) else: solutes.append(molecule) # Ok - we have now divided everything up into groups for solute in solutes: solute_group.add(solute) for protein in proteins: protein_group.add(protein) for water in waters: solvent_group.add(water) water_group.add(water) for solvent in solvents: solvent_group.add(solvent) for ion in ions: solvent_group.add(ion) ion_group.add(ion) if solute_group.nMolecules() > 0: system.add(solute_group) if protein_group.nMolecules() > 0: system.add(protein_group) if solvent_group.nMolecules() > 0: system.add(solvent_group) if water_group.nMolecules() > 0: system.add(water_group) if ion_group.nMolecules() > 0: system.add(ion_group) print("Number of solute molecules == %s" % solute_group.nMolecules()) print("Number of protein molecules == %s" % protein_group.nMolecules()) print("Number of ions == %s" % ion_group.nMolecules()) print("Number of water molecules == %s" % water_group.nMolecules()) print("Number of solvent molecules == %s" % solvent_group.nMolecules()) print( "(solvent group is waters + ions + unidentified single-residue molecules)" ) system.setProperty("space", space) system.add(SpaceWrapper(Vector(0), all_group)) system.applyConstraints() print("Returning the constructed system") return system
def loadQMMMSystem(): """This function is called to set up the system. It sets everything up, then returns a System object that holds the configured system""" print("Loading the system...") t = QTime() if os.path.exists(s3file.val): print("Loading existing s3 file %s..." % s3file.val) loadsys = Sire.Stream.load(s3file.val) else: print("Loading from Amber files %s / %s..." % (topfile.val, crdfile.val)) # Add the name of the ligand to the list of solute molecules sys_scheme = NamingScheme() sys_scheme.addSoluteResidueName(ligand_name.val) # Load up the system. This will automatically find the protein, solute, water, solvent # and ion molecules and assign them to different groups loadsys = createSystem(topfile.val, crdfile.val, sys_scheme) ligand_mol = findMolecule(loadsys, ligand_name.val) if ligand_mol is None: print( "Cannot find the ligand (%s) in the set of loaded molecules!" % ligand_name.val) sys.exit(-1) # Center the system with the ligand at (0,0,0) loadsys = centerSystem(loadsys, ligand_mol) ligand_mol = loadsys[ligand_mol.number()][0].molecule() if reflection_radius.val is None: loadsys = addFlexibility(loadsys, naming_scheme=sys_scheme) else: loadsys = addFlexibility(loadsys, Vector(0), reflection_radius.val, naming_scheme=sys_scheme) Sire.Stream.save(loadsys, s3file.val) ligand_mol = findMolecule(loadsys, ligand_name.val) if ligand_mol is None: print("Cannot find the ligand (%s) in the set of loaded molecules!" % ligand_name.val) sys.exit(-1) # Now build the QM/MM system system = System("QMMM system") if loadsys.containsProperty("reflection center"): reflect_center = loadsys.property("reflection center").toVector()[0] reflect_radius = float( str(loadsys.property("reflection sphere radius"))) system.setProperty("reflection center", AtomCoords(CoordGroup(1, reflect_center))) system.setProperty("reflection sphere radius", VariantProperty(reflect_radius)) space = Cartesian() else: space = loadsys.property("space") if loadsys.containsProperty("average solute translation delta"): system.setProperty("average solute translation delta", \ loadsys.property("average solute translation delta")) if loadsys.containsProperty("average solute rotation delta"): system.setProperty("average solute rotation delta", \ loadsys.property("average solute rotation delta")) # create a molecule group to hold all molecules all_group = MoleculeGroup("all") # create a molecule group for the ligand ligand_group = MoleculeGroup("ligand") ligand_group.add(ligand_mol) all_group.add(ligand_mol) groups = [] groups.append(ligand_group) # pull out the groups that we want from the two systems # create a group to hold all of the fixed molecules in the bound leg fixed_group = MoleculeGroup("fixed_molecules") if MGName("fixed_molecules") in loadsys.mgNames(): fixed_group.add(loadsys[MGName("fixed_molecules")]) if save_pdb.val: # write a PDB of the fixed atoms in the bound and free legs if not os.path.exists(outdir.val): os.makedirs(outdir.val) PDB().write(fixed_group, "%s/fixed.pdb" % outdir.val) # create a group to hold all of the mobile solute molecules mobile_solutes_group = MoleculeGroup("mobile_solutes") if MGName("mobile_solutes") in loadsys.mgNames(): mobile_solutes_group.add(loadsys[MGName("mobile_solutes")]) mobile_solutes_group.remove(ligand_mol) if mobile_solutes_group.nMolecules() > 0: all_group.add(mobile_solutes_group) groups.append(mobile_solutes_group) # create a group to hold all of the mobile solvent molecules mobile_solvents_group = MoleculeGroup("mobile_solvents") if MGName("mobile_solvents") in loadsys.mgNames(): mols = loadsys[MGName("mobile_solvents")] for molnum in mols.molNums(): solvent_mol = mols[molnum][0].molecule() mobile_solvents_group.add(solvent_mol) all_group.add(mobile_solvents_group) print("The number of mobile solvent molecules is %d." % mobile_solvents_group.nMolecules()) groups.append(mobile_solvents_group) # create the groups to hold all of the protein molecules. We will use "extract" to # pull out only those protein atoms that are in the mobile region protein_intra_group = MoleculeGroup("protein_intra_group") mobile_proteins_group = MoleculeGroup("proteins") mobile_protein_sidechains_group = MoleculeGroup("mobile_sidechains") mobile_protein_backbones_group = MoleculeGroup("mobile_backbones") if MGName("protein_sidechains") in loadsys.mgNames() or \ MGName("protein_backbones") in loadsys.mgNames(): all_proteins = Molecules() try: protein_sidechains = loadsys[MGName("protein_sidechains")] all_proteins.add(protein_sidechains.molecules()) except: protein_sidechains = MoleculeGroup() try: protein_backbones = loadsys[MGName("protein_backbones")] all_proteins.add(protein_backbones.molecules()) except: protein_backbones = MoleculeGroup() try: boundary_molecules = loadsys[MGName("boundary_molecules")] all_proteins.add(boundary_molecules.molecules()) except: boundary_molecules = MoleculeGroup() for molnum in all_proteins.molNums(): protein_mol = Molecule.join(all_proteins[molnum]) if protein_mol.selectedAll(): protein_intra_group.add(protein_mol) all_group.add(protein_mol) mobile_protein = [] if protein_sidechains.contains(molnum): sidechains = protein_sidechains[molnum] for sidechain in sidechains: mobile_protein_sidechains_group.add(sidechain) mobile_protein += sidechains if protein_backbones.contains(molnum): backbones = protein_backbones[molnum] for backbone in backbones: mobile_protein_backbones_group.add(backbone) mobile_protein += backbones if len(mobile_protein) > 0: mobile_proteins_group.add(Molecule.join(mobile_protein)) else: # only some of the atoms have been selected. We will extract # the mobile atoms and will then update all of the other selections print("Extracting the mobile atoms of protein %s" % protein_mol.molecule()) new_protein_mol = protein_mol.extract() print("Extracted %d mobile atoms from %d total atoms..." % \ (new_protein_mol.nAtoms(), protein_mol.molecule().nAtoms())) protein_intra_group.add(new_protein_mol) all_group.add(new_protein_mol) mobile_protein_view = new_protein_mol.selection() mobile_protein_view = mobile_protein_view.selectNone() if protein_sidechains.contains(molnum): sidechains = protein_sidechains[molnum] for sidechain in sidechains: view = new_protein_mol.selection() view = view.selectNone() for atomid in sidechain.selection().selectedAtoms(): atom = protein_mol.atom(atomid) resatomid = ResAtomID(atom.residue().number(), atom.name()) view = view.select(resatomid) mobile_protein_view = mobile_protein_view.select( resatomid) if view.nSelected() > 0: mobile_protein_sidechains_group.add( PartialMolecule(new_protein_mol, view)) if protein_backbones.contains(molnum): backbones = protein_backbones[molnum] for backbone in backbones: view = new_protein_mol.selection() view = view.selectNone() for atomid in backbone.selection().selectedAtoms(): atom = protein_mol.atom(atomid) resatomid = ResAtomID(atom.residue().number(), atom.name()) view = view.select(resatomid) mobile_protein_view = mobile_protein_view.select( resatomid) if view.nSelected() > 0: mobile_protein_backbones_group.add( PartialMolecule(new_protein_mol, view)) print("Number of moved protein sidechain residues = %s" % mobile_protein_sidechains_group.nViews()) print("Number of moved protein backbone residues = %s" % mobile_protein_backbones_group.nViews()) if mobile_protein_view.nSelected() > 0: mobile_proteins_group.add( PartialMolecule(new_protein_mol, mobile_protein_view)) groups.append(mobile_protein_backbones_group) groups.append(mobile_protein_sidechains_group) groups.append(all_group) # finished added in all of the proteins for group in groups: if group.nMolecules() > 0: print("Adding group %s" % group.name()) system.add(group) # now add in the forcefields for the system... print("Creating the forcefields for the QM/MM system...") # first, group together the molecules grouped above into convenient # groups for the forcefields # group holding just the ligand ligand_mols = ligand_group.molecules() # group holding all of the mobile atoms mobile_mols = mobile_solvents_group.molecules() mobile_mols.add(mobile_solutes_group.molecules()) mobile_mols.add(protein_intra_group.molecules()) # group holding all of the mobile atoms in the bound leg, excluding the # buffer atoms that are fixed, but bonded to mobile atoms mobile_buffered_mols = mobile_solvents_group.molecules() mobile_buffered_mols.add(mobile_solutes_group.molecules()) mobile_buffered_mols.add(mobile_proteins_group.molecules()) # group holding all of the protein molecules that need intramolecular terms calculated protein_intra_mols = protein_intra_group.molecules() # group holding all of the solute molecules that nede intramolecular terms calculated solute_intra_mols = mobile_solutes_group.molecules() forcefields = [] ### ### INTRA-ENERGY OF THE LIGAND AND CLUSTER ### # intramolecular energy of the ligand ligand_intraclj = IntraCLJFF("ligand:intraclj") ligand_intraclj = setCLJProperties(ligand_intraclj, space) ligand_intraclj.add(ligand_mols) ligand_intraff = InternalFF("ligand:intra") ligand_intraff.add(ligand_mols) forcefields.append(ligand_intraclj) forcefields.append(ligand_intraff) ligand_mm_nrg = ligand_intraclj.components().total( ) + ligand_intraff.components().total() ### ### FORCEFIELDS INVOLVING THE LIGAND/CLUSTER AND OTHER ATOMS ### # forcefield holding the energy between the ligand and the mobile atoms in the # bound leg ligand_mobile = InterGroupCLJFF("system:ligand-mobile") ligand_mobile = setCLJProperties(ligand_mobile, space) ligand_mobile.add(ligand_mols, MGIdx(0)) ligand_mobile.add(mobile_mols, MGIdx(1)) qm_ligand = QMMMFF("system:ligand-QM") qm_ligand.add(ligand_mols, MGIdx(0)) qm_ligand = setQMProperties(qm_ligand, space) zero_energy = 0 if not intermolecular_only.val: if qm_zero_energy.val is None: # calculate the delta value for the system - this is the difference between # the MM and QM intramolecular energy of the ligand t.start() print("\nComparing the MM and QM energies of the ligand...") mm_intra = ligand_intraclj.energy().value( ) + ligand_intraff.energy().value() print("MM energy = %s kcal mol-1 (took %s ms)" % (mm_intra, t.elapsed())) t.start() zero_sys = System() zero_sys.add(qm_ligand) qm_intra = zero_sys.energy().value() print("QM energy = %s kcal mol-1 (took %s ms)" % (qm_intra, t.elapsed())) print("\nSetting the QM zero energy to %s kcal mol-1" % (qm_intra - mm_intra)) qm_ligand.setZeroEnergy((qm_intra - mm_intra) * kcal_per_mol) zero_energy = qm_intra - mm_intra else: print("\nManually setting the QM zero energy to %s" % qm_zero_energy.val) qm_ligand.setZeroEnergy(qm_zero_energy.val) zero_energy = qm_zero_energy.val qm_ligand.add(mobile_mols, MGIdx(1)) ligand_mm_nrg += ligand_mobile.components().total() ligand_qm_nrg = qm_ligand.components().total() + ligand_mobile.components( ).lj() if intermolecular_only.val: # the QM model still uses the MM intramolecular energy of the ligand ligand_qm_nrg += ligand_intraclj.components().total( ) + ligand_intraff.components().total() forcefields.append(ligand_mobile) forcefields.append(qm_ligand) if fixed_group.nMolecules() > 0: # there are fixed molecules # Whether or not to disable the grid and calculate all energies atomisticly if disable_grid: # we need to renumber all of the fixed molecules so that they don't clash # with the mobile molecules print("Renumbering fixed molecules...") fixed_group = renumberMolecules(fixed_group) # forcefield holding the energy between the ligand and the fixed atoms in the bound leg if disable_grid: ligand_fixed = InterGroupCLJFF("system:ligand-fixed") ligand_fixed = setCLJProperties(ligand_fixed, space) ligand_fixed = setFakeGridProperties(ligand_fixed, space) ligand_fixed.add(ligand_mols, MGIdx(0)) ligand_fixed.add(fixed_group, MGIdx(1)) qm_ligand.add(fixed_group, MGIdx(1)) ligand_mm_nrg += ligand_fixed.components().total() ligand_qm_nrg += ligand_fixed.components().lj() forcefields.append(ligand_fixed) else: ligand_fixed = GridFF2("system:ligand-fixed") ligand_fixed = setCLJProperties(ligand_fixed, space) ligand_fixed = setGridProperties(ligand_fixed) ligand_fixed.add(ligand_mols, MGIdx(0)) ligand_fixed.addFixedAtoms(fixed_group) qm_ligand.addFixedAtoms(fixed_group) ligand_mm_nrg += ligand_fixed.components().total() ligand_qm_nrg += ligand_fixed.components().lj() forcefields.append(ligand_fixed) ### ### FORCEFIELDS NOT INVOLVING THE LIGAND ### # forcefield holding the intermolecular energy between all molecules mobile_mobile = InterCLJFF("mobile-mobile") mobile_mobile = setCLJProperties(mobile_mobile, space) mobile_mobile.add(mobile_mols) other_nrg = mobile_mobile.components().total() forcefields.append(mobile_mobile) # forcefield holding the energy between the mobile atoms and # the fixed atoms if disable_grid.val: mobile_fixed = InterGroupCLJFF("mobile-fixed") mobile_fixed = setCLJProperties(mobile_fixed) mobile_fixed = setFakeGridProperties(mobile_fixed, space) mobile_fixed.add(mobile_buffered_mols, MGIdx(0)) mobile_fixed.add(fixed_group, MGIdx(1)) other_nrg += mobile_fixed.components().total() forcefields.append(mobile_fixed) else: mobile_fixed = GridFF2("mobile-fixed") mobile_fixed = setCLJProperties(mobile_fixed, space) mobile_fixed = setGridProperties(mobile_fixed) # we use mobile_buffered_group as this group misses out atoms that are bonded # to fixed atoms (thus preventing large energies caused by incorrect non-bonded calculations) mobile_fixed.add(mobile_buffered_mols, MGIdx(0)) mobile_fixed.addFixedAtoms(fixed_group) other_nrg += mobile_fixed.components().total() forcefields.append(mobile_fixed) # intramolecular energy of the protein if protein_intra_mols.nMolecules() > 0: protein_intraclj = IntraCLJFF("protein_intraclj") protein_intraclj = setCLJProperties(protein_intraclj, space) protein_intraff = InternalFF("protein_intra") for molnum in protein_intra_mols.molNums(): protein_mol = Molecule.join(protein_intra_mols[molnum]) protein_intraclj.add(protein_mol) protein_intraff.add(protein_mol) other_nrg += protein_intraclj.components().total() other_nrg += protein_intraff.components().total() forcefields.append(protein_intraclj) forcefields.append(protein_intraff) # intramolecular energy of any other solutes if solute_intra_mols.nMolecules() > 0: solute_intraclj = IntraCLJFF("solute_intraclj") solute_intraclj = setCLJProperties(solute_intraclj, space) solute_intraff = InternalFF("solute_intra") for molnum in solute_intra_mols.molNums(): solute_mol = Molecule.join(solute_intra_mols[molnum]) solute_intraclj.add(solute_mol) solute_intraff.add(solute_mol) other_nrg += solute_intraclj.components().total() other_nrg += solute_intraff.components().total() forcefields.append(solute_intraclj) forcefields.append(solute_intraff) ### ### NOW ADD THE FORCEFIELDS TO THE SYSTEM ### ### ### SETTING THE FORCEFIELD EXPRESSIONS ### lam = Symbol("lambda") e_slow = ((1 - lam) * ligand_qm_nrg) + (lam * ligand_mm_nrg) + other_nrg e_fast = ligand_mm_nrg + other_nrg de_by_dlam = ligand_mm_nrg - ligand_qm_nrg for forcefield in forcefields: system.add(forcefield) system.setConstant(lam, 0.0) system.setComponent(Symbol("E_{fast}"), e_fast) system.setComponent(Symbol("E_{slow}"), e_slow) system.setComponent(Symbol("dE/dlam"), de_by_dlam) system.setComponent(system.totalComponent(), e_slow) system.setProperty("space", space) if space.isPeriodic(): # ensure that all molecules are wrapped into the space with the ligand at the center print("Adding in a space wrapper constraint %s, %s" % (space, ligand_mol.evaluate().center())) system.add(SpaceWrapper(ligand_mol.evaluate().center(), all_group)) system.applyConstraints() print("\nHere are the values of all of the initial energy components...") t.start() printEnergies(system.energies()) print("(these took %d ms to evaluate)\n" % t.elapsed()) # Create a monitor to monitor the free energy average system.add("dG/dlam", MonitorComponent(Symbol("dE/dlam"), AverageAndStddev())) if intermolecular_only.val: print( "\n\n## This simulation uses QM to model *only* the intermolecular energy between" ) print( "## the QM and MM atoms. The intramolecular energy of the QM atoms is still" ) print("## modelled using MM.\n") else: print( "\n\n## This simulation uses QM to model both the intermolecular and intramolecular" ) print( "## energies of the QM atoms. Because the this, we have to adjust the 'zero' point" ) print( "## of the QM potential. You need to add the value %s kcal mol-1 back onto the" % zero_energy) print("## QM->MM free energy calculated using this program.\n") return system
def saveMolecules(filebase, system, fileformat, property_map={}): """Save a molecular system to file. Parameters ---------- filebase : str The base name of the output file. system : :class:`System <BioSimSpace._SireWrappers.System>`, \ :class:`Molecule< BioSimSpace._SireWrappers.Molecule>` [ BioSimSpace._SireWrappers.Molecule ] The molecular system. fileformat : str, [str] The file format (or formats) to save to. property_map : dict A dictionary that maps system "properties" to their user defined values. This allows the user to refer to properties with their own naming scheme, e.g. { "charge" : "my-charge" } Returns ------- files : [str] The list of files that were generated. Examples -------- Load a molecular system from AMBER coordinate and topology files then try to save it to all supported file formats. >>> import BioSimSpace as BSS >>> system = BSS.IO.readMolecules(["ala.rst7", "ala.prm7"]) >>> for format in BSS.IO.fileFormats(): ... try: ... BSS.IO.saveMolecules("test", system, format) ... except: ... print("Could not convert to format: '%s'" % format) Load a molecular system from AMBER coordinate and topology files then try to save it to GROMACS format, mapping and un-mapping the charge property along the way. >>> import BioSimSpace as BSS >>> system = BSS.IO.readMolecules(["ala.rst7", "ala.prm7"], property_map={"charge" : "my-charge"}) >>> BSS.IO.saveMolecules("test", system, ["gro87", "grotop"], property_map={"charge" : "my-charge"}) """ global _has_gmx_warned if _gromacs_path is None and not _has_gmx_warned: _warn( "BioSimSpace.IO: Please install GROMACS (http://www.gromacs.org) " "for GROMACS topology file support.") _has_gmx_warned = True # Check that the filebase is a string. if type(filebase) is not str: raise TypeError("'filebase' must be of type 'str'") # Check that that the system is of the correct type. # A System object. if type(system) is _System: pass # A Molecule object. elif type(system) is _Molecule: system = [system] # A list of Molecule objects. elif type(system) is list and all( isinstance(x, _Molecule) for x in system): pass # Invalid type. else: raise TypeError( "'system' must be of type 'BioSimSpace.SireWrappers.System', " "'BioSimSpace._SireWrappers.Molecule, or a list of " "'BiSimSpace._SireWrappers.Molecule' types.") # Check that fileformat argument is of the correct type. # Convert to a list if a single string is passed. # We split on ',' since the user might pass system.fileFormats() as the argument. if type(fileformat) is str: fileformat = fileformat.split(",") # Lists and tuples are okay! elif type(fileformat) is list: pass elif type(fileformat) is tuple: pass # Invalid. else: raise TypeError( "'fileformat' must be a 'str' or a 'list' of 'str' types.") # Make sure all items in list or tuple are strings. if not all(isinstance(x, str) for x in fileformat): raise TypeError( "'fileformat' must be a 'str' or a 'list' of 'str' types.") # Make a list of the matched file formats. formats = [] # Make sure that all of the formats are valid. for format in fileformat: try: f = _formats_dict[format.replace(" ", "").upper()][0] formats.append(f) except KeyError: raise ValueError("Unsupported file format '%s'. Supported formats " "are: %s." % (format, str(_formats))) # Validate the map. if type(property_map) is not dict: raise TypeError("'property_map' must be of type 'dict'") # Copy the map. _property_map = property_map.copy() # Add the GROMACS topology file path. if _gromacs_path is not None and ("GROMACS_PATH" not in _property_map): _property_map["GROMACS_PATH"] = _gromacs_path # We have a list of molecules. Create a new system and add each molecule. if type(system) is list: # Create a Sire system and molecule group. s = _SireSystem.System("BioSimSpace System") m = _SireMol.MoleculeGroup("all") # Add all of the molecules to the group. for molecule in system: m.add(molecule._getSireMolecule()) # Add the molecule group to the system. s.add(m) # Wrap the system. system = _System(s) # Get the directory name. dirname = _os.path.dirname(filebase) # If the user has passed a directory, make sure that is exists. if _os.path.basename(filebase) != filebase: # Create the directory if it doesn't already exist. if not _os.path.isdir(dirname): _os.makedirs(dirname, exist_ok=True) # Store the current working directory. dir = _os.getcwd() # Change to the working directory for the process. # This avoid problems with relative paths. if dirname != "": _os.chdir(dirname) # A list of the files that have been written. files = [] # Save the system using each file format. for format in formats: # Add the file format to the property map. _property_map["fileformat"] = _SireBase.wrap(format) # Write the file. try: file = _SireIO.MoleculeParser.save(system._getSireSystem(), filebase, _property_map) files += file except: if dirname != "": _os.chdir(dir) raise IOError("Failed to save system to format: '%s'" % format) from None # Change back to the original directory. if dirname != "": _os.chdir(dir) # Return the list of files. return files
def test_grid_sim(verbose=False): oldsys = System() newsys = System() oldsys.add(cluster) oldsys.add(old_clusterff) oldsys.add(old_fixedff) newsys.add(cluster) newsys.add(new_clusterff) t = QElapsedTimer() t.start() old_total = oldsys.energy().value() oldns = t.nsecsElapsed() t.start() new_total = newsys.energy().value() newns = t.nsecsElapsed() ff = newsys[FFName("new_clusterff")] print(ff.grid()) old_cnrg = oldsys.energy( old_clusterff.components().coulomb() ).value() + \ oldsys.energy( old_fixedff.components().coulomb() ).value() old_ljnrg = oldsys.energy( old_clusterff.components().lj() ).value() + \ oldsys.energy( old_fixedff.components().lj() ).value() new_cnrg = newsys.energy(new_clusterff.components().coulomb()).value() new_ljnrg = newsys.energy(new_clusterff.components().lj()).value() if verbose: print("OLD: %s %s %s %s : %s ms" % (old_total, old_cnrg + old_ljnrg, old_cnrg, old_ljnrg, 0.000001 * oldns)) print("NEW: %s %s %s %s : %s ms" % (new_total, new_cnrg + new_ljnrg, new_cnrg, new_ljnrg, 0.000001 * newns)) moves = RigidBodyMC(cluster) moves.setReflectionSphere(reflect_sphere_center, reflect_sphere_radius) moves.setGenerator(RanGenerator(42)) t.start() moves.move(oldsys, 1000, False) move_oldns = t.nsecsElapsed() moves.setGenerator(RanGenerator(42)) t.start() moves.move(newsys, 1000, False) move_newns = t.nsecsElapsed() t.start() old_total = oldsys.energy().value() old_ns = t.nsecsElapsed() t.start() new_total = newsys.energy().value() new_ns = t.nsecsElapsed() old_cnrg = oldsys.energy( old_clusterff.components().coulomb() ).value() + \ oldsys.energy( old_fixedff.components().coulomb() ).value() old_ljnrg = oldsys.energy( old_clusterff.components().lj() ).value() + \ oldsys.energy( old_fixedff.components().lj() ).value() new_cnrg = newsys.energy(new_clusterff.components().coulomb()).value() new_ljnrg = newsys.energy(new_clusterff.components().lj()).value() if verbose: print("\nMoves: %s ms vs. %s ms" % (0.000001 * move_oldns, 0.000001 * move_newns)) print("OLD SYS: %s %s %s %s : %s ms" % (old_total, old_cnrg + old_ljnrg, old_cnrg, old_ljnrg, 0.000001 * old_ns)) print("NEW SYS: %s %s %s %s : %s ms" % (new_total, new_cnrg + new_ljnrg, new_cnrg, new_ljnrg, 0.000001 * new_ns)) newsys.mustNowRecalculateFromScratch() oldsys.mustNowRecalculateFromScratch() t.start() old_total = oldsys.energy().value() old_ns = t.nsecsElapsed() t.start() new_total = newsys.energy().value() new_ns = t.nsecsElapsed() old_cnrg = oldsys.energy( old_clusterff.components().coulomb() ).value() + \ oldsys.energy( old_fixedff.components().coulomb() ).value() old_ljnrg = oldsys.energy( old_clusterff.components().lj() ).value() + \ oldsys.energy( old_fixedff.components().lj() ).value() new_cnrg = newsys.energy(new_clusterff.components().coulomb()).value() new_ljnrg = newsys.energy(new_clusterff.components().lj()).value() if verbose: print("\nRecalculate energy") print("OLD SYS: %s %s %s %s : %s ms" % (old_total, old_cnrg + old_ljnrg, old_cnrg, old_ljnrg, 0.000001 * old_ns)) print("NEW SYS: %s %s %s %s : %s ms" % (new_total, new_cnrg + new_ljnrg, new_cnrg, new_ljnrg, 0.000001 * new_ns))
def test_sim(verbose=False): oldsys = System() newsys = System() #oldsys.add(mols) #newsys.add(mols) oldsys.add(oldff) newsys.add(newff) t = QElapsedTimer() oldsys.mustNowRecalculateFromScratch() newsys.mustNowRecalculateFromScratch() t.start() nrgs = oldsys.energies() oldns = t.nsecsElapsed() t.start() nrgs = newsys.energies() newns = t.nsecsElapsed() oldcnrg = oldsys.energy(oldff.components().coulomb()).value() oldljnrg = oldsys.energy(oldff.components().lj()).value() newcnrg = newsys.energy(newff.components().coulomb()).value() newljnrg = newsys.energy(newff.components().lj()).value() if verbose: print("\nStarting energy") print("OLD SYS: %s %s %s : %s ms" % (oldcnrg + oldljnrg, oldcnrg, oldljnrg, 0.000001 * oldns)) print("NEW SYS: %s %s %s : %s ms" % (newcnrg + newljnrg, newcnrg, newljnrg, 0.000001 * newns)) moves = RigidBodyMC(mols) moves.setGenerator(RanGenerator(42)) t.start() moves.move(oldsys, nmoves, False) move_oldns = t.nsecsElapsed() old_naccepted = moves.nAccepted() old_nrejected = moves.nRejected() moves.setGenerator(RanGenerator(42)) moves.clearStatistics() t.start() moves.move(newsys, nmoves, False) move_newns = t.nsecsElapsed() new_naccepted = moves.nAccepted() new_nrejected = moves.nRejected() t.start() nrgs = oldsys.energies() oldns = t.nsecsElapsed() t.start() nrgs = newsys.energies() newns = t.nsecsElapsed() oldcnrg = oldsys.energy(oldff.components().coulomb()).value() oldljnrg = oldsys.energy(oldff.components().lj()).value() newcnrg = newsys.energy(newff.components().coulomb()).value() newljnrg = newsys.energy(newff.components().lj()).value() if verbose: print("\nMoves: %s ms vs. %s ms" % (0.000001 * move_oldns, 0.000001 * move_newns)) print("OLD SYS: %s %s %s : %s ms" % (oldcnrg + oldljnrg, oldcnrg, oldljnrg, 0.000001 * oldns)) print("nAccepted() = %s, nRejected() = %s" % (old_naccepted, old_nrejected)) print("NEW SYS: %s %s %s : %s ms" % (newcnrg + newljnrg, newcnrg, newljnrg, 0.000001 * newns)) print("nAccepted() = %s, nRejected() = %s" % (new_naccepted, new_nrejected)) oldsys.mustNowRecalculateFromScratch() newsys.mustNowRecalculateFromScratch() t.start() nrgs = oldsys.energies() oldns = t.nsecsElapsed() t.start() nrgs = newsys.energies() newns = t.nsecsElapsed() r_oldcnrg = oldsys.energy(oldff.components().coulomb()).value() r_oldljnrg = oldsys.energy(oldff.components().lj()).value() r_newcnrg = newsys.energy(newff.components().coulomb()).value() r_newljnrg = newsys.energy(newff.components().lj()).value() if verbose: print("\nRecalculated energy") print( "OLD SYS: %s %s %s : %s ms" % (r_oldcnrg + r_oldljnrg, r_oldcnrg, r_oldljnrg, 0.000001 * oldns)) print( "NEW SYS: %s %s %s : %s ms" % (r_newcnrg + r_newljnrg, r_newcnrg, r_newljnrg, 0.000001 * newns))
.setProperty("charge", 0*mod_electron) \ .setProperty("LJ", LJParameter.dummy()) \ .setProperty("element", Element(0)) \ .molecule().atom(AtomName("H2")) \ .setProperty("PDB-atom-name", "Xx") \ .setProperty("charge", 0*mod_electron) \ .setProperty("LJ", LJParameter.dummy()) \ .setProperty("element", Element(0)) \ .molecule().commit() titrator = Titrator() titrator.setPositiveTemplate(sodium) titrator.setNegativeTemplate(chloride) titrator.setNeutralTemplate(water) system = System() cljff = InterCLJFF("cljff") cljff.add(molecules) solvent = MoleculeGroup("solvent") solvent.add(molecules) titrator.setMoleculeGroup(solvent) system.add(cljff) system.add(solvent) system.setProperty("space", space) print("Initialising the ions...") titrator.applyTo(system)
def test_system(verbose=False): cljff = InterCLJFF() mincoords = Vector(-18.3854, -18.66855, -18.4445) maxcoords = Vector(18.3854, 18.66855, 18.4445) vol = PeriodicBox(mincoords, maxcoords) cljff.setSpace(vol) mols = PDB().read("../io/water.pdb") if verbose: print("Read in %d molecules!" % mols.nMolecules()) i = 0 mol = mols.moleculeAt(0).molecule() mol = mol.edit().atom( AtomName("O00") ) \ .setProperty("LJ", LJParameter(3.15363*angstrom, \ 0.1550*kcal_per_mol)).molecule() \ .atom( AtomName("H01") ) \ .setProperty("charge", 0.520 * mod_electron).molecule() \ .atom( AtomName("H02") ) \ .setProperty("charge", 0.520 * mod_electron).molecule() \ .atom( AtomName("M03") ) \ .setProperty("charge", -1.04 * mod_electron).molecule() \ .commit() charges = mol.property("charge") ljs = mol.property("LJ") cljff.add(mol) for i in range(1, mols.nMolecules()): mol = mols.moleculeAt(i).molecule() mol = mol.edit().setProperty("charge", charges) \ .setProperty("LJ", ljs) \ .commit() cljff.add(mol) system = System() system.add(cljff) nrg = system.energy() if verbose: print("System energy = %s" % (nrg)) copy_system = System(system) nrg2 = copy_system.energy() if verbose: print("Copy energy: %s (should be %s)" % (nrg2, nrg)) assert_almost_equal(nrg.value(), nrg2.value(), 5) copy_system.mustNowRecalculateFromScratch() nrg3 = copy_system.energy() if verbose: print("Copy energy: %s (should be %s)" % (nrg2, nrg)) assert_almost_equal(nrg.value(), nrg3.value(), 5)
def readXmlParameters(pdbfile, xmlfile): # 1) Read a pdb file describing the system to simulate p = PDB2(pdbfile) s = p.toSystem() molecules = s.molecules() #print (molecules) with open(pdbfile, "r") as f: for line in f: if line.split()[0] == "CRYST1": print(line) pbc_x = float(line.split()[1]) pbc_y = float(line.split()[2]) pbc_z = float(line.split()[3]) space = PeriodicBox(Vector(pbc_x, pbc_y, pbc_z)) break else: space = Cartesian() #print("space:", space) system = System() # 2) Now we read the xml file, and store parameters for each molecule import xml.dom.minidom as minidom xmldoc = minidom.parse(xmlfile) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: TYPE ~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_type = xmldoc.getElementsByTagName('Type') dicts_type = [] for items in itemlist_type: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_type.append(d) dicts_tp = str(dicts_type).split() #print (dicts_tp) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: ATOM ~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_atom = xmldoc.getElementsByTagName('Atom') dicts_atom = [] for items in itemlist_atom: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_atom.append(d) dicts_at = str(dicts_atom).split() #print (dicts_at) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: BOND ~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_bond = xmldoc.getElementsByTagName('Bond') dicts_bond = [] for items in itemlist_bond: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_bond.append(d) dicts_b = str(dicts_bond).split() #print (dicts_b) nbond = itemlist_bond.length #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: ANGLE ~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_angle = xmldoc.getElementsByTagName('Angle') dicts_angle = [] for items in itemlist_angle: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_angle.append(d) dicts_ang = str(dicts_angle).split() #print (dicts_angle) nAngles = itemlist_angle.length #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: PROPER ~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_proper = xmldoc.getElementsByTagName('Proper') dicts_proper = [] for items in itemlist_proper: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_proper.append(d) dicts_pr = str(dicts_proper).split() #print (dicts_pr) nProper = itemlist_proper.length #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: IMPROPER ~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_improper = xmldoc.getElementsByTagName('Improper') dicts_improper = [] for items in itemlist_improper: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_improper.append(d) dicts_impr = str(dicts_improper).split() #print (dicts_impr) nImproper = itemlist_improper.length #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: VIRTUAL SITES ~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_VirtualSite = xmldoc.getElementsByTagName('VirtualSite') dicts_virtualsite = [] for items in itemlist_VirtualSite: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_virtualsite.append(d) #dicts_vs = str(dicts_virtualsite).split() #print (dicts_vs) nVirtualSites = itemlist_VirtualSite.length v_site_CLJ = [] for i in range(0, int(len(dicts_atom))): if dicts_atom[i]['type'][0] == 'v': v_site_CLJ = dicts_atom[i] dicts_virtualsite.append(v_site_CLJ) for i in range(0, len(itemlist_VirtualSite)): dicts_virtualsite[i].update( dicts_virtualsite[i + len(itemlist_VirtualSite)]) dicts_virtualsite[i].update( dicts_virtualsite[i + 2 * len(itemlist_VirtualSite)]) dict_vs = [] for i in range(0, len(itemlist_VirtualSite)): dicts_virtualsite[i] dict_vs.append(dicts_virtualsite[i]) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~ TAG NAME: RESIDUE ~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_residue = xmldoc.getElementsByTagName('Residue') dicts_residue = [] for items in itemlist_residue: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_residue.append(d) dicts_res = str(dicts_residue).split() #print (dicts_res) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~ TAG NAME: NON BONDED FORCE ~~~~~~~~~~~~~~~~ #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ itemlist_nonbond = xmldoc.getElementsByTagName('NonbondedForce') dicts_nonb = [] for items in itemlist_nonbond: d = {} for a in items.attributes.values(): d[a.name] = a.value dicts_nonb.append(d) dicts_nb = str(dicts_nonb).split() #print (dicts_nb) nNonBonded = itemlist_nonbond.length # 3) Now we create an Amberparameters object for each molecule molnums = molecules.molNums() newmolecules = Molecules() for molnum in molnums: mol = molecules.at(molnum) #print (mol) # Add potential virtual site parameters if len(dicts_virtualsite) > 0: mol = mol.edit().setProperty( "virtual-sites", vsiteListToProperty(dict_vs)).commit() # We populate the Amberparameters object with a list of bond, angle, dihedrals # We look up parameters from the contents of the xml file # We also have to set the atomic parameters (q, sigma, epsilon) editmol = mol.edit() mol_params = AmberParameters(editmol) #SireMol::AmberParameters() atoms = editmol.atoms() # We update atom parameters see setAtomParameters in SireIO/amber.cpp l2122 natoms = editmol.nAtoms() #print("number of atoms is %s" %natoms) #natoms don't include the virtual sites! # Loop over each molecule in the molecules object opls = [] for i in range(0, int(len(dicts_atom) / 2)): opl = {} opl = dicts_atom[i]['type'] opls.append(opl) name = [] for i in range(0, int(len(dicts_atom) / 2)): nm = {} nm = dicts_atom[i]['name'] name.append(nm) two = [] #print(len(name)) for i in range(0, len(name)): t = (opls[i], name[i]) two.append(t) import numpy as np atom_sorted = [] for j in range(0, len(two)): for i in range(int(len(dicts_atom) / 2), len(dicts_atom)): if dicts_atom[i]['type'] == two[j][0]: dic_a = {} dic_a = dicts_atom[i] atom_sorted.append(dic_a) type_sorted = [] for j in range(0, len(two)): for i in range(0, int(len(dicts_type))): if dicts_type[i]['name'] == two[j][0]: dic_t = {} dic_t = dicts_type[i] type_sorted.append(dic_t) print(" ") print("There are ", natoms, " atoms in this molecule. ") print("*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*") for atom in atoms: editatom = editmol.atom(atom.index()) i = int(str(atom.number()).split('(')[1].replace(")", " ")) editatom.setProperty( "charge", float(atom_sorted[i - 1]['charge']) * mod_electron) editatom.setProperty("mass", float(type_sorted[i - 1]['mass']) * g_per_mol) editatom.setProperty( "LJ", LJParameter( float(atom_sorted[i - 1]['sigma']) * 10 * angstrom, float(atom_sorted[i - 1]['epsilon']) / 4.184 * kcal_per_mol)) editatom.setProperty("ambertype", dicts_atom[i - 1]['type']) editmol = editatom.molecule() # Now we create a connectivity see setConnectivity in SireIO/amber.cpp l2144 # XML data tells us how atoms are bonded in the molecule (Bond 'from' and 'to') if natoms > 1: print("Set up connectivity") con = [] for i in range(0, int(nbond / 2)): if natoms > 1: connect_prop = {} connect_prop = dicts_bond[i]['from'], dicts_bond[i]['to'] con.append(connect_prop) conn = Connectivity(editmol.info()).edit() for j in range(0, len(con)): conn.connect(atoms[int(con[j][0])].index(), atoms[int(con[j][1])].index()) editmol.setProperty("connectivity", conn.commit()).commit() mol = editmol.setProperty("connectivity", conn.commit()).commit() system.update(mol) # Now we add bond parameters to the Sire molecule. We also update amberparameters see SireIO/amber.cpp l2154 internalff = InternalFF() bondfuncs = TwoAtomFunctions(mol) r = internalff.symbols().bond().r() for j in range(0, len(con)): bondfuncs.set( atoms[int(con[j][0])].index(), atoms[int(con[j][1])].index(), float(dicts_bond[j + len(con)]['k']) / (2 * 100 * 4.184) * (float(dicts_bond[j + len(con)]['length']) * 10 - r)**2) bond_id = BondID(atoms[int(con[j][0])].index(), atoms[int(con[j][1])].index()) mol_params.add( bond_id, float(dicts_bond[j + len(con)]['k']) / (2 * 100 * 4.184), float(dicts_bond[j + len(con)]['length']) * 10) editmol.setProperty("bonds", bondfuncs).commit() molecule = editmol.commit() mol_params.getAllBonds() editmol.setProperty( "amberparameters", mol_params).commit() # Weird, should work - investigate ? molecule = editmol.commit() # Now we add angle parameters to the Sire molecule. We also update amberparameters see SireIO/amber.cpp L2172 if natoms > 2: print("Set up angles") anglefuncs = ThreeAtomFunctions(mol) at1 = [] for i in range(0, nAngles): a1 = {} to_str1 = str(re.findall(r"\d+", str(dicts_angle[i]['class1']))) if dicts_atom[i]['type'][0] == 'o': #if opls_ a1 = int( to_str1.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: #if QUBE_ a1 = int( to_str1.replace("[", "").replace("]", "").replace("'", "")) at1.append(a1) at2 = [] for i in range(0, nAngles): a2 = {} to_str2 = str(re.findall(r"\d+", str(dicts_angle[i]['class2']))) if dicts_atom[i]['type'][0] == 'o': #if opls_ a2 = int( to_str2.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: #if QUBE_ a2 = int( to_str2.replace("[", "").replace("]", "").replace("'", "")) at2.append(a2) at3 = [] for i in range(0, nAngles): a3 = {} to_str3 = str(re.findall(r"\d+", str(dicts_angle[i]['class3']))) if dicts_atom[i]['type'][0] == 'o': #if opls_ a3 = int( to_str3.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: #if QUBE_ a3 = int( to_str3.replace("[", "").replace("]", "").replace("'", "")) at3.append(a3) theta = internalff.symbols().angle().theta() for j in range(0, nAngles): anglefuncs.set( atoms[at1[j]].index(), atoms[at2[j]].index(), atoms[at3[j]].index(), float(dicts_angle[j]['k']) / (2 * 4.184) * ((float(dicts_angle[j]['angle']) - theta)**2)) angle_id = AngleID(atoms[int(at1[j])].index(), atoms[int(at2[j])].index(), atoms[int(at3[j])].index()) mol_params.add(angle_id, float(dicts_angle[j]['k']) / (2 * 4.184), float(dicts_angle[j]['angle'])) # Now we add dihedral parameters to the Sire molecule. We also update amberparameters see SireIO/amber.cpp L2190 if natoms > 3: print("Set up dihedrals") di1 = [] for i in range(0, nProper): d1 = {} to_str1 = str( re.findall(r"\d+", str(dicts_proper[i]['class1']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d1 = int( to_str1.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: #if QUBE_ d1 = int( to_str1.replace("[", "").replace("]", "").replace("'", "")) di1.append(d1) di2 = [] for i in range(0, nProper): d2 = {} to_str2 = str( re.findall(r"\d+", str(dicts_proper[i]['class2']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d2 = int( to_str2.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: #if QUBE_ d2 = int( to_str2.replace("[", "").replace("]", "").replace("'", "")) di2.append(d2) di3 = [] for i in range(0, nProper): d3 = {} to_str3 = str( re.findall(r"\d+", str(dicts_proper[i]['class3']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d3 = int( to_str3.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: #if QUBE_ d3 = int( to_str3.replace("[", "").replace("]", "").replace("'", "")) di3.append(d3) di4 = [] for i in range(0, nProper): d4 = {} to_str4 = str( re.findall(r"\d+", str(dicts_proper[i]['class4']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d4 = int( to_str4.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: #if QUBE_ d4 = int( to_str4.replace("[", "").replace("]", "").replace("'", "")) di4.append(d4) dihedralfuncs = FourAtomFunctions(mol) phi = internalff.symbols().dihedral().phi() for i in range(0, nProper): if atoms[int(di1[i])].index() != atoms[int(di4[i])].index(): dihedral_id = DihedralID(atoms[int(di1[i])].index(), atoms[int(di2[i])].index(), atoms[int(di3[i])].index(), atoms[int(di4[i])].index()) dih1 = float(dicts_proper[i]['k1']) / 4.184 * (1 + Cos( int(dicts_proper[i]['periodicity1']) * phi - float(dicts_proper[i]['phase1']))) dih2 = float(dicts_proper[i]['k2']) / 4.184 * (1 + Cos( int(dicts_proper[i]['periodicity2']) * phi - float(dicts_proper[i]['phase2']))) dih3 = float(dicts_proper[i]['k3']) / 4.184 * (1 + Cos( int(dicts_proper[i]['periodicity3']) * phi - float(dicts_proper[i]['phase3']))) dih4 = float(dicts_proper[i]['k4']) / 4.184 * (1 + Cos( int(dicts_proper[i]['periodicity4']) * phi - float(dicts_proper[i]['phase4']))) dih_fun = dih1 + dih2 + dih3 + dih4 dihedralfuncs.set(dihedral_id, dih_fun) for t in range(1, 5): mol_params.add( dihedral_id, float(dicts_proper[i]['k%s' % t]) / 4.184, int(dicts_proper[i]['periodicity%s' % t]), float(dicts_proper[i]['phase%s' % t])) print("Set up impropers") di_im1 = [] for i in range(0, nImproper): d1 = {} to_str1 = str( re.findall(r"\d+", str(dicts_improper[i]['class1']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d1 = int( to_str1.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: d1 = int( to_str1.replace("[", "").replace("]", "").replace("'", "")) di_im1.append(d1) di_im2 = [] for i in range(0, nImproper): d2 = {} to_str2 = str( re.findall(r"\d+", str(dicts_improper[i]['class2']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d2 = int( to_str2.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: d2 = int( to_str2.replace("[", "").replace("]", "").replace("'", "")) di_im2.append(d2) di_im3 = [] for i in range(0, nImproper): d3 = {} to_str3 = str( re.findall(r"\d+", str(dicts_improper[i]['class3']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d3 = int( to_str3.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: d3 = int( to_str3.replace("[", "").replace("]", "").replace("'", "")) di_im3.append(d3) di_im4 = [] for i in range(0, nImproper): d4 = {} to_str4 = str( re.findall(r"\d+", str(dicts_improper[i]['class4']))) if dicts_atom[0]['type'][0] == 'o': #if opls_ d4 = int( to_str4.replace("[", "").replace("]", "").replace( "'", "")) - 800 else: d4 = int( to_str4.replace("[", "").replace("]", "").replace("'", "")) di_im4.append(d4) improperfuncs = FourAtomFunctions(mol) phi_im = internalff.symbols().improper().phi() for i in range(0, nImproper): improper_id = ImproperID(atoms[int(di_im2[i])].index(), atoms[int(di_im3[i])].index(), atoms[int(di_im1[i])].index(), atoms[int(di_im4[i])].index()) imp1 = float(dicts_improper[i]['k1']) * (1 / 4.184) * (1 + Cos( int(dicts_improper[i]['periodicity1']) * phi_im - float(dicts_improper[i]['phase1']))) imp2 = float(dicts_improper[i]['k2']) * (1 / 4.184) * (1 + Cos( int(dicts_improper[i]['periodicity2']) * phi_im - float(dicts_improper[i]['phase2']))) imp3 = float(dicts_improper[i]['k3']) * (1 / 4.184) * (1 + Cos( int(dicts_improper[i]['periodicity3']) * phi_im - float(dicts_improper[i]['phase3']))) imp4 = float(dicts_improper[i]['k4']) * (1 / 4.184) * (1 + Cos( int(dicts_improper[i]['periodicity4']) * phi_im - float(dicts_improper[i]['phase4']))) imp_fun = imp1 + imp2 + imp3 + imp4 improperfuncs.set(improper_id, imp_fun) #print(improperfuncs.potentials()) for t in range(1, 5): mol_params.add( improper_id, float(dicts_improper[i]['k%s' % t]) * (1 / 4.184), int(dicts_improper[i]['periodicity%s' % t]), float(dicts_improper[i]['phase%s' % t])) mol = editmol.setProperty("bond", bondfuncs).commit() mol = editmol.setProperty("angle", anglefuncs).commit() mol = editmol.setProperty("dihedral", dihedralfuncs).commit() mol = editmol.setProperty("improper", improperfuncs).commit() system.update(mol) # Now we work out non bonded pairs see SireIO/amber.cpp L2213 print("Set up nbpairs") print("*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*") ## Define the bonded pairs in a list that is called are12 #print("Now calculating 1-2 intercactions") are12 = [] for i in range(0, natoms): for j in range(0, natoms): if conn.areBonded(atoms[i].index(), atoms[j].index()) == True: #ij = {} ij = (i, j) are12.append(ij) are12_bckup = are12[:] #print("Now calculating 1-3 intercactions") are13 = [] for i in range(0, natoms): for j in range(0, natoms): if conn.areAngled(atoms[i].index(), atoms[j].index()) == True: ij = {} ij = (i, j) are13.append(ij) are13_bckup = are13[:] # print("Now calculating 1-4 intercactions") are14 = [] for i in range(0, natoms): for j in range(0, natoms): if conn.areDihedraled( atoms[i].index(), atoms[j].index()) == True and conn.areAngled( atoms[i].index(), atoms[j].index()) == False: ij = {} ij = (i, j) are14.append(ij) are14_bckup = are14[:] # print("Now calculating the non-bonded intercactions") bonded_pairs_list = are12_bckup + are13_bckup + are14_bckup nb_pair_list = [] for i in range(0, natoms): #print("i=",i) for j in range(0, natoms): if i != j and (i, j) not in bonded_pairs_list: nb_pair_list.append((i, j)) are_nb_bckup = nb_pair_list[:] nbpairs = CLJNBPairs(editmol.info(), CLJScaleFactor(0, 0)) #print("Now setting 1-2 intercactions") for i in range(0, len(are12)): scale_factor1 = 0 scale_factor2 = 0 nbpairs.set(atoms.index(int(are12[i][0])), atoms.index(int(are12[i][1])), CLJScaleFactor(scale_factor1, scale_factor2)) #print("Now setting 1-3 intercactions") for i in range(0, len(are13)): scale_factor1 = 0 scale_factor2 = 0 nbpairs.set(atoms.index(int(are13[i][0])), atoms.index(int(are13[i][1])), CLJScaleFactor(scale_factor1, scale_factor2)) # print("Now setting 1-4 intercactions") for i in range(0, len(are14)): scale_factor1 = 1 / 2 scale_factor2 = 1 / 2 nbpairs.set(atoms.index(int(are14[i][0])), atoms.index(int(are14[i][1])), CLJScaleFactor(scale_factor1, scale_factor2)) mol_params.add14Pair( BondID(atoms.index(int(are14[i][0])), atoms.index(int(are14[i][1]))), scale_factor1, scale_factor2) # print("Now setting non-bonded intercactions") #print("*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*") for i in range(0, len(nb_pair_list)): scale_factor1 = 1 scale_factor2 = 1 nbpairs.set(atoms.index(int(nb_pair_list[i][0])), atoms.index(int(nb_pair_list[i][1])), CLJScaleFactor(scale_factor1, scale_factor2)) # print("~~~~~~~~~~~~~~~~~~`") mol = editmol.setProperty("intrascale", nbpairs).commit() system.update(mol) #print("Setup name of qube FF") mol = mol.edit().setProperty("forcefield", ffToProperty("qube")).commit() system.update(mol) molecule = editmol.commit() newmolecules.add(molecule) return (newmolecules, space)
rdfmonitor = RDFMonitor(tip4p, solvent_group) oxygen = [("O00", ResNum(1))] hydrogen = [("H01", ResNum(1)), ("H02", ResNum(1))] rdfmonitor.addRDF(oxygen, oxygen, RDF(0, 15, 150)) rdfmonitor.addRDF(oxygen, hydrogen, RDF(0, 15, 150)) rdfmonitor.addRDF(hydrogen, oxygen, RDF(0, 15, 150)) rdfmonitor.addRDF(hydrogen, hydrogen, RDF(0, 15, 150)) monitors.set(Symbol("RDF"), rdfmonitor) # create a system that can be used to simulate these groups # using the forcefields that we have constructed system = System(groups, ffields, monitors) # set the space in which the simulation will occur system.setSpace(space) # create a rigid body MC move that moves random solvent # molecules, with the solvent molecules picked uniformly mc = RigidBodyMC(PrefSampler(tip4p, 200.0, all_mols)) # Create a multiple-time-step MC move that performs 500 # rigid body moves of the solvent using e_fast, then accepts # or rejects the whole block of moves using e_total mtsmc = MTSMC(mc, e_fast.function(), 500) mtsmc.setEnergyComponent(e_total.function())
def makeSim(system, ligand_mol, watersys): """Create simulation systems with and without the ligand and return those systems together with the moves""" stage1 = System("with_ligand") stage2 = System("without_ligand") if system.containsProperty("reflection center"): reflection_center = system.property("reflection center").toVector()[0] reflection_radius = float( str(system.property("reflection sphere radius"))) stage1.setProperty("reflection center", AtomCoords(CoordGroup(1, reflection_center))) stage1.setProperty("reflection sphere radius", VariantProperty(reflection_radius)) stage2.setProperty("reflection center", AtomCoords(CoordGroup(1, reflection_center))) stage2.setProperty("reflection sphere radius", VariantProperty(reflection_radius)) # create a molecule group for fixed atoms (everything except the mobile water) fixed_group = MoleculeGroup("fixed") if MGName("fixed_molecules") in system.mgNames(): fixed_group.add(system[MGName("fixed_molecules")]) if MGName("mobile_solutes") in system.mgNames(): fixed_group.add(system[MGName("mobile_solutes")]) if MGName("protein_sidechains") in system.mgNames() or \ MGName("protein_backbones") in system.mgNames(): all_proteins = Molecules() try: protein_sidechains = system[MGName("protein_sidechains")] all_proteins.add(protein_sidechains.molecules()) except: pass try: protein_backbones = system[MGName("protein_backbones")] all_proteins.add(protein_backbones.molecules()) except: pass try: boundary_molecules = system[MGName("boundary_molecules")] all_proteins.add(boundary_molecules.molecules()) except: pass for molnum in all_proteins.molNums(): protein_mol = Molecule.join(all_proteins[molnum]) fixed_group.add(protein_mol) stage1_fixed_group = MoleculeGroup(fixed_group) stage2_fixed_group = MoleculeGroup(fixed_group) stage1_fixed_group.add(ligand_mol) stage2_fixed_group.remove(ligand_mol) mobile_group = MoleculeGroup("mobile_group") if MGName("mobile_solvents") in system.mgNames(): mobile_group.add(system[MGName("mobile_solvents")]) stage1_mobile_group = MoleculeGroup(mobile_group) stage2_mobile_group = MoleculeGroup(mobile_group) # now find water molecules from the water system that can be substituted for the ligand watermols = findOverlappingWaters(ligand_mol, watersys) stage2_mobile_group.add(watermols) print("The number of stage 1 fixed non-solvent molecules is %d." % stage1_fixed_group.nMolecules()) print("The number of stage 1 mobile solvent molecules is %d." % stage1_mobile_group.nMolecules()) print("The number of stage 2 fixed non-solvent molecules is %d." % stage2_fixed_group.nMolecules()) print("The number of stage 2 mobile solvent molecules is %d." % stage2_mobile_group.nMolecules()) # write a PDB of all of the fixed molecules PDB().write(stage1_mobile_group, "stage1_mobile_atoms.pdb") PDB().write(stage2_mobile_group, "stage2_mobile_atoms.pdb") PDB().write(stage1_fixed_group, "stage1_fixed_atoms.pdb") PDB().write(stage2_fixed_group, "stage2_fixed_atoms.pdb") # create the forcefields if use_fast_ff.val: stage1_ff = InterFF("ff") stage2_ff = InterFF("ff") stage1_ff.setCLJFunction( CLJShiftFunction(Cartesian(), coul_cutoff.val, lj_cutoff.val)) stage2_ff.setCLJFunction( CLJShiftFunction(Cartesian(), coul_cutoff.val, lj_cutoff.val)) if disable_grid.val: stage1_ff.disableGrid() stage2_ff.disableGrid() else: stage1_ff.enableGrid() stage1_ff.setGridSpacing(grid_spacing.val) stage1_ff.setGridBuffer(grid_buffer.val) stage2_ff.enableGrid() stage2_ff.setGridSpacing(grid_spacing.val) stage2_ff.setGridBuffer(grid_buffer.val) stage1_ff.add(stage1_mobile_group) stage1_ff.setFixedAtoms(stage1_fixed_group.molecules()) stage2_ff.add(stage2_mobile_group) stage2_ff.setFixedAtoms(stage2_fixed_group.molecules()) stage1.add(stage1_ff) stage1.setComponent(stage1.totalComponent(), stage1_ff.components().total()) stage2.add(stage1_ff) stage2.setComponent(stage2.totalComponent(), stage2_ff.components().total()) else: # forcefield holding the energy between the mobile atoms and # the fixed atoms if disable_grid.val: stage1_mobile_fixed = InterGroupCLJFF("mobile-fixed") stage1_mobile_fixed = setCLJProperties(stage1_mobile_fixed) stage1_mobile_fixed = setFakeGridProperties(stage1_mobile_fixed) stage1_mobile_fixed.add(stage1_mobile_group, MGIdx(0)) stage1_mobile_fixed.add(stage1_fixed_group, MGIdx(1)) stage2_mobile_fixed = InterGroupCLJFF("mobile-fixed") stage2_mobile_fixed = setCLJProperties(stage2_mobile_fixed) stage2_mobile_fixed = setFakeGridProperties(stage2_mobile_fixed) stage2_mobile_fixed.add(stage2_mobile_group, MGIdx(0)) stage2_mobile_fixed.add(stage2_fixed_group, MGIdx(1)) else: stage1_mobile_fixed = GridFF2("mobile-fixed") stage1_mobile_fixed = setCLJProperties(stage1_mobile_fixed) stage1_mobile_fixed = setGridProperties(stage1_mobile_fixed) stage1_mobile_fixed.add(stage1_mobile_group, MGIdx(0)) stage1_mobile_fixed.addFixedAtoms(stage1_fixed_group) stage2_mobile_fixed = GridFF2("mobile-fixed") stage2_mobile_fixed = setCLJProperties(stage2_mobile_fixed) stage2_mobile_fixed = setGridProperties(stage2_mobile_fixed) stage2_mobile_fixed.add(stage2_mobile_group, MGIdx(0)) stage2_mobile_fixed.addFixedAtoms(stage2_fixed_group) # forcefield holding the energy between fixed atoms stage1_mobile_mobile = InterCLJFF("mobile-mobile") stage1_mobile_mobile = setCLJProperties(stage1_mobile_mobile) stage1_mobile_mobile.add(stage1_mobile_group) stage2_mobile_mobile = InterCLJFF("mobile-mobile") stage2_mobile_mobile = setCLJProperties(stage2_mobile_mobile) stage2_mobile_mobile.add(stage2_mobile_group) stage1.add(stage1_mobile_group) stage1.add(stage1_mobile_fixed) stage1.add(stage1_mobile_mobile) stage2.add(stage2_mobile_group) stage2.add(stage2_mobile_fixed) stage2.add(stage2_mobile_mobile) stage1.setComponent( stage1.totalComponent(), stage1_mobile_mobile.components().total() + stage1_mobile_fixed.components().total()) stage2.setComponent( stage2.totalComponent(), stage2_mobile_mobile.components().total() + stage2_mobile_fixed.components().total()) stage1.add(stage1_mobile_group) stage2.add(stage2_mobile_group) stage1.add("volume_map", VolMapMonitor(stage1_mobile_group), 1000) stage2.add("volume_map", VolMapMonitor(stage2_mobile_group), 1000) max_water_translation = 0.15 * angstroms max_water_rotation = 15 * degrees stage1_moves = WeightedMoves() if stage1_mobile_group.nViews() > 0: rb_moves = RigidBodyMC(stage1_mobile_group) rb_moves.setMaximumTranslation(max_water_translation) rb_moves.setMaximumRotation(max_water_rotation) if stage1.containsProperty("reflection sphere radius"): reflection_radius = float( str(stage1.property("reflection sphere radius"))) * angstroms reflection_center = stage1.property( "reflection center").toVector()[0] rb_moves.setReflectionSphere(reflection_center, reflection_radius) stage1_moves.add(rb_moves, stage1_mobile_group.nViews()) stage2_moves = WeightedMoves() if stage2_mobile_group.nViews() > 0: rb_moves = RigidBodyMC(stage2_mobile_group) rb_moves.setMaximumTranslation(max_water_translation) rb_moves.setMaximumRotation(max_water_rotation) if stage2.containsProperty("reflection sphere radius"): reflection_radius = float( str(stage2.property("reflection sphere radius"))) * angstroms reflection_center = stage2.property( "reflection center").toVector()[0] rb_moves.setReflectionSphere(reflection_center, reflection_radius) stage2_moves.add(rb_moves, stage2_mobile_group.nViews()) stage1_moves.setTemperature(temperature.val) stage2_moves.setTemperature(temperature.val) seed = random_seed.val if seed is None: seed = RanGenerator().randInt(100000, 1000000) print("Using generated random number seed %d" % seed) else: print("Using supplied random number seed %d" % seed) stage1_moves.setGenerator(RanGenerator(seed)) stage2_moves.setGenerator(RanGenerator(seed + 7)) return ((stage1, stage1_moves), (stage2, stage2_moves))
def estimateDG(topfile=None,crdfile=None,pertfile=None, trajfile=None,librarypath=None): """ This subroutine loads a trajectory for an alchemical state, and a list of ligand molecules For each frame of the trajectory for each perturbed ligand Align the perturbed ligand onto reference ligand. Generate K poses Accumulate exp energy difference Estimate (w bootstrapping) free energy difference & uncertainties """ print ("HELLO ESTIMATE DG") # Setup system describing alchemical state amber = Amber() (molecules, space) = amber.readCrdTop(crdfile, topfile) morphfile = Parameter("morphfile",pertfile,""".""") system = createSystemFreeEnergy(molecules, morphfile=morphfile) cutoff_type = Parameter(".","cutoffperiodic",""".""") cutoff_dist = Parameter(".",10*angstrom,""".""") rf_dielectric = Parameter(".",82.0,""".""") shift_delta = Parameter(".",2.0,""".""") coulomb_power = Parameter(".",0,""".""") combining_rules = Parameter(".","arithmetic",""".""") lambda_val = Parameter(".",0.0,""".""") system = setupForceFieldsFreeEnergy(system, space, cutoff_type=cutoff_type, cutoff_dist=cutoff_dist, rf_dielectric=rf_dielectric, shift_delta=shift_delta, coulomb_power=coulomb_power, combining_rules=combining_rules, lambda_val=lambda_val) # Load ligands library # FIX ME ! Don't include ligands that have already been simulated ! library = loadLibrary(librarypath) library_deltaenergies = {} # library_deltaenergies contain the list of computed energy differences for ligand in library: library_deltaenergies[ligand] = [] #import pdb; pdb.set_trace() # Now scan trajectory start_frame = 1 end_frame = 3 step_frame = 1 trajfile = Parameter(".",trajfile,""".""") mdtraj_trajfile = mdtraj.open(trajfile.val,'r') nframes = len(mdtraj_trajfile) if end_frame > (nframes - 1): end_frame = nframes - 1 mdtraj_trajfile.seek(start_frame) current_frame = start_frame energies = {} for (ID, ligand) in library: energies[ID] = [] while (current_frame <= end_frame): print ("#Processing frame %s " % current_frame) frames_xyz, cell_lengths, cell_angles = mdtraj_trajfile.read(n_frames=1) system = updateSystemfromTraj(system, frames_xyz, cell_lengths, cell_angles) ref_ligand = system[MGName("solutes")].molecules().first().molecule() ref_nrg = system.energy() print (ref_nrg) for (ID, ligand) in library: # Align ligand onto reference ligand mapping = AtomMCSMatcher(1*second).match(ref_ligand, PropertyMap(), ligand, PropertyMap()) mapper = AtomResultMatcher(mapping) # This does a RB alignment # TODO) Explore optimised alignment codes # For instance could construct aligned ligand by reusing MCSS coordinates # and completing topology for variable part using BAT internal coordinates # Also, better otherwise never get intramolecular energy variations ! # Basic test...SAME LIGAND should give 0 energy difference ! # FIXME) Return multiple coordinates and update system in each instance aligned_ligand = ligand.move().align(ref_ligand, AtomMatchInverter(mapper)) #print (ref_ligand.property("coordinates").toVector()) #print ("####") #print (aligned_ligand.property("coordinates").toVector()) # FIXME) Optimise for speed new_system = System() new_space = system.property("space") new_system.add( system[MGName("solvent")] ) sols = MoleculeGroup("solutes") solref = MoleculeGroup("solute_ref") solhard = MoleculeGroup("solute_ref_hard") soltodummy = MoleculeGroup("solute_ref_todummy") solfromdummy = MoleculeGroup("solute_ref_fromdummy") sols.add(aligned_ligand) solref.add(aligned_ligand) solhard.add(aligned_ligand) new_system.add(sols) new_system.add(solref) new_system.add(solhard) new_system.add(soltodummy) new_system.add(solfromdummy) #print ("###") # DONE) Optimise for speed, only doing ligand energies #print (new_system[MGName("solutes")].first().molecule().property("coordinates").toVector()) new_system = setupForceFieldsFreeEnergy(new_system, new_space, cutoff_type=cutoff_type, cutoff_dist=cutoff_dist, rf_dielectric=rf_dielectric, shift_delta=shift_delta, coulomb_power=coulomb_power, combining_rules=combining_rules, lambda_val=lambda_val) new_nrg = new_system.energy() print (new_nrg) energies[ID].append( new_nrg - ref_nrg ) # for each conformation generated # consider further optimisation (rapid MC --> if loaded flex files?) # update 'perturbed' group with aligned ligand coordinates # compute 'perturbed' energy # accumulate 'perturbed' - reference #import pdb; pdb.set_trace() current_frame += step_frame import pdb; pdb.set_trace() # Now convert accumulated data int return 0
PDB().write(mols, "test0000.pdb") space = PeriodicBox((0, 0, 0), (10, 10, 10)) switchfunc = HarmonicSwitchingFunction(4.5, 4.0) ljff = InterLJFF(space, switchfunc) ljff.add(mols) ffields = ForceFields() ffields.add(ljff) all_mols = MoleculeGroup("all", mols) system = System(all_mols, ffields) system.setSpace(space) mc = RigidBodyMC(UniformSampler(all_mols)) mc.setMaximumTranslation(0.1 * angstrom) volmc = VolumeMove(MapAsMolecules(all_mols)) volmc.setVolumeChangingFunction(UniformVolumeChange(50 * angstrom3)) moves = WeightedMoves() moves.add(mc, 125) moves.add(volmc, 1) for i in range(1, 1001): print("Running block %d" % i)
def run(self, molecule, work_dir=None, queue=None): """Run the parameterisation protocol. Parameters ---------- molecule : BioSimSpace._SireWrappers.Molecule The molecule to apply the parameterisation protocol to. work_dir : str The working directory. queue : queue.Queue The thread queue is which this method has been run. Returns ------- molecule : BioSimSpace._SireWrappers.Molecule The parameterised molecule. """ if type(molecule) is not _Molecule: raise TypeError( "'molecule' must be of type 'BioSimSpace._SireWrappers.Molecule'" ) if type(work_dir) is not None and type(work_dir) is not str: raise TypeError("'work_dir' must be of type 'str'") if type(queue) is not None and type(queue) is not _queue.Queue: raise TypeError("'queue' must be of type 'queue.Queue'") # Set work_dir to the current directory. if work_dir is None: work_dir = _os.getcwd() # Create the file prefix. prefix = work_dir + "/" # Create a copy of the molecule. new_mol = molecule.copy() # Use the net molecular charge passed as an option. if self._net_charge is not None: charge = self._net_charge else: # The user will likely have passed a bare PDB or Mol2 file. # Antechamber expects the molecule to be uncharged, or integer # charged (where the charge, or number of electrons, is passed with # the -nc flag). # Get the total charge on the molecule. if "charge" in self._property_map: _property_map = {"charge": self._property_map["charge"]} prop = self._property_map["charge"] else: _property_map = {"charge": "charge"} prop = "charge" # The molecule has a charge property. if new_mol._getSireObject().hasProperty(prop): charge = new_mol.charge(property_map=_property_map).magnitude() # Charge is non-integer, try to fix it. if abs(round(charge) - charge) > 0: new_mol._fixCharge(property_map=_property_map) charge = round(charge) else: charge = None # Only try "formal_charge" when "charge" is missing. Unlikely to have # both if this is a bare molecule, but the user could be re-parameterising # an existing molecule. if charge is None: # Get the total formal charge on the molecule. if "formal_charge" in self._property_map: _property_map = { "charge": self._property_map["formal_charge"] } prop = self._property_map["charge"] else: _property_map = {"charge": "formal_charge"} prop = "formal_charge" if new_mol._getSireObject().hasProperty(prop): charge = new_mol.charge( property_map=_property_map).magnitude() # Compute the formal charge ourselves to check that it is consistent. formal_charge = _formalCharge(molecule).magnitude() if charge != formal_charge: _warnings.warn( "The formal charge on the molecule is %d " "but we estimate it to be %d" % (charge, formal_charge)) else: msg = ( "The molecule has no 'charge' or 'formal_charge' information, and " "no 'net_charge' option has been passed. You can use the " "'BioSimSpace.Parameters.formalCharge' function to compute the " "formal charge") raise _ParameterisationError(msg) # Create a new system and molecule group. s = _SireSystem.System("BioSimSpace System") m = _SireMol.MoleculeGroup("all") # Add the molecule. m.add(new_mol._getSireObject()) s.add(m) # Write the system to a PDB file. try: pdb = _SireIO.PDB2(s) pdb.writeToFile(prefix + "antechamber.pdb") except Exception as e: msg = "Failed to write system to 'PDB' format." if _isVerbose(): raise IOError(msg) from e else: raise IOError(msg) from None # Generate the Antechamber command. command = ("%s -at %d -i antechamber.pdb -fi pdb " + "-o antechamber.mol2 -fo mol2 -c %s -s 2 -nc %d") % ( _protocol._antechamber_exe, self._version, self._charge_method.lower(), charge) with open(prefix + "README.txt", "w") as file: # Write the command to file. file.write("# Antechamber was run with the following command:\n") file.write("%s\n" % command) # Create files for stdout/stderr. stdout = open(prefix + "antechamber.out", "w") stderr = open(prefix + "antechamber.err", "w") # Run Antechamber as a subprocess. proc = _subprocess.run(command, cwd=work_dir, shell=True, stdout=stdout, stderr=stderr) stdout.close() stderr.close() # Antechamber doesn't return sensible error codes, so we need to check that # the expected output was generated. if _os.path.isfile(prefix + "antechamber.mol2"): # Run parmchk to check for missing parameters. command = ("%s -s %d -i antechamber.mol2 -f mol2 " + "-o antechamber.frcmod") % (_protocol._parmchk_exe, self._version) with open(prefix + "README.txt", "a") as file: # Write the command to file. file.write("\n# ParmChk was run with the following command:\n") file.write("%s\n" % command) # Create files for stdout/stderr. stdout = open(prefix + "parmchk.out", "w") stderr = open(prefix + "parmchk.err", "w") # Run parmchk as a subprocess. proc = _subprocess.run(command, cwd=work_dir, shell=True, stdout=stdout, stderr=stderr) stdout.close() stderr.close() # The frcmod file was created. if _os.path.isfile(prefix + "antechamber.frcmod"): # Now call tLEaP using the partially parameterised molecule and the frcmod file. # tLEap will run in the same working directory, using the Mol2 file generated by # Antechamber. # Try to find a force field file. if self._version == 1: ff = _protocol._find_force_field("gaff") else: ff = _protocol._find_force_field("gaff2") # Write the LEaP input file. with open(prefix + "leap.txt", "w") as file: file.write("source %s\n" % ff) file.write("mol = loadMol2 antechamber.mol2\n") file.write("loadAmberParams antechamber.frcmod\n") file.write("saveAmberParm mol leap.top leap.crd\n") file.write("quit") # Generate the tLEaP command. command = "%s -f leap.txt" % _protocol._tleap_exe with open(prefix + "README.txt", "a") as file: # Write the command to file. file.write( "\n# tLEaP was run with the following command:\n") file.write("%s\n" % command) # Create files for stdout/stderr. stdout = open(prefix + "tleap.out", "w") stderr = open(prefix + "tleap.err", "w") # Run tLEaP as a subprocess. proc = _subprocess.run(command, cwd=work_dir, shell=True, stdout=stdout, stderr=stderr) stdout.close() stderr.close() # tLEaP doesn't return sensible error codes, so we need to check that # the expected output was generated. if _os.path.isfile(prefix + "leap.top") and _os.path.isfile(prefix + "leap.crd"): # Load the parameterised molecule. try: par_mol = _Molecule( _IO.readMolecules([ prefix + "leap.top", prefix + "leap.crd" ])._getSireObject()[_SireMol.MolIdx(0)]) except Exception as e: msg = "Failed to read molecule from: 'leap.top', 'leap.crd'" if _isVerbose(): raise IOError(msg) from e else: raise IOError(msg) from None # Make the molecule 'mol' compatible with 'par_mol'. This will create # a mapping between atom indices in the two molecules and add all of # the new properties from 'par_mol' to 'mol'. new_mol._makeCompatibleWith( par_mol, property_map=self._property_map, overwrite=True, verbose=False) # Record the forcefield used to parameterise the molecule. new_mol._forcefield = ff else: raise _ParameterisationError("tLEaP failed!") else: raise _ParameterisationError("Parmchk failed!") else: raise _ParameterisationError("Antechamber failed!") if queue is not None: queue.put(new_mol) return new_mol
def createSystemFreeEnergy(molecules, morphfile=None): r"""creates the system for free energy calculation Parameters ---------- molecules : Sire.molecules Sire object that contains a lot of information about molecules Returns ------- system : Sire.system """ print ("Create the System...") moleculeNumbers = molecules.molNums() moleculeList = [] for moleculeNumber in moleculeNumbers: molecule = molecules.molecule(moleculeNumber).molecule() moleculeList.append(molecule) # # The code below assumes that the solute to be perturbed is # the first molecule in the top file. # The residue name of the first residue in this molecule is # used to name the solute. This is used later to match # templates in the flex/pert files. solute = moleculeList[0] lig_name = solute.residue(ResIdx(0)).name().value() solute = solute.edit().rename(lig_name).commit() perturbations_lib = PerturbationsLibrary(morphfile.val) solute = perturbations_lib.applyTemplate(solute) perturbations = solute.property("perturbations") lam = Symbol("lambda") initial = Perturbation.symbols().initial() final = Perturbation.symbols().final() solute = solute.edit().setProperty("perturbations", perturbations.recreate((1 - lam) * initial + lam * final)).commit() # We put atoms in three groups depending on what happens in the perturbation # non dummy to non dummy --> the hard group, uses a normal intermolecular FF # non dummy to dummy --> the todummy group, uses SoftFF with alpha = Lambda # dummy to non dummy --> the fromdummy group, uses SoftFF with alpha = 1 - Lambda # We start assuming all atoms are hard atoms. Then we call getDummies to find which atoms # start/end as dummies and update the hard, todummy and fromdummy groups accordingly solute_grp_ref = MoleculeGroup("solute_ref", solute) solute_grp_ref_hard = MoleculeGroup("solute_ref_hard") solute_grp_ref_todummy = MoleculeGroup("solute_ref_todummy") solute_grp_ref_fromdummy = MoleculeGroup("solute_ref_fromdummy") solute_ref_hard = solute.selectAllAtoms() solute_ref_todummy = solute_ref_hard.invert() solute_ref_fromdummy = solute_ref_hard.invert() to_dummies, from_dummies = getDummies(solute) if to_dummies is not None: ndummies = to_dummies.count() dummies = to_dummies.atoms() for x in range(0, ndummies): dummy_index = dummies[x].index() solute_ref_hard = solute_ref_hard.subtract(solute.select(dummy_index)) solute_ref_todummy = solute_ref_todummy.add(solute.select(dummy_index)) if from_dummies is not None: ndummies = from_dummies.count() dummies = from_dummies.atoms() for x in range(0, ndummies): dummy_index = dummies[x].index() solute_ref_hard = solute_ref_hard.subtract(solute.select(dummy_index)) solute_ref_fromdummy = solute_ref_fromdummy.add(solute.select(dummy_index)) solute_grp_ref_hard.add(solute_ref_hard) solute_grp_ref_todummy.add(solute_ref_todummy) solute_grp_ref_fromdummy.add(solute_ref_fromdummy) solutes = MoleculeGroup("solutes") solutes.add(solute) molecules = MoleculeGroup("molecules") molecules.add(solute) solvent = MoleculeGroup("solvent") for molecule in moleculeList[1:]: molecules.add(molecule) solvent.add(molecule) all = MoleculeGroup("all") all.add(molecules) all.add(solvent) all.add(solutes) all.add(solute_grp_ref) all.add(solute_grp_ref_hard) all.add(solute_grp_ref_todummy) all.add(solute_grp_ref_fromdummy) # Add these groups to the System system = System() system.add(solutes) system.add(solute_grp_ref) system.add(solute_grp_ref_hard) system.add(solute_grp_ref_todummy) system.add(solute_grp_ref_fromdummy) system.add(molecules) system.add(solvent) system.add(all) return system