User:Remig/plico/remap

From Jmol
< User:Remig‎ | plico
Revision as of 13:43, 18 March 2014 by Remig (talk | contribs)
Jump to navigation Jump to search

Remap allows you to change the chain ID, atom numbers and/or residue numbers of a polypeptide chain by mouse actions. It also calculates group values [amino acid names (GLY, THR, etc.)]. Finally it prints the 1 char resultant string to the console.

Note that it will also remove all waters, hydrogens and %B alternates when any chain is updated.

Remap is a member of the Plico suite of protein folding tools described here. It may be installed and accessed as a macro with the file:

Title=PLICO Remap
Script=script <path to your scripts folder>/remap.spt;plicoRemap

saved as plicoRemap.macro in your .jmol/macros folder as described in Macro.

Copy and paste the following to a text editor and save to your scripts folder as remap.spt:

#   remap - Jmol script by Ron Mignery
#   v1.2 beta    3/18/2014 for Jmol 14
#
#   Calculate or change polypeptide chain, atom number, residue names and/or residue
#    numbers and print the resultant 1 char string
#
var gAppendNew = TRUE

# Search for N-C-C-0
function getBBnCAidx(idx) {
    if ({atomIndex=idx}.element == "N") {
        var c1 = (connected({atomIndex=idx}) and not {hydrogen})
        for (var i1 = 1; i1 <= c1.size; i1++) {
            if (c1[i1].element == "C") {
                var c2 = (connected({atomIndex=@{c1[i1].atomIndex}}) and not {hydrogen})
                for (var i2 = 1; i2 <= c2.size; i2++) {
                    if (c2[i2].element == "C") {
                        var c3 = (connected({atomIndex=@{c2[i2].atomIndex}})
                            and not {hydrogen})
                        for (var i3 = 1; i3 <= c3.size; i3++) {
                            if (c3[i3].element == "O") {
                                return c1[i1].atomIndex
                            }
                        }
                    }               
                }
            }
        }
    }
    return -1
}

# Find N-terminal N
function findN0idx(aIdx) {

    select {atomIndex=aIdx}
    var cSet = {selected}
    while (cSet.size > 0) {
        for (var i = 1; i <= cSet.size; i++) {
            var idx = cSet[i].atomIndex
            var caIdx = getBBnCAidx(idx)
            if (caIdx >= 0) {
                if ({connected({atomIndex=idx}) and not {hydrogen}}.size < 2) {
                    return idx
                }            
            }
        }
        cSet = connected({selected}) and not {selected} and not {hydrogen}
        select {selected} or cset
    }
    return -1
}

