Exemple #1
0
 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()
Exemple #2
0
    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)
Exemple #3
0
    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()
Exemple #4
0
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)