Ejemplo n.º 1
0
 def __init__(self, assy, atomset = None, name = None): # revised 060413
     """
     #doc; for doc of atomset, see take_atomset
     """
     Chunk.__init__(self, assy, self._name_when_empty(assy))
     if atomset is not None:
         self.take_atomset(atomset, name = name)
     return
Ejemplo n.º 2
0
 def __init__(self, assy, atomset=None, name=None):  # revised 060413
     """
     #doc; for doc of atomset, see take_atomset
     """
     Chunk.__init__(self, assy, self._name_when_empty(assy))
     if atomset is not None:
         self.take_atomset(atomset, name=name)
     return
 def _draw_outside_local_coords(self, glpane, disp, drawLevel, is_chunk_visible):
     Chunk._draw_outside_local_coords(self, glpane, disp, drawLevel, is_chunk_visible)
     for atom in self.atoms.itervalues():
         if hasattr(atom, '_site_atom_jig'):
             color = 'not used'
             atom._site_atom_jig._draw_jig(glpane, color) # note: needs to be in abs coords
             ## print "called %r._draw_jig" % atom # works
             pass
         continue
     return
 def _draw_outside_local_coords(self, glpane, disp, drawLevel,
                                is_chunk_visible):
     Chunk._draw_outside_local_coords(self, glpane, disp, drawLevel,
                                      is_chunk_visible)
     for atom in self.atoms.itervalues():
         if hasattr(atom, '_site_atom_jig'):
             color = 'not used'
             atom._site_atom_jig._draw_jig(
                 glpane, color)  # note: needs to be in abs coords
             ## print "called %r._draw_jig" % atom # works
             pass
         continue
     return
Ejemplo n.º 5
0
    def build_struct(self, name, parameters, position):
        """
        Build an Atom (as a chunk) according to the given parameters.
        
        @param name: The name which should be given to the toplevel Node of the
                     generated structure. The name is also passed in self.name.
        @type  name: str

        @param parameters: The parameter tuple returned from 
                           L{gather_parameters()}.
        @type  parameters: tuple

        @param position: Unused. The xyz position is obtained from the 
                         I{parameters} tuple.
        @type position:  position

        @return: The new structure, i.e. some flavor of a Node, which
                 has not yet been added to the model.  Its structure
                 should depend only on the values of the passed
                 parameters, since if the user asks to build twice, this
                 method may not be called if the parameterss have not
                 changed.
        @rtype:  Node
        """
        x, y, z, theElement, theAtomType = parameters

        # Create new chunk to contain the atom.
        outMolecule = Chunk(self.win.assy, self.name)
        theAtom = Atom(theElement, V(x, y, z), outMolecule)
        theAtom.set_atomtype(theAtomType)
        theAtom.make_enough_bondpoints()

        return outMolecule
Ejemplo n.º 6
0
def insertgms_new(assy, filename):
    """
    Reads a GAMESS DAT file and inserts it into the existing model.
    Returns: 0 = Success
                   1 = Failed
    """

    gmsAtomList = _get_atomlist_from_gms_outfile(assy, filename)

    if not gmsAtomList:
        return 1  # No atoms read.

    dir, nodename = os.path.split(filename)
    mol = Chunk(assy, nodename)
    ndix = {}

    n = 0

    for a in gmsAtomList:
        print a
        pos = a.posn()
        fpos = (float(pos[0]), float(pos[1]), float(pos[2]))
        na = Atom(a.element.symbol, fpos, mol)
        ndix[n] = na
        n += 1

    if mol is not None:
        assy.addmol(mol)
        return 0
    else:
        return 1
Ejemplo n.º 7
0
    def constructModel(self, elm, pos, dispMode):
        """
        This is to try to repeat what 'make_Atom_and_bondpoints()' method does,
        but hope to remove some stuff not needed here.
        The main purpose is to build the geometry model for element display.

        @param elm: An object of class Elem
        @param elm: L{Elem}

        @param dispMode: the display mode of the atom
        @type  dispMode: int

        @return: the Chunk which contains the geometry model.
        @rtype: L{Chunk}
        """
        assy = Assembly(None, run_updaters=False)
        assy.set_glpane(self)  # sets .o and .glpane
        mol = Chunk(assy, 'dummy')
        atm = Atom(elm.symbol, pos, mol)
        atm.display = dispMode
        ## bruce 050510 comment: this is approximately how you should change the atom type (e.g. to sp2) for this new atom:
        if self.hybrid_type_name:
            atm.set_atomtype_but_dont_revise_singlets(self.hybrid_type_name)
        ## see also atm.element.atomtypes -> a list of available atomtype objects for that element
        ## (which can be passed to set_atomtype_but_dont_revise_singlets)
        atm.make_bondpoints_when_no_bonds()

        self.elementMode = True
        return mol
Ejemplo n.º 8
0
    def _finish_molecule():
        """
        Perform some operations after reading entire PDB chain:
          - rebuild (infer) bonds
          - rename molecule to reflect a chain ID
          - delete protein object if this is not a protein
          - append the molecule to the molecule list
        """
        
        if mol == water:
            # Skip water, to be added explicitly at the end.
            return
        
        if mol.atoms:  
            ###print "READING PDB ", (mol, numconects, chainId)
            
            mol.name = pdbid.lower() + chainId

            ###idzialprint "SEQ = ", mol.protein.get_sequence_string()
            ###print "SEC = ", mol.protein.get_secondary_structure_string()
            
            if mol.protein.count_c_alpha_atoms() == 0:
                # If there is no C-alpha atoms, consider the chunk 
                # as a non-protein. But! Split it into individual 
                # hetero groups.
                res_list = mol.protein.get_amino_acids()
                assy.part.ensure_toplevel_group()
                hetgroup = Group("Heteroatoms", assy, assy.part.topnode) 
                for res in res_list:
                    hetmol = Chunk(assy, 
                                   res.get_three_letter_code().replace(" ", "") + \
                                   "[" + str(res.get_id()) + "]")
                    for atom in res.get_atom_list():
                        newatom = Atom(atom.element.symbol, atom.posn(), hetmol)
                    # New chunk - infer the bonds anyway (this is not
                    # correct, should first check connectivity read from
                    # the PDB file CONECT records).
                    inferBonds(hetmol)
                    hetgroup.addchild(hetmol)
                mollist.append(hetgroup)
            else:
                #if numconects == 0:
                #    msg = orangemsg("PDB file has no bond info; inferring bonds")
                #    env.history.message(msg)
                #    # let user see message right away (bond inference can take significant 
                #    # time) [bruce 060620]
                #    env.history.h_update() 

                # For protein - infer the bonds anyway.
                inferBonds(mol)
                    
                mol.protein.set_chain_id(chainId)
                mol.protein.set_pdb_id(pdbid)
                if mol.atoms:
                    mollist.append(mol)                
        else:
            env.history.message( redmsg( "Warning: Pdb file contained no atoms"))
            env.history.h_update() 
Ejemplo n.º 9
0
 def create_methane_test(self, params, name):
     # example: build some methanes
     print "create_methane_test"
     assy = self.win.assy
     from geometry.VQT import V
     from model.chunk import Chunk
     from model.chem import Atom
     mol = Chunk(assy, 'bug') # name is reset below!
     n = max(params[0],1)
     for x in range(n):
       for y in range(2):
         ## build methane, much like make_Atom_and_bondpoints method does it
         pos = V(x,y,0)
         atm = Atom('C', pos, mol)
         atm.make_bondpoints_when_no_bonds() # notices atomtype
     mol.name = name
     ## assy.addmol(mol)
     return mol
Ejemplo n.º 10
0
    def makeChunkFromAtomList(self,
                              atomList,
                              name = None,
                              group = None,
                              color = None):
        """
        Creates a new chunk from the given atom list.

        @param atomList: List of atoms from which to create the chunk.
        @type  atomList: list

        @param name: Name of new chunk. If None, we'll assign one.
        @type  name: str

        @param group: The group to add the new chunk to. If None, the new chunk
                      is added to the bottom of the model tree.
        @type  group: L{Group}

        @param color: Color of new chunk. If None, no chunk color is assigned
                      (chunk atoms will be drawn in their element colors).
        @type  color: tuple

        @return: The new chunk.
        @rtype:  L{Chunk}

        """
        assert atomList

        if name:
            newChunk = Chunk(self.assy, name)
        else:
            newChunk = Chunk(self.assy, gensym("Chunk", self.assy))

        for a in atomList:
            a.hopmol(newChunk)

        if group is not None:
            group.addchild(newChunk) #bruce 080318 addmember -> addchild
        else:
            self.addnode(newChunk)

        newChunk.setcolor(color, repaint_in_MT = False)

        return newChunk
Ejemplo n.º 11
0
def insertin(assy, filename):
    _init()

    dir, nodename = os.path.split(filename)

    mol = Chunk(assy, nodename)
    mol.showOverlayText = True

    file = open(filename)
    lines = file.readlines()
    atoms = {}
    transform = InternalCoordinatesToCartesian(len(lines), None)
    for line in lines:
        columns = line.strip().split()
        index = int(columns[0])
        name = columns[1]
        type = columns[2]
        na = int(columns[4])
        nb = int(columns[5])
        nc = int(columns[6])
        r = float(columns[7])
        theta = float(columns[8])
        phi = float(columns[9])

        transform.addInternal(index, na, nb, nc, r, theta, phi)
        xyz = transform.getCartesian(index)

        if (index > 3):
            if (AMBER_AtomTypes.has_key(type)):
                sym = AMBER_AtomTypes[type]
            else:
                print "unknown AMBER atom type, substituting Carbon: %s" % type
                sym = "C"

            a = Atom(sym, A(xyz), mol)
            atoms[index] = a
            a.setOverlayText(type)
            if (na > 3):
                a2 = atoms[na]
                bond_atoms(a, a2)

    assy.addmol(mol)
