def make(self, assy, name, params, position=V(0, 0, 0), editCommand=None): height, width, bond_length, endings = params PROFILE = False if PROFILE: sw = Stopwatch() sw.start() mol = Chunk(assy, name) atoms = mol.atoms z = 0.0 self.populate(mol, height, width, z, bond_length, endings, position) if PROFILE: t = sw.now() env.history.message( greenmsg("%g seconds to build %d atoms" % (t, len(atoms.values())))) return mol
def build_struct(self, name, params, position): """ Build a graphene sheet from the parameters in the Property Manager. """ height, width, bond_length, endings = params PROFILE = False if PROFILE: sw = Stopwatch() sw.start() mol = Chunk(self.win.assy, self.name) atoms = mol.atoms z = 0.0 self.populate(mol, height, width, z, bond_length, endings, position) if PROFILE: t = sw.now() env.history.message(greenmsg("%g seconds to build %d atoms" % (t, len(atoms.values())))) return mol
def make(self, assy, name, params, position = V(0, 0, 0), editCommand = None): height, width, bond_length, endings = params PROFILE = False if PROFILE: sw = Stopwatch() sw.start() mol = Chunk(assy, name) atoms = mol.atoms z = 0.0 self.populate(mol, height, width, z, bond_length, endings, position) if PROFILE: t = sw.now() env.history.message(greenmsg("%g seconds to build %d atoms" % (t, len(atoms.values())))) return mol
def build_struct(self, name, params, position, mol=None, createPrinted=False): """ Build a nanotube from the parameters in the Property Manger dialog. """ length, n, m, bond_length, zdist, xydist, \ twist, bend, members, endings, numwalls, spacing = params # This can take a few seconds. Inform the user. # 100 is a guess on my part. Mark 051103. if not createPrinted: # If it's a multi-wall tube, only print the "Creating" message once. if length > 100.0: env.history.message(self.cmd + "This may take a moment...") self.chirality = Chirality(n, m, bond_length) PROFILE = False if PROFILE: sw = Stopwatch() sw.start() xyz = self.chirality.xyz if mol == None: mol = Chunk(self.win.assy, name) atoms = mol.atoms mlimits = self.chirality.mlimits # populate the tube with some extra carbons on the ends # so that we can trim them later self.chirality.populate(mol, length + 4 * self.chirality.maxlen, members != 0) # Apply twist and distortions. Bends probably would come # after this point because they change the direction for the # length. I'm worried about Z distortion because it will work # OK for stretching, but with compression it can fail. BTW, # "Z distortion" is a misnomer, we're stretching in the Y # direction. for atm in atoms.values(): # twist x, y, z = atm.posn() twistRadians = twist * z c, s = cos(twistRadians), sin(twistRadians) x, y = x * c + y * s, -x * s + y * c atm.setposn(V(x, y, z)) for atm in atoms.values(): # z distortion x, y, z = atm.posn() z *= (zdist + length) / length atm.setposn(V(x, y, z)) length += zdist for atm in atoms.values(): # xy distortion x, y, z = atm.posn() radius = self.chirality.R x *= (radius + 0.5 * xydist) / radius y *= (radius - 0.5 * xydist) / radius atm.setposn(V(x, y, z)) # Judgement call: because we're discarding carbons with funky # valences, we will necessarily get slightly more ragged edges # on nanotubes. This is a parameter we can fiddle with to # adjust the length. My thought is that users would prefer a # little extra length, because it's fairly easy to trim the # ends, but much harder to add new atoms on the end. LENGTH_TWEAK = bond_length # trim all the carbons that fall outside our desired length # by doing this, we are introducing new singlets for atm in atoms.values(): x, y, z = atm.posn() if (z > .5 * (length + LENGTH_TWEAK) or z < -.5 * (length + LENGTH_TWEAK)): atm.kill() # Apply bend. Equations are anomalous for zero bend. if abs(bend) > pi / 360: R = length / bend for atm in atoms.values(): x, y, z = atm.posn() theta = z / R x, z = R - (R - x) * cos(theta), (R - x) * sin(theta) atm.setposn(V(x, y, z)) def trimCarbons(): # trim all the carbons that only have one carbon neighbor for i in range(2): for atm in atoms.values(): if not atm.is_singlet() and len(atm.realNeighbors()) == 1: atm.kill() trimCarbons() # if we're not picky about endings, we don't need to trim carbons if endings == "Capped": # buckyball endcaps addEndcap(mol, length, self.chirality.R) if endings == "Hydrogen": # hydrogen terminations for atm in atoms.values(): atm.Hydrogenate() elif endings == "Nitrogen": # nitrogen terminations dstElem = PeriodicTable.getElement('N') atomtype = dstElem.find_atomtype('sp2') for atm in atoms.values(): if len(atm.realNeighbors()) == 2: atm.Transmute(dstElem, force=True, atomtype=atomtype) # Translate structure to desired position for atm in atoms.values(): v = atm.posn() atm.setposn(v + position) if PROFILE: t = sw.now() env.history.message(greenmsg("%g seconds to build %d atoms" % (t, len(atoms.values())))) if numwalls > 1: n += int(spacing * 3 + 0.5) # empirical tinkering params = (length, n, m, bond_length, zdist, xydist, twist, bend, members, endings, numwalls-1, spacing) self.build_struct(name, params, position, mol=mol, createPrinted=True) return mol
def build_struct(self, name, params, position, mol=None, createPrinted=False): """ Build a nanotube from the parameters in the Property Manger dialog. """ length, n, m, bond_length, zdist, xydist, \ twist, bend, members, endings, numwalls, spacing = params # This can take a few seconds. Inform the user. # 100 is a guess on my part. Mark 051103. if not createPrinted: # If it's a multi-wall tube, only print the "Creating" message once. if length > 100.0: env.history.message(self.cmd + "This may take a moment...") self.chirality = Chirality(n, m, bond_length) PROFILE = False if PROFILE: sw = Stopwatch() sw.start() xyz = self.chirality.xyz if mol == None: mol = Chunk(self.win.assy, name) atoms = mol.atoms mlimits = self.chirality.mlimits # populate the tube with some extra carbons on the ends # so that we can trim them later self.chirality.populate(mol, length + 4 * self.chirality.maxlen, members != 0) # Apply twist and distortions. Bends probably would come # after this point because they change the direction for the # length. I'm worried about Z distortion because it will work # OK for stretching, but with compression it can fail. BTW, # "Z distortion" is a misnomer, we're stretching in the Y # direction. for atm in atoms.values(): # twist x, y, z = atm.posn() twistRadians = twist * z c, s = cos(twistRadians), sin(twistRadians) x, y = x * c + y * s, -x * s + y * c atm.setposn(V(x, y, z)) for atm in atoms.values(): # z distortion x, y, z = atm.posn() z *= (zdist + length) / length atm.setposn(V(x, y, z)) length += zdist for atm in atoms.values(): # xy distortion x, y, z = atm.posn() radius = self.chirality.R x *= (radius + 0.5 * xydist) / radius y *= (radius - 0.5 * xydist) / radius atm.setposn(V(x, y, z)) # Judgement call: because we're discarding carbons with funky # valences, we will necessarily get slightly more ragged edges # on nanotubes. This is a parameter we can fiddle with to # adjust the length. My thought is that users would prefer a # little extra length, because it's fairly easy to trim the # ends, but much harder to add new atoms on the end. LENGTH_TWEAK = bond_length # trim all the carbons that fall outside our desired length # by doing this, we are introducing new singlets for atm in atoms.values(): x, y, z = atm.posn() if (z > .5 * (length + LENGTH_TWEAK) or z < -.5 * (length + LENGTH_TWEAK)): atm.kill() # Apply bend. Equations are anomalous for zero bend. if abs(bend) > pi / 360: R = length / bend for atm in atoms.values(): x, y, z = atm.posn() theta = z / R x, z = R - (R - x) * cos(theta), (R - x) * sin(theta) atm.setposn(V(x, y, z)) def trimCarbons(): # trim all the carbons that only have one carbon neighbor for i in range(2): for atm in atoms.values(): if not atm.is_singlet() and len(atm.realNeighbors()) == 1: atm.kill() trimCarbons() # if we're not picky about endings, we don't need to trim carbons if endings == "Capped": # buckyball endcaps addEndcap(mol, length, self.chirality.R) if endings == "Hydrogen": # hydrogen terminations for atm in atoms.values(): atm.Hydrogenate() elif endings == "Nitrogen": # nitrogen terminations dstElem = PeriodicTable.getElement('N') atomtype = dstElem.find_atomtype('sp2') for atm in atoms.values(): if len(atm.realNeighbors()) == 2: atm.Transmute(dstElem, force=True, atomtype=atomtype) # Translate structure to desired position for atm in atoms.values(): v = atm.posn() atm.setposn(v + position) if PROFILE: t = sw.now() env.history.message( greenmsg("%g seconds to build %d atoms" % (t, len(atoms.values())))) if numwalls > 1: n += int(spacing * 3 + 0.5) # empirical tinkering params = (length, n, m, bond_length, zdist, xydist, twist, bend, members, endings, numwalls - 1, spacing) self.build_struct(name, params, position, mol=mol, createPrinted=True) return mol
def build(self, name, assy, position, mol=None, createPrinted=False): """ Build a Peptide from the parameters in the Property Manger dialog. """ endPoint1, endPoint2 = self.getEndPoints() cntAxis = endPoint2 - endPoint1 length = vlen(cntAxis) # This can take a few seconds. Inform the user. # 100 is a guess. --Mark 051103. if not createPrinted: # If it's a multi-wall tube, only print the "Creating" message once. if length > 100.0: env.history.message("This may take a moment...") PROFILE = False if PROFILE: sw = Stopwatch() sw.start() xyz = self.xyz if mol == None: mol = Chunk(assy, name) atoms = mol.atoms mlimits = self.mlimits # populate the tube with some extra carbons on the ends # so that we can trim them later self.populate(mol, length + 4 * self.maxlen) # Apply twist and distortions. Bends probably would come # after this point because they change the direction for the # length. I'm worried about Z distortion because it will work # OK for stretching, but with compression it can fail. BTW, # "Z distortion" is a misnomer, we're stretching in the Y # direction. for atm in atoms.values(): # twist x, y, z = atm.posn() twistRadians = self.twist * z c, s = cos(twistRadians), sin(twistRadians) x, y = x * c + y * s, -x * s + y * c atm.setposn(V(x, y, z)) for atm in atoms.values(): # z distortion x, y, z = atm.posn() z *= (self.zdist + length) / length atm.setposn(V(x, y, z)) length += self.zdist for atm in atoms.values(): # xy distortion x, y, z = atm.posn() radius = self.getRadius() x *= (radius + 0.5 * self.xydist) / radius y *= (radius - 0.5 * self.xydist) / radius atm.setposn(V(x, y, z)) # Judgement call: because we're discarding carbons with funky # valences, we will necessarily get slightly more ragged edges # on Peptides. This is a parameter we can fiddle with to # adjust the length. My thought is that users would prefer a # little extra length, because it's fairly easy to trim the # ends, but much harder to add new atoms on the end. LENGTH_TWEAK = self.getBondLength() # trim all the carbons that fall outside our desired length # by doing this, we are introducing new singlets for atm in atoms.values(): x, y, z = atm.posn() if z > 0.5 * (length + LENGTH_TWEAK) or z < -0.5 * (length + LENGTH_TWEAK): atm.kill() # Apply bend. Equations are anomalous for zero bend. if abs(self.bend) > pi / 360: R = length / self.bend for atm in atoms.values(): x, y, z = atm.posn() theta = z / R x, z = R - (R - x) * cos(theta), (R - x) * sin(theta) atm.setposn(V(x, y, z)) def trimCarbons(): """ Trim all the carbons that only have one carbon neighbor. """ for i in range(2): for atm in atoms.values(): if not atm.is_singlet() and len(atm.realNeighbors()) == 1: atm.kill() trimCarbons() # If we're not picky about endings, we don't need to trim carbons if self.endings == "Capped": # buckyball endcaps addEndcap(mol, length, self.getRadius()) if self.endings == "Hydrogen": # hydrogen terminations for atm in atoms.values(): atm.Hydrogenate() elif self.endings == "Nitrogen": # nitrogen terminations. # This option has been removed from the "Endings" combo box # in the PM. 2008-05-02 --mark dstElem = PeriodicTable.getElement("N") atomtype = dstElem.find_atomtype("sp2") for atm in atoms.values(): if len(atm.realNeighbors()) == 2: atm.Transmute(dstElem, force=True, atomtype=atomtype) # Translate structure to desired position for atm in atoms.values(): v = atm.posn() atm.setposn(v + position) if PROFILE: t = sw.now() env.history.message(greenmsg("%g seconds to build %d atoms" % (t, len(atoms.values())))) if self.numwalls > 1: n += int(self.spacing * 3 + 0.5) # empirical tinkering self.build(name, assy, endPoint1, endPoint2, position, mol=mol, createPrinted=True) # Orient the Peptide. if self.numwalls == 1: # This condition ensures that MWCTs get oriented only once. self._orient(mol, endPoint1, endPoint2) return mol