def __initCreate(self): if not self.create: from Amber import AmberCreateSystem self.create = AmberCreateSystem(FFlist=self.FF, informative=False) if self.amberOFF: tmpoff = self.amberOFF.writeTmp() self.create.loadOff(tmpoff) # will write to temporary file location self.amberOFF.cleanTmp()
def saveOFF(self, outname, inpdb=None, unitname='sys', extraff=[]): "From a PDBModel or File, load into tLeap and save as ObjectFile." from Amber import AmberCreateSystem if not inpdb and self.pdb: inpdb = self.pdb else: raise AutoPrepareError, "Input needed." prepare = AmberCreateSystem() prepare.createOFF(outname, inpdb, extraff=extraff, **kwargs) outoff = outname+'.lib' return osp.abspath(outoff)
def setPDBfromTOPCRD(self): "Save a PDB file from the TOP and CRD files in attributes." import time from Amber import AmberCreateSystem self.getTmpTopCrdFiles() self.tmp_pdb = tmp = T.tempfile.mktemp() + '.pdb' create = AmberCreateSystem(informative=False) create.ambpdb(self.tmp_top, self.tmp_crd, self.tmp_pdb) time.sleep(1) # delay to allow ampdb work self.pdb = open(self.tmp_pdb, 'r').read() self.cleanTmp()
class System(object): """ """ def __init__(self, name=None, fromfile=None, amberPDB=None, amberOFF=None, unitName=None, extraResList=[], FF=S.DEF_AMBER_FF, **kwargs): """ Initialize a system object. :arg str name: Identified name for the system. If None, a random name will be generated ``mdmix_system_XXX``. :arg str fromfile: Path to already pickled System object to be loaded. :arg str amberPDB: Path to PDB file already prepared to amber standards and ready for topology generation. :arg str amberOFF: Path to Amber Object File (OFF) containing the system already parameterized and stored as a Leap Unit. :arg str uniName: Name of the unit containing the system in the OFF file. If not given, the first name found in the file will be used. :arg list extraResList: Non standard residue names to consider as part of the macromolecule. :arg list FF: Forcefields used to parameterize the system in the OFF file or in the preparation of the PDB (atom names should coincide). If non-standard residues are present, any frcmod file used should also be given for correctly parameterizing them. """ if fromfile: self.load(fromfile) else: if not name: # Generate random string import random, string randstr = ''.join( random.choice(string.ascii_uppercase + string.digits) for _ in range(3)) name = 'mdmix_system_' + randstr self.name = name self.extraResList = extraResList self.sysFilePath = self.name + '.msys' # Try to find path of extra FF files if given self.FF = [] for f in FF: if osp.exists(f): self.FF.append(osp.abspath(f)) else: self.FF.append( f ) # it might be a parm file located in amber standard folders (to be checked later) # Files to be generated self.amberOFF = None #: :class:`~OFFManager.OFFManager` object to store the amber object file with the system. To be set with :meth:`setOFF` self.unitName = None #: To be set with :meth:`setOFF` self.ref = None #: PDB of the macromolecule, generated from :attr:`amberOFF` and :attr:`extraResList` # Internal control attrs self.create = False self.__filecreated = False # OFF constructor has priority if amberOFF: self.setOFF(amberOFF, unitName) elif amberPDB: self.setAmberPDB(amberPDB, **kwargs) else: pass # Wait for incorporation of data later def __repr__(self): return "%s System" % self.name def __str__(self): s = "SYSTEM:%s\n" % self.name if self.FF: s += "\tFF:%s\n" % self.FF if self.extraResList: s += "\tExtraRes:%s\n" % self.extraResList return s def __add__(self, other): from MDSettings import MDSettings from Replicas import Replica if isinstance(other, MDSettings): other = [other] if isinstance(other, list): # Check elements are MDSettings objects out = [] for el in other: if isinstance(el, MDSettings): sys = self.solvate(el.solvent) out.append(Replica(sys, el)) if len(out) == 1: return out[0] return out # def __getstate__(self): # d = self.__dict__.copy() # del d['log'] # return d # # def __setstate__(self, d): # d['log'] = logging.getLogger("System (%s)"%d['name']) # self.__dict__.update(d) def __initCreate(self): if not self.create: from Amber import AmberCreateSystem self.create = AmberCreateSystem(FFlist=self.FF, informative=False) if self.amberOFF: tmpoff = self.amberOFF.writeTmp() self.create.loadOff( tmpoff) # will write to temporary file location self.amberOFF.cleanTmp() def __cleanCreate(self): if self.create: self.create.leap.close() self.create = None def setAmberPDB(self, amberPDB, FF=[], **kwargs): """ Set up an amber object file departing from a PDB file already prepared to amber standards and ready for topology generation. Despite a good PDB file is expected, some cleaning process will take place: - Cap N and C terminus - Rename HIS residues according to protonation - Rename CYS to CYX if needed, and disulfide bridges built in tLeap - Removal of all hydrogen atoms to let tLeap add them back. :arg str amberPDB: Path to PDB file complying with amber specifications. :arg list FF: Forcefield names and modification files that might be needed to correctly interpret the PDB by tLeap. :kwargs: Check :meth:`~AutoPrepare.AmberPDBCleaner.cleanPDB` method for extra parameters that are accepted to control automatic cleaning of the PDB. :return: Nothing will be returned, the object file generated will be stored in :attr:`amberOFF` as an :class:`~OFFManager.OFFManager` object. """ if not osp.exists(amberPDB): raise BadFile, "PDB file %s does not exists" FF = FF or self.FF self.__initCreate() self.create.createOFF(self.name, amberPDB, extraff=FF, **kwargs) outoff = self.name + '.lib' self.setOFF(outoff, 'sys') def setOFF(self, amberOFF, unitname=None): """ Save Amber Object file as :class:`OFFManager.OFFManager` object in :attr:`amberOFF`. :attr:`unitName` will be set. :arg str amberOFF: Path to amber object file. :arg str unitname: Name of the unit we should use in the future. If not given, automatically take the first unit found in the file. """ from OFFManager import OFFManager # Special case: test # Grab off from testing directory if amberOFF.lower() == 'test': print "WORKING WITH A TEST SYSTEM!" amberOFF = T.testRoot('pep', 'pep.off') self.name = 'testsystem' self.sysFilePath = self.name + '.msys' self.amberOFF = OFFManager(amberOFF) if not unitname: units = self.amberOFF.getUnits() unitname = units[0] self.unitName = unitname self.__createRef() def solvate(self, solvent, suffix=None, tmp=True): """ Solvate system in OFF using solvent *solvent*. A PRMTOP and PRMCRD files will be saved and paths stored to :attr:`top` and :attr:`crd`. :arg solvent: Solvent Instance or Name to fetch the Solvent Instance in the database. :type: str or :class:`~Solvents.Solvent` :arg str suffix: Suffix for output files. Prefix will be the system name. E.g.: ``systemname_suffix.prmtop`` and ``systemname_suffix.prmcrd``. :arg bool tmp: Work in temporary folder. """ if not self.amberOFF: raise SystemError, "Can not solvate if no Amber Object File is assigned." if isinstance(solvent, str): solvent = Solvents.getSolvent(solvent) if not solvent: raise SystemError, 'Invalid solvent instance or name.' # Build a loger just for this method log = logging.getLogger("SystemLogger") log.info("Solvating %s with solvent mixture %s" % (self.name, solvent.name)) suffix = suffix or solvent.name name = '{0}_{1}'.format(self.name, suffix) prmtop = name + '.prmtop' prmcrd = name + '.prmcrd' if tmp: if isinstance(tmp, str): path = tmp else: path = T.tempDir() prmtop = osp.join(path, prmtop) prmcrd = osp.join(path, prmcrd) # Initiate AmberCreateSystem with loaded AmberOFF # Solvate, neutralize self.__initCreate() self.create.solvateOrganic( self.unitName, solvent=solvent) # It will work even if its water self.create.saveAmberParm(self.unitName, prmtop, prmcrd) self.__cleanCreate() s = SolvatedSystem(name, prmtop, prmcrd, solvent=solvent.name, ref=self.ref) return s def writeOFF(self, fname): "Write Object File to disk file with name *fname*" if self.amberOFF: return self.amberOFF.write(fname) def __createRef(self): """ Create reference pdb and store it in self.ref """ import Biskit as bi # Initiate AmberCreateSystem with loaded AmberOFF self.__initCreate() self.create.saveAmberParm(self.unitName, 'tmp.top', 'tmp.crd') self.create.ambpdb('tmp.top', 'tmp.crd', 'tmp.pdb') self.ref = bi.PDBModel('tmp.pdb') self.ref.source.set_string("System %s reference" % self.name) # Remove tmp files [os.remove('tmp.' + ext) for ext in ('top', 'crd', 'pdb')] self.__cleanCreate() def copy(self): """ Return a copy of the system object so it can be altered. sysFilePath will be reset and __creted """ import copy return copy.deepcopy(self) def write(self, outfile=None): "Save object __dict__ to pickled file." outfile = outfile or self.sysFilePath with FileLock(outfile) as lock: d = self.__dict__.copy() d['create'] = None #Dont pickle Amber class if loaded # del d['log'] T.dump(d, outfile) self.sysFilePath = osp.abspath(outfile) self.__sysfile = True def load(self, sysfile=None): "Load existing project from pickled file" f = sysfile or self.sysFilePath if not osp.exists(f): raise BadFile, "File %s not found." % f with FileLock(f) as lock: d = T.load(f) # d['log'] = logging.getLogger("System (%s)"%d['name']) self.__dict__.update(d)