Ejemplo n.º 12
0
def insertin(assy, filename):
    _init()

    dir, nodename = os.path.split(filename)

    mol = Chunk(assy, nodename)
    mol.showOverlayText = True

    file = open(filename)
    lines = file.readlines()
    atoms = {}
    transform = InternalCoordinatesToCartesian(len(lines), None)
    for line in lines:
        columns = line.strip().split()
        index = int(columns[0])
        name = columns[1]
        type = columns[2]
        na = int(columns[4])
        nb = int(columns[5])
        nc = int(columns[6])
        r = float(columns[7])
        theta = float(columns[8])
        phi = float(columns[9])

        transform.addInternal(index, na, nb, nc, r, theta, phi)
        xyz = transform.getCartesian(index)

        if (index > 3):
            if (AMBER_AtomTypes.has_key(type)):
                sym = AMBER_AtomTypes[type]
            else:
                print "unknown AMBER atom type, substituting Carbon: %s" % type
                sym = "C"

            a = Atom(sym, A(xyz), mol)
            atoms[index] = a
            a.setOverlayText(type)
            if (na > 3):
                a2 = atoms[na]
                bond_atoms(a, a2)

    assy.addmol(mol)
Ejemplo n.º 13
0
    def makeChunkFromSelectedAtoms(self):
        """
        Create a new chunk from the selected atoms.
        """

        #ninad 070411 moved the original method out of 'merge' method to
        #facilitate implementation of 'Create New Chunk
        #from selected atoms' feature

        cmd = greenmsg("Create New Chunk: ")
        if not self.selatoms:
            msg1 = "Create New Chunk: "
            msg2 = redmsg('Select some atoms first to create a new chunk')
            env.history.message(msg1 + msg2)
            return

        #ninad070411 : Following checks if the selected molecules
        #belong to more than one chunk. If they don't (i.e. if they are a part of
        # a sinle chunk, it returns from the method with proper histry msg

        molList = []
        for atm in self.selatoms.values():
            if not len(molList) > 1:
                mol = atm.molecule
                if mol not in molList:
                    molList.append(mol)

        if len(molList) < 2:
            msg1 = "Create New Chunk: "
            msg2 = redmsg('Not created as the selected atoms are part of the \
            same chunk.')
            env.history.message(msg1 + msg2)
            return

        #bruce 060329 new feature: work on atoms too (put all selected atoms into a new chunk)
        self.ensure_toplevel_group(
        )  # avoid bug for part containing just one chunk, all atoms selected
        numol = Chunk(self.assy, gensym("Chunk", self.assy))
        natoms = len(self.selatoms)
        for a in self.selatoms.values():
            # leave the moved atoms picked, so still visible
            a.hopmol(numol)
        self.addmol(numol)
        #e should we add it in the same groups (and just after the chunks) which these atoms used to belong to?
        # could use similar scheme to placing jigs...
        msg = fix_plurals(
            "made chunk from %d atom(s)" %
            natoms)  # len(numol.atoms) would count bondpoints, this doesn't
        msg = msg.replace('chunk', numol.name)
        env.history.message(cmd + msg)
        self.w.win_update()
Ejemplo n.º 14
0
    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
Ejemplo n.º 15
0
    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
Ejemplo n.º 16
0
 def _makeChunkFromAtomList(self, atomList):
     """
     Creates a new chunk from the given atom list.
     
     @param atomList: List of atoms from which to create the chunk.
     @type  atomList: list
     
     @return: The new chunk.
     @rtype:  L{Chunk}
     
     @deprecated: use ops_rechunk.makeChunkFromAtomsList() instead.
     
     """
     if not atomList:
         print "bug in creating chunks from the given atom list"
         return
     
     newChunk = Chunk(self.win.assy, gensym("Chunk", self.win.assy))
     for a in atomList:            
         # leave the moved atoms picked, so still visible
         a.hopmol(newChunk)
     return newChunk   
Ejemplo n.º 17
0
    def makeChunkFromAtomList(self,
                              atomList,
                              name=None,
                              group=None,
                              color=None):
        """
        Creates a new chunk from the given atom list.
        
        @param atomList: List of atoms from which to create the chunk.
        @type  atomList: list
        
        @param name: Name of new chunk. If None, we'll assign one.
        @type  name: str
        
        @param group: The group to add the new chunk to. If None, the new chunk
                      is added to the bottom of the model tree.
        @type  group: L{Group}
        
        @param color: Color of new chunk. If None, no chunk color is assigned
                      (chunk atoms will be drawn in their element colors).
        @type  color: tuple
        
        @return: The new chunk.
        @rtype:  L{Chunk}
        
        """
        assert atomList

        if name:
            newChunk = Chunk(self.assy, name)
        else:
            newChunk = Chunk(self.assy, gensym("Chunk", self.assy))

        for a in atomList:
            a.hopmol(newChunk)

        if group is not None:
            group.addchild(newChunk)  #bruce 080318 addmember -> addchild
        else:
            self.addnode(newChunk)

        newChunk.setcolor(color, repaint_in_MT=False)

        return newChunk
Ejemplo n.º 18
0
def _readpdb(assy, 
             filename, 
             isInsert = False, 
             showProgressDialog = False, 
             chainId = None):
    """
    Read a Protein DataBank-format file into a single new chunk, which is 
    returned unless there are no atoms in the file, in which case a warning
    is printed and None is returned. (The new chunk (if returned) is in assy,
    but is not yet added into any Group or Part in assy -- caller must do that.)
    Unless isInsert = True, set assy.filename to match the file we read,
    even if we return None.
    
    @param assy: The assembly.
    @type  assy: L{assembly}
    
    @param filename: The PDB filename to read.
    @type  filename: string
    
    @param isInsert: If True, the PDB file will be inserted into the current
                     assembly. If False (default), the PDB is opened as the 
                     assembly.
    @param isInsert: boolean
    
    @param showProgressDialog: if True, display a progress dialog while reading
                               a file.
    @type  showProgressDialog: boolean
    
    @return: A chunk containing the contents of the PDB file.
    @rtype:  L{Chunk}
    
    @see: U{B{PDB File Format}<http://www.wwpdb.org/documentation/format23/v2.3.html>}
    """
        
    fi = open(filename,"rU")
    lines = fi.readlines()
    fi.close()
    
    dir, nodename = os.path.split(filename)
    if not isInsert:
        assy.filename = filename
    ndix = {}
    mol = Chunk(assy, nodename)
    numconects = 0

    atomname_exceptions = {
        "HB":"H", #k these are all guesses -- I can't find this documented 
                  # anywhere [bruce 070410]
        ## "HE":"H", ### REVIEW: I'm not sure about this one -- 
                    ###          leaving it out means it's read as Helium,
        # but including it erroneously might prevent reading an actual Helium 
        # if that was intended.
        # Guess for now: include it for ATOM but not HETATM. (So it's 
        # specialcased below, rather than being included in this table.)
        # (Later: can't we use the case of the 'E' to distinguish it from He?)
        "HN":"H",
     }
    
    # Create and display a Progress dialog while reading the MMP file. 
    # One issue with this implem is that QProgressDialog always displays 
    # a "Cancel" button, which is not hooked up. I think this is OK for now,
    # but later we should either hook it up or create our own progress
    # dialog that doesn't include a "Cancel" button. --mark 2007-12-06
    if showProgressDialog:
        _progressValue = 0
        _progressFinishValue = len(lines)
        win = env.mainwindow()
        win.progressDialog.setLabelText("Reading file...")
        win.progressDialog.setRange(0, _progressFinishValue)
        _progressDialogDisplayed = False
        _timerStart = time.time()
    for card in lines:
        key = card[:6].lower().replace(" ", "")
        if key in ["atom", "hetatm"]:
            ## sym = capitalize(card[12:14].replace(" ", "").replace("_", "")) 
            # bruce 080508 revision (guess at a bugfix for reading NE1-saved
            # pdb files):
            # get a list of atomnames to try; use the first one we recognize.
            # Note that full atom name is in columns 13-16 i.e. card[12:16];
            # see http://www.wwpdb.org/documentation/format2.3-0108-us.pdf,
            # page 156. The old code only looked at two characters,
            # card[12:14] == columns 13-14, and discarded ' ' and '_',
            # and capitalized (the first character only). The code as I revised
            # it on 070410 also discarded digits, and handled HB, HE, HN
            # (guesses) using the atomname_exceptions dict.
            name4 = card[12:16].replace(" ", "").replace("_", "")
            name3 = card[12:15].replace(" ", "").replace("_", "")
            name2 = card[12:14].replace(" ", "").replace("_", "")
            def nodigits(name):
                for bad in "0123456789":
                    name = name.replace(bad, "")
                return name
            atomnames_to_try = [
                name4, # as seems best according to documentation
                name3,
                name2, # like old code
                nodigits(name4),
                nodigits(name3),
                nodigits(name2) # like code as revised on 070410
            ]
            foundit = False
            for atomname in atomnames_to_try:
                atomname = atomname_exceptions.get(atomname, atomname)
                if atomname == "HE" and key == "atom":
                    atomname = "H" # see comment in atomname_exceptions
                sym = capitalize(atomname) # turns either 'he' or 'HE' into 'He'
                try:
                    PeriodicTable.getElement(sym)
                except:
                    # note: this typically fails with AssertionError 
                    # (not e.g. KeyError) [bruce 050322]
                    continue
                else:
                    foundit = True
                    break
                pass
            if not foundit:
                msg = "Warning: Pdb file: will use Carbon in place of unknown element %s in: %s" \
                    % (name4, card)
                print msg #bruce 070410 added this print
                env.history.message( redmsg( msg ))

                ##e It would probably be better to create a fake atom, so the 
                # CONECT records would still work.
                #bruce 080508 let's do that:
                sym = "C"
                
                # Better still might be to create a fake element, 
                # so we could write out the pdb file again
                # (albeit missing lots of info). [bruce 070410 comment]
                
                # Note: an advisor tells us:
                #   PDB files sometimes encode atomtypes,
                #   using C_R instead of C, for example, to represent sp2 
                #   carbons.
                # That particular case won't trigger this exception, since we
                # only look at 2 characters [eventually, after trying more, as of 080508],
                # i.e. C_ in that case. It would be better to realize this means
                # sp2 and set the atomtype here (and perhaps then use it when
                # inferring bonds,  which we do later if the file doesn't have 
                # any bonds). [bruce 060614/070410 comment]

            # Now the element name is in sym.
            xyz = map(float, [card[30:38], card[38:46], card[46:54]] )
            n = int(card[6:11])
            a = Atom(sym, A(xyz), mol)
            ndix[n] = a            
        elif key == "conect":
            try:
                a1 = ndix[int(card[6:11])]
            except:
                #bruce 050322 added this level of try/except and its message;
                # see code below for at least two kinds of errors this might
                # catch, but we don't try to distinguish these here. BTW this 
                # also happens as a consequence of not finding the element 
                # symbol, above,  since atoms with unknown elements are not 
                # created.
                env.history.message( redmsg( "Warning: Pdb file: can't find first atom in CONECT record: %s" % (card,) ))
            else:
                for i in range(11, 70, 5):
                    try:
                        a2 = ndix[int(card[i:i+5])]
                    except ValueError:
                        # bruce 050323 comment:
                        # we assume this is from int('') or int(' ') etc;
                        # this is the usual way of ending this loop.
                        break
                    except KeyError:
                        #bruce 050322-23 added history warning for this,
                        # assuming it comes from ndix[] lookup.
                        env.history.message( redmsg( "Warning: Pdb file: can't find atom %s in: %s" % (card[i:i+5], card) ))
                        continue
                    bond_atoms(a1, a2)
                    numconects += 1
            
        if showProgressDialog: # Update the progress dialog.
            _progressValue += 1
            if _progressValue >= _progressFinishValue:
                win.progressDialog.setLabelText("Building model...")
            elif _progressDialogDisplayed:
                win.progressDialog.setValue(_progressValue)
            else:
                _timerDuration = time.time() - _timerStart
                if _timerDuration > 0.25: 
                    # Display progress dialog after 0.25 seconds
                    win.progressDialog.setValue(_progressValue)
                    _progressDialogDisplayed = True
    
    if showProgressDialog: # Make the progress dialog go away.
        win.progressDialog.setValue(_progressFinishValue) 
    
    #bruce 050322 part of fix for bug 433: don't return an empty chunk
    if not mol.atoms:
        env.history.message( redmsg( "Warning: Pdb file contained no atoms"))
        return None
    if numconects == 0:
        msg = orangemsg("PDB file has no bond info; inferring bonds")
        env.history.message(msg)
        # let user see message right away (bond inference can take significant 
        # time) [bruce 060620]
        env.history.h_update() 
        inferBonds(mol)
    return mol
