User:Remig/plico/fold trna

From Jmol
Jump to navigation Jump to search

Fold_trna predicts the tertiary structure of any tRNA from its sequence provided the tRNA has the universal elements of functional tRNAs: (proceeding 5' to 3') a 7 base-pair stem, 3 upaired nts, a 4 base-pair D stem, a 7, 8 or 9 base D loop, 1 unpaired nt, a 5 base-pair acceptor stem, a 7 base acceptor loop, 5 unpaired NTs or else a variable stem loop of any size, a TUCG stem of 5 base-pairs, a UCG loop of 7 bases, no NTs before the acceptor stem, and a final unpaired N or NCCA.

This script prompts for a tRNA sequence string (5' to 3', ACGUs only, with or without 3'CCA). The Genomic tRNA Database at http://lowelab.ucsc.edu/GtRNAdb/ is an excellent source for such strings.

It then loads a corresponding template tRNA from the PDB, replaces the template nucleotides with the input string nucleotide, minimizes to fix any resulting collisions, and, if needed, creates and inserts a variable loop.

The process takes a few minutes: the yellow progress message in the upper left will go pink for the duration.

The template used depends on the D loop size as follows:

   7:  1yfg    8:  3l0u    9:1ffy

Variable loop positioning is templated on the PDB entry 1ser.

The end model is double-bonded to prevent minimization errors. Use the Convert macro to remove them if desired.

Fold_trna 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 Fold tRNA
Script=script <path to your scripts directory>/fold_trna.spt;plico_fold_trna

saved as plicoFoldTrna.macro in your .jmol/macros directory as described in Macro.

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

#   fold_trna - Jmol script by Ron Mignery
#   v1.3 beta    4/12/2016 -axis is now a reserved word
#
#   fold_trna predicts the tertiary structure of any tRNA from its sequence
#   provided the tRNA has the universal elements of functional tRNAs:
#   (proceeding 5' to 3') a 7 base-pair stem, 3 upaired nts, a 4 base-pair
#   D stem, a 7, 8 or 9 base D loop, 1 unpaired nt,  a 5 base-pair 
#   acceptor stem, a 7 base acceptor loop, 5 unpaired NTs or else a variable
#   stem loop of any size, a TUCG stem of 5 base-pairs, a TUCG loop of 7
#   bases, no NTs before the acceptor stem, and a final unpaired N or NCCA.
#   Not all base pairs need be canonical.
#
#   This script prompts for a tRNA sequence string
#   (5' to 3', ACGUs only, with or without 3'CCA).
#   The Genomic tRNA Database at http://lowelab.ucsc.edu/GtRNAdb/
#   is an excellent source for such strings.
#
#   It then loads a corresponding template tRNA from the PDB, replaces the template
#   nucleotides with the input string nucleotide, minimizes to fix any
#   resulting collisions, and, if needed, creates and inserts a variable loop.
#
#   The process takes a few minutes: the yellow progress message in the upper
#   left will go pink for the duration.
#   
#   The template used depends on the D loop size as follows:
#       7:  1yfg    8:  3l0u    9:1ffy
#   
#   Variable loop positioning is templated on 1ser.
#   
#   The end model is double-bonded to prevent minimization errors.
#   Use the Convert macro to remove them if desired.
#
#   fold_rna uses the PLICO scripts plicoCommon.spt, plicoNTcommon.spt,
#   polymeraze.spt, remapNT.spt, and convert_residue.spt which must be
#   available in the same directory from which fold_rna.spt is loaded.

# TOP LEVEL FUNCTION - Find and fold all loops
function plico_fold_trna(iChain) {

    gMenuMin = false
    bind "LEFT-CLICK" "+:plico_menu_toggle";

    # Load common functions if not already
    if (kCommon < 7) {
        script $SCRIPT_PATH$plicoCommon.spt
        if (kCommon < 7) {
            prompt ("A newer version of plicoCommon.SPT is required")
            quit
        }
    }
    if (kNTcommon < 6) {
        script $SCRIPT_PATH$plicoNTcommon.spt
        if (kNTcommon < 6) {
            prompt ("A newer version of plicoNTcommon.SPT is required")
            quit
        }
    }
    if (iChain == "") {
        iChain = gChain1
    }
    
    align_trna()
}

function align_trna() {
    if (kPolymeraze < 1) {
        script $SCRIPT_PATH$polymeraze.spt
        echo dl polymeraze.spt
        if (kPolymeraze < 1) {
            prompt ("The Plico script polymeraze.spt (1.14+) is required")
            quit
        }
    }
    if (kRemapNT < 2) {
        script $SCRIPT_PATH$remapNT.spt
        echo dl remapNT.spt
        if (kRemapNT < 2) {
            prompt ("The Plico script remapNT.spt (1.14+) is required")
            quit
        }
    }
    if (kConvert < 1) {
        script $SCRIPT_PATH$convert_residue.spt
        echo dl convert_residue.spt
        if (kConvert < 1) {
            prompt ("The Plico script convert_residue.spt (1.4+) is required")
            quit
        }
    }
    
    # Prompt for new
    var nseq = prompt("Enter new tRNA NT sequence (ACGTU...)", "")%9999%0
    try {
    
        # If new is trna
        if (nseq.size > 67) {
            nseq = nseq.replace("T", "U")
            
            # Remove 3' CCA if present
            if (nseq[nseq.size-2][nseq.size] == "CCA") {
                if (eval_pairing( nseq, 1, nseq.size-4, 3) > 6) {
                    nseq = nseq[1][nseq.size-3]
                }
            }

            # Calc D loop size
            var dn = 7
            var ds = eval_pairing(nseq, 10, 24, 4)
            if (eval_pairing(nseq, 10, 25, 4) > ds) {
                ds = eval_pairing(nseq, 10, 25, 4)
                dn = 8
            }
            if (eval_pairing(nseq, 10, 26, 4) > ds) {
                dn = 9
            }
            
            var tpdb = ""
            set echo TOP LEFT
            background ECHO pink
            switch (dn) {
            case 7: # 1yfg
                tpdb = "1yfg"
                gEcho = "aligning tRNA... Loading " + tpdb
                echo @gEcho
                load "=1yfg"
                delete 74-76
                delete {connected(connected(atomName="C12"))} #T6A
                #convert_nt(16, "A", "U")
                #convert_nt(47, "A", "U")
                break
            case 8: # 3l0u
                tpdb = "3l0u"
                gEcho = "aligning tRNA... Loading " + tpdb
                echo @gEcho
                load "=3l0u"
                break
            case 9: # 1ffy
                tpdb = "1ffy"
                gEcho = "aligning tRNA... Loading " + tpdb
                echo @gEcho
                load "=1ffy"
                delete not :T
                delete 74
                break
            default :
                throw "D loop not 7-9 bases"
            }
            refresh
            delete ligands
            delete hoh
            delete {atomName="CM?"}
            delete not connected
            
            set echo TOP LEFT
            gEcho = "aligning tRNA... Remapping " + tpdb
            echo @gEcho
            gChain1 = "A"
            remap_nt( 1, true, 1)
            {atomName="O"}.atomName="OP1" # 1yfg?
            center

            var a = {all}.atomno.min
            var iChain = {atomno=a}.chain
            var rmin = get_resno_min(iChain)
            var rmax = get_resno_max(iChain)
            var pn5 = 1
            var pn3 = nseq.size
            
            # Convert from 5' and 3' until meet
            set echo TOP LEFT
            gEcho = "aligning tRNA... Converting " + tpdb
            echo @gEcho
            for (var i = 0; i < (37+dn); i++) {
                var ac1 = get_atom_rcn(rmin+i, iChain, "C1\'")
                if (ac1.group != nseq[pn5+i]) {
                    convert_nt(rmin+i, iChain, nseq[pn5+i])
                }
            }
            for (var i = 0; i < 28; i++) {
                var ac1 = get_atom_rcn(rmax-i, iChain, "C1\'")
                if (ac1.group != nseq[pn3-i]) {
                    convert_nt(rmax-i, iChain, nseq[pn3-i])
                }
            }
            set echo TOP LEFT
            gEcho = "aligning tRNA... Renumbering atoms"
            echo @gEcho
            update_atomnos(iChain)
            
            # Double bond the bases and add Hs to keep minimizations kosher
            set echo TOP LEFT
            gEcho = "aligning tRNA... Double-bonding"
            echo @gEcho
            double_bond_planars(iChain, false)
            
            # Position at origin
            select all
            var ac1 = get_atom_rcn(rmin, iChain, "C1\'")
            var ac2 = get_atom_rcn(rmin, iChain, "C2\'")
            var ac3 = get_atom_rcn(rmin, iChain, "C3\'")
            translateSelected @{-ac1.xyz}
            
            var caxis = cross({1 0 0}, ac2.xyz)
            var curangle =  angle({1 0 0}, {0 0 0}, ac2.xyz)
            rotateSelected @caxis {0 0 0} @{curangle}
            
            caxis = cross({0 -1 0}, ac3.xyz)
            curangle =  angle({0 -1 0}, {0 0 0}, ac3.xyz)
            rotateSelected @caxis {0 0 0} @{curangle}
            translateSelected {-4 0 0}
            center {0 0 0}
            
            # Fix new collisions                
            set echo TOP LEFT
            /*for (var i = 1; i < get_resno_max(iChain); i++) {*/
                gEcho = "aligning tRNA... Minimizing collisions NT" + i
                echo @gEcho
                #minimize_for_collision(i, iChain)
            /*}*/
            fix_p_res_range(1, get_resno_max(iChain), iChain, true) 
            
            # If more on new
            var rr =  pn3-pn5-(rmax-rmin)+1
            if (rr > 1) {
            
                # Renumber 3' fragment += rr
                delete {resno=@{38+dn}}
                var aP = get_atom_rcn(39+dn, iChain, "P")
                set echo TOP LEFT
                gEcho = "aligning tRNA... Remapping from NT" + (39+dn)
                echo @gEcho
                remap_nt(aP.atomIndex, true, 38+dn+rr)
                # Make var loop base

                make_var_loop_base( 37+dn, iChain)
                fix_all_nt_collisions(iChain)
                if (is_form_a(38+dn+rr, iChain) == false) {
                    to_ab_nt_res(38+dn+rr, -1, iChain, true)
                }
                pair_it_res( 38+dn+rr, 37+dn, -1, iChain, iChain)
                
                var aO3 = get_atom_rcn(38+dn+rr, iChain, "O3\'")
                aP = get_atom_rcn(39+dn+rr, iChain, "P")
                var aRot = get_atom_rcn(37+dn, iChain, "P")
                fix_p_res(39+dn+rr, iChain, true)
                select {(resno=@{38+dn+rr}) or (resno=@{37+dn})}
                for (var i = 0; i < 2; i++) {        
                    pivot_to_close_atoms( aO3, aP, aRot, 1.74)
                    fix_p_res(39+dn+rr, iChain, true)
                }
                fix_all_nt_collisions(iChain)
                
                # Gen variable loop
                gen_variable_loop(nSeq, rr, dn, iChain) # CALL
            }
            
            # Fix new collisions                
            fix_all_nt_collisions(iChain)
            /*
            set echo TOP LEFT
            for (var i = 1; i < get_resno_max(iChain); i++) {
                gEcho = "aligning tRNA... Minimizing collisions NT" + i
                echo @gEcho
                #minimize_for_collision(i, iChain)
            }
            for (var i = 1; i < get_resno_max(iChain); i++) {
                gEcho = "aligning tRNA... Repairing backbone NT" + i
                echo @gEcho
                #fix_p_res(i, iChain, true)
            }
            */
            
            select all
            color jmol       
            
            set echo TOP LEFT
            background ECHO yellow
            gEcho = "tRNA aligned..."
            echo @gEcho
        }
        else {
            throw "string is too short (<68)"
        }
    }
    catch(e) {
        set echo TOP LEFT
        gEcho = format("Unable to process... %s", thrown_value)
        echo @gEcho
    }
}

function gen_variable_loop(nSeq, rr, dn, iChain) {
    var seq = "RS" + (nSeq[38+dn][37+dn+rr])
    gAppendNew = appendNew
    set appendNew false
    
    # Gen the loop at the origin
    for (var i = 0; i < rr; i++) {
    
        # Add and stack 5' res
        set echo TOP LEFT
        gEcho = "aligning tRNA... Adding " + nSeq[38+dn+i] + (38+dn+i)
        echo @gEcho
        gA = "data \"append nt\"\n"
        gA += gen_nt(38+dn+i, nSeq[38+dn+i], true, false); # CALL
        gA += "end \"append nt\""
        script inline @{gA}
        refresh
        to_ab_nt_res(38+dn+i, -1, iChain, true)
        base_stack_res(38+dn+i, 37+dn+i, iChain, iChain, 4.8, 23.7, true)
        connect_res_nt( 37+dn+i, 38+dn+i, iChain, false)
        fix_p_res(37+dn+i, iChain, true)
        fix_p_res(38+dn+i, iChain, true)
    } # endfor +rr res
    
    # Pair up the loop
    set echo TOP LEFT
    gEcho = "aligning tRNA... Form variable stem-loop"
    echo @gEcho
    for (var i = 0; i < rr\2; i++) {
        pair_it_res(37+dn+rr-i, 38+dn+i, -1, iChain, iChain)
    }
    
    # Make a tetra loop
    # If PYR
    if ((nSeq[36+dn+(rr/2)] = "U") or (nSeq[36+dn+(rr/2)] = "C")) {
        #echo make uncg fold
        make_uncg_loop(36+dn+(rr/2), 37+dn, iChain)
    }
    # else 
    else {
        #echo make gnra fold
        make_gnra_loop(36+dn+(rr/2), 37+dn, iChain)
    }
    for (var i = 0; i < rr\2; i++) {
        if (eval_pairing( nseq, 38+dn+i, 37+dn+rr-1, 1) > 0) {
            pair_it_res(38+dn+i, 37+dn+rr-i, -1, iChain, iChain)
        }
        else {
            break
        }
    }
    fix_p_res_range(37+dn, 36+dn+rr, iChain, true) 
    for (var i = 0; i < 5; i++) {
        minimize_for_collision(35+dn+(rr\2)+i, iChain)
    }
    
    # Connect loop
    connect_res_nt( 37+dn, 38+dn, iChain, false)
    connect_res_nt( 37+dn+rr, 38+dn+rr, iChain, false)

    appendNew = gAppendNew
}

function make_var_loop_base( r5, iChain) {
    var vs = [5.35, 108.6, 97.7, 95.5, -54.2, 24.2, -38.9, -8.4]
    position_nt_by_vs(r5-1, r5-2, r5, vs, iChain, iChain)
    
    vs = [10.36, 61.7, 72.5, 64.7, -40.8, 62.4, -8.4, -19.3]
    position_nt_by_vs(r5, r5-1, r5+1, vs, iChain, iChain)
    
    fix_p_res(r5, iChain, true)
    fix_p_res(r5+1, iChain, true)
}

# end fold_trna.spt

Contributors

Remig