# Bound to ALT-LEFT-CLICK by plicoRemap
function remapCargoMB() {
    var idx =_atomPicked
    
    if ({atomIndex=idx}.element == "H") {
        idx = connected({atomIndex=idx})[1].atomIndex
    }
    
    # If n-terminal N can be found
    var n0idx = findN0idx(idx)
    var isValid = FALSE
    var newResno = 1
    var newChain = "A"
    var newAtomno = 1
    if (n0idx >= 0) {
    
        # Prompt for new designators
        var p = prompt("Enter n-terminal atom designator as\n"
            + "   <resno>:<chain>.N#<atomno>", "1:A.N#1")%0

        # If valid
        var iColon = p.find(":")
        if (iColon > 0) {
            var iDot = p.find(".")
            if (iDot > 0) {
                var iHash = p.find("#")
                if (iHash > 0) {
                    newResno = 0 + (p[1][iColon-1])
                    newChain = p[iColon+1][iDot-1]
                    newAtomno = 0 + (p[iHash+1][0])
                    if ((newResno > 0)
                        and (newChain.size == 1)
                        and (newAtomno > 0)) {
                            isValid = TRUE
                    }
                }
            }
        }
    }
    if (isValid) {
 
        delete {hydrogen}
        delete {hoh}
        delete %B
        ssbonds off
        
        # Build inline pdb file
        var ls = "data \"append remap\"\n"
        var rs = ""
        var ls1 = format("%s:", newChain)
               
        select {atomIndex=n0idx}
        var cSet = {selected}
        var newAtomName = "N"
        var newGroup = "UNK"
        var s1 = "X"
        var newGreek = ""
        var newCount = ""
        var isCB = FALSE
        var nIdx = n0idx
        var proDidx = -1
        var oxtIdx = -1
        while ((nIdx >= n0idx) or (cSet.size > 0)) {
            var s = array(1, 2, 3)
            var pTrp = 0
            if (cSet.size == 0) {
                    ls += rs.replace("UNK", newGroup).replace("  SeG" , " SeG ")
                    ls1 += s1
                    rs = ""
                    newResno++
                    nIdx = -1
                    proIdx = -1
                    newGroup = "UNK"
                    s1 = "X"
                    newAtomName = "N"
                    isCB = FALSE
            }
            else if (cSet.size == 1) {
                if (newAtomName == "N") {
                    newGreek = ""
                    newAtomName = "CA"
                }
                else if (newAtomName == "CA") {
                    newGreek = "A"
                    newAtomName = "C"
                }
                else if (newAtomName == "C") {
                    newGroup = "GLY"
                    s1 = "G"
                    newGreek = ""
                    newAtomName = "O"
                }
                else if (newAtomName == "CB") {
                    if (cSet[1].element == "C") {
                        newGroup = "ALA" # for now
                        s1 = "A"
                        newGreek = "B"
                    }
                    newAtomName = "XG"
                }
                else if (newAtomName == "XG") {
                    if (proDidx >= 0) {
                        newGroup = "PRO"
                        s1 = "P"
                        proDidx = -1
                    }
                    if (cSet[1].element == "O") { # SER CYS SEC
                        newGroup = "SER"
                        s1 = "S"
                    }
                    else if (cSet[1].element == "S") {
                        newGroup = "CYS"
                        s1 = "C"
                    }
                    else if (cSet[1].element == "Se") {
                        newGroup = "SEC"
                        s1 = "U"
                    }
                    newGreek = "G"
                    newAtomName = "XD"
                }
                else if (newAtomName == "XD") {
                    if (newGroup == "VAL") {
                        newGroup = "ILE"
                        s1 = "I"
                        newCount = "1"
                    }
                    newGreek = "D"
                    newAtomName = "XE"
                }
                else if (newAtomName == "XE") {
                    newGroup = "MET"
                    s1 = "M"
                    newGreek = "E"
                    newAtomName = "XZ"
                }
                else if (newAtomName == "XZ") {
                    if (cSet[1].element == "N") {
                        newGroup = "LYS"
                        s1 = "K"
                    }
                    else {
                        newGroup = "PHE" # for now
                        s1 = "F"
                    }
                    newGreek = "Z"
                    newAtomName = "XH"
                }
                else if (newAtomName == "XH") {
                    if (cSet[1].element == "O") {
                        newGroup = "TYR"
                        s1 = "Y"
                    }
                    else {
                        newGroup = "TRP" # for now
                        s1 = "W"
                        newCount = "2"
                    }
                    newGreek = "H"
                    newAtomName = "N"
                }
            }
            else if (cSet.size == 2) {
                var hasN = ((cSet[1].element == "N") or (cSet[2].element == "N"))
                var hasO = ((cSet[1].element == "O") or (cSet[2].element == "O"))

                # If CA 2
                if (newAtomName == "CA") {
                    var iKeep = -1
                    for (var i = 1; i <= cSet.size; i++) {
                        if (connected(cSet[i]) > 2) {
                            iKeep = i
                        }
                        else {
                            proDidx = cSet[i].atomIndex
                            cSet[i].selected = FALSE
                        }
                    }
                    cSet = cSet[iKeep]
                    newGroup = "PRO"
                    s1 = "P"
                    newGreek = "A"
                    newAtomName = "C"
                }
                
                # Else if C or CB 2
                else if (newAtomName == "C") {
                    for (var i = 1; i <= cSet.size; i++) {
                    
                        # If it connects O and (N or O)
                        var tSet = (connected(cSet[i]) and not {selected})
                        var oCount = 0
                        var nCount = 0
                        for (var j = 1; j <= tSet.size; j++) {
                            oCount += ((tSet[j].element == "O") ? 1 : 0)
                            nCount += ((tSet[j].element == "N") ? 1 : 0)
                        }
                        if ((nCount > 0) or (oCount > 1)) { # C
                            newGreek = ""
                            newAtomName = "O"
                        }
                        else { # CB
                            isCB = TRUE
                            cSet[i].selected = FALSE
                            cSet = (cSet and not cSet[i])
                            continue
                        } 
                    } # endfor
                }
                
                # Else if O or N 2
                else if (newAtomName == "O") {
                    var iKeep = -1
                    for (var i = 1; i <= cSet.size; i++) {
                        if (cSet[i].element != "O") {
                            if (cSet[i].element == "N") {
                                nIdx = cSet[i].atomIndex
                            }
                            cSet[i].selected = FALSE
                        }
                        else {
                            iKeep = i
                        }
                    }
                    cSet = cSet[iKeep]
                    newGreek = ""
                    newAtomName = (isCB ? "CB" : "N")
                }
                
                # Else if N or CB 2
                else if (newAtomName == "CB") {
                    for (var i = 1; i <= cSet.size; i++) {
                        if (cSet[i].element != "C") {
                            nIdx = cSet[i].atomIndex
                            cSet[i].selected = FALSE
                            continue
                        }
                        newGreek = "B"
                        newAtomName = "XG"
                    } # endfor
                }
                
                    
                # Else if XG or XGn 2
                else if (newAtomName == "XG") { # VAL THR ILE
                    newGroup = (hasO ? "THR" : "VAL")
                    s1 = (hasO ? "T" : "V")
                    newGreek = "G"
                    newAtomName = "XD"
                }
                        
                    
                # Else if XD or XDn 2
                else if (newAtomName == "XD") { # LEU ASP ASN
                    var cTrp = (connected(cSet[2]) and not {selected})
                    var sTrp = ((trp.size > 0) ? (trp[1].element=="N") : FALSE)
                    if ((cSet[2].element != "C") or sTrp
                        or ((connected(cSet[1]) and not {selected}).size == 0)) {
                        bRev = TRUE
                    }
                    if ((cSet[2].element == "O") or (cSet[1].element == "N")
                        or ((cSet[1].element == "C") and (cSet[2].element != "C"))) {
                        bRev = TRUE
                    }
                    if (hasN) {
                        if (hasO) {
                            newGroup = "ASN"
                            s1 = "N"
                        }
                        else {
                            newGroup = "HIS"
                            s1 = "H"
                        }
                    }
                    else if (hasO) {
                        newGroup = "ASP"
                        s1 = "D"
                    }
                    else {
                        newGroup = "LEU" # for now
                        s1 = "L"
                    }
                    newGreek = "D"
                    newAtomName = "XE"
                }
                    
                # Else if XE or XEn 2
                else if (newAtomName == "XE") { # GLU GLN HIS
                    if ((cSet[2].element == "O") or (cSet[1].element == "N")
                        or ((cSet[1].element == "C") and (cSet[2].element != "C"))) {
                        bRev = TRUE
                    }
                    if (hasO) {
                        if (hasN) {
                            newGroup = "GLN"
                            s1 = "Q"
                        }
                        else {
                            newGroup = "GLU"
                            s1 = "E"
                        }
                    }
                    newGreek = "E"
                    newAtomName = "XZ"
                }
                    
                # Else if XZ 2
                else if (newAtomName == "XZ") { # ARG
                    if (newGroup == "TRP") {
                        pTrp = 1
                    }
                    newGreek = "Z"
                    newAtomName = "XH"
                }
                    
                # Else if XH 2
                else if (newAtomName == "XH") { # ARG
                    newGroup = "ARG"
                    s1 = "R"
                    newGreek = "H"
                    newAtomName = "N"
                }
            }
            
            # Else cSet.size = 3
            else {
                # If  O
                if (newAtomName == "O") {
                    var oCount = 0
                    var iKeep = -1
                    for (var i = 1; i <= cSet.size; i++) {
                        if (cSet[i].element != "O") {
                            if (cSet[i].element == "N") {
                                nIdx = cSet[i].atomIndex
                            }
                            cSet[i].selected = FALSE
                        }
                        else {
                            oCount++
                            if (iKeep < 0) {
                                iKeep = i
                            }
                            else {
                                oxtIdx = cSet[i].atomIndex
                            }
                        }
                    }
                    cset = cSet[iKeep[1]]
                    newGreek = ""
                    newAtomName = (isCB ? "CB" : "N")
                }
                else if (newAtomName == "CA") { # PRO
                    var iKeep = -1
                    for (var i = 1; i <= cSet.size; i++) {
                        if (connected(cSet[i]) > 2) {
                            iKeep = i
                        }
                    }
                    cSet = cSet[iKeep]

                    newGreek = "A"
                    newAtomName = "C"
                }
                else if (newAtomName == "XE") { # TRP
                    for (var i = 1; i <= cSet.size; i++) {
                        if (cSet[i].element == "N") {
                            s[1] = i
                        }
                        else if (connected(cSet[i]) > 2) {
                            s[2] = i
                        }
                        else {
                            s[3] = i
                        }
                    }
                    newGroup = "TRP"
                    s1 = "W"
                    newGreek = "E"
                    newAtomName = "XZ"
                }
                else {
                }
            }
            
            for (var i = 1; i <= cSet.size; i++) {
                rs += format("ATOM  %5d  %-4sUNK ", newAtomNo,
                    (cSet[s[i]].element + newGreek
                    + ((cSet.size > 1) ? (i+pTrp) : newCount)))
                rs += format("%s%4d    %8.3f", newChain, newResno, cSet[s[i]].x)          
                rs += format("%8.3f%8.3f\n", cSet[s[i]].y, cSet[s[i]].z)
                if (newGreek == "XT") {
                    newGreek == ""
                }
                newAtomno++
            }
            newCount = ""
            cSet = (connected({selected}) and not {selected}
                and not {atomIndex=@nIdx} and not {atomIndex=proDidx})
            select ({selected} or cSet and not {atomIndex=nIdx}
                 and not {atomIndex=proDidx})
            
        } # endwhile 
        
        # Replace chain with new chain
        if (oxtIdx >= 0) {
            rs += format("ATOM  %5d  OXT UNK %s", newAtomNo, newChain)
            rs += format("%4d    %8.3f", newResno, {atomIndex=oxtIdx}.x)          
            rs += format("%8.3f%8.3f\n", {atomIndex=oxtIdx}.y, {atomIndex=oxtIdx}.z)
        }
        ls += rs.replace("UNK", newGroup).replace("  SeG" , " SeG ")
        ls1 += s1
        delete {selected}
        ls += "end \"append remap\""
        script inline @{ls}
        var xx = {element="Xx"}
        for (var i = 1; i <= xx.size; i++) {
             connect 1.8 {atomindex=@{xx[i].atomIndex}}
        }
        ssbonds on
        gEcho += format("|Chain %s has been rebuilt", newChain)
        set echo TOP LEFT
        echo @gEcho
        print ls1
                        
    }    
}

# Top level of Remap
function plicoRemap() {
    
    # Push selected
    gSelSaves = {selected}
    
    gAppendNew = appendNew
    set appendNew FALSE
    gScheme = defaultColorScheme
    gAltScheme = ((gScheme == "Jmol") ? "Rasmol" : "Jmol")
    set echo TOP LEFT
    background ECHO yellow
    gEcho = "_______REMAP_______|ALT-CLICK=select chain|DOUBLE-CLICK=exit"
    echo @gEcho
    gChain = ""
    unbind

    set picking ON
    bind "ALT-LEFT-CLICK" "_pickAtom";
    bind "ALT-LEFT-CLICK" "+:remapCargoMB";
    bind "DOUBLE" "remapExit";
}

# Bound to DOUBLE by plicoRemap
function remapExit() {
    unbind
    halo off 
    echo
    select all
    color {selected} @gScheme
    gBusy = FALSE
    set appendNew gAppendNew
    
    # Pop selected
    select gSelSaves
}
# End of REMAP.SPT

Contributors

Remig