Ejemplo n.º 19
0
    def modifySeparate(self, new_old_callback = None):
        """
        For each Chunk (named N) containing any selected atoms,
        move the selected atoms out of N (but without breaking any bonds)
        into a new Chunk which we name N-frag. If N is now empty, remove it.

        @param new_old_callback: If provided, then each time we create a new
            (and nonempty) fragment N-frag, call new_old_callback with the
            2 args N-frag and N (that is, with the new and old molecules).
        @type  new_old_callback: function

        @warning: we pass the old mol N to that callback, even if it has no
                  atoms and we deleted it from this assembly.
        """
        # bruce 040929 wrote or revised docstring, added new_old_callback feature
        # for use from Extrude.
        # Note that this is called both from a tool button and for internal uses.
        # bruce 041222 removed side effect on selection mode, after discussion
        # with Mark and Josh. Also added some status messages.
        # Questions: is it good to refrain from merging all moved atoms into one
        # new mol? If not, then if N becomes empty, should we rename N-frag to N?

        cmd = greenmsg("Separate: ")

        if not self.selatoms: # optimization, and different status msg
            msg =  redmsg("No atoms selected")
            env.history.message(cmd + msg)
            return
        if 1:
            #bruce 060313 mitigate bug 1627, or "fix it by doing something we'd rather not always have to do" --
            # create (if necessary) a new toplevel group right now (before addmol does), avoiding a traceback
            # when all atoms in a clipboard item part consisting of a single chunk are selected for this op,
            # and the old part.topnode (that chunk) disappears from loss of atoms before we add the newly made chunk
            # containing those same atoms.
            # The only things wrong with this fix are:
            # - It's inefficient (so is the main algorithm, and it'd be easy to rewrite it to be faster, as explained below).
            # - The user ends up with a new Group even if one would theoretically not have been needed.
            #   But that's better than a traceback and disabled session, so for A7 this fix is fine.
            # - The same problem might arise in other situations (though I don't know of any), so ideally we'd
            #   have a more general fix.
            # - It's nonmodular for this function to have to know anything about Parts.
            ##e btw, a simpler way to do part of the following is "part = self". should revise this when time to test it. [bruce 060329]
            someatom = self.selatoms.values()[0] # if atoms in multiple parts could be selected, we'd need this for all their mols
            part = someatom.molecule.part
            part.ensure_toplevel_group()
            # this is all a kluge; a better way would be to rewrite the main algorithm to find the mols
            # with selected atoms, only make numol for those, and add it (addmol) before transferring all the atoms to it.
            pass
        numolist=[]
        for mol in self.molecules[:]: # new mols are added during the loop!
            numol = Chunk(self.assy, gensym(mol.name + "-frag", self.assy)) # (in modifySeparate)
            for a in mol.atoms.values():
                if a.picked:
                    # leave the moved atoms picked, so still visible
                    a.hopmol(numol)
            if numol.atoms:
                numol.setDisplayStyle(mol.display) # Fixed bug 391.  Mark 050710
                numol.setcolor(mol.color, repaint_in_MT = False)
                    #bruce 070425, fix Extrude bug 2331 (also good for Separate in general), "nice to have" for A9
                self.addmol(numol) ###e move it to just after the one it was made from? or, end of same group??
                numolist+=[numol]
                if new_old_callback:
                    new_old_callback(numol, mol) # new feature 040929
        msg = fix_plurals("Created %d new chunk(s)" % len(numolist))
        env.history.message(cmd + msg)
        self.w.win_update() #e do this in callers instead?
Ejemplo n.º 20
0
    def build_struct(self, name, params, position, mol=None, createPrinted=False):
        """
        Build a peptide from a sequence entered through the Property Manager dialog.
        """

        if len(self.peptide_cache) == 0:
            return None

        # Create a molecule
        mol = Chunk(self.win.assy,name)

        # Generate dummy atoms positions

        self.prev_coords[0][0] = position[0] - 1.499
        self.prev_coords[0][1] = position[1] + 1.539
        self.prev_coords[0][2] = position[2]

        self.prev_coords[1][0] = position[0] - 1.499
        self.prev_coords[1][1] = position[1]
        self.prev_coords[1][2] = position[2]

        self.prev_coords[2][0] = position[0]
        self.prev_coords[2][1] = position[1]
        self.prev_coords[2][2] = position[2]

        # Add a N-terminal hydrogen
        atom = Atom("H", position, mol)
        atom._is_aromatic = False
        atom._is_single = False
        self.nterm_hydrogen = atom

        # Generate the peptide chain.
        self.length = 1
        for index, phi, psi in self.peptide_cache:
            name, short_name, symbol, zmatrix, size = AMINO_ACIDS[index]
            self._buildResiduum(mol, zmatrix, size, phi, psi, None, symbol)

        # Add a C-terminal OH group
        self._buildResiduum(mol, CTERM_ZMATRIX, 5, 0.0, 0.0, None, symbol)        
        
        # Compute bonds (slow!)
        # This should be replaced by a proper bond assignment.
        inferBonds(mol)

        mol._protein_helix = []
        mol._protein_sheet = []
        
        # Assign proper bond orders.
        i = 1
        for atom in mol.atoms.itervalues():
            if self.ss_idx == 1:
                mol._protein_helix.append(i) 
            elif self.ss_idx == 2:
                mol._protein_sheet.append(i)  
            if atom.bonds:
                for bond in atom.bonds:
                    if bond.atom1.getAtomTypeName()=="sp2" and \
                       bond.atom2.getAtomTypeName()=="sp2":
                        if (bond.atom1._is_aromatic and
                            bond.atom2._is_aromatic):
                            bond.set_v6(V_AROMATIC)
                        elif ((bond.atom1._is_aromatic == False and
                               bond.atom1._is_aromatic == False) and
                               not (bond.atom1._is_single and
                                    bond.atom2._is_single)):
                            bond.set_v6(V_DOUBLE)
            i += 1
                            
        # Remove temporary attributes.
        for atom in mol.atoms.itervalues():
            del atom._is_aromatic
            del atom._is_single

        return mol
