Esempio n. 1
0
    def generateBuildingBlockXYZ(self):

        # create a building block generator using the standard parameter file for this object
        strandGen = PBG(self.paramFilename)

        # construct a prototype beta strand building block
        strandBB = strandGen.generateBuildingBlock(self.strandLength)

        # generate an array of strand building blocks
        BBs = [
            strandBB.cloneBuildingBlock() for _ in range(0, self.numStrands)
        ]
        baseLine = [
            self.startPos +
            n * self.betaStrandSeparation * self.crossStrandDirectorHat
            for n in range(self.numStrands)
        ]
        directors = [self.inStrandDirectorHat for n in range(self.numStrands)]
        rotation = [0.0 for n in range(self.numStrands)]

        # modify the strands if we are anti-parallel
        if not self.parallel:
            baseLine = [
                basePoint if n % 2 == 0 else basePoint + self.offsetXYZ
                for n, basePoint in enumerate(baseLine)
            ]
            directors = [
                self.inStrandDirectorHat if n % 2 == 0 else -1 *
                self.inStrandDirectorHat for n in range(self.numStrands)
            ]
            rotation = [
                rot if n % 2 == 0 else 0 for n, rot in enumerate(rotation)
            ]

        # do the sheet construction:
        [
            BB.transformBBToLabFrame(director, pos,
                                     rot) for director, pos, rot, BB in zip(
                                         directors, baseLine, rotation, BBs)
        ]

        # if we are adding loops then construct the loops
        if self.numLoopResidues > 0:
            Loops = self.constructLoops(BBs)

        # compile the final building block
        retBB = BBs[0]
        if self.numLoopResidues > 0:
            for BB, Loop in zip(BBs[1:], Loops):
                retBB.append(Loop)
                retBB.append(BB)
        else:
            [retBB.append(BB) for BB in BBs[1:]]

        return retBB.blockXYZVals
Esempio n. 2
0
    def initialiseParameters(self):
        BBG.initialiseParameters(self)

        self.numResiduesAlphaHelix = self.getParam('numResiduesAlphaHelix')
        self.lengthPerResidueAlpha = self.getParam('lengthPerResidueAlpha')
        self.lengthPerResidueBeta = self.getParam('lengthPerResidueBeta')
        self.terminiSeparation = self.getParam('terminiSeparation')
        self.numBetaSheets = self.getParam('numBetaSheets')
        self.numBetaStrands = self.getParam('numBetaStrands')
        self.betaStrandLength = self.getParam('betaStrandLength')
        self.betaSheetRx = self.getParam('betaSheetRx')
        self.betaSheetRy = self.getParam('betaSheetRy')
        self.betaSheetRz = self.getParam('betaSheetRz')
        self.alphaBetaSeparation = self.getParam('alphaBetaSeparation')
        self.alphaHelixAtomName = self.getParam('alphaHelixAtomName')
        self.betaStrandAtomName = self.getParam('betaStrandAtomName')
        self.coilAtomName = self.getParam('coilAtomName')

        self.BSG = BSG(self.paramFilename)
        self.AHG = PBG(self.paramFilename)
        self.PHG = PHG(self.paramFilename)
        self.USP = NBB(self.paramFilename)
        self.SPEBBG = SPEBBG(self.paramFilename)

        if self.noLoadErrors == False:
            print "Critical Parameters are undefined for Spidroin Object"
            sys.exit()
Esempio n. 3
0
 def initialiseParameters(self):
     # initialise the constrained polymer parent
     CPBBG.initialiseParameters(self)
     
     # load the backbone building object
     self.PBG = PBG(self.paramFilename)
     
     if self.noLoadErrors == False:            
         print "Critical Parameters are undefined for hairpin"
         sys.exit()        
Esempio n. 4
0
    def initialiseParameters(self):
        # initialise the constrained polymer parent
        CPBBG.initialiseParameters(self)

        self.distEpsilon = self.getParam("distEpsilon")
        self.maxNumConnectingMoves = self.getParam("maxNumConnectingMoves")
        self.springConstant = self.getParam("springConstant")
        self.connectingTemp = self.getParam("connectingTemp")

        # load the backbone building object
        self.PBG = PBG(self.paramFilename)

        if self.noLoadErrors == False:
            print "Critical Parameters are undefined for hairpin"
            sys.exit()
