def makeBackbones(backboneDictList): ''' Takes the backbone dictionary and makes a list of backbone building blocks defined in their own block frames ''' backboneSet = [] for backbone in backboneDictList: # create a backbone generator object for the polymer backboneBBG = RPPBBG(backbone['filename']) # create the starting point of the polymer startPointBackBone = np.array([0.0, 0.0, backbone['Z1']]) # generate the frustrum containing the polymer envelopeList = [ 'frustum ' + str(backbone['Z1']) + ' ' + str(backbone['R1']) + ' ' + str(backbone['Z2']) + ' ' + str(backbone['R2']) ] # assume failure rejectPolymer = True # loop until we get a viable polymer while rejectPolymer: # generate polymerBB of appropriate length. backboneBB = backboneBBG.generateBuildingBlock( backbone['numMonomers'], startPointBackBone, backbone['alpha1'], backbone['alpha2'], backbone['beta1'], backbone['beta2'], backbone['minDist'], backbone['bondLength'], envelopeList=envelopeList, visualiseEnvelope=(0, 100, backbone['name'] + '_envelope.xyz')) backboneBB.blockAtomNames = backbone['monomerNames'] # check that Z coord of point 0 is below z last point of polymer otherwise reject polymer and choose another one. if backboneBB.blockXYZVals[0][2] < backboneBB.blockXYZVals[-1][2]: rejectPolymer = False else: print("Polymer Rejected. Doing another.") # add building block to list of block copolymer segments if not backboneSet: backboneSet = [cp.copy(backboneBB)] else: backboneSet.append(cp.copy(backboneBB)) return backboneSet
def initialiseParameters(self): # ensure parent initialisation takes place and core values are initialised BBG.initialiseParameters(self) self.particleName = self.getParam('particleName') self.RPPBBG = RPPBBG(self.paramFilename) self.VPCBBG = VPCBBG(self.paramFilename) if self.noLoadErrors == False: print( "Critical Parameters are undefined for branched polymer network object" ) sys.exit()
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
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)
brush1 = GeneralBlockPolymer(polymerBrushDict) brush2 = GeneralBlockPolymer(polymerBrushDict) brush3 = GeneralBlockPolymer(polymerBrushDict) brush4 = GeneralBlockPolymer(polymerBrushDict) brush5 = GeneralBlockPolymer(polymerBrushDict) #fIO.saveXYZList(brush1[0], brush1[1], 'brush1.xyz') #fIO.saveXYZList(brush2[0], brush2[1], 'brush2.xyz') #fIO.saveXYZList(brush3[0], brush3[1], 'brush3.xyz') #fIO.saveXYZList(brush4[0], brush4[1], 'brush4.xyz') #fIO.saveXYZList(brush5[0], brush5[1], 'brush5.xyz') from Library.VolumePackEllipsoid import VolumePackEllipsoidBBG as VPEBBG SphereBBG = VPEBBG('VolumePackEllipsoid.txt') unimerBBG = RPPBBG('RandomPolymer.txt') numBrushes = 50 #185 #430 numUnimers = 200 brushRadius = 50 unimerRadius = 20 SphereRadius = 600 phiMin = -180 phiMax = 180 thetaMin = -90 thetaMax = 0 centerPos = np.array([0.0, 0.0, 0.0]) # generate the XYZVals packed in the outer cylinder BrushSphereBB = SphereBBG.generateBuildingBlock(numBrushes, SphereRadius,