Ejemplo n.º 21
0
    def make_aligned(self,
                     assy,
                     name,
                     aa_idx,
                     phi, psi,
                     pos1, pos2,
                     secondary = SS_COIL,
                     fake_chain = False,
                     length = None):
        """
        Build and return a chunk that is a h**o-peptide aligned to
        a pos2-pos1 vector.

        @param aa_idx: amino acid type (index in AMINO_ACIDS list)
        @type aa_idx: int

        @param name: chunk name
        @type name: string

        @param phi, psi: peptide bond angles
        @type phi, psi: float

        @param pos1, pos2: desired peptide positions (beginning and end)
        @type pos1, pos2: V

        @param secondary: secondary structure class, used for visual representation
        The actual peptide chain conformation is based on phi / psi angles.
        @type secondary: int

        @param fake_chain: if True, create only C-alpha atoms. used for drawing
        peptide trace image during interactive peptide placement (used by
        PeptideLine_GraphicsMode.py)
        @type fake_chain: boolean

        @param length: optional peptide length (number of amino acids), if
        not specified, pos1 and pos2 are used to figure out the length
        @type length: int

        @return: A h**o-polypeptide chain.
        @rtype:  L{Chunk}
        """

        if not length:
            self.length = self.get_number_of_res(pos1, pos2, phi, psi)
            if self.length == 0:
                return None
        else:
            self.length = length

        # Create a molecule
        mol = Chunk(assy, name)

        if not fake_chain:
            mol.protein = Protein()
            mol.protein.set_chain_id('A')

        # Generate dummy atoms positions
        self.prev_coords[0][0] = pos1[0] - 1.0
        self.prev_coords[0][1] = pos1[1] - 1.0
        self.prev_coords[0][2] = pos1[2]

        self.prev_coords[1][0] = pos1[0] - 1.0
        self.prev_coords[1][1] = pos1[1]
        self.prev_coords[1][2] = pos1[2]

        self.prev_coords[2][0] = pos1[0]
        self.prev_coords[2][1] = pos1[1]
        self.prev_coords[2][2] = pos1[2]

        name, short_name, symbol, zmatrix, size = AMINO_ACIDS[aa_idx]

        # Add a N-terminal hydrogen
        self.nterm_hydrogen = None

        # Initially, the Peptide Builder was creating peptide structures
        # saturated at both ends, i.e. with N-terminal hydrogen and C-terminal
        # OH group present. Currently, this code is commented out to allow
        # connecting multiple peptide structure be creating bonds between
        # the C- and N- terminal ends of two individual structures.
        """
        if not fake_chain:
            atom = Atom("H", pos1, mol)
            atom._is_aromatic = False
            atom._is_single = False
            self.nterm_hydrogen = atom
            mol.protein.add_pdb_atom(atom, "H", 1, name)
            atom.pdb_info = {}
            atom.pdb_info['atom_name'] = "H"
            atom.pdb_info['residue_name'] = short_name
            atom.pdb_info['residue_id'] = "  1 "
            atom.pdb_info['standard_atom'] = True
        """

        self.init_ca = None

        # Generate the peptide chain.
        for idx in range(int(self.length)):
            self._buildResidue(mol, zmatrix, size, idx+1, phi, psi, secondary, None, short_name, fake_chain=fake_chain)

        # See the comment above.
        """
        # Add a C-terminal OH group
        self._buildResidue(mol, CTERM_ZMATRIX, 5, int(self.length), 0.0, 0.0, secondary, None, short_name, fake_chain=fake_chain)
        """

        # Compute bonds (slow!)
        # This should be replaced by a proper bond assignment.

        if not fake_chain:
            inferBonds(mol)

        # Assign proper bond orders.
        i = 1
        for atom in mol.atoms.itervalues():
            if atom.bonds:
                for bond in atom.bonds:
                    if bond.atom1.getAtomTypeName()=="sp2" and \
                       bond.atom2.getAtomTypeName()=="sp2":
                        if (bond.atom1._is_aromatic and
                            bond.atom2._is_aromatic):
                            bond.set_v6(V_AROMATIC)
                        elif ((bond.atom1._is_aromatic == False and
                               bond.atom1._is_aromatic == False) and
                               not (bond.atom1._is_single and
                                    bond.atom2._is_single)):
                            bond.set_v6(V_DOUBLE)
            i += 1

        # Remove temporary attributes.
        for atom in mol.atoms.itervalues():
            del atom._is_aromatic
            del atom._is_single

        # Axis of first selected chunk
        ax = V(0.,0.,1.)
        mol.rot(Q(mol.getaxis(),ax))

        self._orient(mol, pos2, pos1)

        if self.init_ca:
            mol.move(pos1 - self.init_ca.posn())

        mol_dummy = None

        return mol
Ejemplo n.º 22
0
    def buildChunk(self, assy):
        """
        Build Chunk for the cookies. First, combine bonds from
        all layers together, which may fuse some half bonds to full bonds.
        """
        from model.chunk import Chunk
        from model.chem import Atom
        from utilities.constants import gensym

        numLayers = len(self.bondLayers)
        if numLayers:
            allBonds = {}
            allCarbons = {}

            # Copy the bonds, carbons and hedron from the first layer
            for ii in range(numLayers):
                if self.bondLayers.has_key(ii):
                    for bKey, bValue in self.bondLayers[ii].items():
                        allBonds[bKey] = bValue

                    del self.bondLayers[ii]
                    break

            for carbons in self.carbonPosDict.values():
                for cKey, cValue in carbons.items():
                    allCarbons[cKey] = cValue

            for hedrons in self.hedroPosDict.values():
                for hKey, hValue in hedrons.items():
                    allCarbons[hKey] = hValue

            for bonds in self.bondLayers.values():
                for bKey, bValues in bonds.items():
                    if bKey in allBonds:
                        existValues = allBonds[bKey]
                        for bValue in bValues:
                            if type(bValue) == type((1, 1)):
                                if bValue[1]:
                                    ctValue = (bValue[0], 0)
                                else:
                                    ctValue = (bValue[0], 1)
                                if ctValue in existValues:
                                    idex = existValues.index(ctValue)
                                    existValues[idex] = bValue[0]
                                else:
                                    existValues += [bValue]
                            else:
                                existValues += [bValue]
                        allBonds[bKey] = existValues
                    else:
                        allBonds[bKey] = bValues

            # print "allbonds: ", allBonds
            # print "allCarbons: ", allCarbons

            carbonAtoms = {}
            mol = Chunk(assy, gensym("Crystal", assy))
            for bKey, bBonds in allBonds.items():
                keyHedron = True
                if len(bBonds):
                    for bond in bBonds:
                        if keyHedron:
                            if type(bBonds[0]) == type(1) or (not bBonds[0][1]):
                                if not bKey in carbonAtoms:
                                    keyAtom = Atom("C", allCarbons[bKey], mol)
                                    carbonAtoms[bKey] = keyAtom
                                else:
                                    keyAtom = carbonAtoms[bKey]
                                keyHedron = False

                        if keyHedron:
                            if type(bond) != type((1, 1)):
                                raise ValueError, (bKey, bond, bBonds)
                            else:
                                xp = (allCarbons[bKey] + allCarbons[bond[0]]) / 2.0
                                keyAtom = Atom("X", xp, mol)

                        if type(bond) == type(1) or bond[1]:
                            if type(bond) == type(1):
                                bvKey = bond
                            else:
                                bvKey = bond[0]
                            if not bvKey in carbonAtoms:
                                bondAtom = Atom("C", allCarbons[bvKey], mol)
                                carbonAtoms[bvKey] = bondAtom
                            else:
                                bondAtom = carbonAtoms[bvKey]
                        else:
                            xp = (allCarbons[bKey] + allCarbons[bond[0]]) / 2.0
                            bondAtom = Atom("X", xp, mol)

                        bond_atoms(keyAtom, bondAtom)

            if len(mol.atoms) > 0:
                # bruce 050222 comment: much of this is not needed, since mol.pick() does it.
                # Note: this method is similar to one in BuildCrystal_Command.py.
                assy.addmol(mol)
                assy.unpickall_in_GLPane()
                # was unpickparts; not sure _in_GLPane is best (or that
                # this is needed at all) [bruce 060721]
                mol.pick()
                assy.mt.mt_update()

        return  # from buildChunk