Esempio n. 5
0
class peptideHairpinGenerator(CPBBG):
    ''' This class returns a randomly coiled peptide backbone between two sets of points 
    A and B, which is packed into an external envelope. The backbone does not
    self-intersect and the coil avoids a user supplied set of external points.  
    
    The class inherits the functionality of the constrainedPolymerClass.
    The generateSpaceCurve method of that class is overridden to provide an unfolded 
    peptideBackbone.
    
    The user supplies three points for pointsA and pointsB. PointsA form the initial seed for the chain.
    The first point in A is non negotiable and fixed. But the second and third points
    are movable once the initial connected chain has been built.
    
    The main advantage of providing three points is so that derivatives as well as the end points match up,
    yielding a much smoother link between coils.
    
    PointsA and pointsB are supplied in the format m0, m1 and m2 where m0 is the innermost point of a connector.
    Thus point m2 (the third point in pointsA) is actually the start of the chain. This is important.
    Throughouth the project connectors are defined as m0, m1 and m2.
    
    The energy function is overloaded to compute the energy of two springs between the 
    two atoms at the free end of the chain and the two atoms of the second anchor; Points B is 
    then computed based on the distance between them. Conformations with smaller 
    amounts of energy are found by picking C-CA or N-CA bonds at random and 
    performing dihedral moves of the entire free end of chain from the selected 
    bond onwards.  (PS at some time point later this gradient thing was abandoned because it took too long. 
    The code was greyed out in the PE function, but you can put it back in if you want).
    
    Each time a move is made the new energy of the two springs is calculated for the 
    new position. If the move results in lower total spring energy than the lowest energy 
    yet found it is accepted. If the spring energy is larger than the current minimum 
    the move is accepted with a probability based on the boltzman factor between the 
    current lowest energy and the new energy.
    
    As the distance between the end point and point B shrinks the allowed size 
    range of rotations shrinks rapidly.
        
    The naming functions and allowedList functions are also overridden so
    that only the alpha carbons are allowed to be used in the dihedral twist 
    rotations. This restriction preserves the peptide bond angles in the chain.
     
    Once a double anchored space curve is generated, with anchor points at 
    pointsA and B, the procedure for randomising the coil with crankshaft moves and 
    folding the chain into an envelope is the same as for the coiled polymer baseclass.
    
    The final structure is exported as a building block class.'''

      
    def __init__(self, paramFilename):
        # initialise the parameter dictionary for the base classes
        CPBBG.__init__(self, paramFilename)
        
    def initialiseParameters(self):
        # initialise the constrained polymer parent
        CPBBG.initialiseParameters(self)
        
        # load the backbone building object
        self.PBG = PBG(self.paramFilename)
        
        if self.noLoadErrors == False:            
            print "Critical Parameters are undefined for hairpin"
            sys.exit()        

    def generateBuildingBlock(  self, 
                                numResidues, 
                                pointsA,
                                pointsB,
                                minDist,
                                numCrankMoves,
                                pointsToAvoid=[],
                                visualiseEnvelope=(0,20), 
                                envelopeList=['None'],
                                nameCA=False):
        self.numResidues = numResidues
        self.numPoints = self.numResidues * 3
        bondLength = 0.0 # not used in this game
        self.nameCA = nameCA
        self.minDist = minDist

        # set up the right reference points
        self.pointA = pointsA[2]
        self.pointB = pointsB[2]
        self.pointsA = pointsA[:]
        self.pointsB = pointsB[:]
        
        self.parseEnvelopeList(envelopeList)
        self.blockRefPoint = self.generateBuildingBlockRefPoint()
        
        # prematurely add pointsToAvoid and parse the envelope due to the pointsA and pointsB checks below
        self.pointsToAvoid = pointsToAvoid 
        
        # check starting points are legal or it's gonna be a long wait.
        for pos in self.pointsA:
            if not self.checkPointInBounds(pos):
                print "Error Warning: One of pointsA out of bounds"
                time.sleep(3)
             
        for pos in self.pointsB:
            if not self.checkPointInBounds(pos):
                print "Error Warning: One of pointsB out of bounds"
                time.sleep(3)
        
        return CPBBG.generateBuildingBlock(self, self.numPoints, pointsA[2], pointsB[2], minDist, bondLength, numCrankMoves, visualiseEnvelope=visualiseEnvelope, pointsToAvoid=pointsToAvoid, envelopeList=envelopeList) 

    def generateAllowedList(self, short=False):
        # add the first and last points to the allowed list.
        # This is important to allow the full chain to be able to be mapped into the envelope.
        allowed = [0, self.numPoints-1]
        
        # over ride the naming of the atoms with ca=True. 
        names = self.generateBuildingBlockNames(ca=True)
        
        # if the minimisation is already close then only make moves in the last ten CAs closest to the chain 
        if short:
            [ allowed.insert(-1,i) for i, name in enumerate(names) if name=='CA' and i>(len(names) - 10) ]
        else:
            [ allowed.insert(-1,i) for i, name in enumerate(names) if name=='CA' ]
        
        return allowed

    def generateSpaceCurve(self):
        # Over-rides the generate space curve function of the parent to generate a peptide backbone
        # and a pseudo energy landscape approach to find an initial chain with the end point fixed
        # at point B.
        # create a regular backBone using PointsA as the first residue
        peptideBackbone = self.PBG.generateBuildingBlock(self.numResidues, seedResidue = [self.pointsA[2], self.pointsA[1], self.pointsA[0]])
        return peptideBackbone.getAtomsXYZ()  
        
    def PE(self, xyzVals):
        # Over load PE function to include two springs - between the last two points
        # ensures a smooth connection to other polymers
        PE = 0.0
        # add spring between pointB[2] and end of xyzVals with equilibrium at pointB
        dist1 = np.linalg.norm(xyzVals[-1] - self.pointsB[2])
        PE += 0.5 * 3 * self.springConstant * dist1**2
        
        # add spring between pointsB[1] and end of xyzVals[-2] 
        dist2 = 0.0
        # dist2 = np.linalg.norm(xyzVals[-2] - self.pointsB[1])
        # PE += 0.5 * 2 * self.springConstant * dist2**2
        
        return PE, np.sqrt(dist1**2 + dist2**2)
        
    def generateBuildingBlockNames(self, ca=False):
        
        if self.nameCA:
            names = ['N', 'CA', 'C'] * self.numResidues
        else:
            names = ['N', 'C', 'C'] * self.numResidues
        
        # override the externally controlled member variable nameCA with a local variable
        if ca==True:
            names = ['N', 'CA', 'C'] * self.numResidues
        
        return names

    def generateBuildingBlockConnectors(self):
        # N connector first, then C Connector 
        return [ [2, 1, 0], [self.numPoints-3, self.numPoints-2, self.numPoints-1] ]
Esempio n. 6
0
        
        return names

    def generateBuildingBlockConnectors(self):
        # N connector first, then C Connector 
        return [ [2, 1, 0], [self.numPoints-3, self.numPoints-2, self.numPoints-1] ]
        
if __name__ == "__main__":
    
    
    # get the file name from the command line
    filename = sys.argv[1]

    # create the generator objects.
    hairPinGen = peptideHairpinGenerator(filename)
    backboneGenerator = PBG(filename)
    
    # generate 1 residue seed building block
    seedResidue = backboneGenerator.generateBuildingBlock(1)
    
    # generate starting points and move the seed to those points extracting
    # the xyzVals each time. 
    numResidues = 20
    pointA = np.array([10.0, 10.0, 10.0])
    pointB = np.array([0.0, 0.0, 0.0])
    
    print "Estimate min num residues: ", np.linalg.norm(pointA-pointB)/3.5
    
    seedResidue.placeAtom(2, pointA)
    seedResidue.setBlockRefPoint(pointA)
    seedResidue.orientToDirector(np.array([-1.0, 1.0, 0.0]))
Esempio n. 7
0
def decoratePolymerBackbone(brushDictList, backboneInfo): 

    # unpack input
    backboneXYZ = backboneInfo[0]
    backboneNames = backboneInfo[1]
    backboneSegmentLengths = backboneInfo[2]
    backboneTNBList = backboneInfo[3]

    # break the list of XYZ points into list of points for each segment
    backBoneXYZList = breakListToSubList(backboneXYZ, np.cumsum(np.concatenate((np.array([0]), backboneSegmentLengths), 0)))

    # set up output
    polymerXYZ = cp.copy(backboneXYZ)
    polymerNames = cp.copy(backboneNames)
    
    for brush, numBrushes, TNB, points in zip(brushDictList, backboneSegmentLengths, backboneTNBList, backBoneXYZList):
        if brush['numMonomers']>0:
            # create the brush generator. Default is polymer. Check to see if we want a peptide brush 
            if 'Peptide' in brush['mode']:
                brushBBG = PBG(brush['filename'])
                brushBB = brushBBG.generateBuildingBlock(brush['numMonomers']) # only need to create this once for peptide backbones as they are either alpha or beta.
                brushBB.blockAtomNames = brush['monomerNames']
            else:
                brushBBG = RPPBBG(brush['filename'])
        
            # Set the angle of each brush around the segment director defined relative to the Binormal in the TNB frame for that polymer.
            # The range of angles is defined in the dictionary.
            brushPhaseAngles = [ rnd.uniform(0, brush['phaseRange'] * np.pi/180.0) for _ in range(0, numBrushes) ]

            # if the word Alternate is in the mode than add 180 to every other phase        
            if "Alternate" in brush['mode']:
                for index in range(0, numBrushes):
                    if index % 2 ==0:
                        brushPhaseAngles[index] += np.pi
            
            # if the word "mirror" is in the mode then add 180 randomly to half the brush phases 
            if "Mirror" in brush['mode']:
                numFlipped = 0
                indexList = list(range(0, numBrushes))
                while numFlipped < numBrushes/2:
                    index = rnd.choice(indexList)
                    brushPhaseAngles[index] += np.pi
                    numFlipped += 1
                    indexList.remove(index)    
        
            # generate directors in direction of phase angles
            brushDirectors = [ np.cos(angle) * TNB[2] + np.sin(angle) * TNB[1] for angle in brushPhaseAngles] 
            brushDirectorsNorm = [ d/np.linalg.norm(d) for d in brushDirectors]
    
            # for each of the points in the backbone generate a brush as defined    
            for point, director in zip(points, brushDirectorsNorm):
                if "Polymer" in brush['mode'] and not "Peptide" in brush['mode']:
                    # if we're doing a polymer then generate a new polymer with the given polymer parameters for each pass.
                    polyStart = np.array([ 0.0, 0.0, brush['Z1']])
                    envelopeList = ['frustum ' + str(brush['Z1'] - brush['minDist']) + ' ' + str(brush['R1']) + ' ' + str(brush['Z2']) + ' ' + str(brush['R2'])]
                
                    brushBB = brushBBG.generateBuildingBlock( brush['numMonomers'],
                                                              polyStart,
                                                              brush['alpha1'],
                                                              brush['alpha2'],
                                                              brush['beta1'],
                                                              brush['beta2'],
                                                              brush['minDist'],
                                                              brush['bondLength'],
                                                              envelopeList=envelopeList,
                                                              visualiseEnvelope=(0, 100, brush['name'] + '_envelope.xyz'))
                    # work out the block director
                    if brush['numMonomers']>2:
                        blockDirector = coords.axisFromHelix(brushBB.blockXYZVals)
                    else:
                        if brush['numMonomers']==2:
                            blockDirector = brushBB.blockXYZVals[1] - brushBB.blockXYZVals[0]
                            blockDirector = blockDirector/np.linalg.norm(blockDirector)
                        if brush['numMonomers']==1:
                            blockDirector = np.array([0.0, 0.0, 1.0])
    
                    # rotate the brush and set it at the right place
                    brushXYZVals = coords.transformFromBlockFrameToLabFrame(director, point + brush['bondLength'] * director, 0.0, blockDirector, brushBB.blockXYZVals[0], brushBB.blockXYZVals)
            
                    # concatenate the brush positions and the brush names to the output arrays
                    polymerXYZ = np.concatenate( (polymerXYZ, brushXYZVals), 0)
                    polymerNames = np.concatenate( (polymerNames, brush['monomerNames']), 0)
        
    return polymerXYZ, polymerNames 
