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 generateBuildingBlockXYZ(self): # create the first residue in the BB if self.seedResidue == None: strand = self.startResidue() else: strand = self.seedResidue # tally the number of residues we added to strand numResidues = 1 # loop until we've added the right number of residues while numResidues < self.numResidues: # create new residue from the last three points residue = self.generateResidue(strand[-3:]) # add the new Residues to the strandVec list [strand.append(monomer) for monomer in residue] numResidues += 1 # perform final orientation depending on whether or not a seed residue was provided. # If seed was provided then don't fiddle with orientation at all. # if seed wasn't provided then return the strand with it's centre of mass # at the origin and it's helical axis pointing along the z-axis if self.seedResidue == None and self.numResidues > 3: # This structure was created in such a way that the first two atoms are # aligned with Z vector. We want the structure to be returned so it is at it's # centre of mass and also with the helical axis pointing up the z axis. # We will use the transformation from Lab to Block to achieve this, # with a little bit of hacking of the member variables. # find the helix axis and the centre of mass of the construct # as it is right now. currentDirector = coords.axisFromHelix(strand) currentDirectorHat = currentDirector / np.linalg.norm( currentDirector) currentCOM = cart.getCentreOfMass(strand) # Now specify the orientation and position that we want to map to. # store the refPoint as a member variable. targetRefPoint = np.array([0.0, 0.0, 0.0]) targetDirectorHat = np.array([0.0, 0.0, 1.0]) # modify the strand accordingly with the universal transformation function strand = coords.transformFromBlockFrameToLabFrame( targetDirectorHat, targetRefPoint, 0.0, currentDirectorHat, currentCOM, strand) return list( np.around(strand, 12) ) # round the positions to 12.dp - cleans up machine precision noise on zeroes
def generateSpaceCurve(self): # generates a space curve with a specified bond angle, dihedrals and bondlength b = self.bondLength n = self.numPoints # generate 3 points a distance b apart one of which is pointA s2 = self.pointA - b * self.blockDirectorHat s1Dir = np.array([ rnd.uniform(0.0, 1.0), rnd.uniform(0.0, 1.0), rnd.uniform(0.0, 1.0) ]) s1 = s2 - b * s1Dir / np.linalg.norm(s1Dir) spaceCurve = [s1, s2, self.pointA] # have first point so add a further n-1 points for _ in range(n - 1): # construct TNB frame from last three points of the space curve tnb = coords.constructTNBFrame(spaceCurve[-3], spaceCurve[-2], spaceCurve[-1]) if self.angularRange[0] == 'None': # compute a new direction based on beta and alpha alpha = self.alpha beta = self.beta else: # if the angular range is set then pick a random direction. (hope it's not too madly self intersecting. Got a bit chill about that later on. # careful narrow choices of ranges can give good results without checking for intersections. alpha = rnd.uniform(self.angularRange[0], self.angularRange[1]) beta = rnd.uniform(self.angularRange[2], self.angularRange[3]) dirn = coords.generateTNBVecXYZ(tnb, beta, alpha) # construct next space curve point spaceCurve.append(spaceCurve[-1] + b * dirn / np.linalg.norm(dirn)) currentAxis = coords.axisFromHelix(spaceCurve[2:]) currentRefPoint = self.pointA spaceCurve = coords.transformFromBlockFrameToLabFrame( self.blockDirectorHat, self.pointA, 0.0, currentAxis, currentRefPoint, spaceCurve[2:]) return spaceCurve
def generateSpaceCurve(self): # generates a space curve with specified bondLength but with bond angles and dihedrals # chosen from a range b = self.bondLength n = self.numPoints # generate 3 points a distance b apart one of which is pointA s2 = self.pointA - b * self.blockDirectorHat s1Dir = np.array([ rnd.uniform(0.0, 1.0), rnd.uniform(0.0, 1.0), rnd.uniform(0.0, 1.0) ]) s1 = s2 - b * s1Dir / np.linalg.norm(s1Dir) spaceCurve = [s1, s2, self.pointA] # have first point so add a further n-1 points for _ in range(n - 1): # construct TNB frame from last three points of the space curve tnb = coords.constructTNBFrame(spaceCurve[-3], spaceCurve[-2], spaceCurve[-1]) beta = rnd.uniform(self.beta1, self.beta2) alpha = rnd.uniform(self.alpha1, self.alpha2) # compute a new direction based on beta and alpha dirn = coords.generateTNBVecXYZ(tnb, beta, alpha) # construct next space curve point spaceCurve.append(spaceCurve[-1] + b * dirn / np.linalg.norm(dirn)) # chop the starting points off spaceCurve = spaceCurve[2:] if self.SpaceCurveTransform == True: currentAxis = coords.axisFromHelix(spaceCurve) currentRefPoint = self.pointA spaceCurve = coords.transformFromBlockFrameToLabFrame( self.blockDirectorHat, self.pointA, 0.0, currentAxis, currentRefPoint, spaceCurve) return spaceCurve
def genHsaPoints(filename, xyzVals, directors): print("working on file:", filename) # create the pdb object generator XYZObjGen = XYZBBG() # create the hsa object hsa = XYZObjGen.generateBuildingBlock(filename) xyzValsOut = [] xyzNames = [] # minVals = np.min(hsa.blockXYZVals, 0) # maxVals = np.max(hsa.blockXYZVals, 0) for pos, dirn in zip(xyzVals, directors): xyzValsOut += coords.transformFromBlockFrameToLabFrame( dirn, pos, 0, hsa.blockDirectorHat, hsa.blockRefPoint, hsa.blockXYZVals) newNames = ['W' if name == 'W' else 'C' for name in hsa.blockAtomNames] xyzNames += newNames return xyzValsOut, xyzNames
def connectBackboneSegments(backboneSet, connectorDictList): ''' connects together a set of polymer building block objects according to the connection information in the connectorDictList. The order of the segments is defined by the order they appear in the backboneSet list. If there are N segments there must be N-1 connector objects with the link information. The connector information contains the angle between polymer directors, and the azimuthal rotation between the directors of each segment, as well as the distance from the last monomer of the first polymer and the first monomer of the second polymer, in the direction of the first polymer's labdirector. The first two segments are always contained in the zx plane, and the first polymer is always aligned with the z axis. Setting all the azimuthal rotations to zero thus keeps all subsequent segments in the zx plane which is useful for 2D figures, and for defining a zero plane to put side brushes in later on.''' # intialise the first labdirector, TNB frame and start point labDirector = np.array([0.0, 0.0, 1.0]) labBidirector = np.array([1.0, 0.0, 0.0]) # initial bi-director along the x axis. labNormDirector = np.cross(labDirector, labBidirector) zeroPoint = np.array([0.0, 0.0, 0.0]) # initialise the output arrays with data from the first segment. backboneXYZ = backboneSet[0].blockXYZVals backboneNames = backboneSet[0].blockAtomNames backboneIndexList = [len(backboneXYZ)] backboneTNBList = [ (cp.copy(labDirector), cp.copy(labNormDirector), cp.copy(labBidirector) ) ] # find the principal axis of the first segment blockDirector = coords.axisFromHelix(backboneXYZ) # rotate the xyz vals to the z-axis lab director and translate the first point to the zeroPoint as defined backboneXYZ = coords.transformFromBlockFrameToLabFrame(labDirector, zeroPoint, 0.0, blockDirector, backboneXYZ[0], backboneXYZ) # loop through the connectors and remaining segments orienting them according to the instructions in the connector list for connector, newBackboneSegmentBB in zip(connectorDictList, backboneSet[1:]): # generate unit TNB frame for the last segment TNB = [labDirector, labNormDirector, labBidirector] # compute the lab director for the new block and connector information, which is defined relative to end of last polymer. newLabDirector = coords.generateTNBVecXYZ(TNB, connector['beta']*np.pi/180.0, connector['alpha']*np.pi/180.0) # compute the zero point for the new block to attach to the end of the polymer backbone as it is just now zeroPoint = backboneXYZ[-1] + connector['displacement'] * newLabDirector # find the current principal axis of the new segment blockDirector = coords.axisFromHelix(newBackboneSegmentBB.blockXYZVals) # rotate the xyz vals to the z-axis lab director and translate the first point to the zeroPoint as defined newBackboneXYZ = coords.transformFromBlockFrameToLabFrame(newLabDirector, zeroPoint, 0.0, blockDirector, newBackboneSegmentBB.blockXYZVals[0], newBackboneSegmentBB.blockXYZVals) # generate new TNB frame for the next segment labNormDirector = np.cross(labDirector, newLabDirector) labBidirector = np.cross(labNormDirector, newLabDirector) labDirector = newLabDirector # add the output information to the output arrays backboneXYZ = np.concatenate((backboneXYZ, newBackboneXYZ), 0) backboneNames = np.concatenate((backboneNames, newBackboneSegmentBB.blockAtomNames), 0) backboneIndexList.append(len(newBackboneXYZ)) backboneTNBList.append((cp.copy(newLabDirector), cp.copy(labNormDirector), cp.copy(labBidirector))) # return all the information that describes the backbone necessary for decorating it with side chains return (backboneXYZ, backboneNames, backboneIndexList, backboneTNBList)
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
else: outerUnimerStrands.append(GeneralBlockPolymer(polymerBrushDict)) # generate unique polymer strands for i in range(numPolymersPerSphere): print(i, "unimers out of: ", numPolymersPerSphere) if i==0: innerUnimerStrands=[GeneralBlockPolymer(polymerBrushDict)] else: innerUnimerStrands.append(GeneralBlockPolymer(polymerBrushDict)) # transform the strands to the sphere points curStrand = 0 for directorHat, pos, strand in zip(outerDirectorsHat, outerSpherePoints, outerUnimerStrands): labRotation = rnd.uniform(0, 2 * np.pi) xyzVals = coords.transformFromBlockFrameToLabFrame(directorHat, pos, labRotation, np.array([0.0, 0.0, 1.0]), strand[0][0], strand[0]) if curStrand==0: xyzValsList = xyzVals allNames = strand[1] else: xyzValsList = np.concatenate((xyzValsList, xyzVals), 0) allNames = np.concatenate( (allNames, strand[1]), 0) curStrand += 1 # transform the strands to the sphere points and add to output for directorHat, pos, strand in zip(innerDirectorsHat, innerSpherePoints, innerUnimerStrands): labRotation = rnd.uniform(0, 2 * np.pi) xyzVals = coords.transformFromBlockFrameToLabFrame(directorHat, pos, labRotation, np.array([0.0, 0.0, 1.0]), strand[0][0], strand[0]) xyzValsList = np.concatenate((xyzValsList, xyzVals), 0) allNames = np.concatenate( (allNames, strand[1]), 0) curStrand += 1
def generateBuildingBlock(self, numPoints, pointA, pointB, minDist, bondLength, numCrankMoves, pointsToAvoid=[], envelopeList=["None"]): self.numPoints = numPoints self.labPointA = pointA self.labPointB = pointB self.baseLength = np.linalg.norm(pointA - pointB) self.bondLength = float(bondLength) self.minDist = minDist self.blockPointA = np.array([-self.baseLength / 2, 0.0, 0.0]) self.blockPointB = np.array([self.baseLength / 2, 0.0, 0.0]) self.numCrankMoves = numCrankMoves self.allowedList = self.generateAllowedList() if self.dumpInterimFiles: fIO.saveXYZList([self.blockPointA, self.blockPointB], ['Ca', 'O'], 'blockPoints.xyz') # 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 pointsToAvoid information from the labFrame to the block frame blockPointsToAvoid = coords.transformFromLabFrameToBlockFrame( self.labDirector, self.labRefPoint, self.labRotation, self.blockDirectorHat, self.blockRefPoint, pointsToAvoid) if self.dumpInterimFiles == 1: # these are debugging tests to make sure the transform is correct blockPointATrans = coords.transformFromLabFrameToBlockFrame( self.labDirector, self.labRefPoint, self.labRotation, self.blockDirectorHat, self.blockRefPoint, [pointA])[0] blockPointBTrans = coords.transformFromLabFrameToBlockFrame( self.labDirector, self.labRefPoint, self.labRotation, self.blockDirectorHat, self.blockRefPoint, [pointB])[0] fIO.saveXYZList([blockPointATrans, blockPointBTrans], ['Ca', 'O'], "blockPointsTransFromLab.xyz") fIO.saveXYZ(blockPointsToAvoid, 'Li', "blockPointsToAvoid.xyz") labPointsToAvoidTrans = coords.transformFromBlockFrameToLabFrame( self.labDirector, self.labRefPoint, self.labRotation, self.blockDirectorHat, self.blockRefPoint, blockPointsToAvoid) fIO.saveXYZ(labPointsToAvoidTrans, 'Be', "labPointsToAvoidTrans.xyz") # parse the envelope list now to check pointA and point B self.parseEnvelopeList(envelopeList) # store points to avoid to check pointA and point B self.pointsToAvoid = blockPointsToAvoid # check starting points are legal or it's gonna be a long wait. if not self.checkPointInBounds(self.blockPointA): print "Error Warning: PointA out of bounds" time.sleep(3) if not self.checkPointInBounds(self.blockPointB): print "Error Warning: PointB out of bounds" time.sleep(3) return BBG.generateBuildingBlock(self, numPoints, minDist, envelopeList=envelopeList, pointsToAvoid=blockPointsToAvoid)
NumPolysNoHPMA, -BaseX / 2.0, BaseX / 2.0, -BaseY / 2.0, BaseY / 2.0, -BaseZ / 2.0, BaseZ / 2.0, NoHPMAMinDist) polysNoHPMAXYZVals = [] polysNoHPMANames = [] curPoint = 0 for point in PolysNoHPMAPoints.blockXYZVals: print curPoint, " of ", NumPolysNoHPMA # produce said polymer and move it to where we want it polysNoHPMAStrand = generateEBeamPolymer(NumPEG, 0, PolyGen, FZ1, FRadius1, FZ2, FRadius2, AtomicMinDist, bondLength) theta, phi = coords.pickRandomPointOnUnitSphere() director = coords.sphericalPolar2XYZ(np.array([1.0, theta, phi])) rotation = rnd.uniform(0, 2 * np.pi) newXYZVals = coords.transformFromBlockFrameToLabFrame( director, point, rotation, polysNoHPMAStrand.blockDirectorHat, polysNoHPMAStrand.getCOM(), polysNoHPMAStrand.blockXYZVals) if curPoint == 0: polysNoHPMAXYZVals = cp.copy(newXYZVals) polysNoHPMANames = cp.copy(polysNoHPMAStrand.blockAtomNames) else: polysNoHPMAXYZVals = np.concatenate( (polysNoHPMAXYZVals, cp.copy(newXYZVals)), 0) polysNoHPMANames = np.concatenate( (polysNoHPMANames, cp.copy( polysNoHPMAStrand.blockAtomNames)), 0) if curPoint < 5: fIO.saveXYZList(polysNoHPMAStrand.blockXYZVals, polysNoHPMAStrand.blockAtomNames, "polysNoHPMAStrand_" + str(curPoint) + ".xyz")
def Framboise(OuterRadius, InnerRadius, MicelleRadius, numOuter, numInner, numMicelles, numPointsMicelle, minDistInner, minDistOuter, minDistIntraMicelle, minDistExtraMicelle, theta1, theta2, phi1, phi2, surfaceSphereFilename, volumeSphereFilename, micelleBrush, vesicleBrush): # defines an outer vesicle and series of inner micelles and populates each type of point in these lists with a suitably defined # polymer brush. totalNumberOfBrushes = numMicelles * numPointsMicelle + numOuter + numInner # define the main outer vesicle points and directors vesicleData = vesicle(OuterRadius, InnerRadius, numOuter, numInner, minDistInner, minDistOuter, theta1, theta2, phi1, phi2, np.array([0.0, 0.0, 0.0]), np.array([0.0, 0.0, 1.0]), 0.0, surfaceSphereFilename, nameInner='C', nameOuter='C') # define centers of micelles envelopeList = ['innersphere ' + str(InnerRadius + 0.7 * minDistExtraMicelle), 'outersphere ' + str(OuterRadius - 0.7 * minDistExtraMicelle)] spherePack = VPEBBG(volumeSphereFilename) micelleCentrePointsBB = spherePack.generateBuildingBlock( numMicelles, OuterRadius, OuterRadius, OuterRadius, theta1, theta2, phi1, phi2, minDistExtraMicelle, envelopeList=envelopeList, defaultBlockRefPoint = np.array([0.0, 0.0, 0.0])) # generate the points, directors for each micelle micelleData = [] for micelleCentrePoint in micelleCentrePointsBB.blockXYZVals: newMicelle = micelle( MicelleRadius, numPointsMicelle, minDistIntraMicelle, -90, 90, -180, 180, micelleCentrePoint, np.array([0.0, 0.0, 1.0]), 0.0, surfaceSphereFilename, name='C') micelleData.append(newMicelle) # generate polymerBrush for each point in each micelle and transfer to framboiseXYZ and framboiseNames framboiseXYZ = [] framboiseNames = [] firstTime = True; i = 0 for curMicelle in micelleData: for point, dirNorm in zip(curMicelle[0], curMicelle[2]): if firstTime: (brushDir, brushRefPoint, brushXyzVals, brushNames) = PB(micelleBrush) newXyzVals = coords.transformFromBlockFrameToLabFrame(dirNorm, point, rnd.uniform(0, 2 * np.pi), brushDir, brushRefPoint, brushXyzVals) framboiseXYZ = newXyzVals framboiseNames = brushNames firstTime = False else: (brushDir, brushRefPoint, brushXyzVals, brushNames) = PB(micelleBrush) newXyzVals = coords.transformFromBlockFrameToLabFrame(dirNorm, point, rnd.uniform(0, 2 * np.pi), brushDir, brushRefPoint, brushXyzVals) framboiseXYZ += newXyzVals framboiseNames = np.concatenate( (framboiseNames, brushNames), 0 ) i+=1 if i%10==0: print "Completed Brush " + str(i) + " of " + str(totalNumberOfBrushes) # set the peptide brushnames to B (enables different colour to be used for centre of vesicles framboiseNames = [ 'B' if a=='C' else a for a in framboiseNames] # for each point in the vesicle create a polymer brush for point, dirNorm in zip(vesicleData[0], vesicleData[2]): (brushDir, brushRefPoint, brushXyzVals, brushNames) = PB(vesicleBrush) newXyzVals = coords.transformFromBlockFrameToLabFrame(dirNorm, point, rnd.uniform(0, 2 * np.pi), brushDir, brushRefPoint, brushXyzVals) framboiseXYZ += newXyzVals framboiseNames = np.concatenate( (framboiseNames, brushNames), 0 ) i+=1 if i%10==0: print "Completed Brush " + str(i) + " of " + str(totalNumberOfBrushes) return (framboiseXYZ,list(framboiseNames))
def transformBBToLabFrame(self, labDirector, labRefPoint, labRotation): self.blockXYZVals = coord.transformFromBlockFrameToLabFrame(labDirector, labRefPoint, labRotation, self.blockDirectorHat, self.blockRefPoint, self.blockXYZVals) self.blockDirectorHat = coord.transformFromBlockFrameToLabFrame(labDirector, labRefPoint, labRotation, self.blockDirectorHat, self.blockRefPoint, [self.blockRefPoint + self.blockDirectorHat])[0] - labRefPoint self.blockRefPoint = labRefPoint
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)
def generateUnimer(self, point, director, numPoints, pointsToAvoid, maxNumAttempts): # half the time, scale the number of points by a random factor between 0.5 and 1.0 # otherwise all the unimers will leave the box if rnd.uniform(0.0, 1.0) > 1.0: numPoints *= rnd.uniform(0.5, 1.0) # make the numPoints an integer numPoints = int(numPoints) # develop the frustum definition in the block frame of the unimer z1 = -self.bondLength r1 = self.bondLength z2 = numPoints * self.bondLength r2 = z2 * np.tan(self.coneAngle / 2.0) localEnvelopeList = [ "frustum " + str(z1) + ' ' + str(r1) + ' ' + str(z2) + ' ' + str(r2) ] if numPoints == 0: print("Zero Length Polymer") numPointsOutside = numPoints numLoops = 0 # loop until we create a unimer that satisfies constraints. Can set maxNumAttempts depending on how bothered we are about constraints. while numPointsOutside > 0 and numLoops < maxNumAttempts: if numLoops > 0: print( "Re-generating Unimer - exceeds global envelope. Attempt: ", numLoops + 1, "of ", maxNumAttempts) # generate the unimer in it's own block frame starting at origin. Don't worry about outer envelope or other points at this stage unimer = self.RPPBBG.generateBuildingBlock( numPoints, np.array([0.0, 0.0, 0.0]), self.alpha1, self.alpha2, self.beta1, self.beta2, self.monomerMinDist, self.bondLength, pointsToAvoid=[], envelopeList=localEnvelopeList, SpaceCurveTransform=self.SpaceCurveTransform) #visualiseEnvelope=(100000,200,'envelopeUnimer.xyz')) if self.dumpInterimFiles == 1: fIO.saveXYZ(unimer.blockXYZVals, 'Ca', 'preRotUnimer.xyz') # now rotate and translate the unimer xyzVals to their final point rotXYZVals = coords.transformFromBlockFrameToLabFrame( director, point, 0.0, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), unimer.blockXYZVals) # Now check that the unimer is entirely within the outer box, and any global specified user envelope, # Also make sure that the unimer is networkMinDist points away from existing pointsToAvoid. # Won't self check the unimer against itself only the points to avoid. Allows to have two minDists. # One for the monomer distance along the backbone, and one for the distance between unimers (2 * worm tube radius). # enables the unimer bondlength to be small which makes for smoother unimer chains. numPointsOutside = len( self.checkEnvelope(rotXYZVals, ignorePTA=False, pointsToAvoid=pointsToAvoid)) # increment loop counter numLoops += 1 return rotXYZVals
# 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) theta, phi = coords.pickRandomPointOnUnitSphere()
def generateBuildingBlockXYZ(self): print "load spidroin coil information" spidroinCoilSpecies1Names, spidroinCoilSpecies1XYZ = fIO.loadXYZ( self.spidroinSpecies1FName) spidroinCoilSpecies2Names, spidroinCoilSpecies2XYZ = fIO.loadXYZ( self.spidroinSpecies2FName) print "Generating spidroin sites within cluster" spidroinPositionBB = self.SPEBBG.generateBuildingBlock( self.numPointsInCluster, self.clusterRX, self.clusterRY, self.clusterRZ, -90.0, 90.0, -180.0, 180.0, self.SpidroinRadius) # compute the positions and orientations of each individual spidroin within it's cluster spidroinPositions = spidroinPositionBB.blockXYZVals spidroinDirectors = [spidPos for spidPos in spidroinPositions] spidroinDirectorsHat = [ spidDir / np.linalg.norm(spidDir) for spidDir in spidroinDirectors ] spidroinRots = [ rnd.uniform(0, 360) for _ in range(0, self.numPointsInCluster) ] print "Generating cluster positions within the larger aggregate" clusterPositionBB = self.VPEBBG.generateBuildingBlock( self.numClustersInAggregate, self.aggregateRX, self.aggregateRY, self.aggregateRZ, -90.0, 90.0, -180.0, 180.0, (max(self.clusterRX, self.clusterRY, self.clusterRZ) + self.species2AltitudeBoost + self.TerminalExtension)) clusterPositions = clusterPositionBB.blockXYZVals clusterDirectors = [clustPos for clustPos in clusterPositions] clusterDirectorsHat = [ clustDir / np.linalg.norm(clustDir) for clustDir in clusterDirectors ] clusterRots = [ rnd.uniform(0, 360) for _ in range(0, self.numClustersInAggregate) ] fIO.saveXYZ(clusterPositions, 'Ne', 'aggClusterPoints.xyz') print "Producing Cluster" # sety up output arrays clusterXYZ = [] clusterNames = [] spidroinNum = 0 # loop through the right number of times for the species1 data for rotation, director, position in zip( spidroinRots[0:self.numSpidroinSpecies1], spidroinDirectorsHat[0:self.numSpidroinSpecies1], spidroinPositions[0:self.numSpidroinSpecies1]): print spidroinNum if len(clusterXYZ) == 0: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies1XYZ[:]) clusterXYZ = xyzVals[:] clusterNames = spidroinCoilSpecies1Names else: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies1XYZ[:]) clusterXYZ = np.concatenate((clusterXYZ, xyzVals[:]), 0) clusterNames = np.concatenate( (clusterNames[:], spidroinCoilSpecies1Names), 0) spidroinNum += 1 # loop throught the species2 data and add the species two data at a slightly higher altitude. for rotation, director, position in zip( spidroinRots[self.numSpidroinSpecies1:], spidroinDirectorsHat[self.numSpidroinSpecies1:], spidroinPositions[self.numSpidroinSpecies1:]): print spidroinNum xyzVals = coords.transformFromBlockFrameToLabFrame( director, position + director * self.species2AltitudeBoost, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies2XYZ[:]) clusterXYZ = np.concatenate((clusterXYZ, xyzVals[:]), 0) clusterNames = np.concatenate( (clusterNames[:], spidroinCoilSpecies2Names), 0) spidroinNum += 1 fIO.saveXYZList(clusterXYZ, clusterNames, "cluster.xyz") print "Producing aggregate" # sety up output arrays aggregateXYZ = [] aggregateNames = [] clusterNum = 0 # loop through the right number of times for the species1 data for rotation, director, position in zip(clusterRots, clusterDirectorsHat, clusterPositions): print clusterNum if len(aggregateXYZ) == 0: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), clusterXYZ) aggregateXYZ = xyzVals[:] aggregateNames = clusterNames else: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), clusterXYZ) aggregateXYZ = np.concatenate((aggregateXYZ, xyzVals[:]), 0) aggregateNames = np.concatenate((aggregateNames, clusterNames), 0) clusterNum += 1 fIO.saveXYZList(aggregateXYZ, aggregateNames, "spidroinAggregate.xyz") self.namesTemp = aggregateNames return aggregateXYZ
def generateBuildingBlockXYZ(self): print "load spidroin coil information" spidroinCoilSpecies1Names, spidroinCoilSpecies1XYZ = fIO.loadXYZ( self.spidroinSpecies1FName) spidroinCoilSpecies2Names, spidroinCoilSpecies2XYZ = fIO.loadXYZ( self.spidroinSpecies2FName) print "Generating spidroin sites within cluster" spidroinPositionBB = self.VPESCPBBG.generateBuildingBlock( self.numPointsInCluster, self.clusterRX, self.clusterRY, self.clusterRZ, -90.0, 90.0, -180.0, 180.0, -10.0, 10.0, -10.0, 10.0, self.monomerRadius, self.terminalSeparation, 2) # compute the positions and orientations of each individual spidroin within it's cluster spidroinPositionInfo = spidroinPositionBB.blockXYZVals spidroinPositions = [ (pos + spidroinPositionInfo[2 * i + 1]) / 2.0 for i, pos in enumerate(spidroinPositionInfo[0:-1:2]) ] spidroinDirectors = [ (2.0 * float(rnd.randint(0, 1)) - 1.0) * (spidroinPositionInfo[2 * i + 1] - pos) for i, pos in enumerate(spidroinPositionInfo[0:-1:2]) ] spidroinDirectorsHat = [ director / np.linalg.norm(director) for director in spidroinDirectors ] spidroinRots = [ rnd.uniform(0.0, 360.0) for _ in range(0, self.numPointsInCluster) ] print "Generating cluster positions within the larger aggregate" clusterPositionBB = self.VPESCPBBG.generateBuildingBlock( self.numClustersInAggregate, self.aggregateRX, self.aggregateRY, self.aggregateRZ, -90.0, 90.0, -180.0, 180.0, -90.0, 90.0, -180.0, 180.0, self.clusterRY, self.clusterRX, 2) clusterPositionInfo = clusterPositionBB.blockXYZVals clusterPositions = [ (pos + clusterPositionInfo[2 * i + 1]) / 2.0 for i, pos in enumerate(clusterPositionInfo[0:-1:2]) ] clusterDirectors = [ (clusterPositionInfo[2 * i + 1] - pos) for i, pos in enumerate(clusterPositionInfo[0:-1:2]) ] clusterDirectorsHat = [ clustDir / np.linalg.norm(clustDir) for clustDir in clusterDirectors ] clusterRots = [0.0 for _ in range(0, self.numClustersInAggregate)] fIO.saveXYZList(spidroinPositions, ['Ca', 'O'] * self.numPointsInCluster, 'aggClusterPoints.xyz') print "Producing Cluster" # sety up output arrays clusterXYZ = [] clusterNames = [] spidroinNum = 0 # loop through the right number of times for the species1 data for rotation, director, position in zip( spidroinRots[0:self.numSpidroinSpecies1], spidroinDirectorsHat[0:self.numSpidroinSpecies1], spidroinPositions[0:self.numSpidroinSpecies1]): print spidroinNum if len(clusterXYZ) == 0: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies1XYZ[:]) clusterXYZ = xyzVals[:] clusterNames = spidroinCoilSpecies1Names else: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies1XYZ[:]) clusterXYZ = np.concatenate((clusterXYZ, xyzVals[:]), 0) clusterNames = np.concatenate( (clusterNames[:], spidroinCoilSpecies1Names), 0) spidroinNum += 1 # loop throught the species2 data and add the species two data at a slightly higher altitude. for rotation, director, position in zip( spidroinRots[self.numSpidroinSpecies1:], spidroinDirectorsHat[self.numSpidroinSpecies1:], spidroinPositions[self.numSpidroinSpecies1:]): print spidroinNum xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([1.0, 0.0, 0.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies2XYZ[:]) clusterXYZ = np.concatenate((clusterXYZ, xyzVals[:]), 0) clusterNames = np.concatenate( (clusterNames[:], spidroinCoilSpecies2Names), 0) spidroinNum += 1 fIO.saveXYZList(clusterXYZ, clusterNames, "cluster.xyz") print "Producing aggregate" # sety up output arrays aggregateXYZ = [] aggregateNames = [] clusterNum = 0 # loop through the right number of times for the species1 data for rotation, director, position in zip(clusterRots, clusterDirectorsHat, clusterPositions): print clusterNum if len(aggregateXYZ) == 0: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), clusterXYZ) aggregateXYZ = xyzVals[:] aggregateNames = clusterNames else: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), clusterXYZ) aggregateXYZ = np.concatenate((aggregateXYZ, xyzVals[:]), 0) aggregateNames = np.concatenate((aggregateNames, clusterNames), 0) clusterNum += 1 fIO.saveXYZList(aggregateXYZ, aggregateNames, "spidroinAggregate.xyz") self.namesTemp = aggregateNames return aggregateXYZ
alpha1 = 40 alpha2 = 50 beta1 = 110 beta2 = 130 minDist = 1.0 bondLength = 2.0 polymers = [ PolymerGenerator.generateBuildingBlock(numMonomers, pointA, alpha1, alpha2, beta1, beta2, minDist, bondLength) for _ in range(0, numPoints) ] outputXYZ = [] # hello for unimer, basePoint in zip(polymers, baseSPhereBB.blockXYZVals): director = basePoint / np.linalg.norm(basePoint) newUnimerXYZ = coords.transformFromBlockFrameToLabFrame( director, basePoint, 0.0, np.array([0.0, 0.0, 1.0]), pointA, unimer.blockXYZVals) outputXYZ += cp.copy(newUnimerXYZ) fIO.saveXYZ(outputXYZ, 'C', "unimers.xyz") print("Example done")
def generateBuildingBlockXYZ(self): print "Computing standard CTerminus for export as PDB" refPosCTerm = np.array([ -self.spidroinTerminusSeparation / 2.0, 0.0, -2.7 ]) # this last 2.7 is a total hack to get pointB in the envelope self.CTerminusAll = self.CTerminusGen.generateBuildingBlock( backboneOnly=False, director=self.CTermDirectorHat, showBlockDirector=False) self.CTerminusBackbone = self.CTerminusGen.generateBuildingBlock( backboneOnly=True, director=self.CTermDirectorHat, showBlockDirector=False) self.CTerminusAll.transformBBToLabFrame(self.spidroinDirector, refPosCTerm, self.CTermRot) self.CTerminusBackbone.transformBBToLabFrame(self.spidroinDirector, refPosCTerm, self.CTermRot) print "Computing standard NTerminus for export as PDB" refPosNTerm = np.array( [self.spidroinTerminusSeparation / 2.0, 0.0, 0.0]) self.NTerminusAll = self.NTerminusGen.generateBuildingBlock( backboneOnly=False, director=self.NTermDirectorHat, showBlockDirector=False) self.NTerminusBackbone = self.NTerminusGen.generateBuildingBlock( backboneOnly=True, director=self.NTermDirectorHat, showBlockDirector=False) self.NTerminusAll.transformBBToLabFrame(self.spidroinDirector, refPosNTerm, self.NTermRot) self.NTerminusBackbone.transformBBToLabFrame(self.spidroinDirector, refPosNTerm, self.NTermRot) print "Generating spidroin sites within cluster" spidroinPositionBB = SPEBBG.generateBuildingBlock( self, self.numPointsInCluster, self.clusterRX, self.clusterRY, self.clusterRZ, -90, 90, -180, 180, self.SpidroinRadius) # compute the positions and orientations of each individual spidroin within it's cluster spidroinPositions = spidroinPositionBB.xyzVals spidroinDirectors = [spidPos for spidPos in spidroinPositions] spidroinDirectorsHat = [ spidDir / np.linalg.norm(spidDir) for spidDir in spidroinDirectors ] spidroinRots = [ rnd.uniform(0, 360) for _ in range(0, self.numSpidroins) ] print "Generating cluster positions with in the aggregate" clusterPositionBB = SPEBBG.generateBuildingBlock( self, self.numClustersInAggregate, self.aggregateRX, self.aggregateRY, self.aggregateRZ, -90, 90, -180, 180, max(self.clusterRX, self.clusterRY, self.clusterRZ) + self.species2AltitudeBoost + self.TerminalExtension) clusterPositions = clusterPositionBB.xyzVals clusterDirectors = [clustPos for clustPos in clusterPositions] clusterDirectorsHat = [ clustDir / np.linalg.norm(clustDir) for clustDir in clusterDirectors ] clusterRots = [ rnd.uniform(0, 360) for _ in range(0, self.numClustersInAggregate) ] print "load spidroin coil information" spidroinCoilSpecies1XYZ, spidroinCoilSpecies1Names = fIO.loadXYZ( self.spidroinSpecies1FName) spidroinCoilSpecies2XYZ, spidroinCoilSpecies2Names = fIO.loadXYZ( self.spidroinSpecies2FName) print "Producing Cluster of clusters" # sety up output arrays NTermPoints = [] CTermPoints = [] xyzValCoils = [] names = [] for clustDirector, clustPosition, clustRotation in zip( clusterDirectorsHat, clusterPositions, clusterRots): # loop through the right number of times for the species1 data for rotation, director, position in zip( spidroinRots[0:self.numSpidroinSpecies1], spidroinDirectorsHat[0:self.numSpidroinSpecies1], spidroinPositions[0:self.numSpidroinSpecies1]): if len(NTermPoints) == 0: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies1XYZ[:]) xyzVals = coords.transformFromBlockFrameToLabFrame( clustDirector, clustPosition, clustRotation, director, position, xyzVals) NTermPoints = xyzVals[0] NTermPoints = xyzVals[-1] xyzValCoils = xyzVals names = spidroinCoilSpecies1Names else: xyzVals = coords.transformFromBlockFrameToLabFrame( director, position, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies1XYZ[:]) xyzVals = coords.transformFromBlockFrameToLabFrame( clustDirector, clustPosition, clustRotation, director, position, xyzVals) NTermPoints = np.concatenate((NTermPoints, xyzVals[0]), 0) CTermPoints = np.concatenate((CTermPoints, xyzVals[0]), 0) xyzValCoils = np.concatenate((xyzValCoils, xyzVals), 0) names = np.concatenate((names, spidroinCoilSpecies1Names), 0) # loop throught the species2 data and add the species two data at a slightly higher altitude. for rotation, director, position in zip( spidroinRots[self.numSpidroinSpecies1:], spidroinDirectorsHat[self.numSpidroinSpecies1:], spidroinPositions[self.numSpidroinSpecies1:]): xyzVals = coords.transformFromBlockFrameToLabFrame( director, position + director * self.species2AltitudeBoost, rotation, np.array([0.0, 0.0, 1.0]), np.array([0.0, 0.0, 0.0]), spidroinCoilSpecies2XYZ[:]) xyzVals = coords.transformFromBlockFrameToLabFrame( clustDirector, clustPosition, clustRotation, director, position, xyzVals) NTermPoints = np.concatenate((NTermPoints, xyzVals[0]), 0) CTermPoints = np.concatenate((CTermPoints, xyzVals[0]), 0) xyzValCoils = np.concatenate((xyzValCoils, xyzVals), 0) names = np.concatenate((names, spidroinCoilSpecies2Names), 0) self.namesTemp = names return xyzValCoils