def testComputePBCVectors(self): """ Tests computing periodic box vectors """ deg90 = 90 * degrees vecs = computePeriodicBoxVectors(1, 2, 3, deg90, deg90, deg90) a, b, c = vecs self.assertAlmostEqual(a[0] / nanometers, 1) self.assertAlmostEqual(a[1] / nanometers, 0) self.assertAlmostEqual(a[2] / nanometers, 0) self.assertAlmostEqual(b[0] / nanometers, 0) self.assertAlmostEqual(b[1] / nanometers, 2) self.assertAlmostEqual(b[2] / nanometers, 0) self.assertAlmostEqual(c[0] / nanometers, 0) self.assertAlmostEqual(c[1] / nanometers, 0) self.assertAlmostEqual(c[2] / nanometers, 3) # Make sure round-trip works la, lb, lc, al, be, ga = computeLengthsAndAngles(vecs) self.assertAlmostEqual(la, 1) self.assertAlmostEqual(lb, 2) self.assertAlmostEqual(lc, 3) self.assertAlmostEqual(al, math.pi / 2) self.assertAlmostEqual(be, math.pi / 2) self.assertAlmostEqual(ga, math.pi / 2) # Now test a truncated octahedron. Can't do a simple round-trip though, # due to the reduced form. So test the *second* round-trip, which should # yield the same measurements vecs = computePeriodicBoxVectors(4.24388485, 4.24388485, 4.24388485, 109.4712190 * degrees, 109.4712190 * degrees, 109.4712190 * degrees) la, lb, lc, al, be, ga = computeLengthsAndAngles(vecs) vecs2 = computePeriodicBoxVectors(la, lb, lc, al, be, ga) la2, lb2, lc2, al2, be2, ga2 = computeLengthsAndAngles(vecs2) # Now make sure that the round-trip worked self.assertAlmostEqual(strip_units(la), strip_units(la2)) self.assertAlmostEqual(strip_units(lb), strip_units(lb2)) self.assertAlmostEqual(strip_units(lc), strip_units(lc2)) self.assertAlmostEqual(strip_units(al), strip_units(al2)) self.assertAlmostEqual(strip_units(be), strip_units(be2)) self.assertAlmostEqual(strip_units(ga), strip_units(ga2)) # Check that the vectors are the same a1, a2, a3 = vecs b1, b2, b3 = vecs2 for x, y in zip(a1, b1): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a2, b2): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a3, b3): self.assertAlmostEqual(strip_units(x), strip_units(y))
def testComputePBCVectors(self): """ Tests computing periodic box vectors """ deg90 = 90 * degrees vecs = computePeriodicBoxVectors(1, 2, 3, deg90, deg90, deg90) a, b, c = vecs self.assertAlmostEqual(a[0]/nanometers, 1) self.assertAlmostEqual(a[1]/nanometers, 0) self.assertAlmostEqual(a[2]/nanometers, 0) self.assertAlmostEqual(b[0]/nanometers, 0) self.assertAlmostEqual(b[1]/nanometers, 2) self.assertAlmostEqual(b[2]/nanometers, 0) self.assertAlmostEqual(c[0]/nanometers, 0) self.assertAlmostEqual(c[1]/nanometers, 0) self.assertAlmostEqual(c[2]/nanometers, 3) # Make sure round-trip works la, lb, lc, al, be, ga = computeLengthsAndAngles(vecs) self.assertAlmostEqual(la, 1) self.assertAlmostEqual(lb, 2) self.assertAlmostEqual(lc, 3) self.assertAlmostEqual(al, math.pi / 2) self.assertAlmostEqual(be, math.pi / 2) self.assertAlmostEqual(ga, math.pi / 2) # Now test a truncated octahedron. Can't do a simple round-trip though, # due to the reduced form. So test the *second* round-trip, which should # yield the same measurements vecs = computePeriodicBoxVectors(4.24388485, 4.24388485, 4.24388485, 109.4712190*degrees, 109.4712190*degrees, 109.4712190*degrees) la, lb, lc, al, be, ga = computeLengthsAndAngles(vecs) vecs2 = computePeriodicBoxVectors(la, lb, lc, al, be, ga) la2, lb2, lc2, al2, be2, ga2 = computeLengthsAndAngles(vecs2) # Now make sure that the round-trip worked self.assertAlmostEqual(strip_units(la), strip_units(la2)) self.assertAlmostEqual(strip_units(lb), strip_units(lb2)) self.assertAlmostEqual(strip_units(lc), strip_units(lc2)) self.assertAlmostEqual(strip_units(al), strip_units(al2)) self.assertAlmostEqual(strip_units(be), strip_units(be2)) self.assertAlmostEqual(strip_units(ga), strip_units(ga2)) # Check that the vectors are the same a1, a2, a3 = vecs b1, b2, b3 = vecs2 for x, y in zip(a1, b1): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a2, b2): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a3, b3): self.assertAlmostEqual(strip_units(x), strip_units(y))
def testReducePBCVectors(self): """ Checks that reducePeriodicBoxVectors properly reduces vectors """ a = Vec3(4.24388485, 0.0, 0.0) b = Vec3(-1.4146281691908937, 4.001173048368583, 0.0) c = Vec3(-1.4146281691908937, -2.0005862820516203, 3.4651176446201674) vecs = reducePeriodicBoxVectors((a, b, c)*nanometers) vecs2 = computePeriodicBoxVectors(4.24388485, 4.24388485, 4.24388485, 109.4712190*degrees, 109.4712190*degrees, 109.4712190*degrees) # Check that the vectors are the same a1, a2, a3 = vecs b1, b2, b3 = vecs2 for x, y in zip(a1, b1): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a2, b2): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a3, b3): self.assertAlmostEqual(strip_units(x), strip_units(y))
def testReducePBCVectors(self): """ Checks that reducePeriodicBoxVectors properly reduces vectors """ a = Vec3(4.24388485, 0.0, 0.0) b = Vec3(-1.4146281691908937, 4.001173048368583, 0.0) c = Vec3(-1.4146281691908937, -2.0005862820516203, 3.4651176446201674) vecs = reducePeriodicBoxVectors((a, b, c) * nanometers) vecs2 = computePeriodicBoxVectors(4.24388485, 4.24388485, 4.24388485, 109.4712190 * degrees, 109.4712190 * degrees, 109.4712190 * degrees) # Check that the vectors are the same a1, a2, a3 = vecs b1, b2, b3 = vecs2 for x, y in zip(a1, b1): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a2, b2): self.assertAlmostEqual(strip_units(x), strip_units(y)) for x, y in zip(a3, b3): self.assertAlmostEqual(strip_units(x), strip_units(y))
def __init__(self, file): """Load a PDBx/mmCIF file. The atom positions and Topology can be retrieved by calling getPositions() and getTopology(). Parameters ---------- file : string the name of the file to load. Alternatively you can pass an open file object. """ top = Topology() ## The Topology read from the PDBx/mmCIF file self.topology = top self._positions = [] # Load the file. inputFile = file if isinstance(file, str): inputFile = open(file) reader = PdbxReader(inputFile) data = [] reader.read(data) block = data[0] # Build the topology. atomData = block.getObj('atom_site') atomNameCol = atomData.getAttributeIndex('auth_atom_id') atomIdCol = atomData.getAttributeIndex('id') resNameCol = atomData.getAttributeIndex('auth_comp_id') resNumCol = atomData.getAttributeIndex('auth_seq_id') resInsertionCol = atomData.getAttributeIndex('pdbx_PDB_ins_code') chainIdCol = atomData.getAttributeIndex('auth_asym_id') elementCol = atomData.getAttributeIndex('type_symbol') altIdCol = atomData.getAttributeIndex('label_alt_id') modelCol = atomData.getAttributeIndex('pdbx_PDB_model_num') xCol = atomData.getAttributeIndex('Cartn_x') yCol = atomData.getAttributeIndex('Cartn_y') zCol = atomData.getAttributeIndex('Cartn_z') lastChainId = None lastResId = None atomTable = {} atomsInResidue = set() models = [] for row in atomData.getRowList(): atomKey = ((row[resNumCol], row[chainIdCol], row[atomNameCol])) model = ('1' if modelCol == -1 else row[modelCol]) if model not in models: models.append(model) self._positions.append([]) modelIndex = models.index(model) if row[altIdCol] != '.' and atomKey in atomTable and len(self._positions[modelIndex]) > atomTable[atomKey].index: # This row is an alternate position for an existing atom, so ignore it. continue if modelIndex == 0: # This row defines a new atom. if lastChainId != row[chainIdCol]: # The start of a new chain. chain = top.addChain(row[chainIdCol]) lastChainId = row[chainIdCol] lastResId = None if lastResId != row[resNumCol] or lastChainId != row[chainIdCol] or (lastResId == '.' and row[atomNameCol] in atomsInResidue): # The start of a new residue. resId = (None if resNumCol == -1 else row[resNumCol]) resIC = ('' if resInsertionCol == -1 else row[resInsertionCol]) res = top.addResidue(row[resNameCol], chain, resId, resIC) lastResId = row[resNumCol] atomsInResidue.clear() element = None try: element = elem.get_by_symbol(row[elementCol]) except KeyError: pass atom = top.addAtom(row[atomNameCol], element, res, row[atomIdCol]) atomTable[atomKey] = atom atomsInResidue.add(row[atomNameCol]) else: # This row defines coordinates for an existing atom in one of the later models. try: atom = atomTable[atomKey] except KeyError: raise ValueError('Unknown atom %s in residue %s %s for model %s' % (row[atomNameCol], row[resNameCol], row[resNumCol], model)) if atom.index != len(self._positions[modelIndex]): raise ValueError('Atom %s for model %s does not match the order of atoms for model %s' % (row[atomIdCol], model, models[0])) self._positions[modelIndex].append(Vec3(float(row[xCol]), float(row[yCol]), float(row[zCol]))*0.1) for i in range(len(self._positions)): self._positions[i] = self._positions[i]*nanometers ## The atom positions read from the PDBx/mmCIF file. If the file contains multiple frames, these are the positions in the first frame. self.positions = self._positions[0] self.topology.createStandardBonds() self._numpyPositions = None # Record unit cell information, if present. cell = block.getObj('cell') if cell is not None and cell.getRowCount() > 0: row = cell.getRow(0) (a, b, c) = [float(row[cell.getAttributeIndex(attribute)])*0.1 for attribute in ('length_a', 'length_b', 'length_c')] (alpha, beta, gamma) = [float(row[cell.getAttributeIndex(attribute)])*math.pi/180.0 for attribute in ('angle_alpha', 'angle_beta', 'angle_gamma')] self.topology.setPeriodicBoxVectors(computePeriodicBoxVectors(a, b, c, alpha, beta, gamma)) # Add bonds based on struct_conn records. connectData = block.getObj('struct_conn') if connectData is not None: res1Col = connectData.getAttributeIndex('ptnr1_label_seq_id') res2Col = connectData.getAttributeIndex('ptnr2_label_seq_id') atom1Col = connectData.getAttributeIndex('ptnr1_label_atom_id') atom2Col = connectData.getAttributeIndex('ptnr2_label_atom_id') asym1Col = connectData.getAttributeIndex('ptnr1_label_asym_id') asym2Col = connectData.getAttributeIndex('ptnr2_label_asym_id') typeCol = connectData.getAttributeIndex('conn_type_id') connectBonds = [] for row in connectData.getRowList(): type = row[typeCol][:6] if type in ('covale', 'disulf', 'modres'): key1 = (row[res1Col], row[asym1Col], row[atom1Col]) key2 = (row[res2Col], row[asym2Col], row[atom2Col]) if key1 in atomTable and key2 in atomTable: connectBonds.append((atomTable[key1], atomTable[key2])) if len(connectBonds) > 0: # Only add bonds that don't already exist. existingBonds = set(top.bonds()) for bond in connectBonds: if bond not in existingBonds and (bond[1], bond[0]) not in existingBonds: top.addBond(bond[0], bond[1]) existingBonds.add(bond)
def __init__(self, file): """Load a prmtop file.""" ## The Topology read from the prmtop file self.topology = top = Topology() self.elements = [] # Load the prmtop file prmtop = amber_file_parser.PrmtopLoader(file) self._prmtop = prmtop # Add atoms to the topology PDBFile._loadNameReplacementTables() lastResidue = None c = top.addChain() for index in range(prmtop.getNumAtoms()): resNumber = prmtop.getResidueNumber(index) if resNumber != lastResidue: lastResidue = resNumber resName = prmtop.getResidueLabel(iAtom=index).strip() if resName in PDBFile._residueNameReplacements: resName = PDBFile._residueNameReplacements[resName] r = top.addResidue(resName, c) if resName in PDBFile._atomNameReplacements: atomReplacements = PDBFile._atomNameReplacements[resName] else: atomReplacements = {} atomName = prmtop.getAtomName(index).strip() if atomName in atomReplacements: atomName = atomReplacements[atomName] # Get the element from the prmtop file if available if prmtop.has_atomic_number: try: element = elem.Element.getByAtomicNumber(int(prmtop._raw_data['ATOMIC_NUMBER'][index])) except KeyError: element = None else: # Try to guess the element from the atom name. upper = atomName.upper() if upper.startswith('CL'): element = elem.chlorine elif upper.startswith('NA'): element = elem.sodium elif upper.startswith('MG'): element = elem.magnesium elif upper.startswith('ZN'): element = elem.zinc else: try: element = elem.get_by_symbol(atomName[0]) except KeyError: element = None top.addAtom(atomName, element, r) self.elements.append(element) # Add bonds to the topology atoms = list(top.atoms()) for bond in prmtop.getBondsWithH(): top.addBond(atoms[bond[0]], atoms[bond[1]]) for bond in prmtop.getBondsNoH(): top.addBond(atoms[bond[0]], atoms[bond[1]]) # Set the periodic box size. if prmtop.getIfBox(): box = prmtop.getBoxBetaAndDimensions() top.setPeriodicBoxVectors(computePeriodicBoxVectors(*(box[1:4] + box[0:1]*3)))
def __init__(self, file): """Load a prmtop file.""" ## The Topology read from the prmtop file self.topology = top = Topology() self.elements = [] # Load the prmtop file prmtop = amber_file_parser.PrmtopLoader(file) self._prmtop = prmtop # Add atoms to the topology PDBFile._loadNameReplacementTables() lastResidue = None c = top.addChain() for index in range(prmtop.getNumAtoms()): resNumber = prmtop.getResidueNumber(index) if resNumber != lastResidue: lastResidue = resNumber resName = prmtop.getResidueLabel(iAtom=index).strip() if resName in PDBFile._residueNameReplacements: resName = PDBFile._residueNameReplacements[resName] r = top.addResidue(resName, c) if resName in PDBFile._atomNameReplacements: atomReplacements = PDBFile._atomNameReplacements[resName] else: atomReplacements = {} atomName = prmtop.getAtomName(index).strip() if atomName in atomReplacements: atomName = atomReplacements[atomName] # Get the element from the prmtop file if available if prmtop.has_atomic_number: try: element = elem.Element.getByAtomicNumber( int(prmtop._raw_data['ATOMIC_NUMBER'][index])) except KeyError: element = None else: # Try to guess the element from the atom name. upper = atomName.upper() if upper.startswith('CL'): element = elem.chlorine elif upper.startswith('NA'): element = elem.sodium elif upper.startswith('MG'): element = elem.magnesium elif upper.startswith('ZN'): element = elem.zinc else: try: element = elem.get_by_symbol(atomName[0]) except KeyError: element = None top.addAtom(atomName, element, r) self.elements.append(element) # Add bonds to the topology atoms = list(top.atoms()) for bond in prmtop.getBondsWithH(): top.addBond(atoms[bond[0]], atoms[bond[1]]) for bond in prmtop.getBondsNoH(): top.addBond(atoms[bond[0]], atoms[bond[1]]) # Set the periodic box size. if prmtop.getIfBox(): box = prmtop.getBoxBetaAndDimensions() top.setPeriodicBoxVectors( computePeriodicBoxVectors(*(box[1:4] + box[0:1] * 3)))
def __init__(self, file): """Load a PDBx/mmCIF file. The atom positions and Topology can be retrieved by calling getPositions() and getTopology(). Parameters: - file (string) the name of the file to load. Alternatively you can pass an open file object. """ top = Topology() ## The Topology read from the PDBx/mmCIF file self.topology = top self._positions = [] # Load the file. inputFile = file if isinstance(file, str): inputFile = open(file) reader = PdbxReader(inputFile) data = [] reader.read(data) block = data[0] # Build the topology. atomData = block.getObj('atom_site') atomNameCol = atomData.getAttributeIndex('label_atom_id') atomIdCol = atomData.getAttributeIndex('id') resNameCol = atomData.getAttributeIndex('label_comp_id') resIdCol = atomData.getAttributeIndex('label_seq_id') resNumCol = atomData.getAttributeIndex('auth_seq_id') asymIdCol = atomData.getAttributeIndex('label_asym_id') chainIdCol = atomData.getAttributeIndex('label_entity_id') elementCol = atomData.getAttributeIndex('type_symbol') altIdCol = atomData.getAttributeIndex('label_alt_id') modelCol = atomData.getAttributeIndex('pdbx_PDB_model_num') xCol = atomData.getAttributeIndex('Cartn_x') yCol = atomData.getAttributeIndex('Cartn_y') zCol = atomData.getAttributeIndex('Cartn_z') lastChainId = None lastResId = None lastAsymId = None atomTable = {} atomsInResidue = set() models = [] for row in atomData.getRowList(): atomKey = ((row[resIdCol], row[asymIdCol], row[atomNameCol])) model = ('1' if modelCol == -1 else row[modelCol]) if model not in models: models.append(model) self._positions.append([]) modelIndex = models.index(model) if row[altIdCol] != '.' and atomKey in atomTable and len( self._positions[modelIndex]) > atomTable[atomKey].index: # This row is an alternate position for an existing atom, so ignore it. continue if modelIndex == 0: # This row defines a new atom. if lastChainId != row[chainIdCol]: # The start of a new chain. chain = top.addChain(row[asymIdCol]) lastChainId = row[chainIdCol] lastResId = None lastAsymId = None if lastResId != row[resIdCol] or lastAsymId != row[ asymIdCol] or (lastResId == '.' and row[atomNameCol] in atomsInResidue): # The start of a new residue. res = top.addResidue( row[resNameCol], chain, None if resNumCol == -1 else row[resNumCol]) lastResId = row[resIdCol] lastAsymId = row[asymIdCol] atomsInResidue.clear() element = None try: element = elem.get_by_symbol(row[elementCol]) except KeyError: pass atom = top.addAtom(row[atomNameCol], element, res, row[atomIdCol]) atomTable[atomKey] = atom atomsInResidue.add(row[atomNameCol]) else: # This row defines coordinates for an existing atom in one of the later models. try: atom = atomTable[atomKey] except KeyError: raise ValueError( 'Unknown atom %s in residue %s %s for model %s' % (row[atomNameCol], row[resNameCol], row[resIdCol], model)) if atom.index != len(self._positions[modelIndex]): raise ValueError( 'Atom %s for model %s does not match the order of atoms for model %s' % (row[atomIdCol], model, models[0])) self._positions[modelIndex].append( Vec3(float(row[xCol]), float(row[yCol]), float(row[zCol])) * 0.1) for i in range(len(self._positions)): self._positions[i] = self._positions[i] * nanometers ## The atom positions read from the PDBx/mmCIF file. If the file contains multiple frames, these are the positions in the first frame. self.positions = self._positions[0] self.topology.createStandardBonds() self._numpyPositions = None # Record unit cell information, if present. cell = block.getObj('cell') if cell is not None and cell.getRowCount() > 0: row = cell.getRow(0) (a, b, c) = [ float(row[cell.getAttributeIndex(attribute)]) * 0.1 for attribute in ('length_a', 'length_b', 'length_c') ] (alpha, beta, gamma) = [ float(row[cell.getAttributeIndex(attribute)]) * math.pi / 180.0 for attribute in ('angle_alpha', 'angle_beta', 'angle_gamma') ] self.topology.setPeriodicBoxVectors( computePeriodicBoxVectors(a, b, c, alpha, beta, gamma)) # Add bonds based on struct_conn records. connectData = block.getObj('struct_conn') if connectData is not None: res1Col = connectData.getAttributeIndex('ptnr1_label_seq_id') res2Col = connectData.getAttributeIndex('ptnr2_label_seq_id') atom1Col = connectData.getAttributeIndex('ptnr1_label_atom_id') atom2Col = connectData.getAttributeIndex('ptnr2_label_atom_id') asym1Col = connectData.getAttributeIndex('ptnr1_label_asym_id') asym2Col = connectData.getAttributeIndex('ptnr2_label_asym_id') typeCol = connectData.getAttributeIndex('conn_type_id') connectBonds = [] for row in connectData.getRowList(): type = row[typeCol][:6] if type in ('covale', 'disulf', 'modres'): key1 = (row[res1Col], row[asym1Col], row[atom1Col]) key2 = (row[res2Col], row[asym2Col], row[atom2Col]) if key1 in atomTable and key2 in atomTable: connectBonds.append((atomTable[key1], atomTable[key2])) if len(connectBonds) > 0: # Only add bonds that don't already exist. existingBonds = set(top.bonds()) for bond in connectBonds: if bond not in existingBonds and ( bond[1], bond[0]) not in existingBonds: top.addBond(bond[0], bond[1]) existingBonds.add(bond)
def init_simulation(self, complex_list): settings = AdvancedSettings.instance self.__forcefield = settings.get_forcefield() # Create topology topology = Topology() added_atoms = dict() positions = [] PDBFile._loadNameReplacementTables() self.__complex_list = complex_list min_x = max_x = min_y = max_y = min_z = max_z = None Logs.debug("Create topology") for complex in complex_list: for molecule in complex.molecules: for chain in molecule.chains: sim_chain = topology.addChain() for residue in chain.residues: residueName = residue.molecular.name if residueName in PDBFile._atomNameReplacements: atomReplacements = PDBFile._atomNameReplacements[residueName] else: atomReplacements = {} sim_residue = topology.addResidue(residue.molecular.name, sim_chain) for atom in residue.atoms: molecular = atom.molecular symbol = MDSimulationProcess.get_atom_symbol(molecular.name, len(residue._atoms)) atom_name = molecular.name if atom_name in atomReplacements: atom_name = atomReplacements[atom_name] sim_atom = topology.addAtom(atom_name, symbol, sim_residue) added_atoms[atom.index] = sim_atom position = molecular.position positions.append(Vec3(position.x * 0.1 * nanometer, position.y * 0.1 * nanometer, position.z * 0.1 * nanometer)) if min_x == None or position.x < min_x: min_x = position.x if max_x == None or position.x > max_x: max_x = position.x if min_y == None or position.y < min_y: min_y = position.y if max_y == None or position.y > max_y: max_y = position.y if min_z == None or position.z < min_z: min_z = position.z if max_z == None or position.z > max_z: max_z = position.z topology.createStandardBonds() topology.createDisulfideBonds(positions) added_bonds = set(topology.bonds()) for complex in complex_list: for molecule in complex.molecules: for chain in molecule.chains: for residue in chain.residues: for bond in residue.bonds: if bond.index in added_bonds: continue atom1 = added_atoms[bond.atom1.index] atom2 = added_atoms[bond.atom2.index] type = MDSimulationProcess.get_bond_type(bond.molecular.kind) topology.addBond(atom1, atom2, type) added_bonds.add(bond.index) # topology.setPeriodicBoxVectors(computePeriodicBoxVectors(max_x - min_x, max_y - min_y, max_z - min_z, 90, 90, 90)) topology.setPeriodicBoxVectors(computePeriodicBoxVectors(49.163, 45.981, 38.869, 90.00, 90.00, 90.00)) # Create simulation parameters # nonbondedMethod = PME [templates, residues] = self.__forcefield.generateTemplatesForUnmatchedResidues(topology) for index, residue in enumerate(residues): template = templates[index] print("unmatched residue:", residue) # for index, template in enumerate(templates): # residue = residues[index] # residue_bonds = list(residue.internal_bonds())+list(residue.external_bonds()) # print("residue bonds:", residue_bonds) # (unique_res_bonds, unique_tmp_bonds) = ForceField.findMissingBonds(residue, template) # print("UNIQUE RESIDUE BONDS:", unique_res_bonds) # print("UNIQUE TEMPLATE BONDS:", unique_tmp_bonds) # print(f"RESIDUE {residue.name}:") # if len(unique_res_bonds) > 0: # print("Missing bonds:") # for res_bond in unique_res_bonds: # print(f"\n{res_bond}") # print(f"TEMPLATE {template.name}:") # if len(unique_tmp_bonds) > 0: # print("Missing bonds:") # for tmp_bond in unique_tmp_bonds: # print(f"\n{tmp_bond}") # print("-------------------------") # for bond in unique_res_bonds: # template.name += '[' + ForceField.getAtomID(bond[0]) + '<-->' + ForceField.getAtomID(bond[1]) + ']' # if bond[0] in residue.atoms() and bond[1] in residue.atoms(): # template.addBondByName(bond[0].name, bond[1].name) # else: # template.addExternalBondByName(bond[0].name) # if template.name not in self.__forcefield._templates: # self.__forcefield.registerResidueTemplate(template) # print(f"registering template {template.name}") # else: # print(f"redundant template {template.name} ********************") # system = self.__forcefield.createSystem(topology, nonbondedMethod = NoCutoff, nonbondedCutoff = 1 * nanometer, constraints = HBonds) system = settings.get_system(topology) # Set the simulation # integrator = LangevinIntegrator(300 * kelvin, 1 / picosecond, 0.002 * picosecond) integrator = settings.get_integrator() if settings.system_thermostat is not 'None': temp = settings.system_generation_temp col_rate = settings.integrator_collision_rate system.addForce(mm.AndersenThermostat(temp*kelvin, col_rate/picoseconds)) # simulation = Simulation(topology, system, integrator) self.__simulation = settings.get_simulation(positions) # Set reporting settings.attach_reporter(MDReporter, self.simulation_result) self.__simulation.context.setPositions(positions) if settings.simulation_minimize: self.__plugin.send_notification(nanome.util.enums.NotificationTypes.message, "Minimizing...") self.__simulation.minimizeEnergy() if settings.system_random_init_vel: self.__simulation.context.setVelocitiesToTemperature(settings.system_generation_temp*kelvin) eq_steps = settings.simulation_equilibrium_steps if eq_steps: self.__plugin.send_notification(nanome.util.enums.NotificationTypes.message, "Equilibrating...") self.simulate(complex_list, eq_steps)