Esempio n. 8
0
                # then throw a wobbly.
                if np.linalg.norm((zPos - pos)) <= self.minDist:
                    inBounds= False
                    if self.verbose==1: 
                        print("Packing violation")

        return inBounds
        
        
if __name__ == '__main__':
    
    # get the file name from the command line
    filename = sys.argv[1]

    # create a beta backbone generator object using static file parameters
    backboneObject = PBG(filename)

    # generate backbone realtime parameters
    numPos = 3* 8
    startPos = np.array([0.0, 0.0, 0.0])
    director = np.array([0.0, 0.0, 1.0])
    rotation = 0 * np.pi/180
    offset =  np.array([4.8, 0.0, 0.0])
    polarity = 'CN'
    
    backBoneBuildingBlock1 = backboneObject.generateBuildingBlock(numPos, polarity) 
    backBoneBuildingBlock1.transformFromBlockFrameToLabFrame(director, startPos, rotation)
    backBoneBuildingBlock1.exportBBK("backbone1")
    backBoneBuildingBlock2 = backboneObject.generateBuildingBlock(numPos, polarity) 
    backBoneBuildingBlock2.transformFromBlockFrameToLabFrame(director, startPos + offset, rotation)
    backBoneBuildingBlock2.exportBBK("backbone2")
Esempio n. 9
0
    def exportBBK(self, fileroot):
        fIO.saveXYZList(self.blockXYZVals, self.blockAtomNames, fileroot + '.xyz')
        line1 = "floatlist blockRefPoint " + str(self.blockRefPoint[0]) + " " + str(self.blockRefPoint[1]) + " " + str(self.blockRefPoint[2]) + "\n"
        line2 = "floatlist blockOrientation " + str(self.blockDirectorHat[0]) + " " + str(self.blockDirectorHat[1]) + " " + str(self.blockDirectorHat[2]) + "\n"
        lines = "intlist blockConnectors" 
        for connection in self.blockConnectors:
            lines += " " + str(connection[0]) + " " + str(connection[1]) + " " + str(connection[2])
        lines +='\n'
        fIO.writeTextFile([line1, line2, lines], fileroot + '.bbk')

if __name__=="__main__":

    from Library.peptideBackbone import peptideBackboneGenerator as PBG
        
    # set up an alpha helix generator object using the alphaHelix parameters
    helixGenerator = PBG("alphaHelix.txt")
     
    # specify the desired location and orientations of two specific helices
    numResidues = 16
    refPoint1 = np.array([0.0, 0.0, 0.0])
    director1 = np.array([0.0, 0.0, 1.0])
    refPoint2 = np.array([20.0, 0.0, 0.0])
    director2 = np.array([1.0, 0.0, 1.0])
    
    # generate helix1 using the generator function 
    helix1 = helixGenerator.generateBuildingBlock(numResidues, showBlockDirector=False)
    helix1.transformBBToLabFrame(director1, refPoint1, 0)
    
    # generate helix 2 using the generator function
    helix2 = helixGenerator.generateBuildingBlock(numResidues, showBlockDirector=False)
    helix2.transformBBToLabFrame(director2, refPoint2, 0)
Esempio n. 10
0
import numpy as np
from Library.peptideBackbone import peptideBackboneGenerator as PBG
from Library.SurfacePackSphere import SurfacePackSphereBBG as SPSBBG
from Library.VolumePackEllipsoid import VolumePackEllipsoidBBG as VPEBBG
import Utilities.fileIO as fIO
peptideBBG = PBG('betastrand.txt')
sphereBBG = SPSBBG('SurfacePackSphere.txt')
VolSphereBBG = VPEBBG('VolumePackEllipsoid.txt')

numResidues = 5
minDist = 1.0

numStrands = 100
centerPos = np.array([-0,-0, -0])
director = np.array([0, 0, 1])
rotation = 0
radius1 = 22
radius2 = 12
radius3 = 8
theta1 = -90
theta2 = 90
phi1 = -135
phi2 = 135
minDist1 = 3.0
minDist2 = 1.0
minDist3 = 1.0

