def to_file_pdb(item, molecular_system=None, atom_indices='all', structure_indices='all', output_filename=None): from io import StringIO from openmm.app import PDBFile from molsysmt import __version__ as msm_version from openmm import Platform # the openmm version is taken from this module (see: openmm/app/pdbfile.py) tmp_io = StringIO() PDBFile.writeFile(item.topology, item.positions, tmp_io, keepIds=True) filedata = tmp_io.getvalue() openmm_version = Platform.getOpenMMVersion() filedata = filedata.replace( 'WITH OPENMM ' + openmm_version, 'WITH OPENMM ' + openmm_version + ' BY MOLSYSMT ' + msm_version) tmp_io.close() del (tmp_io) with open(output_filename, 'w') as file: file.write(filedata) tmp_item = output_filename if molecular_system is not None: tmp_molecular_system = molecular_system.combine_with_items( tmp_item, atom_indices=atom_indices, structure_indices=structure_indices) else: tmp_molecular_system = None return tmp_item, tmp_molecular_system
def _fix(self, atoms): try: from pdbfixer import PDBFixer from openmm.app import PDBFile except ImportError: raise ImportError('Please install PDBFixer and OpenMM 7.6 in order to use ClustENM.') stream = createStringIO() title = atoms.getTitle() writePDBStream(stream, atoms) stream.seek(0) fixed = PDBFixer(pdbfile=stream) stream.close() fixed.missingResidues = {} fixed.findNonstandardResidues() fixed.replaceNonstandardResidues() fixed.removeHeterogens(False) fixed.findMissingAtoms() fixed.addMissingAtoms() fixed.addMissingHydrogens(self._ph) stream = createStringIO() PDBFile.writeFile(fixed.topology, fixed.positions, stream, keepIds=True) stream.seek(0) self._atoms = parsePDBStream(stream) self._atoms.setTitle(title) stream.close() self._topology = fixed.topology self._positions = fixed.positions
def to_pdb(item, atom_indices='all', structure_indices='all', topology_item=None, trajectory_item=None, coordinates_item=None, box_item=None, output_filename=None): from io import StringIO from openmm.app import PDBFile #from openmm.version import short_version from molsysmt import __version__ as msm_version from openmm import Platform # the openmm version is taken from this module (see: openmm/app/pdbfile.py) tmp_io = StringIO() positions = get_coordinates_from_system(item)[0] PDBFile.writeFile(item.topology, positions, tmp_io, keepIds=True) openmm_version = Platform.getOpenMMVersion() filedata = filedata.replace( 'WITH OPENMM ' + openmm_version, 'WITH OPENMM ' + openmm_version + ' BY MOLSYSMT ' + msm_version) tmp_io.close() del (tmp_io) if output_filename == '.pdb': return filedata else: with open(output_filename, 'w') as file: file.write(filedata) pass
def addHydrogens(): if 'addHydrogens' in request.form: pH = float(request.form.get('ph', '7')) fixer.addMissingHydrogens(pH) if 'addWater' in request.form: padding, boxSize, boxShape = None, None, None if request.form['boxType'] == 'geometry': padding = float(request.form['geomPadding']) * unit.nanometer boxShape = request.form['geometryDropdown'] else: boxSize = (float(request.form['boxx']), float( request.form['boxy']), float( request.form['boxz'])) * unit.nanometer ionicStrength = float(request.form['ionicstrength']) * unit.molar positiveIon = request.form['positiveion'] + '+' negativeIon = request.form['negativeion'] + '-' fixer.addSolvent(boxSize=boxSize, padding=padding, boxShape=boxShape, positiveIon=positiveIon, negativeIon=negativeIon, ionicStrength=ionicStrength) elif 'addMembrane' in request.form: lipidType = request.form['lipidType'] padding = float(request.form['membranePadding']) * unit.nanometer ionicStrength = float(request.form['ionicstrength']) * unit.molar positiveIon = request.form['positiveion'] + '+' negativeIon = request.form['negativeion'] + '-' fixer.addMembrane(lipidType=lipidType, minimumPadding=padding, positiveIon=positiveIon, negativeIon=negativeIon, ionicStrength=ionicStrength) # Save the new PDB file. uploadedFiles['originalFile'] = uploadedFiles['file'] pdb = StringIO() if session['pdbType'] == 'pdb': try: PDBFile.writeFile(fixer.topology, fixer.positions, pdb, True) except: # This can happen if the ids are too large to fit in the allowed space. pdb = StringIO() PDBFile.writeFile(fixer.topology, fixer.positions, pdb, False) else: PDBxFile.writeFile(fixer.topology, fixer.positions, pdb, True) temp = tempfile.TemporaryFile() temp.write(pdb.getvalue().encode('utf-8')) name = uploadedFiles['file'][0][1] dotIndex = name.rfind('.') if dotIndex == -1: prefix = name suffix = '' else: prefix = name[:dotIndex] suffix = name[dotIndex:] uploadedFiles['file'] = [(temp, prefix + '-processed' + suffix)] return showSimulationOptions()
def writePDBFixed(self): 'Write the fixed (initial) structure to a pdb file.' try: from openmm.app import PDBFile except ImportError: raise ImportError('Please install PDBFixer and OpenMM 7.6 in order to use ClustENM.') PDBFile.writeFile(self._topology, self._positions, open(self.getTitle()[:-8] + 'fixed.pdb', 'w'), keepIds=True)
def to_string_pdb_text(item, atom_indices='all', coordinates=None, box=None, check=True): if check: digest_item(item, 'openmm.Topology') atom_indices = digest_atom_indices(atom_indices) coordinates = digest_coordinates(coordinates) box = digest_box(box) from io import StringIO from openmm.app import PDBFile from molsysmt import __version__ as msm_version from openmm import Platform # the openmm version is taken from this module (see: openmm/app/pdbfile.py) from molsysmt import puw n_structures = coordinates.shape[0] if n_structures > 1: import warnings warnings.warn( "Openmm.Topology/to_string_pdb_text got more than a single structure. Only the 0-th is taken." ) tmp_io = StringIO() coordinates = puw.convert(coordinates[0], 'nm', to_form='openmm.unit') PDBFile.writeFile(item, coordinates, tmp_io, keepIds=True) filedata = tmp_io.getvalue() openmm_version = Platform.getOpenMMVersion() filedata = filedata.replace( 'WITH OPENMM ' + openmm_version, 'WITH OPENMM ' + openmm_version + ' BY MOLSYSMT ' + msm_version) tmp_io.close() del (tmp_io) tmp_item = filedata return tmp_item
def cleanProtein(structure, mutator=None, regexes=None, hydrogens=True, run_pdb2pqr=True, quiet=False, remove_numerical_chain_id=False, method="geobind", **kwargs): """ Perform any operations needed to modify the structure or sequence of a protein chain. """ prefix = structure.name # used for file names if remove_numerical_chain_id: # APBS and TABI-PB does not process numerical chain IDs correctly. This is a work-around available_ids = list( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") # find current chain ids taken_ids = set() for chain in structure.get_chains(): cid = chain.get_id() taken_ids.add(cid) # iterate over chains and update chain_map = {} for chain in structure.get_chains(): cid = chain.get_id() if cid.isnumeric(): # we want to replace this chain id while len(available_ids) > 0: new_id = available_ids.pop() if new_id in taken_ids: continue else: break chain_map[cid] = new_id chain.id = new_id else: chain_map[cid] = cid if method == "geobind": # set up needed objects if regexes is None: regexes = data.regexes if mutator is None: mutator = ResidueMutator(data.tripeptides, data.chem_components) # remove non-standard residues for chain in structure.get_chains(): replace = [] remove = [] for residue in chain: resn = residue.get_resname().strip() resid = residue.get_id() if resn in data.chem_components and heavyAtomCount(residue) / ( data.chem_components[resn]['heavy_atom_count'] - 1) < 0.6: # too many missing atoms - replace residue replace.append(resid) elif mutator.standard(resn): if resid[0] == ' ': continue else: remove.append( (resid, "removed HETATM standard residue: %s")) elif resn == 'HOH' or resn == 'WAT': remove.append((resid, None)) elif regexes["SOLVENT_COMPONENTS"].search(resn): continue elif mutator.modified(resn): replace.append(resid) else: remove.append((resid, "removed unrecognized residue: %s")) for rid, reason in remove: if reason is not None and not quiet: logging.info(reason, chain[rid].get_resname()) chain.detach_child(rid) for rid in replace: replacement = mutator.mutate(chain[rid]) if replacement: if not quiet: logging.info("replacing residue %s with %s", chain[rid].get_resname(), replacement.get_resname()) replacement.id = rid idx = chain.child_list.index(chain[rid]) chain.child_list[idx] = replacement else: if not quiet: logging.info( "could not perform replacement on %s, removing", chain[rid].get_resname()) chain.detach_child(rid) elif method == "pdbfixer": try: from pdbfixer import PDBFixer from openmm.app import PDBFile except ModuleNotFoundError: raise ModuleNotFoundError( "The dependencies 'pdbfixer' and 'openmm' are required with option 'method=\"pdbfixer\"'" ) # create a temp file tmpFile1 = tempFileName(prefix, 'pdb') structure.save(tmpFile1) # run pdbfixer fixer = PDBFixer(filename=tmpFile1) fixer.findMissingResidues() fixer.findNonstandardResidues() fixer.replaceNonstandardResidues() fixer.removeHeterogens(False) fixer.findMissingAtoms() fixer.addMissingAtoms() tmpFile2 = tempFileName(prefix, 'pdb') PDBFile.writeFile(fixer.topology, fixer.positions, open(tmpFile2, 'w'), keepIds=True) # load new fixed structure structure = StructureData(tmpFile2, name=prefix) # clean up os.remove(tmpFile1) os.remove(tmpFile2) # run PDB2PQR if requested if run_pdb2pqr: structure, pqrFile = runPDB2PQR(structure, **kwargs) # remove hydrogens if requested if not hydrogens: stripHydrogens(structure) # decide what to return rargs = [structure] if run_pdb2pqr: rargs.append(pqrFile) if remove_numerical_chain_id: rargs.append(chain_map) return tuple(rargs)
def getCurrentStructure(): pdb = StringIO() PDBFile.writeFile(fixer.topology, fixer.positions, pdb) return pdb.getvalue()