Ejemplo n.º 23
0
def _get_atomlist_from_gms_outfile(assy, filename):
    """
    Read the atoms from a GAMESS OUT file into an atom list, which is returned,
    unless there are no atoms in the file, in which case a warning is printed
    and None is returned.
    """
    fi = open(filename, "rU")
    lines = fi.readlines()
    fi.close()

    dir, nodename = os.path.split(filename)
    mol = Chunk(assy, nodename)

    newAtomList = []
    countdown = 0
    equilibruim_found = False
    atoms_found = False

    for card in lines:

        if failpat.search(
                card):  # GAMESS Aborted.  No atom data will be found.
            print card
            env.history.message(redmsg(card))
            break

        if noconvpat.search(card):  # Geometry search is not converged.
            print card
            env.history.message(redmsg(card))
            break

        # If this card is found:
        # "1     ***** EQUILIBRIUM GEOMETRY LOCATED *****\n"
        # we know we have a successfully optimized structure/set of atoms.
        # If this card is not found, the optimization failed for some reason.
        # Atom positions begin soon after this card.
        if card == "1     ***** EQUILIBRIUM GEOMETRY LOCATED *****\n":
            equilibruim_found = True
            continue

        # The atom positions we want ALWAYS begin 2 lines after this card:
        # " COORDINATES OF ALL ATOMS ARE (ANGS)\n"
        # which follows the previous card.
        # This is one way to fix the problem mentioned above.
        # I've commented the code below out since it needs further work to do what
        # we need, and there is a chance we will not need this if GAMESS-US has
        # the same number of lines (6) after the "EQUILIBRIUM" card above.
        #
        # P.S. The reason we do not just look for this card by itself is that there
        # can be many of them.  There is only one "EQUILIBRIUM" card, and the
        # good atoms follow that card.
        # 050624 Mark

        if equilibruim_found:
            if card == " COORDINATES OF ALL ATOMS ARE (ANGS)\n":
                atoms_found = True
                reading_atoms = True
                countdown = 2
                continue

        if not equilibruim_found or not atoms_found:
            continue

        if countdown:
            countdown -= 1
            #            print countdown, card # for debugging only.
            continue

        # The current card contains atom type and position.

        n = 0

        if reading_atoms:
            #            print "_get_atomlist_from_gms_outfile:", card
            if len(card) < 10:
                reading_atoms = False  # Finished reading atoms.
                break
            m = irecpat.match(card)
            sym = capitalize(m.group(1))
            try:
                PeriodicTable.getElement(sym)
            except:
                env.history.message(
                    redmsg(
                        "Warning: GAMESS OUT file: unknown element %s in: %s" %
                        (sym, card)))
            else:
                xyz = map(float, (m.group(2), m.group(3), m.group(4)))
                a = Atom(sym, A(xyz), mol)
                newAtomList += [a]

# Let caller handle history msgs.  Mark 050712
#    if not newAtomList:
#        msg = "Warning: GAMESS file contains no equilibrium geometry.  No atoms read into part."
#        env.history.message( redmsg(msg))
#        return None

    return newAtomList
Ejemplo n.º 24
0
def _readgms(assy, filename, isInsert=False):
    """
    Read the atoms from a GAMESS DAT file into a single new chunk, which is returned,
    unless there are no atoms in the file, in which case a warning is printed
    and None is returned. (The new chunk (if returned) is in assy, but is not
    yet added into any Group or Part in assy -- caller must do that.)
    """
    fi = open(filename, "rU")
    lines = fi.readlines()
    fi.close()

    dir, nodename = os.path.split(filename)
    ndix = {}
    mol = Chunk(assy, nodename)
    countdown = 0
    equilibruim_found = False
    atoms_found = False

    for card in lines:

        if failpat.search(
                card):  # GAMESS Aborted.  No atom data will be found.
            print card
            break

        # If this card is found:
        # "1     ***** EQUILIBRIUM GEOMETRY LOCATED *****\n"
        # we know we have a successfully optimized structure/set of atoms.
        # If this card is not found, the optimization failed for some reason.
        # Atom positions begin soon after this card.
        if card == "1     ***** EQUILIBRIUM GEOMETRY LOCATED *****\n":
            equilibruim_found = True
            continue

        # The atom positions we want ALWAYS begin 2 lines after this card:
        # " COORDINATES OF ALL ATOMS ARE (ANGS)\n"
        # which follows the previous card.
        # This is one way to fix the problem mentioned above.
        # I've commented the code below out since it needs further work to do what
        # we need, and there is a chance we will not need this if GAMESS-US has
        # the same number of lines (6) after the "EQUILIBRIUM" card above.
        #
        # P.S. The reason we do not just look for this card by itself is that there
        # can be many of them.  There is only one "EQUILIBRIUM" card, and the
        # good atoms follow that card.
        # 050624 Mark

        if equilibruim_found:
            if card == " COORDINATES OF ALL ATOMS ARE (ANGS)\n":
                atoms_found = True
                reading_atoms = True
                countdown = 2
                continue

        if not equilibruim_found or not atoms_found:
            continue

        if countdown:
            countdown -= 1
            #            print countdown, card # for debugging only.
            continue

        # The current card contains atom type and position.

        n = 0

        if reading_atoms:
            if len(card) < 10:
                reading_atoms = False  # Finished reading atoms.
                break
            m = irecpat.match(card)
            sym = capitalize(m.group(1))
            try:
                PeriodicTable.getElement(sym)
            except:
                env.history.message(
                    redmsg(
                        "Warning: GAMESS DAT file: unknown element %s in: %s" %
                        (sym, card)))
            else:
                xyz = map(float, (m.group(2), m.group(3), m.group(4)))
                a = Atom(sym, A(xyz), mol)
                ndix[n] = a
                n += 1

    # Don't return an empty chunk.
    if not mol.atoms:
        msg = "Warning: GAMESS file contains no equilibrium geometry.  No atoms read into part."
        env.history.message(redmsg(msg))
        return None

    # Need to compute and add bonds for this chunk.  I'll ask Bruce how to best accomplish this.
    # In the meantime, let's warn the user that no bonds have been formed since it
    # is impossible to see this in vdW display mode.
    # Mark 050623.
    msg = "Warning: Equilibrium geometry found.  Atoms read into part, but there are no bonds."
    env.history.message(orangemsg(msg))
    return mol
Ejemplo n.º 25
0
    def getObjectStructure(self):
        startdate = datetime.now()
        print(
            str(startdate) + ' -Calling method getObjectStructure() begins <<')
        print " __request", request
        objectId = request.args.get('objectId')
        bucketname = request.args.get('bucketName')
        osd_dump = self.getOsdDump()

        # objectIdd=request.form['objectId']
        #bucketnamee=request.form['bucketName']
        Log.debug("__getS3Object(objectId=" + str(objectId) +
                  ", bucketName= " + str(bucketname) + ")")

        #Log.debug("getS3Object(objectIdd="+str(objectIdd)+", bucketNamee= "+str(bucketnamee)+")")
        #Retrieve the bucketId using the bucket name

        bucketId = self.getBucketInfo(bucketname)["bucketid"]
        #Get the pool name using the
        poolname = self.getBucketInfo(bucketname)["poolname"]

        #Retrieve the pool id
        poolid = self.getPoolId(poolname)
        #poolname=getPoolName(bucketName)
        extended_objectId = bucketId + "_" + objectId
        #Retrieve the user.rgw.manifest that contains the chunks list for the object
        #usermnf=self.getUserRgwManifest(poolname,extended_objectId)

        #Retrieve the chunk base name in the user.rgw.manifest attribute
        chunkbasename = self.getChunkBaseName(poolname, extended_objectId)

        print '__Chunk base name: ', chunkbasename
        if len(chunkbasename):  #chek if there is chunk por not for the object
            #Retrieve the chunks list of the object
            chunks = self.getChunks(bucketId, poolname, objectId,
                                    chunkbasename)
            chunks.append(extended_objectId
                          )  #Add the last object that is around 512.0 kb
        else:
            chunks = [extended_objectId]

        print "__Chunks list", chunks
        #bucketInfo=self.getBucketInfo(bucketId)
        chunklist = []
        pgs = []
        osds = []
        osdids = []
        pgid4osd = []
        for chunk in chunks:
            if len(chunk) > 0:
                print 'Chunk= ', chunk
                chunksize = self.getChunkSize(poolname, chunk)
                pgid = self.getPgId(poolname, '  ' + chunk)
                c = Chunk(chunk, chunksize, pgid[0])
                chunklist.append(c)
                if pgid4osd.count(pgid[1]) == 0:
                    pgid4osd.append(pgid[1])

                if pgid4osd.count(pgid[0]) == 0:
                    pgid4osd.append(pgid[0])

                #Create the PG for this chunk
                #ef __init__(self,pgid,state,acting, up, acting_primary, up_primary):
                pginfos = self.getOsdMapInfos(pgid[1])
                pg = PG(pgid[0], pginfos['state'], pginfos['acting'],
                        pginfos['up'], pginfos['acting_primary'],
                        pginfos['up_primary'])
                # print(pg.dump())
                pgs.append(pg)  #Append the PG in the pgs list
            # print "____ OSD List for PG ", pgid[1],self.getOsdsListForPg(pgid[1])
        for pgid in pgid4osd:
            for id in self.getOsdsListForPg(
                    pgid):  #sortir la boucle pour les pg
                if osdids.count(id) == 0:
                    osdids.append(
                        id)  #construct the list of the OSD to be displayed

        #Log.debug("Total number of chunks retrived:"+str(nbchunks))

    # print "_____osds list=",osdids
        for osdid in osdids:  #Loop the OSD list and retrieve the osd and add it in the osds list fot the S3 object
            osd = self.getOsdInfos(osd_dump, osdid)
            #print(osd.dump())
            osds.append(osd)

        s3object = S3Object(extended_objectId, bucketname, bucketId, poolid,
                            poolname, self.getPoolType(poolname, poolid),
                            self.getChunkSize(poolname, extended_objectId),
                            chunklist, pgs, osds)
        print(s3object.dump())
        duration = datetime.now() - startdate
        Log.info(
            str(datetime.now()) +
            ' ___Calling method getObjectStructure() end >> duration= ' +
            str(duration.seconds))
        return s3object.dump()