# generate the XYZVals in the packed spaced
SphereBB = sphereBBG.generateBuildingBlock(numStrands, radius1, theta1, theta2, phi1, phi2, minDist1)
SphereBB.transformBBToLabFrame(director, centerPos, rotation)
SphereBB.exportBBK("sphereBasePoints")
Esempio n. 11
0
class spidroinProteinGenerator(BBG):
    # Each spidroin protein consists of two alpha helical termini and a main
    # body that consists of regions of beta sheet structures linked
    # by hairpin turns.

    def __init__(self, filename):
        BBG.__init__(self, filename)

    def initialiseParameters(self):
        BBG.initialiseParameters(self)

        self.numResiduesAlphaHelix = self.getParam('numResiduesAlphaHelix')
        self.lengthPerResidueAlpha = self.getParam('lengthPerResidueAlpha')
        self.lengthPerResidueBeta = self.getParam('lengthPerResidueBeta')
        self.terminiSeparation = self.getParam('terminiSeparation')
        self.numBetaSheets = self.getParam('numBetaSheets')
        self.numBetaStrands = self.getParam('numBetaStrands')
        self.betaStrandLength = self.getParam('betaStrandLength')
        self.betaSheetRx = self.getParam('betaSheetRx')
        self.betaSheetRy = self.getParam('betaSheetRy')
        self.betaSheetRz = self.getParam('betaSheetRz')
        self.alphaBetaSeparation = self.getParam('alphaBetaSeparation')
        self.alphaHelixAtomName = self.getParam('alphaHelixAtomName')
        self.betaStrandAtomName = self.getParam('betaStrandAtomName')
        self.coilAtomName = self.getParam('coilAtomName')

        self.BSG = BSG(self.paramFilename)
        self.AHG = PBG(self.paramFilename)
        self.PHG = PHG(self.paramFilename)
        self.USP = NBB(self.paramFilename)
        self.SPEBBG = SPEBBG(self.paramFilename)

        if self.noLoadErrors == False:
            print "Critical Parameters are undefined for Spidroin Object"
            sys.exit()

    def generateBuildingBlock(self,
                              startPos,
                              direction,
                              rotation,
                              alignDirectors=True,
                              showDirector=False,
                              nameByBuildingBlockType=True):
        self.numPoints = 0
        self.spidroinDirector = np.array([0.0, 0.0, 1.0])
        self.spidroindRefPoint = np.array([0.0, 0.0, 0.0])
        self.nameByBuildingBlockType = nameByBuildingBlockType

        return BBG.generateBuildingBlock(self,
                                         self.numPoints,
                                         startPos,
                                         direction,
                                         rotation,
                                         alignDirectors=alignDirectors,
                                         showDirector=showDirector)

    def generateBuildingBlockXYZ(self):

        # build the components

        print "Constructing N termninus alpha helix"
        AH_NTerm_numPoints = self.numResiduesAlphaHelix * 3
        AH_NTerm_startPos = np.array([
            -self.terminiSeparation / 2, 0.0,
            self.numResiduesAlphaHelix * self.lengthPerResidueAlpha
        ])
        AH_NTerm_director = 1 * self.spidroinDirector
        AH_NTerm_rotation = 0
        AH_NTerm_polarity = 'NC'

        # Create the N terminus alpha helix bundle
        self.NTerminusAlphaHelix = self.AHG.generateBuildingBlock(
            AH_NTerm_numPoints,
            AH_NTerm_startPos,
            AH_NTerm_director,
            AH_NTerm_rotation,
            AH_NTerm_polarity,
            alignDirectors=True,
            showDirector=False)
        if self.nameByBuildingBlockType:
            self.NTerminusAlphaHelix.replaceNames(self.alphaHelixAtomName)

        print "Constructing C termninus alpha helix"
        AH_CTerm_numPoints = self.numResiduesAlphaHelix * 3
        AH_CTerm_startPos = np.array([self.terminiSeparation / 2, 0.0, 0.0])
        AH_CTerm_director = -1 * self.spidroinDirector
        AH_CTerm_rotation = 0
        AH_CTerm_polarity = 'NC'

        # Create the C terminus alpha helix bundle
        self.CTerminusAlphaHelix = self.AHG.generateBuildingBlock(
            AH_CTerm_numPoints,
            AH_CTerm_startPos,
            AH_CTerm_director,
            AH_CTerm_rotation,
            AH_CTerm_polarity,
            alignDirectors=True,
            showDirector=False)

        if self.nameByBuildingBlockType:
            self.CTerminusAlphaHelix.replaceNames(self.alphaHelixAtomName)

        BS_centre = np.array(
            [0.0, 0.0, -self.betaSheetRz - self.alphaBetaSeparation])
        BS_director = self.spidroinDirector
        BS_rotation = 0
        BS_minDist = 0.8 * np.sqrt(2) * max([
            4.8 * self.numBetaStrands,
            self.betaStrandLength * self.lengthPerResidueBeta
        ])

        print "Constructing Beta Sheet Start Points"

        # then create the start point for a bundle of beta sheets packed uniformly in space
        betaSheetStartPointsBB = self.SPEBBG.generateBuildingBlock(
            self.numBetaSheets, BS_centre, BS_director, BS_rotation,
            self.betaSheetRx, self.betaSheetRy, self.betaSheetRz, BS_minDist)
        betaSheetStartPoints = betaSheetStartPointsBB.xyzVals

        betaSheetDirectors = []
        # create beta sheet directors
        for n in range(0, self.numBetaSheets):
            theta, phi = coords.pickRandomPointOnUnitSphere()
            betaSheetDirectors.append(
                coords.sphericalPolar2XYZ(np.array([1.0, theta, phi])))

        inStrandDirector = np.array([0.0, 0.0, 1.0])
        crossStrandDirector = np.array([1.0, 0.0, 0.0])
        rotation = rnd.uniform(0, 2 * np.pi)
        offset = np.array([0.0, 0.0, 0.0])

        print "Constructing Beta Sheets"

        # create the betaSheets
        self.betaSheetBBs = [
            self.BSG.generateBuildingBlock(self.numBetaStrands,
                                           self.betaStrandLength,
                                           startPos,
                                           globalDirector,
                                           inStrandDirector,
                                           crossStrandDirector,
                                           rotation,
                                           offset,
                                           polarity='NC',
                                           parallel=True,
                                           loopedEnds=False) for startPos,
            globalDirector in zip(betaSheetStartPoints, betaSheetDirectors)
        ]

        if self.nameByBuildingBlockType:
            [
                bsheet.replaceNames(self.betaStrandAtomName)
                for bsheet in self.betaSheetBBs
            ]

        # assemble the components
        spidroinXYZ = self.NTerminusAlphaHelix.xyzVals
        for betaSheet in self.betaSheetBBs:
            spidroinXYZ += betaSheet.xyzVals
        spidroinXYZ += self.CTerminusAlphaHelix.xyzVals

        return spidroinXYZ

    def generateBuildingBlockDirector(self):
        return np.array([0.0, 0.0, 1.0])

    def generateBuildingBlockRefPoint(self):
        return np.array([0.0, 0.0, 0.0])

    def generateBuildingBlockNames(self):
        spidroinNames = self.NTerminusAlphaHelix.atomNames
        for betaSheet in self.betaSheetBBs:
            spidroinNames += betaSheet.atomNames
        spidroinNames += self.CTerminusAlphaHelix.atomNames
        return spidroinNames
Esempio n. 12
0
        # should be a unit vector already but just in case
        newCoordXYZRelHat = newCoordXYZRel/np.linalg.norm(newCoordXYZRel) 
        
        # scale the vector by the bondlength and add it to the last point in the list to give new position vector
        return p3 + self.bondLength * newCoordXYZRelHat
        
    def getParams(self):
        return self.params 

if __name__ == '__main__':
    
    # get the file name from the command line
    filename = sys.argv[1]

    # create a beta backbone generator object using static file parameters
    backboneObject = PBG(filename)

    # generate backbone realtime parameters
    numPos = 3* 8
    startPos = np.array([0.0, 0.0, 0.0])
    director = np.array([0.0, 0.0, 1.0])
    rotation = 0 * np.pi/180
    offset =  np.array([600, 0.0, 0.0])
    connectors = [[2, 1, 0], [numPos - 3, numPos - 2, numPos - 1]]
    backBoneBuildingBlock1 = backboneObject.generateBuildingBlock(numPos, 'CN', connectors) 
    backBoneBuildingBlock1.transformFromBlockFrameToLabFrame(director, startPos, rotation)
    backBoneBuildingBlock1.exportBBK("backbone1")
    backBoneBuildingBlock2 = backboneObject.generateBuildingBlock(numPos, 'NC',  connectors) 
    backBoneBuildingBlock2.transformFromBlockFrameToLabFrame(director, startPos, rotation)
    backBoneBuildingBlock2.exportBBK("backbone2")
