def pickRandomPointInDefinedSpace(self): theta, phi = coords.pickRandomPointOnUnitSphereInAngRange( self.thetaDir1, self.thetaDir2, self.phiDir1, self.phiDir2) dirn = coords.sphericalPolar2XYZ(np.array([1.0, theta, phi])) return (coords.pickRandomPointInEllipsoidRange( self.xRadius, self.yRadius, self.zRadius, self.theta1, self.theta2, self.phi1, self.phi2), dirn)
def genDirector(self, point, minNumPoints, gDirector, angle, maxNumAttempts, within=True): numPoints = 0 maxNumPoints = 0 numLoops = 0 # loop until we exceed the minimum number of points requested or we have tried 10 times while numPoints < minNumPoints and numLoops < maxNumAttempts: if numLoops > 0: print("Finding alternative director. Attempt: ", numLoops + 1, "of ", maxNumAttempts) if within: # for choosing first generation unimers (must be within angle of gDirector) theta, phi = coords.pickRandomPointOnUnitSphereInAngRange( np.pi / 2 - angle, np.pi / 2, -np.pi, np.pi) else: # for choosing nth generation unimers (must be between angle and 2 angle of gdirector) theta, phi = coords.pickRandomPointOnUnitSphereInAngRange( np.pi / 2 - 2 * angle, np.pi / 2 - angle, -np.pi, np.pi) # convert theta, phi pair to xyz vectors directorHat = coords.sphericalPolar2XYZ(np.array([1.0, theta, phi])) # rotate director to take into account orientation of globalDirector directorHatRot = coords.transformFromBlockFrameToLabFrame( gDirector, np.array([0.0, 0.0, 0.0]), 0.0, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), [directorHat])[0] # calculate distance along director vector to the outer edge of the box. dist2Box = self.dist2Box(point, directorHatRot) # compute number of points we can fit in there assuming straight line to edge of box numPoints = int(dist2Box / self.bondLength) # make a note of the direction that gives the largest number of points so far if numPoints > maxNumPoints: maxDirector = cp.copy(directorHatRot) maxNumPoints = numPoints if numPoints < minNumPoints: print("low num points") numLoops += 1 # if we have exited the loop then check to see if we have succeeded. # if we have failed then return the best director we encountered. if numPoints < minNumPoints: print("Warning: Director choice resulted in short polymer") numPoints = maxNumPoints directorHatRot = maxDirector return (directorHatRot, numPoints)
def pickRandomPointInDefinedSpace(self): theta, phi = coords.pickRandomPointOnUnitSphereInAngRange( self.thetaDir1, self.thetaDir2, self.phiDir1, self.phiDir2) dirn = coords.sphericalPolar2XYZ(np.array([1.0, theta, phi])) return (np.array([ rnd.uniform(-self.xSize / 2, self.xSize / 2), rnd.uniform(-self.ySize / 2, self.ySize / 2), rnd.uniform(-self.zSize / 2, self.zSize / 2) ]), dirn)
def makeHSADistribution(num0, num1, num2, num3, num4, num5, x, y, z, minDist): # create the cubic distribution cubeGen = VPCBBG('VolumePackCuboid.txt') # create the NPack object. numPoints = num0 + num1 + num2 + num3 + num4 + num5 # generate the building block SpacePackBB = cubeGen.generateBuildingBlock(numPoints, -x / 2, x / 2, -y / 2, y / 2, -z / 2, z / 2, minDist) # dump the base points to file fIO.saveXYZ(SpacePackBB.blockXYZVals, 'CA', 'points.xyz') # generate sufficient random orientiation vectors thetaPhiArray = [ coords.pickRandomPointOnUnitSphere() for _ in range(numPoints) ] directors = [ coords.sphericalPolar2XYZ(np.array([1.0, angs[0], angs[1]])) for angs in thetaPhiArray ] xyzVals0, names0 = genHsaPoints('hsa_apo.xyz', SpacePackBB.blockXYZVals[0:num0], directors[0:num1]) xyzVals1, names1 = genHsaPoints('hsa_with1.xyz', SpacePackBB.blockXYZVals[num0:num0 + num1], directors[num0:num0 + num1]) xyzVals2, names2 = genHsaPoints( 'hsa_with2.xyz', SpacePackBB.blockXYZVals[num0 + num1:num0 + num1 + num2], directors[num0 + num1:num0 + num1 + num2]) xyzVals3, names3 = genHsaPoints( 'hsa_with3.xyz', SpacePackBB.blockXYZVals[num0 + num1 + num2:num0 + num1 + num2 + num3], directors[num0 + num1 + num2:num0 + num1 + num2 + num3]) xyzVals4, names4 = genHsaPoints( 'hsa_with4.xyz', SpacePackBB.blockXYZVals[num0 + num1 + num2 + num3:num0 + num1 + num2 + num3 + num4], directors[num0 + num1 + num2 + num3:num0 + num1 + num2 + num3 + num4]) xyzVals5, names5 = genHsaPoints( 'hsa_with5.xyz', SpacePackBB.blockXYZVals[num0 + num1 + num2 + num3 + num4:], directors[num0 + num1 + num2 + num3 + num4:]) fIO.saveXYZList(xyzVals0, names0, 'hsa0All.xyz') fIO.saveXYZList(xyzVals1, names1, 'hsa1All.xyz') fIO.saveXYZList(xyzVals2, names2, 'hsa2All.xyz') fIO.saveXYZList(xyzVals3, names3, 'hsa3All.xyz') fIO.saveXYZList(xyzVals4, names4, 'hsa4All.xyz') fIO.saveXYZList(xyzVals5, names5, 'hsa5All.xyz')
# create the positions of all the straight polymers straightPolymers = CuboidPackBBG.generateBuildingBlock(numStraightPolymers, -BoxX/2.0, BoxX/2.0, -BoxY/2.0, BoxY/2.0, -BoxZ/2.0, BoxZ/2.0, 1.3 * armEndRad, pointsToAvoid = pointsToAvoid) for point in straightPolymers.blockXYZVals: pointsToAvoid.append(cp.copy(point)) # create the positions of all the Helical polymers helicalPolymers = CuboidPackBBG.generateBuildingBlock(numHelicalPolymers, -BoxX/2.0, BoxX/2.0, -BoxY/2.0, BoxY/2.0, -BoxZ/2.0, BoxZ/2.0, 1.3 * armEndRad, pointsToAvoid = pointsToAvoid) # generate the 3 spirals and build up a list of xyzVals and names as we go for all the elements of the image spiral = 0 for spiralPos in spirals3XYZBB.blockXYZVals: filename = "uncut_spiral_3_" + str(spiral) + ".xyz" curXYZVals, curNamesAll = Spiral(3, numParticlesArm, armEndRad, particleName, ConstrainedPolyGen, spiralAngularDisplacement, bondLength, alpha1, alpha2, beta1, beta2, atomicMinDist, filename) theta, phi = coords.pickRandomPointOnUnitSphere() director = coords.sphericalPolar2XYZ(np.array([1.0, theta, phi])) curXYZValsNew = coords.transformFromBlockFrameToLabFrame(director, spiralPos, rnd.uniform(0, 2* np.pi), np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), curXYZVals) if spiral == 0: xyzValsAll = cp.copy(curXYZValsNew) namesAll = cp.copy(curNamesAll) else: for xyzVal in curXYZValsNew: xyzValsAll.append(cp.copy(xyzVal)) for name in curNamesAll: namesAll.append(cp.copy(name)) spiral += 1 # generate the 4 spirals for spiralPos in spirals4XYZBB.blockXYZVals: filename = "uncut_spiral_4_" + str(spiral) + ".xyz" curXYZVals, curNamesAll = Spiral(4, numParticlesArm, armEndRad, particleName, ConstrainedPolyGen, spiralAngularDisplacement, bondLength, alpha1, alpha2, beta1, beta2, atomicMinDist, filename)
centerPos = np.array([0.0, 0.0, 0.0]) # generate the outer sphere root positions at the mid layer radius and their directors pointing out from the center PolymerSphereOuterBB = SphereBBG.generateBuildingBlock( numPolymersPerOuterSphere, outerSphereFrustumInnerZ, minTheta, maxTheta, minPhi, maxPhi, outerSphereFrustumInnerRadius) PolymerSphereOuterBB.transformBBToLabFrame(np.array([0.0, 0.0, 1.0]), centerPos, 0.0) PolymerSphereOuterBB.exportBBK("OuterSphereBasePoints") PolymerSphereOuterPoints = PolymerSphereOuterBB.blockXYZVals PolymerSphereOuterPointsPolar = [ coords.XYZ2SphericalPolar(pos) for pos in PolymerSphereOuterBB.blockXYZVals ] outerDirectorsHat = [ coords.sphericalPolar2XYZ(np.array([1.0, pos[1], pos[2]])) for pos in PolymerSphereOuterPointsPolar ] # generate the inner sphere root positions at the mid layer radius and their directors pointing in towards the center PolymerSphereInnerBB = SphereBBG.generateBuildingBlock( numPolymersPerInnerSphere, innerSphereFrustumOuterZ, minTheta, maxTheta, minPhi, maxPhi, innerSphereFrustumOuterRadius) PolymerSphereInnerBB.transformBBToLabFrame(np.array([0.0, 0.0, 1.0]), centerPos, 0.0) PolymerSphereInnerBB.exportBBK("OuterSphereBasePoints") PolymerSphereInnerPoints = PolymerSphereInnerBB.blockXYZVals PolymerSphereInnerPointsPolar = [ coords.XYZ2SphericalPolar(pos) for pos in PolymerSphereInnerBB.blockXYZVals ] innerDirectorsHat = [
def convertPointToXYZ(self, pos): # this function takes a numpy array ([r, theta, phi]) and returns an XYZ numpy array. return coords.sphericalPolar2XYZ(pos)
def generateBuildingBlockXYZ(self): # The spidroin model consists of two alpha helical termini proteins which are taken from PDB files # and a long coil of about 3000 residues between them. The long coil is a random chain that must fit inside # a frustum so that it can pack together in a sphere. # # The centre of mass of the two termini are placed at +/- spidroinTerminusSeparation/2.0 on the x axis. print "CTerminus" refPosCTerm = np.array( [-self.spidroinTerminusSeparation / 2.0, 0.0, 0.0]) self.CTerminus = self.CTerminusGen.generateBuildingBlock( director=self.CTermDirectorHat, showBlockDirector=False) self.CTerminus.transformBBToLabFrame(self.spidroinDirector, refPosCTerm, self.CTermRot) if self.nameByBuildingBlockType: self.CTerminus.replaceNames(self.CTerminalAtomName) print "NTerminus" refPosNTerm = np.array( [self.spidroinTerminusSeparation / 2.0, 0.0, 0.0]) self.NTerminus = self.NTerminusGen.generateBuildingBlock( director=self.NTermDirectorHat, showBlockDirector=False) self.NTerminus.transformBBToLabFrame(self.spidroinDirector, refPosNTerm, self.NTermRot) if self.nameByBuildingBlockType: self.NTerminus.replaceNames(self.NTerminalAtomName) # accumulate a pointsToAvoid array as we go. pointsToAvoid = self.NTerminus.blockXYZVals + self.CTerminus.blockXYZVals if self.dumpInterimFiles == 1: fIO.saveXYZ(self.NTerminus.blockXYZVals, self.NTerminalAtomName, "NTerminal.xyz") fIO.saveXYZ(self.CTerminus.blockXYZVals, self.CTerminalAtomName, "CTerminal.xyz") print "constructing BetaSheets" numLoopResidues = 0 betaSheetOffset = np.array([0.0, 0.0, 0.0]) # construct correct number of antiparallel betasheet building blocks without any loops self.betaSheetBBs = [ self.BetasheetG.generateBuildingBlock(self.numBetaStrands, self.betaStrandLength, numLoopResidues, self.minDist, self.inStrandDirectorHat, self.crossStrandDirectorHat, betaSheetOffset, parallel=False) for n in range(0, self.numBetasheets) ] # compute the longest distance available in the beta sheet. # This is the mindist between the centre of mass of two beta sheets # and twice the distance of the betasheet centre of mass from the geometric boundary. # add two to the betaStrandLength to cope with the connection points betasheetSeparation = np.sqrt(( (self.betaStrandLength + 2) * self.betaStrandLengthPerResidue)**2 + (self.numBetaStrands * self.betaStrandSeparation)**2) # inhibit beta sheets from being closer than betaSheetSeparation/2 from the boundary where the coil cannot go. betaEnvelope = [ 'betasphere ' + str(self.betaSphereCenterZ) + ' ' + str(self.betaSphereRadius) ] # envelopeList=['None'] # useful line to have around to override envelope for debugging # compute a large box which surrounds the beta sheet zone XRange = [-1.5 * self.betaSphereRadius, 1.5 * self.betaSphereRadius] YRange = [-1.5 * self.betaSphereRadius, 1.5 * self.betaSphereRadius] ZRange = [self.betaSphereCenterZ - 1.5 * self.betaSphereRadius, 0] # calculate the positions of the centre of masses of the beta sheets within the beta envelope betaSheetCOMBB = self.SPBBG.generateBuildingBlock( self.numBetasheets, XRange, YRange, ZRange, betasheetSeparation, visualiseEnvelope=(10000, 2 * self.betaSphereRadius), envelopeList=betaEnvelope) 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]))) print "Transform Beta Sheet locations" for director, com, betaSheetBB in zip(betaSheetDirectors, betaSheetCOMBB.blockXYZVals, self.betaSheetBBs): betaSheetBB.transformBBToLabFrame(director, com, 0) # rename the atoms in the betasheets if the flag is set if self.nameByBuildingBlockType: for bsheet in self.betaSheetBBs: bsheet.replaceNames(self.betaStrandAtomName) # add the beta sheets to the pointsToAvoid List for betaSheetBB in self.betaSheetBBs: pointsToAvoid = np.concatenate( (pointsToAvoid, betaSheetBB.blockXYZVals), 0) if self.dumpInterimFiles == 1 and self.numBetasheets > 0: # compile the beta sheets into a single entity and dump to file - for debug betaSheets = self.betaSheetBBs[0].blockXYZVals for betaSheet in self.betaSheetBBs[1:]: betaSheets = np.concatenate( (betaSheets, betaSheet.blockXYZVals), 0) fIO.saveXYZ(betaSheets, self.betaStrandAtomName, "betaSheet.xyz") print "Constructing Coils" # Compute the coil start (A) and end (B) points. # Define points m2, m1 and m0 for the s2, s1 and s0 end points of the coil. # ensure a realistic join. There is enough space at the end of the termini to not check for clashes. # The betasheetseparation is increased by 1 residue longer than the strand length to help with this. # find the C-terminus end of the N terminus and calculate where the coil should start ConnectionA = self.NTerminus.getConnectionAtoms(1) # N (psi) C (phi) C (omega) N (psi) C (phi) C connection # s0 s1 s2 m2 m1 m0 # a C to N terminus connection pointsA = self.findCoilPoints(ConnectionA[0], ConnectionA[1], ConnectionA[2], self.CNbondLength, self.CNbondLength, self.CCbondLength, self.phi, self.angleC, self.omega, self.angleN, self.psi, self.angleC) # find the N-terminus end of the C terminus and calculate where the coil should start ConnectionB = self.CTerminus.getConnectionAtoms(0) # C (phi) C (omega) N (psi) C (phi) C (omega) N connection # s0 s1 s2 m2 m1 m0 # an N to C terminus connection pointsB = self.findCoilPoints(ConnectionB[0], ConnectionB[1], ConnectionB[2], self.CNbondLength, self.CCbondLength, self.CNbondLength, self.omega, self.angleN, self.psi, self.angleC, self.phi, self.angleC) betaSheetNPoints = [] betaSheetCPoints = [] # Determine the connector atoms that define the seed points for each coil. # and make a list of the seed points for each free end of coil. # We make an assumption that there are no other beta strand in the vicinity of each beta stranf. # We can help to ensure this by defining an outer sphere when we come to make each coil link to inhibit # the coils from straying too far from the direct path between the end points. for betaSheetBB in self.betaSheetBBs: # get a list of all the connectors for the current beta sheet. # always alternating with N then C terminal connectors depending on how many strands for n in range(0, len(betaSheetBB.getAllConnectionIndices())): connector = betaSheetBB.getConnectionAtoms(n) if n % 2 == 1: # C terminus of beta strand. # compute m0, m1 and m2 in a sub list and append that to the list of coil points # N (psi) C (phi) C (omega) N (psi) C (phi) C connection # s0 s1 s2 m2 m1 m0 betaSheetCPoints.append( self.findCoilPoints( connector[0], connector[1], connector[2], self.CNbondLength, self.CNbondLength, self.CCbondLength, self.phi, self.angleC, self.omega, self.angleN, self.psi, self.angleC)) else: # N Terminus of beta strand # C (phi) C (omega) N (psi) C (phi) C (omega) N connection # s0 s1 s2 m2 m1 m0 betaSheetNPoints.append( self.findCoilPoints(connector[0], connector[1], connector[2], self.CNbondLength, self.CCbondLength, self.CNbondLength, self.omega, self.angleN, self.psi, self.angleC, self.phi, self.angleC)) # seed the coil point list with the global N and C termini of the coil coilPoints = [(pointsA, pointsB) ] # coil pair goes from C terminus to N terminus # so pair[0] is C, pair[1] is N if self.numBetasheets > 0: # find a valid order of cyling through the connectors COrderIndex, NOrderIndex = self.findValidPairOrder( self.numBetasheets, self.numBetaStrands) # Re order N and C points with the chosen valid index order betaSheetNPoints = [ betaSheetNPoints[index] for index in NOrderIndex ] betaSheetCPoints = [ betaSheetCPoints[index] for index in COrderIndex ] # loop through each CPoint, NPoint pair (which will be randomised throughout all the # beta sheets) to make a master list of connections to connect with a randomcoil for CPoint, NPoint in zip(betaSheetCPoints, betaSheetNPoints): newCoilEntry = ( coilPoints[-1][0], NPoint ) # the previous C terminus going to a new N terminus. coilPoints[-1] = ( CPoint, coilPoints[-1][1] ) # a new C terminus going to the last N terminus. coilPoints.insert( -1, newCoilEntry ) # insert the new coil points at the end of the list. if self.dumpInterimFiles == 1: coilPointsXYZ = [] coilPointNames = [] curConnection = 0 names = ['H', 'He', 'Li', 'Be', 'B', 'C', 'N', 'O', 'Ne', 'K' ] # define 10 atoms for 10 colours and then cycle colours # dump all the coilPoints. Colour each pair it's own color to help ID the connectors. for coilPair in coilPoints: for coilConnector in coilPair: coilPointsXYZ += coilConnector #coilPointNames += ['H', 'He', 'Li'] coilPointNames += [ names[curConnection % 10], names[curConnection % 10], names[curConnection % 10] ] curConnection += 1 fIO.saveXYZList(coilPointsXYZ, coilPointNames, "CoilConnectors.xyz") print "Generating Coils" # The total length of the chain is to be broken up into chunks, each of which # must be long enough to reach the next point. We take betaStrandLengthPerResidue as the minimum # length of residue and compute the approximate number of residues needed to reach # between each pair of points in a straight line. spatialDistanceBetweenPoints = [ np.linalg.norm(pair[0][2] - pair[1][2]) for pair in coilPoints ] minVals = [ 2 * int(np.ceil(length / self.betaStrandLengthPerResidue)) for length in spatialDistanceBetweenPoints ] numResiduesInBetaStrands = numBetasheets * self.numBetaStrands * self.betaStrandLength numResiduesInTermini = int( float(self.NTerminus.countAtoms()) / 3.0 + float(self.CTerminus.countAtoms()) / 3.0) numResiduesToDivideUp = self.numResiduesCoil - numResiduesInBetaStrands - numResiduesInTermini if numResiduesToDivideUp < sum(minVals): print "Warning: Not enough residues for minimal coil connections." coilLengths = self.divideTotalSumEvenlyAmongListOfGroups( numResiduesToDivideUp, minVals) numCrankMoves = 0 # generate a random coil between each terminus adding the final loop to pointsToAvoid. # make sure it's inside the global frustum and also inside the local sphere defined by the distance # between the connection points. self.hairpinBBs = [] for coil, coilLength, distance in zip(coilPoints, coilLengths, spatialDistanceBetweenPoints): envelopeList = [ 'frustum ' + str(self.SpidroinFrustumZ1) + ' ' + str(self.SpidroinFrustumMaxRadius) + ' ' + str(self.SpidroinFrustumZ2) + ' ' + str(self.SpidroinFrustumMinRadius) ] envelopeList.append('innersphere ' + str(0.9 * distance / 2.0)) if len(coilPoints) > 1: envelopeList.append('outersphere ' + str(1.5 * distance / 2.0)) #envelopeList=['None'] # useful debug statement # generate the hairpin connection hairpinBB = self.CoilGen.generateBuildingBlock( coilLength, coil[0], coil[1], self.minDist, numCrankMoves, visualiseEnvelope=(0, 300), pointsToAvoid=pointsToAvoid, envelopeList=envelopeList) # add the hairpin to the pointsToAvoid array pointsToAvoid = np.concatenate( (pointsToAvoid, hairpinBB.blockXYZVals), 0) self.hairpinBBs.append(hairpinBB) if self.nameByBuildingBlockType: [hpin.replaceNames(self.hPinAtomName) for hpin in self.hairpinBBs] if self.dumpInterimFiles == 1: hPins = self.hairpinBBs[0].blockXYZVals for hPin in self.hairpinBBs[1:]: hPins = np.concatenate((hPins, hPin.blockXYZVals), 0) fIO.saveXYZ(hPins, self.hPinAtomName, "hPin.xyz") print "hairpins done" # assemble the components into a single final block of xyz values spidroinXYZ = self.NTerminus.blockXYZVals for betaSheet in self.betaSheetBBs: spidroinXYZ = np.concatenate((spidroinXYZ, betaSheet.blockXYZVals), 0) for hPin in self.hairpinBBs: spidroinXYZ = np.concatenate((spidroinXYZ, hPin.blockXYZVals), 0) spidroinXYZ = np.concatenate( (spidroinXYZ, self.CTerminus.blockXYZVals), 0) if self.dumpInterimFiles == 1: fIO.saveXYZ(spidroinXYZ, self.spidroinAtomName, "spidroinAsBlock.xyz") print "Spidroin Done" return spidroinXYZ
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 Spiral(numArms, numParticlesArm, armEndRad, particleName, polyGen, spiralAngularDisplacement, bondLength, alpha1, alpha2, beta1, beta2, AtomicMinDist, filename): # Sets up an N pointed star where the initial director at point A points out to a point, # and the end of the polymer is attracted to a pointB which is an angular displacement away from the # initial director point. Can be quite a large angle. Generates a sort of a spiral. # Don't bother with envelopes and self-intersection checking. Choose your angular ranges carefully. directors = [ coords.sphericalPolar2XYZ(np.array([1.0, 0.0, phi])) for phi in np.linspace(0, 2 * np.pi, numArms, endpoint=False) ] pointsB = [ coords.sphericalPolar2XYZ( np.array([armEndRad, 0.0, phi + spiralAngularDisplacement])) for phi in np.linspace(0, 2 * np.pi, numArms, endpoint=False) ] numCrankMoves = 0 polymerStartPoint = np.array([0.0, 0.0, 0.0]) strands = [ polyGen.generateBuildingBlock( numParticlesArm, polymerStartPoint, pointB, AtomicMinDist, bondLength, numCrankMoves, visualiseEnvelope=(0, 100), angularRange=[alpha1, alpha2, beta1, beta2], startDirector=director) for pointB, director in zip(pointsB, directors) ] [strand.setBlockRefPoint(polymerStartPoint) for strand in strands] names = [particleName] * numParticlesArm strandNum = 0 for strand in strands: strand.blockAtomNames = names[:] strandNum += 1 curStrand = 0 for director, strand in zip(directors, strands): strand.transformBBToLabFrame(director, polymerStartPoint, 0.0) if curStrand == 0: xyzVals = strand.blockXYZVals allNames = strand.blockAtomNames else: for xyzVal in strand.blockXYZVals: xyzVals.append(xyzVal) for name in strand.blockAtomNames: allNames.append(name) curStrand += 1 fIO.saveXYZList(xyzVals, allNames, filename) return xyzVals, allNames
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)
# generate the XYZVals packed in the outer cylinder BrushSphereBB = SphereBBG.generateBuildingBlock(numBrushes, SphereRadius, SphereRadius, SphereRadius, thetaMin, thetaMax, phiMin, phiMax, brushRadius) BrushSphereBB.transformBBToLabFrame(np.array([0.0, 0.0, 1.0]), centerPos, 0.0) BrushSphereBB.exportBBK("sphereBasePoints") BrushSpherePoints = BrushSphereBB.blockXYZVals # find a random director at each point brushAngles = [ coords.pickRandomPointOnUnitSphere() for director in BrushSpherePoints ] brushDirectors = [ coords.sphericalPolar2XYZ(np.array([1.0, angle[0], angle[1]])) for angle in brushAngles ] # generate unique polymer strands for i in range(numBrushes): print(i, "unimers out of: ", numBrushes) if i == 0: Brushes = [GeneralBlockPolymer(polymerBrushDict)] else: Brushes.append(GeneralBlockPolymer(polymerBrushDict)) # transform the brushes to the sphere points curStrand = 0 for directorHat, pos, strand in zip(brushDirectors, BrushSpherePoints, Brushes):