Ejemplo n.º 26
0
    def build_struct(self,
                     name,
                     params,
                     position,
                     mol=None,
                     createPrinted=False):
        """
        Build a peptide from a sequence entered through the Property Manager dialog.
        """

        if len(self.peptide_cache) == 0:
            return None

        # Create a molecule
        mol = Chunk(self.win.assy, name)

        # Generate dummy atoms positions

        self.prev_coords[0][0] = position[0] - 1.499
        self.prev_coords[0][1] = position[1] + 1.539
        self.prev_coords[0][2] = position[2]

        self.prev_coords[1][0] = position[0] - 1.499
        self.prev_coords[1][1] = position[1]
        self.prev_coords[1][2] = position[2]

        self.prev_coords[2][0] = position[0]
        self.prev_coords[2][1] = position[1]
        self.prev_coords[2][2] = position[2]

        # Add a N-terminal hydrogen
        atom = Atom("H", position, mol)
        atom._is_aromatic = False
        atom._is_single = False
        self.nterm_hydrogen = atom

        # Generate the peptide chain.
        self.length = 1
        for index, phi, psi in self.peptide_cache:
            name, short_name, symbol, zmatrix, size = AMINO_ACIDS[index]
            self._buildResiduum(mol, zmatrix, size, phi, psi, None, symbol)

        # Add a C-terminal OH group
        self._buildResiduum(mol, CTERM_ZMATRIX, 5, 0.0, 0.0, None, symbol)

        # Compute bonds (slow!)
        # This should be replaced by a proper bond assignment.
        inferBonds(mol)

        mol._protein_helix = []
        mol._protein_sheet = []

        # Assign proper bond orders.
        i = 1
        for atom in mol.atoms.itervalues():
            if self.ss_idx == 1:
                mol._protein_helix.append(i)
            elif self.ss_idx == 2:
                mol._protein_sheet.append(i)
            if atom.bonds:
                for bond in atom.bonds:
                    if bond.atom1.getAtomTypeName()=="sp2" and \
                       bond.atom2.getAtomTypeName()=="sp2":
                        if (bond.atom1._is_aromatic
                                and bond.atom2._is_aromatic):
                            bond.set_v6(V_AROMATIC)
                        elif ((bond.atom1._is_aromatic == False
                               and bond.atom1._is_aromatic == False)
                              and not (bond.atom1._is_single
                                       and bond.atom2._is_single)):
                            bond.set_v6(V_DOUBLE)
            i += 1

        # Remove temporary attributes.
        for atom in mol.atoms.itervalues():
            del atom._is_aromatic
            del atom._is_single

        return mol
Ejemplo n.º 27
0
    def modifySeparate(self, new_old_callback=None):
        """
        For each Chunk (named N) containing any selected atoms,
        move the selected atoms out of N (but without breaking any bonds)
        into a new Chunk which we name N-frag. If N is now empty, remove it.
        
        @param new_old_callback: If provided, then each time we create a new
            (and nonempty) fragment N-frag, call new_old_callback with the
            2 args N-frag and N (that is, with the new and old molecules).
        @type  new_old_callback: function
        
        @warning: we pass the old mol N to that callback, even if it has no 
                  atoms and we deleted it from this assembly.
        """
        # bruce 040929 wrote or revised docstring, added new_old_callback feature
        # for use from Extrude.
        # Note that this is called both from a tool button and for internal uses.
        # bruce 041222 removed side effect on selection mode, after discussion
        # with Mark and Josh. Also added some status messages.
        # Questions: is it good to refrain from merging all moved atoms into one
        # new mol? If not, then if N becomes empty, should we rename N-frag to N?

        cmd = greenmsg("Separate: ")

        if not self.selatoms:  # optimization, and different status msg
            msg = redmsg("No atoms selected")
            env.history.message(cmd + msg)
            return
        if 1:
            #bruce 060313 mitigate bug 1627, or "fix it by doing something we'd rather not always have to do" --
            # create (if necessary) a new toplevel group right now (before addmol does), avoiding a traceback
            # when all atoms in a clipboard item part consisting of a single chunk are selected for this op,
            # and the old part.topnode (that chunk) disappears from loss of atoms before we add the newly made chunk
            # containing those same atoms.
            # The only things wrong with this fix are:
            # - It's inefficient (so is the main algorithm, and it'd be easy to rewrite it to be faster, as explained below).
            # - The user ends up with a new Group even if one would theoretically not have been needed.
            #   But that's better than a traceback and disabled session, so for A7 this fix is fine.
            # - The same problem might arise in other situations (though I don't know of any), so ideally we'd
            #   have a more general fix.
            # - It's nonmodular for this function to have to know anything about Parts.
            ##e btw, a simpler way to do part of the following is "part = self". should revise this when time to test it. [bruce 060329]
            someatom = self.selatoms.values(
            )[0]  # if atoms in multiple parts could be selected, we'd need this for all their mols
            part = someatom.molecule.part
            part.ensure_toplevel_group()
            # this is all a kluge; a better way would be to rewrite the main algorithm to find the mols
            # with selected atoms, only make numol for those, and add it (addmol) before transferring all the atoms to it.
            pass
        numolist = []
        for mol in self.molecules[:]:  # new mols are added during the loop!
            numol = Chunk(self.assy, gensym(mol.name + "-frag",
                                            self.assy))  # (in modifySeparate)
            for a in mol.atoms.values():
                if a.picked:
                    # leave the moved atoms picked, so still visible
                    a.hopmol(numol)
            if numol.atoms:
                numol.setDisplayStyle(
                    mol.display)  # Fixed bug 391.  Mark 050710
                numol.setcolor(mol.color, repaint_in_MT=False)
                #bruce 070425, fix Extrude bug 2331 (also good for Separate in general), "nice to have" for A9
                self.addmol(
                    numol
                )  ###e move it to just after the one it was made from? or, end of same group??
                numolist += [numol]
                if new_old_callback:
                    new_old_callback(numol, mol)  # new feature 040929
        msg = fix_plurals("Created %d new chunk(s)" % len(numolist))
        env.history.message(cmd + msg)
        self.w.win_update()  #e do this in callers instead?
Ejemplo n.º 28
0
 def kill(self):
     self.restore_atoms_to_their_homes(
     )  # or should we delete them instead?? (this should never matter in our planned uses)
     # this includes self.part = None
     Chunk.kill(self)