Esempio n. 13
0
def GeneralPolymerBrush(brushDict, mode="RandomPolymer"):

    # unpack the brush dictionary
    
    
    
    
    
    
    filenameRandom = brushDict['filenameBlock']
    filenameBrush = brushDict['filenameBrush']
    mode = brushDict['mode']
    
    ABlock = brushDict['ABlock']
    num_A = ABlock['num'] 
    alpha1_A = ABlock['alpha1']
    alpha2_A = ABlock['alpha2'] 
    beta1_A = ABlock['beta1'] 
    beta2_A = ABlock['beta2'] 
    minDist_A = ABlock['minDist'] 
    bondLength_A = ABlock['bondLength']
    Z1_A = ABlock['Z1'] 
    R1_A = ABlock['R1'] 
    Z2_A = ABlock['Z2'] 
    R2_A = ABlock['R2'] 
    
    BBlock = brushDict['BBlock']
    num_B = BBlock['num'] 
    alpha1_B = BBlock['alpha1']
    alpha2_B = BBlock['alpha2'] 
    beta1_B = BBlock['beta1'] 
    beta2_B = BBlock['beta2'] 
    minDist_B = BBlock['minDist'] 
    bondLength_B = BBlock['bondLength']
    Z1_B = BBlock['Z1'] 
    R1_B = BBlock['R1'] 
    Z2_B = BBlock['Z2'] 
    R2_B = BBlock['R2']
    
    brushBlock = brushDict['brushBlock']
    num_brush = brushBlock['num'] 
    alpha1_brush = brushBlock['alpha1']
    alpha2_brush = brushBlock['alpha2'] 
    beta1_brush = brushBlock['beta1'] 
    beta2_brush = brushBlock['beta2'] 
    minDist_brush = brushBlock['minDist'] 
    bondLength_brush = brushBlock['bondLength']
    Z1_brush = brushBlock['Z1'] 
    R1_brush = brushBlock['R1'] 
    Z2_brush = brushBlock['Z2'] 
    R2_brush = brushBlock['R2']
    

    # Mode word must specify one of Polymer or Peptide.  Can also include modifiers Sheet or Random to specify phase of brushes around polymer backbone axis.
    # defaults to RandomPolymer.  Can supply brush polymer parameters via parameter polymer params. These are alpha1, alpha2, beta1, beta2, minDist and bond length. 
    # atom name supplied in filenameBrush.  This is a mess. I know. I don't care.  
    
    # if one of Peptide or Polymer is not in mode then add Polymer to the end of mode. Anything else is dandy. If you specify both peptide and polymer, then Peptide will override.
    if not ("Peptide" in mode or "Polymer" in mode):
        mode = mode + "Polymer"
    
    # generate the block Copolymer backbone
    (polymerXyzVals, polymerNames) = MBCP(num_A, num_B,   Z1_A, R1_A, Z2_A, R2_A, alpha1_A, alpha2_A, beta1_A, beta2_A, minDist_A, bondLength_A, 
                                                        Z1_B, R1_B, Z2_B, R2_B, alpha1_B, alpha2_B, beta1_B, beta2_B, minDist_B, bondLength_B, filenameRandom)
    
    # get axis of block A
    BlockAAxis = coords.axisFromHelix(polymerXyzVals[0:num_A])
    BlockAAxisNorm = BlockAAxis/np.linalg.norm(BlockAAxis) 
    
    # get an orthogonal vector to BlockAAxis which is random. 
    randDirXYZ = BlockAAxis
    randXYZIsAxizXYZ = True
    
    while randXYZIsAxizXYZ: 
        randVecDir = coords.pickRandomPointOnUnitSphere()
        randDirXYZ = coords.sphericalPolar2XYZ(np.array([1.0, randVecDir[0], randVecDir[1]]))
        randXYZIsAxizXYZ = not False in [ np.abs(a - b) < 1e-7 for a, b in zip(randDirXYZ, BlockAAxis) ]
        
    OrthVec = randDirXYZ - np.dot(BlockAAxisNorm, randDirXYZ) * BlockAAxisNorm
    OrthVec1Norm = OrthVec/np.linalg.norm(OrthVec) 
    OrthVec2Norm  = np.cross(OrthVec1Norm, BlockAAxisNorm)

    # now have orthonormal basis for the polymer backbone for the brush part of system 
    
    # create the brush generator. Default is polymer mode. If peptide is included in mode word then over ride to use peptide instead 
    if "Peptide" in mode:
        # create a peptide generator using supplied filename to specify parameters of peptide - filename overides polymerParams
        brushGenerator = PBG(filenameBrush)
        brushObject = brushGenerator.generateBuildingBlock(num_brush) # only need to create this once for peptides as all are the same
    else:
        brushGenerator = RPPBBG(filenameBrush)
    
    # choose the phase angles of each brush
    # initially make the phase angle a little bit random
    brushPhaseAngles = [ rnd.uniform(0, 0.2 * np.pi) for _ in range(0, num_A) ]

    # if Random is in mode then make it very random
    if "Random" in mode:
        brushPhaseAngles = [ rnd.uniform(0, 2 * np.pi) for _ in range(0, num_A) ] 
    
    # if sheet is in mode then make phase zero.
    if "Sheet" in mode:
        brushPhaseAngles = [ 0.0 for _ in range(0, num_A) ]

    # generate directors in direction of phase angles
    brushDirectors = [ np.cos(angle) * OrthVec1Norm + np.sin(angle) * OrthVec2Norm for angle in brushPhaseAngles] 
    brushDirectorsNorm = [ d/np.linalg.norm(d) for d in brushDirectors]

    # for each of the directors (defined by the length of block A) figure out the final xyz vals    
    for point, labDirector in zip(polymerXyzVals[0:num_A], brushDirectorsNorm):
        if "Polymer" in mode and not "Peptide" in mode:
            # if we're doing a polymer then generate a new polymer with the given polymer parameters for each pass.
            polyStart = np.array([ 0.0, 0.0, Z1_brush])
            envelopeList = ['frustum ' + str(Z1_brush - minDist_brush) + ' ' + str(R1_brush) + ' ' + str(Z2_brush) + ' ' + str(R2_brush)]
            
            brushObject = brushGenerator.generateBuildingBlock( num_brush,
                                                                polyStart,
                                                                alpha1_brush,
                                                                alpha2_brush,
                                                                beta1_brush,
                                                                beta2_brush,
                                                                minDist_brush,
                                                                bondLength_brush,
                                                                envelopeList = envelopeList)
        
        newBrushXYZ = coords.transformFromBlockFrameToLabFrame(labDirector, point + minDist_A * labDirector, 0.0, brushObject.blockDirectorHat, brushObject.blockXYZVals[0], brushObject.blockXYZVals)
        polymerXyzVals = np.concatenate((polymerXyzVals, newBrushXYZ), 0) 
        polymerNames = np.concatenate( (polymerNames, brushObject.blockAtomNames), 0 )


    # direction of brush is z-axis.  
    # reference point is the first of the B polymers, which is the numAth entry in the list of xyzVals
    return (np.array([0.0, 0.0, 1.0]), polymerXyzVals[num_A], polymerXyzVals, polymerNames)
Esempio n. 14
0
    def generateBuildingBlockXYZ(self):

        # create a strand and loop generator
        strandGen = PBG(self.paramFilename)
        loopGen = PHG(self.paramFilename)

        loopPoints = []
        sphereCentrePoints = []
        dummyConnector = [[2, 1, 0]]

        # construct the base line for the strand start points
        baseLine = [
            self.startPos +
            n * self.betaStrandSeparation * self.crossStrandDirectorHat
            for n in range(self.numStrands)
        ]

        # construct a prototype beta strand building Block in the defined polarity
        strandA_BB = strandGen.generateBuildingBlock(self.numPoints,
                                                     self.polarity,
                                                     dummyConnector)

        # assume loop length needs to be long enough to stretch a whole beta strand.
        loopLength = int(np.ceil(1.5 * self.strandLength))

        # In a not parallel situation construct the antiparallel strand - StrandB
        # also add the offset to every other strand starting on the first or second strand depending on the polarity
        # also compute the alternative strand building block
        if not self.parallel:
            loopLength = 2  # in a parallel situation the loop is always 2 (residues) long. I just said so.
            if self.polarity == 'NC':
                baseLine = [
                    basePoint + self.offsetXYZ if (n % 2) == 0 else basePoint
                    for n, basePoint in enumerate(baseLine)
                ]
                strandB_BB = strandGen.generateBuildingBlock(
                    self.numPoints, 'CN', dummyConnector)
            else:
                baseLine = [
                    basePoint + self.offsetXYZ if (n % 2) == 1 else basePoint
                    for n, basePoint in enumerate(baseLine)
                ]
                strandB_BB = strandGen.generateBuildingBlock(
                    self.numPoints, 'NC', dummyConnector)

        # compute the relative vector from the end of the first chain to the next atom in the hairpin.
        TNB = coords.constructTNBFrame(strandA_BB.xyzVals[-3],
                                       strandA_BB.xyzVals[-2],
                                       strandA_BB.xyzVals[-1])

        if self.polarity == 'NC':
            # if polarity is NC then the last three values are an NCC triad.
            beta = self.angleC
            alpha = self.phi
            bondLength = self.CNbondLength
        else:
            # if polarity is CN then the last three values are CCN triad.
            beta = self.angleN
            alpha = self.psi
            bondLength = self.CNbondLength

        # the vector from the end of the first strand to its hairpin is defined as the positive connectorVector.
        ConnectorVectorPos = bondLength * coords.generateTNBVecXYZ(
            TNB, beta, alpha)

        # -ve connector vector is the reciprocal of that
        ConnectorVectorNeg = -1 * ConnectorVectorPos

        # for parallel all CVs are always the Positive from end of strand to hairpin
        # and from hairpin to end of strand
        connectorVectorStrandToHairpin = ConnectorVectorPos
        connectorVectorHairpinToStrand = ConnectorVectorPos

        # for parallel strands are always the same set of xyz vals
        curStrandXYZ = strandA_BB.xyzVals

        # now the preparatory stuff is complete begin constructing the beta sheet
        # copy across the first strand to get the structure going.
        buildingBlockXYZ = [baseLine[0] + xyz for xyz in strandA_BB.xyzVals]

        innerRadiusParallel = 0.75 * self.strandLength * 3 * bondLength / 2
        outerRadiusParallel = 40 * self.strandLength * 3 * bondLength / 2
        innerRadiusAntiParallel = 0.9 * self.betaStrandSeparation / 2
        outerRadiusAntiParallel = 40 * self.betaStrandSeparation
        print "Radii: ", innerRadiusParallel, outerRadiusParallel, innerRadiusAntiParallel, outerRadiusAntiParallel
        print "Diameter: ", 2 * innerRadiusParallel, 2 * outerRadiusParallel, 2 * innerRadiusAntiParallel, 2 * outerRadiusAntiParallel

        # contruct the remaining strands following this procedure
        curStrand = 1
        while curStrand < self.numStrands:

            # if parallel, strands and connectorvectors are always the same so do nothing
            # to them.

            # if not parallel work out the connectorVectors for attaching hairpin between
            # the previous strand and the current strand.
            if not self.parallel:
                if (curStrand % 2) == 0:
                    connectorVectorStrandToHairpin = ConnectorVectorNeg
                    connectorVectorHairpinToStrand = ConnectorVectorPos
                    curStrandXYZ = strandA_BB.xyzVals
                if (curStrand % 2) == 1:
                    connectorVectorStrandToHairpin = ConnectorVectorPos
                    connectorVectorHairpinToStrand = ConnectorVectorNeg
                    curStrandXYZ = list(reversed(strandB_BB.xyzVals))

            # loop start is end of building block + connectorvector
            loopStartPoint = buildingBlockXYZ[
                -1] + connectorVectorStrandToHairpin

            loopPoints.append(loopStartPoint)

            # compute values for new strand
            newStrand = [baseLine[curStrand] + xyz for xyz in curStrandXYZ]

            # loop end point is start of next strand - connector vector.
            loopEndPoint = newStrand[0] - connectorVectorHairpinToStrand

            loopPoints.append(loopEndPoint)
            sphereCentrePoint = (loopEndPoint + loopStartPoint) / 2
            sphereCentrePoints.append(sphereCentrePoint)

            print "loopPointdist: ", np.linalg.norm(loopEndPoint -
                                                    loopStartPoint)

            # now we have the length of the loop and the start and end points
            # makes and attempt to stop the hairpin from entering
            # a sphere at the mid point of the start and end points
            if self.loopEnds:
                if self.parallel:

                    loop = loopGen.generateBuildingBlock(
                        loopLength * 3, loopStartPoint, loopEndPoint, 0, -180,
                        180, beta * 180 / np.pi - 40, beta * 180 / np.pi + 40,
                        0.9 * bondLength, bondLength, innerRadiusParallel,
                        outerRadiusParallel, sphereCentrePoint, self.polarity)
                else:
                    loop = loopGen.generateBuildingBlock(
                        loopLength * 3, loopStartPoint, loopEndPoint, 0, -180,
                        180, beta * 180 / np.pi - 40, beta * 180 / np.pi + 40,
                        0.9 * bondLength, bondLength, innerRadiusAntiParallel,
                        outerRadiusAntiParallel, sphereCentrePoint,
                        self.polarity)
                # append the loop to the array
                buildingBlockXYZ = buildingBlockXYZ + loop.xyzVals

            # append each vector to the current output array
            buildingBlockXYZ = buildingBlockXYZ + newStrand

            #next strand
            curStrand += 1

        #buildingBlockXYZ = buildingBlockXYZ + loopPoints
        #buildingBlockXYZ = buildingBlockXYZ + sphereCentrePoints

        self.numPoints = len(buildingBlockXYZ)

        return buildingBlockXYZ