Ejemplo n.º 29
0
def _readpdb_new(assy, 
             filename, 
             isInsert = False, 
             showProgressDialog = False, 
             chainId = None):
    """
    Read a Protein DataBank-format file into a single new chunk, which is 
    returned unless there are no atoms in the file, in which case a warning
    is printed and None is returned. (The new chunk (if returned) is in assy,
    but is not yet added into any Group or Part in assy -- caller must do that.)
    Unless isInsert = True, set assy.filename to match the file we read,
    even if we return None.
    
    @param assy: The assembly.
    @type  assy: L{assembly}
    
    @param filename: The PDB filename to read.
    @type  filename: string
    
    @param isInsert: If True, the PDB file will be inserted into the current
                     assembly. If False (default), the PDB is opened as the 
                     assembly.
    @param isInsert: boolean
    
    @param showProgressDialog: if True, display a progress dialog while reading
                               a file.
    @type  showProgressDialog: boolean
    
    @return: A chunk containing the contents of the PDB file.
    @rtype:  L{Chunk}
    
    @see: U{B{PDB File Format}<http://www.wwpdb.org/documentation/format23/v2.3.html>}
    """

    from protein.model.Protein import is_water
    
    def _finish_molecule():
        """
        Perform some operations after reading entire PDB chain:
          - rebuild (infer) bonds
          - rename molecule to reflect a chain ID
          - delete protein object if this is not a protein
          - append the molecule to the molecule list
        """
        
        if mol == water:
            # Skip water, to be added explicitly at the end.
            return
        
        if mol.atoms:  
            ###print "READING PDB ", (mol, numconects, chainId)
            
            mol.name = pdbid.lower() + chainId

            ###idzialprint "SEQ = ", mol.protein.get_sequence_string()
            ###print "SEC = ", mol.protein.get_secondary_structure_string()
            
            if mol.protein.count_c_alpha_atoms() == 0:
                # If there is no C-alpha atoms, consider the chunk 
                # as a non-protein. But! Split it into individual 
                # hetero groups.
                res_list = mol.protein.get_amino_acids()
                assy.part.ensure_toplevel_group()
                hetgroup = Group("Heteroatoms", assy, assy.part.topnode) 
                for res in res_list:
                    hetmol = Chunk(assy, 
                                   res.get_three_letter_code().replace(" ", "") + \
                                   "[" + str(res.get_id()) + "]")
                    for atom in res.get_atom_list():
                        newatom = Atom(atom.element.symbol, atom.posn(), hetmol)
                    # New chunk - infer the bonds anyway (this is not
                    # correct, should first check connectivity read from
                    # the PDB file CONECT records).
                    inferBonds(hetmol)
                    hetgroup.addchild(hetmol)
                mollist.append(hetgroup)
            else:
                #if numconects == 0:
                #    msg = orangemsg("PDB file has no bond info; inferring bonds")
                #    env.history.message(msg)
                #    # let user see message right away (bond inference can take significant 
                #    # time) [bruce 060620]
                #    env.history.h_update() 

                # For protein - infer the bonds anyway.
                inferBonds(mol)
                    
                mol.protein.set_chain_id(chainId)
                mol.protein.set_pdb_id(pdbid)
                if mol.atoms:
                    mollist.append(mol)                
        else:
            env.history.message( redmsg( "Warning: Pdb file contained no atoms"))
            env.history.h_update() 
                    
    fi = open(filename,"rU")
    lines = fi.readlines()
    fi.close()
    
    mollist = []

    # Lists of secondary structure tuples (res_id, chain_id) 
    helix = []
    sheet = []
    turn = []
    
    dir, nodename = os.path.split(filename)
    if not isInsert:
        assy.filename = filename
    
    ndix = {}
    mol = Chunk(assy, nodename)
    mol.protein = Protein()
    
    # Create a chunk for water molecules.
    water = Chunk(assy, nodename)
            
    numconects = 0
    
    comment_text = ""
    _read_rosetta_info = False
    
    # Create a temporary PDB ID - it should be later extracted from the
    # file header.
    pdbid = nodename.replace(".pdb","").lower()
    
    atomname_exceptions = {
        "HB":"H", #k these are all guesses -- I can't find this documented 
                  # anywhere [bruce 070410]
        "CA":"C", #k these are all guesses -- I can't find this documented 
        ## "HE":"H", ### REVIEW: I'm not sure about this one -- 
                    ###          leaving it out means it's read as Helium,
        # but including it erroneously might prevent reading an actual Helium 
        # if that was intended.
        # Guess for now: include it for ATOM but not HETATM. (So it's 
        # specialcased below, rather than being included in this table.)
        # (Later: can't we use the case of the 'E' to distinguish it from He?)
        "HN":"H",
     }
    
    # Create and display a Progress dialog while reading the MMP file. 
    # One issue with this implem is that QProgressDialog always displays 
    # a "Cancel" button, which is not hooked up. I think this is OK for now,
    # but later we should either hook it up or create our own progress
    # dialog that doesn't include a "Cancel" button. --mark 2007-12-06
    if showProgressDialog:
        _progressValue = 0
        _progressFinishValue = len(lines)
        win = env.mainwindow()
        win.progressDialog.setLabelText("Reading file...")
        win.progressDialog.setRange(0, _progressFinishValue)
        _progressDialogDisplayed = False
        _timerStart = time.time()

    for card in lines:
        key = card[:6].lower().replace(" ", "")
        if key in ["atom", "hetatm"]:
            ## sym = capitalize(card[12:14].replace(" ", "").replace("_", "")) 
            # bruce 080508 revision (guess at a bugfix for reading NE1-saved
            # pdb files):
            # get a list of atomnames to try; use the first one we recognize.
            # Note that full atom name is in columns 13-16 i.e. card[12:16];
            # see http://www.wwpdb.org/documentation/format2.3-0108-us.pdf,
            # page 156. The old code only looked at two characters,
            # card[12:14] == columns 13-14, and discarded ' ' and '_',
            # and capitalized (the first character only). The code as I revised
            # it on 070410 also discarded digits, and handled HB, HE, HN
            # (guesses) using the atomname_exceptions dict.
            name4 = card[12:16].replace(" ", "").replace("_", "")
            name3 = card[12:15].replace(" ", "").replace("_", "")
            name2 = card[12:14].replace(" ", "").replace("_", "")
            chainId = card[21]
            resIdStr = card[22:26].replace(" ", "")
            if resIdStr != "":
                resId = int(resIdStr)
            else:
                resId = 0
            resName = card[17:20]
            sym = card[77:78]
            alt = card[16] # Alternate location indicator
            
            if alt != ' ' and \
               alt != 'A':
                # Skip non-standard alternate location
                # This is not very safe test, it should preserve
                # the remaining atoms. piotr 080715 
                continue
            
###ATOM    131  CB  ARG A  18     104.359  32.924  58.573  1.00 36.93           C  

            def nodigits(name):
                for bad in "0123456789":
                    name = name.replace(bad, "")
                return name
            atomnames_to_try = [
                name4, # as seems best according to documentation
                name3,
                name2, # like old code
                nodigits(name4),
                nodigits(name3),
                nodigits(name2) # like code as revised on 070410
            ]
            
            # First, look at 77-78 field - it should include an element symbol.
            foundit = False
            try:
                PeriodicTable.getElement(sym)
            except:
                pass
            else:
                foundit = True
            if not foundit:
                for atomname in atomnames_to_try:
                    atomname = atomname_exceptions.get(atomname, atomname)
                    if atomname[0] == 'H' and key == "atom":
                        atomname = "H" # see comment in atomname_exceptions
                    sym = capitalize(atomname) # turns either 'he' or 'HE' into 'He'
                    
                    try:
                        PeriodicTable.getElement(sym)
                    except:
                        # note: this typically fails with AssertionError 
                        # (not e.g. KeyError) [bruce 050322]
                        continue
                    else:
                        foundit = True
                        break
                    pass
            if not foundit:
                msg = "Warning: Pdb file: will use Carbon in place of unknown element %s in: %s" \
                    % (name4, card)
                print msg #bruce 070410 added this print
                env.history.message( redmsg( msg ))

                ##e It would probably be better to create a fake atom, so the 
                # CONECT records would still work.
                #bruce 080508 let's do that:
                sym = "C"
                
                # Better still might be to create a fake element, 
                # so we could write out the pdb file again
                # (albeit missing lots of info). [bruce 070410 comment]
                
                # Note: an advisor tells us:
                #   PDB files sometimes encode atomtypes,
                #   using C_R instead of C, for example, to represent sp2 
                #   carbons.
                # That particular case won't trigger this exception, since we
                # only look at 2 characters [eventually, after trying more, as of 080508],
                # i.e. C_ in that case. It would be better to realize this means
                # sp2 and set the atomtype here (and perhaps then use it when
                # inferring bonds,  which we do later if the file doesn't have 
                # any bonds). [bruce 060614/070410 comment]

            _is_water = is_water(resName, name4)
            if _is_water:
                tmpmol = mol
                mol = water
                
            # Now the element name is in sym.
            xyz = map(float, [card[30:38], card[38:46], card[46:54]] )
            n = int(card[6:11])
            a = Atom(sym, A(xyz), mol)
            ndix[n] = a
            
            if not _is_water:
                mol.protein.add_pdb_atom(a, 
                                         name4, 
                                         resId, 
                                         resName)
            
            # Assign secondary structure.            
            if (resId, chainId) in helix:
                mol.protein.assign_helix(resId)
            
            if (resId, chainId) in sheet:
                mol.protein.assign_strand(resId)
                
            if (resId, chainId) in turn:
                mol.protein.assign_turn(resId)
            
            if mol == water:
                mol = tmpmol
            
        elif key == "conect":
            try:
                a1 = ndix[int(card[6:11])]
            except:
                #bruce 050322 added this level of try/except and its message;
                # see code below for at least two kinds of errors this might
                # catch, but we don't try to distinguish these here. BTW this 
                # also happens as a consequence of not finding the element 
                # symbol, above,  since atoms with unknown elements are not 
                # created.
                env.history.message( redmsg( "Warning: Pdb file: can't find first atom in CONECT record: %s" % (card,) ))
            else:
                for i in range(11, 70, 5):
                    try:
                        a2 = ndix[int(card[i:i+5])]
                    except ValueError:
                        # bruce 050323 comment:
                        # we assume this is from int('') or int(' ') etc;
                        # this is the usual way of ending this loop.
                        break
                    except KeyError:
                        #bruce 050322-23 added history warning for this,
                        # assuming it comes from ndix[] lookup.
                        env.history.message( redmsg( "Warning: Pdb file: can't find atom %s in: %s" % (card[i:i+5], card) ))
                        continue
                    bond_atoms(a1, a2)
                    numconects += 1
        elif key == "ter":
            # Finish the current molecule.
            _finish_molecule()
            
            # Discard the original molecule and create a new one. 
            mol = Chunk(assy, nodename)
            mol.protein = Protein()
            numconects = 0
                        
        elif key == "header":
            # Extract PDB ID from the header string.
            pdbid = card[62:66].lower()
            comment_text += card
        
        elif key == "compnd":
            comment_text += card
        
        elif key == "remark":
            comment_text += card
            
        elif key == "model":
            # Check out the MODEL record, ignore everything other than MODEL 1.
            # This behavior has to be optional and set via User Preference.
            # piotr 080714
            model_id = int(card[6:20])
            if model_id > 1:
                # Skip remaining part of the file.
                break
            
        elif key in ["helix", "sheet", "turn"]:
            # Read secondary structure information.
            if key == "helix":
                begin = int(card[22:25])
                end = int(card[34:37])
                chainId = card[19]
                for s in range(begin, end+1):
                    helix.append((s, chainId))            
            elif key == "sheet":
                begin = int(card[23:26])
                end = int(card[34:37])
                chainId = card[21]
                for s in range(begin, end+1):
                    sheet.append((s, chainId))            
            elif key == "turn":
                begin = int(card[23:26])
                end = int(card[34:37])
                chainId = card[19]
                for s in range(begin, end+1):
                    turn.append((s, chainId))            
        else:
            if card[7:15] == "ntrials:":
                _read_rosetta_info = True
                comment_text += "Rosetta Scoring Analysis\n"
            if _read_rosetta_info:
                comment_text += card
                
        if showProgressDialog: # Update the progress dialog.
            _progressValue += 1
            if _progressValue >= _progressFinishValue:
                win.progressDialog.setLabelText("Building model...")
            elif _progressDialogDisplayed:
                win.progressDialog.setValue(_progressValue)
            else:
                _timerDuration = time.time() - _timerStart
                if _timerDuration > 0.25: 
                    # Display progress dialog after 0.25 seconds
                    win.progressDialog.setValue(_progressValue)
                    _progressDialogDisplayed = True
    
    if showProgressDialog: # Make the progress dialog go away.
        win.progressDialog.setValue(_progressFinishValue) 
    
    _finish_molecule()
    
    if water.atoms:
        # Check if there are any water molecules
        water.name = "Solvent"
        # The water should be hidden by default.
        water.hide()
        mollist.append(water)
        
    return (mollist, comment_text)