Esempio n. 15
0
class peptideHairpinGenerator(CPBBG):
    # This class returns a randomly coiled peptide backbone between two sets of points
    # A and B, which is packed into an external envelope. The backbone does not
    # self-intersect and the coil avoids a user supplied set of external points.
    #
    # The class inherits the functionality of the constrainedPolymerClass.
    # but overides the generateSpaceCurve method of that class to provide the initial unfolded polymer.
    #
    # Instead of generating a geometric shape for the polymer, the function
    # uses the peptide backbone class to generate a straight peptide backbone model with
    # appropriate dihedrals, bond angles, bondLengths and number of residues,
    # with the three points specified in pointsA forming the initial seed for the chain.
    # The first point in A is non negotiable and fixed. But the second and third points
    # are movable once the initial chain has been built.
    # PointsA is supplied in the format m0, m1 and m2 where m0 is the innermost point of a connector.
    # Thus point m2 (the third point in pointsA) is actually the start of the chain. This is important.
    # Throughouth the project connectors are defined as m0, m1 and m2.
    #
    #
    # The energy of two springs between the two atoms at the free end of the chain and
    # the two atoms of the second anchor points B is
    # then computed based on the distance between them. Conformations with smaller
    # amounts of energy are found by picking C-CA or N-CA bonds at random and
    # performing dihedral moves of the entire free end of chain from the selected
    # bond onwards.
    #
    # Each time a move is made the new energy of the two springs is calculated for the
    # new position. If the move results in lower total spring energy than the lowest energy
    # yet found it is accepted. If the spring energy is larger than the current minimum
    # the move is accepted with a probability based on the boltzman factor between the
    # current lowest energy and the new energy.
    #
    # As the distance between the end point and point B shrinks the allowed size
    # range of rotations shrinks rapidly.
    #
    # The naming functions and allowedList functions are also overridden so
    # that only the alpha carbons are allowed to be used in the dihedral twist
    # rotations. This restriction preserves the peptide bond angles in the chain.
    #
    # Once a double anchored space curve is generated, with anchor points at
    # pointsA and B, the procedure for randomising the coil with crankshaft moves and
    # folding the chain into an envelope is the same as for the coiled polymer baseclass.
    #
    # The final structure is exported as a building block class.

    def __init__(self, paramFilename):
        # initialise the parameter dictionary for the base classes
        CPBBG.__init__(self, paramFilename)

    def initialiseParameters(self):
        # initialise the constrained polymer parent
        CPBBG.initialiseParameters(self)

        self.distEpsilon = self.getParam("distEpsilon")
        self.maxNumConnectingMoves = self.getParam("maxNumConnectingMoves")
        self.springConstant = self.getParam("springConstant")
        self.connectingTemp = self.getParam("connectingTemp")

        # load the backbone building object
        self.PBG = PBG(self.paramFilename)

        if self.noLoadErrors == False:
            print "Critical Parameters are undefined for hairpin"
            sys.exit()

    def generateBuildingBlock(self,
                              numResidues,
                              pointsA,
                              pointsB,
                              minDist,
                              numCrankMoves,
                              pointsToAvoid=[],
                              envelopeList=['None'],
                              nameCA=False):
        self.numResidues = numResidues
        self.numPoints = self.numResidues * 3
        bondLength = 0.0  # not used in this game
        self.nameCA = nameCA
        self.minDist = minDist

        # set up the right reference points
        self.labPointA = pointsA[2]
        self.labPointB = pointsB[2]
        self.labPointsA = pointsA[:]
        self.labPointsB = pointsB[:]

        # generate the BuildingBlock reference point earlier than usual because
        # we need the transformation for the pointsToAvoid input.
        self.blockRefPoint = self.generateBuildingBlockRefPoint()

        # generate the BuildingBlock director unit vector earlier than usual because
        # we need the transformation for the pointsToAvoid input.
        self.blockDirectorHat = self.generateBuildingBlockDirector()

        # generate the transformation information from building block to labPointA and labPointB
        self.labDirector, self.labRefPoint, self.labRotation = self.computeTransform(
        )

        # convert the pointsA and pointsB information from the labFrame to the block frame
        self.blockPointsA = coords.transformFromLabFrameToBlockFrame(
            self.labDirector, self.labRefPoint, self.labRotation,
            self.blockDirectorHat, self.blockRefPoint, pointsA)
        self.blockPointsB = coords.transformFromLabFrameToBlockFrame(
            self.labDirector, self.labRefPoint, self.labRotation,
            self.blockDirectorHat, self.blockRefPoint, pointsB)
        self.pointsToAvoid = coords.transformFromLabFrameToBlockFrame(
            self.labDirector, self.labRefPoint, self.labRotation,
            self.blockDirectorHat, self.blockRefPoint, pointsToAvoid)

        if self.dumpInterimFiles == 1:
            fIO.saveXYZList(self.blockPointsA + self.blockPointsB,
                            ['Ca', 'Ca', 'Ca', 'O', 'O', 'O'],
                            "blockPointsAB.xyz")

        # parse the envelope list if we intend to use it.
        self.parseEnvelopeList(envelopeList)

        # check starting points are legal or it's gonna be a long wait.
        for pos in self.blockPointsA:
            if not self.checkPointInBounds(pos):
                print "Error Warning: PointA out of bounds"
                time.sleep(3)

        for pos in self.blockPointsB:
            if not self.checkPointInBounds(pos):
                print "Error Warning: PointB out of bounds"
                time.sleep(3)

        return CPBBG.generateBuildingBlock(self,
                                           self.numPoints,
                                           pointsA[2],
                                           pointsB[2],
                                           minDist,
                                           bondLength,
                                           numCrankMoves,
                                           pointsToAvoid=self.pointsToAvoid,
                                           envelopeList=envelopeList)

    def generateAllowedList(self):
        # add the first and last points to the allowed list.
        # This is important to allow the full chain to be able to be mapped into the envelope.
        allowed = [0, self.numPoints - 1]

        # over ride the naming of the atoms with ca=True.
        names = self.generateBuildingBlockNames(ca=True)
        [allowed.insert(-1, i) for i, name in enumerate(names) if name == 'CA']

        return allowed

    def generateSpaceCurve(self):
        # Over-rides the generate space curve function of the parent to generate a peptide backbone
        # and a pseudo energy landscape approach to find an initial chain with the end point fixed
        # at point B.

        # create a regular b0a14ckBone using block Points A as the first residue
        peptideBackbone = self.PBG.generateBuildingBlock(
            self.numResidues, seedResidue=self.blockPointsA)

        if self.dumpInterimFiles == 1:
            fIO.saveXYZList(peptideBackbone.blockXYZVals,
                            peptideBackbone.blockAtomNames,
                            'initialPeptideBackbone.xyz')

        # extract the xyzValues
        xyzVals = peptideBackbone.getAtomsXYZ()

        # perform the energy minimisation that moves the free end to blockPointsB
        xyzVals = self.minimiseEnergy(xyzVals, self.allowedList)

        if self.dumpInterimFiles == 1:
            fIO.saveXYZ(xyzVals, 'K', 'chainConnectedBlockFrame.xyz')

        return xyzVals

    def minimiseEnergy(self, xyzVals, allowedList):
        # Returns a polymer chain which minimises a simple PE function.
        # Performs random dihedral twists on the free end of a polymer,
        # starting at a random bond.
        # Moves resulting in lower energy arrangements are accepted.
        # Moves resulting in higher energy arrangements are accepted
        # with probability that is exponentially smaller with increasing energy difference.
        # Since the primary structure is just a straight line and we are only
        # doing sparse dihedral twists, with only a single bias towards to the pointB,
        # there is a low probability of a self-intersection especially for long chains.
        # This rapidly finds a structure where the point B is within arbitrary distance of pointB.
        # The step size scales in proportion to the distance from point B. So only tiny steps are taken
        # near to the only minimum of the entire potential. Converges rapidly even for large N.

        lowestEnergyMinimum = xyzVals[:]
        initPE, initDist = self.PE(xyzVals)
        curPE = initPE
        minPE = initPE
        curDist = initDist
        minDist = initDist
        maxStepRange = 1.0
        numMoves = 0
        curMin = 0
        while minDist > self.distEpsilon and numMoves < self.maxNumConnectingMoves:

            # compute new conformation based on a random dihedral twist
            newXYZ = self.dihedralTwist(xyzVals, maxStepRange)

            # compute energy and distance of new move
            newPE, newDist = self.PE(newXYZ)

            # compute energy difference with current minimum PE
            deltaPE = newPE - minPE

            # assume we will accept the move.
            acceptMove = True
            # if the currentPE is greater than the minimum then only accept
            # the move with a probability given by the difference in
            # energy of the minimum and current states
            if deltaPE > 0:
                # pick a random value between 0 and 1
                prob = rnd.uniform(0, 1)

                # if that value is larger than the threshold reject the move.
                # The threshold decreases with increasing deltaE, so the
                # higher the energy of the new state relative to the old one
                # the more likely it is we reject the move
                if prob > np.exp(-deltaPE / self.connectingTemp):
                    acceptMove = False

            # if we accept the move then store the new coords
            # and record the energy of the newest accepted move
            if acceptMove:
                xyzVals = newXYZ[:]
                curPE = newPE
                curDist = newDist

            # check the curPE against the minimum energy
            # if we have a new min energy then retain for the future and dump to file.
            if curPE < minPE:
                lowestEnergyMinimum = xyzVals[:]
                minPE = curPE
                minDist = curDist
                maxStepRange = minDist / initDist
                curMin += 1
                self.outline(numMoves, self.maxNumConnectingMoves, minDist,
                             minPE, maxStepRange)
            numMoves += 1

            if numMoves % 100 == 0:
                self.outline(numMoves, self.maxNumConnectingMoves, minDist,
                             minPE, maxStepRange)

        return lowestEnergyMinimum

    def outline(self, n, M, d, E, R):
        print n, "out of ", M, "minDist:", d, "minEnergy:", E, "maxStepRange:", R

    def PE(self, xyzVals):
        PE = 0.0
        # add spring between pointB[2] and end of xyzVals with equilibrium at pointB
        dist1 = np.linalg.norm(xyzVals[-1] - self.blockPointsB[2])
        PE += 0.5 * 3 * self.springConstant * dist1**2

        # add spring between pointsB[1] and end of xyzVals[-2]
        dist2 = np.linalg.norm(xyzVals[-2] - self.blockPointsB[1])
        PE += 0.5 * 2 * self.springConstant * dist2**2

        # add spring between pointsB[0] and end of xyzVals[-3]
        #dist3 = np.linalg.norm(xyzVals[-3] - self.blockPointsB[0])
        #PE += 0.5 * self.springConstant * dist3**2

        # made the first spring the stiffest with second and third springs getting weaker.
        # first spring has largest influence on energy.

        # add weak spring between each CA and refPoint
        # and repulsion at close range
        #for i in allowedList:
        #    posDist = np.linalg.norm(xyzVals[i] - self.blockRefPoint)
        #    PE += +0.5 * 2 * self.springConstant * posDist **2
        #    #PE += -1.0/posDist**6

        # add contribution to PE based on distance between each CA with all the others
        # only look at ordered pairwise combinations without repetition.
        # ie. 1-2, 1-3, 1-4, 2-3, 2-4, 3-4  (leaving out 1-1, 2-2, and 3-1, 4-1 etc)
        #pairWiseCombinations = it.combinations([ pos for n, pos in enumerate(xyzVals) if n in allowedList], 2)
        # iterate and compare each pair to compute contrib to PE
        #for pair in pairWiseCombinations:
        #    PE += -self.epsilon0/np.power(np.linalg.norm(pair[1] - pair[0]), 3)

        # add contribution to PE from every point in pointsToAvoid with
        # every point in the list
        #avoidList = it.product(xyzVals, self.pointsToAvoid)
        # iterate and compare each pair to see if any match
        #for pair in avoidList:
        #    PE += - self.LJRep(pair[0], pair[1])

        return PE, np.sqrt(dist1**2 + dist2**2)

    def dihedralTwist(self, xyzVals, maxStepRange):

        #fIO.saveXYZList(xyzVals, self.blockNames, "preTwist.xyz")
        # can only do this if there are sufficient atoms in the array
        if len(xyzVals) > 3:
            # initialise the axisAtom1Index
            axisAtom1Index = 2
            # keep picking a random atom until we get one in the allowed list.
            while not axisAtom1Index in self.allowedList:
                axisAtom1Index = rnd.randint(0, len(xyzVals) - 3)

            # find the relevant points and rotation axis
            atom1 = xyzVals[axisAtom1Index]
            atom2 = xyzVals[axisAtom1Index + 1]
            rotAxis = atom2 - atom1
            rotAxisHat = rotAxis / np.linalg.norm(rotAxis)

            # pick a step size at random from within the current allowed range
            angle = rnd.uniform(maxStepRange * -np.pi, maxStepRange * np.pi)

            # rotate all the remaining points about the atom1 axis place at atom1 by angle
            xyzVals = [
                p if n < axisAtom1Index + 2 else cart.rotPAboutAxisAtPoint(
                    p, atom1, rotAxisHat, angle) for n, p in enumerate(xyzVals)
            ]

        #fIO.saveXYZ([atom1, atom2], 'O', "atomAxis.xyz")
        #fIO.saveXYZList(xyzVals, self.blockNames, "postTwist.xyz")
        return xyzVals

    def LJRep(self, p1, p2):
        # add a short range repulsive term based on the distance between
        # centre of each point
        return self.epsilon0 / np.power(np.linalg.norm(p1 - p2), 12)

    def generateBuildingBlockNames(self, ca=False):

        if self.nameCA:
            names = ['N', 'CA', 'C'] * self.numResidues
        else:
            names = ['N', 'C', 'C'] * self.numResidues

        # override the externally controlled member variable nameCA with a local variable
        if ca == True:
            names = ['N', 'CA', 'C'] * self.numResidues

        return names

    def generateBuildingBlockConnectors(self):
        # N connector first, then C Connector
        return [[2, 1, 0],
                [self.numPoints - 3, self.numPoints - 2, self.numPoints - 1]]
Esempio n. 16
0
        return names

    def generateBuildingBlockConnectors(self):
        # N connector first, then C Connector
        return [[2, 1, 0],
                [self.numPoints - 3, self.numPoints - 2, self.numPoints - 1]]


if __name__ == "__main__":

    # get the file name from the command line
    filename = sys.argv[1]

    # create the generator objects.
    hairPinGen = peptideHairpinGenerator(filename)
    backboneGenerator = PBG(filename)

    # generate 1 residue seed building block
    seedResidue = backboneGenerator.generateBuildingBlock(1)

    # generate starting points and move the seed to those points extracting
    # the xyzVals each time.
    numResidues = 20
    pointA = np.array([10.0, 10.0, 10.0])
    pointB = np.array([-10.0, 10.0, -10.0])

    print "Estimate min num residues: ", np.linalg.norm(pointA - pointB) / 3.5

    seedResidue.placeAtom(2, pointA)
    seedResidue.setBlockRefPoint(pointA)
    seedResidue.orientToDirector(np.array([-1.0, 1.0, 0.0]))