Ejemplo n.º 30
0
    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
Ejemplo n.º 31
0
 def kill(self):
     self.restore_atoms_to_their_homes() # or should we delete them instead?? (this should never matter in our planned uses)
         # this includes self.part = None
     Chunk.kill(self)
Ejemplo n.º 32
0
    def buildChunk(self, assy):
        """
        Build Chunk for the cookies. First, combine bonds from
        all layers together, which may fuse some half bonds to full bonds.
        """
        from model.chunk import Chunk
        from model.chem import Atom
        from utilities.constants import gensym

        numLayers = len(self.bondLayers)
        if numLayers:
            allBonds = {}
            allCarbons = {}

            #Copy the bonds, carbons and hedron from the first layer
            for ii in range(numLayers):
                if self.bondLayers.has_key(ii):
                    for bKey, bValue in self.bondLayers[ii].items():
                        allBonds[bKey] = bValue

                    del self.bondLayers[ii]
                    break

            for carbons in self.carbonPosDict.values():
                for cKey, cValue in carbons.items():
                    allCarbons[cKey] = cValue

            for hedrons in self.hedroPosDict.values():        
                for hKey, hValue in hedrons.items():
                    allCarbons[hKey] = hValue

            for bonds in self.bondLayers.values():
                for bKey, bValues in bonds.items():
                    if bKey in allBonds:
                        existValues = allBonds[bKey]
                        for bValue in bValues:
                            if type(bValue) == type((1, 1)):
                                if bValue[1]: 
                                    ctValue = (bValue[0], 0)
                                else: 
                                    ctValue = (bValue[0], 1)
                                if ctValue in existValues:
                                    idex = existValues.index(ctValue)
                                    existValues[idex] = bValue[0]
                                else:
                                    existValues += [bValue]
                            else: 
                                existValues += [bValue]
                        allBonds[bKey] = existValues
                    else: allBonds[bKey] = bValues

            #print "allbonds: ", allBonds
            #print "allCarbons: ", allCarbons

            carbonAtoms = {}
            mol = Chunk(assy, gensym("Crystal", assy))
            for bKey, bBonds in allBonds.items():
                keyHedron = True
                if len(bBonds):
                    for bond in bBonds:
                        if keyHedron:
                            if type(bBonds[0]) == type(1) or (not bBonds[0][1]):
                                if not bKey in carbonAtoms:
                                    keyAtom = Atom("C", allCarbons[bKey], mol) 
                                    carbonAtoms[bKey] = keyAtom
                                else:
                                    keyAtom = carbonAtoms[bKey]
                                keyHedron = False

                        if keyHedron:    
                            if type(bond) != type((1, 1)):
                                raise ValueError, (bKey, bond, bBonds)
                            else:
                                xp = (allCarbons[bKey] + allCarbons[bond[0]])/2.0
                                keyAtom = Atom("X", xp, mol)         

                        if type(bond) == type(1) or bond[1]:
                            if type(bond) == type(1):
                                bvKey = bond
                            else: 
                                bvKey = bond[0]
                            if not bvKey in carbonAtoms:
                                bondAtom = Atom("C", allCarbons[bvKey], mol) 
                                carbonAtoms[bvKey] = bondAtom
                            else: 
                                bondAtom = carbonAtoms[bvKey]
                        else:
                            xp = (allCarbons[bKey] + allCarbons[bond[0]])/2.0
                            bondAtom = Atom("X", xp, mol)     

                        bond_atoms(keyAtom, bondAtom)

            if len(mol.atoms) > 0:
                #bruce 050222 comment: much of this is not needed, since mol.pick() does it.
                # Note: this method is similar to one in BuildCrystal_Command.py.
                assy.addmol(mol)
                assy.unpickall_in_GLPane() 
                    # was unpickparts; not sure _in_GLPane is best (or that
                    # this is needed at all) [bruce 060721]
                mol.pick()
                assy.mt.mt_update()

        return # from buildChunk
Ejemplo n.º 33
0
    def make_aligned(self,
                     assy,
                     name,
                     aa_idx,
                     phi,
                     psi,
                     pos1,
                     pos2,
                     secondary=SS_COIL,
                     fake_chain=False,
                     length=None):
        """
        Build and return a chunk that is a h**o-peptide aligned to
        a pos2-pos1 vector.

        @param aa_idx: amino acid type (index in AMINO_ACIDS list)
        @type aa_idx: int

        @param name: chunk name
        @type name: string

        @param phi, psi: peptide bond angles
        @type phi, psi: float

        @param pos1, pos2: desired peptide positions (beginning and end)
        @type pos1, pos2: V

        @param secondary: secondary structure class, used for visual representation
        The actual peptide chain conformation is based on phi / psi angles.
        @type secondary: int

        @param fake_chain: if True, create only C-alpha atoms. used for drawing
        peptide trace image during interactive peptide placement (used by
        PeptideLine_GraphicsMode.py)
        @type fake_chain: boolean

        @param length: optional peptide length (number of amino acids), if
        not specified, pos1 and pos2 are used to figure out the length
        @type length: int

        @return: A h**o-polypeptide chain.
        @rtype:  L{Chunk}
        """

        if not length:
            self.length = self.get_number_of_res(pos1, pos2, phi, psi)
            if self.length == 0:
                return None
        else:
            self.length = length

        # Create a molecule
        mol = Chunk(assy, name)

        if not fake_chain:
            mol.protein = Protein()
            mol.protein.set_chain_id('A')

        # Generate dummy atoms positions
        self.prev_coords[0][0] = pos1[0] - 1.0
        self.prev_coords[0][1] = pos1[1] - 1.0
        self.prev_coords[0][2] = pos1[2]

        self.prev_coords[1][0] = pos1[0] - 1.0
        self.prev_coords[1][1] = pos1[1]
        self.prev_coords[1][2] = pos1[2]

        self.prev_coords[2][0] = pos1[0]
        self.prev_coords[2][1] = pos1[1]
        self.prev_coords[2][2] = pos1[2]

        name, short_name, symbol, zmatrix, size = AMINO_ACIDS[aa_idx]

        # Add a N-terminal hydrogen
        self.nterm_hydrogen = None

        # Initially, the Peptide Builder was creating peptide structures
        # saturated at both ends, i.e. with N-terminal hydrogen and C-terminal
        # OH group present. Currently, this code is commented out to allow
        # connecting multiple peptide structure be creating bonds between
        # the C- and N- terminal ends of two individual structures.
        """
        if not fake_chain:
            atom = Atom("H", pos1, mol)
            atom._is_aromatic = False
            atom._is_single = False
            self.nterm_hydrogen = atom
            mol.protein.add_pdb_atom(atom, "H", 1, name)
            atom.pdb_info = {}
            atom.pdb_info['atom_name'] = "H"
            atom.pdb_info['residue_name'] = short_name
            atom.pdb_info['residue_id'] = "  1 "
            atom.pdb_info['standard_atom'] = True
        """

        self.init_ca = None

        # Generate the peptide chain.
        for idx in range(int(self.length)):
            self._buildResidue(mol,
                               zmatrix,
                               size,
                               idx + 1,
                               phi,
                               psi,
                               secondary,
                               None,
                               short_name,
                               fake_chain=fake_chain)

        # See the comment above.
        """
        # Add a C-terminal OH group
        self._buildResidue(mol, CTERM_ZMATRIX, 5, int(self.length), 0.0, 0.0, secondary, None, short_name, fake_chain=fake_chain)
        """

        # Compute bonds (slow!)
        # This should be replaced by a proper bond assignment.

        if not fake_chain:
            inferBonds(mol)

        # Assign proper bond orders.
        i = 1
        for atom in mol.atoms.itervalues():
            if atom.bonds:
                for bond in atom.bonds:
                    if bond.atom1.getAtomTypeName()=="sp2" and \
                       bond.atom2.getAtomTypeName()=="sp2":
                        if (bond.atom1._is_aromatic
                                and bond.atom2._is_aromatic):
                            bond.set_v6(V_AROMATIC)
                        elif ((bond.atom1._is_aromatic == False
                               and bond.atom1._is_aromatic == False)
                              and not (bond.atom1._is_single
                                       and bond.atom2._is_single)):
                            bond.set_v6(V_DOUBLE)
            i += 1

        # Remove temporary attributes.
        for atom in mol.atoms.itervalues():
            del atom._is_aromatic
            del atom._is_single

        # Axis of first selected chunk
        ax = V(0., 0., 1.)
        mol.rot(Q(mol.getaxis(), ax))

        self._orient(mol, pos2, pos1)

        if self.init_ca:
            mol.move(pos1 - self.init_ca.posn())

        mol_dummy = None

        return mol