Icon representing a recipe

Recipe: AA Edit 1.2

created by LociOiling

Profile


Name
AA Edit 1.2
ID
102274
Shared with
Public
Parent
None
Children
Created on
December 27, 2016 at 21:26 PM UTC
Updated on
December 27, 2016 at 21:26 PM UTC
Description

AA Edit 1.2 is based on SS Edit 1.2. It displays the proteins amino sequence using 1-character codes. For puzzles with "mutable" segments, it applies any updates entered to the protein.

Best for


Code


--[[ AA Edit Get and set primary structure The primary structure of a protein is the sequence of the amino acids that make up the protein. AA Edit displays the current primary structure as a sequence of single-character amino acid codes. The displayed value can be selected and cut or copied. If there are any "mutable" segments, the "Change" button is displayed, and a a new value can be pasted in. If there are no mutable segments, any input to the "AAseq" box is ignored. When the "Change" button is clicked, the currently displayed primary structure is applied to the protein. The input amino acid codes are converted to lower case. The recipe checks each amino acid code against the list of 20 amino acids used in Foldit. Any input not found in the list is ignored, and the corresponding segment is left unchanged. Some puzzles have a mix of mutable and non-mutable segments. The recipe does not attempt to change any non-mutable segments. If the structure list is longer than the protein, AA Edit discards the extra entries at the end of the list. If the structure list is shorter than the protein, AA Edit applies the list to the first *n* segments of the protein, where *n* is the length of the list. Any remaining segments are unchanged. Some puzzles have a terminal ligand represented by a segment which returns "unk" for its amino acid type. This code and anything else not found in the normal list of 20 amino acids is changed to "x" for the purposes of this recipe. Segments with an "x" for their amino acid code in the replacment string are not changed. All changes are written to the scriptlog. See "AA Copy Paste Compare v 1.1.1 -- Brow42" for a full-function recipe that works with primary and primary structures. version 1.2 -- 2016/12/23 -- LociOiling * clone of PS Edit v1.2 * enable 1-step undo with undo.SetUndo ( false ) ]]-- -- -- Globals -- Recipe = "AA Edit" Version = "1.2" ReVersion = Recipe .. " v." .. Version mutable = false -- true if any mutable segments found -- -- amino acid names and abbeviations -- AANames = { w = { "tryptophan", 'TRP', }, g = { "glycine", 'GLY', }, a = { "alanine", 'ALA', }, c = { "cysteine", 'CYS', }, v = { "valine", 'VAL', }, l = { "leucine", 'LEU', }, i = { "isoleucine", 'ILE', }, m = { "methionine", 'MET', }, p = { "proline", 'PRO', }, f = { "phenylalanine", 'PHE', }, y = { "tyrosine", 'TYR', }, r = { "arginine", 'ARG', }, s = { "serine", 'SER', }, t = { "threonine", 'THR', }, n = { "asparagine", 'ASN', }, d = { "aspartate", 'ASP', }, q = { "glutamine", 'GLN', }, e = { "glutamate", 'GLU', }, h = { "histidine", 'HIS', }, k = { "lysine", 'LYS', }, } -- -- end of globals section -- function report_time(start_clock,start_time,clock_msg,time_msg) local seconds,minutes,hours,days if clock_msg==nil then clock_msg="CPU time" end if time_msg==nil then time_msg="Elasped time" end print(string.format("%s",os.date())) days,remainder=math.modf((os.clock()-start_clock)/(24*60*60)) hours,remainder=math.modf(remainder*24) minutes,remainder=math.modf(remainder*60) seconds,remainder=math.modf(remainder*60) print(string.format("%s(%02id:%02ih:%02im:%02is)",clock_msg,days,hours,minutes,seconds)) days,remainder=math.modf(os.difftime(os.time(),start_time)/(24*60*60)) hours,remainder=math.modf(remainder*24) minutes,remainder=math.modf(remainder*60) seconds,remainder=math.modf(remainder*60) print(string.format("%s(%02id:%02ih:%02im:%02is)",time_msg,days,hours,minutes,seconds)) end function getPS ( ) psList = "" for ii = 1, structure.GetCount () do local ps = structure.GetAminoAcid ( ii ) local sName = AANames [ ps ] if sName == nil then ps = "x" end psList = psList .. ps end return psList end function setPS ( oldtab, tab ) local changes = 0 for ii = 1, math.min ( tab:len (), structure.GetCount () ) do local sType = tab:sub ( ii, ii ) local oType = oldtab:sub ( ii, ii ) if sType ~= oType then local sName = AANames [ sType ] if sName ~= nil then if structure.IsMutable ( ii ) then structure.SetAminoAcid ( ii, sType ) changes = changes + 1 else print ( "segment " .. ii .. " is not mutable, skipping change to type \"" .. sType .. "\"" ) end else print ( "segment " .. ii .. ", skipping invalid type \"" .. sType .. "\"" ) end end end return changes end function GetParameters ( tab ) local dlog = dialog.CreateDialog ( ReVersion ) dlog.tab0 = dialog.AddLabel ( "Primary structure" ) dlog.tab = dialog.AddTextbox ( "AASeq", tab ) dlog.u0 = dialog.AddLabel ( "" ) if mutable then dlog.u1 = dialog.AddLabel ( "Usage: use select all and copy, cut, or paste" ) dlog.u2 = dialog.AddLabel ( "to save or change primary structure" ) else dlog.u1 = dialog.AddLabel ( "Usage: use select all and copy" ) dlog.u2 = dialog.AddLabel ( "to save primary structure" ) end dlog.w0 = dialog.AddLabel ( "" ) if mutable then dlog.w1 = dialog.AddLabel ( "Windows: ctrl + a = select all" ) dlog.w2 = dialog.AddLabel ( "Windows: ctrl + x = cut" ) dlog.w3 = dialog.AddLabel ( "Windows: ctrl + c = copy" ) dlog.w4 = dialog.AddLabel ( "Windows: ctrl + v = paste" ) else dlog.w1 = dialog.AddLabel ( "Windows: ctrl + a = select all" ) dlog.w3 = dialog.AddLabel ( "Windows: ctrl + c = copy" ) end dlog.z0 = dialog.AddLabel ( "" ) if mutable then dlog.ok = dialog.AddButton ( "Change" , 1 ) end dlog.exit = dialog.AddButton ( "Exit" , 0 ) if ( dialog.Show ( dlog ) > 0 ) then tab = dlog.tab.value return tab:lower () else return "" end end function main () print ( ReVersion ) print ( "Puzzle: " .. puzzle.GetName () ) print ( "Track: " .. ui.GetTrackName () ) undo.SetUndo ( false ) for ii = 1, structure.GetCount () do if structure.IsMutable ( ii ) == true then mutable = true break end end local changeNum = 0 local psList = "" repeat psList = getPS () print ( "primary structure, change # " .. changeNum ) print ( psList ) local psList2 = GetParameters ( psList ) if psList2:len() > 0 then changeNum = changeNum + 1 local start_clock = os.clock () local start_time = os.time () local filter = behavior.GetFiltersDisabled () behavior.SetFiltersDisabled ( true ) print ( "-------- " .. "start of change " .. changeNum .. " --------" ) local sChg = setPS ( psList, psList2 ) behavior.SetFiltersDisabled ( filter ) report_time ( start_clock, start_time ) print ( sChg .. " segments changed" ) print ( "-------- " .. "end of change " .. changeNum .. " --------" ) end until psList2:len() == 0 cleanup () end function cleanup ( errmsg ) -- -- optionally, do not loop if cleanup causes an error -- (any loop here is automatically terminated after a few iterations, however) -- if CLEANUPENTRY ~= nil then return end CLEANUPENTRY = true print ( "---" ) -- -- model 100 - print recipe name, puzzle, track, time, score, and gain -- local reason local start, stop, line, msg if errmsg == nil then reason = "complete" else -- -- model 120 - civilized errmsg reporting, -- thanks to Bruno K. and Jean-Bob -- start, stop, line, msg = errmsg:find ( ":(%d+):%s()" ) if msg ~= nil then errmsg = errmsg:sub ( msg, #errmsg ) end if errmsg:find ( "Cancelled" ) ~= nil then reason = "cancelled" else reason = "error" end end print ( ReVersion .. " " .. reason ) print ( "Puzzle: " .. puzzle.GetName () ) print ( "Track: " .. ui.GetTrackName () ) if reason == "error" then print ( "Unexpected error detected" ) print ( "Error line: " .. line ) print ( "Error: \"" .. errmsg .. "\"" ) end end xpcall ( main, cleanup )

Comments


LociOiling Lv 1

AA Edit 1.2 displays the primary structure of the protein as a sequence of single-character amino acid codes. The sequence can be copied and pasted using the normal keyboard shortcuts. (For example, on Windows, ctrl-c for copy, and ctrl-v for paste.)

For proteins which contain "mutable" segments, a new sequence can be pasted into the "AASeq" box. When you click the "change" button, the recipe attempts to mutate each segment to the new value entered.

The recipe does not attempt to change non-mutable segments. It does not change any segments where the current amino acid is the same as the new amino acid. It does not change any segments where the new amino acid code is not one of the 20 amino acids recognized by Foldit.

In puzzles with ligands, the ligand may be represented by one or more segments which return amino acid type "unk" instead of one of the normal codes. The recipe changes "unk" to "x" for display purposes. Since "x" is also not one of the recognized Foldit codes, it's ignored when the change is applied.

The "change" button is not displayed for proteins with no mutable segments, and any changes to the AASeq box are ignored in this case.

The general behavior of this recipe is similar to the companion recipe, SS Edit 1.2. If the input sequence is shorter than the length of the protein, the segments at the end of the protein are left unchanged. If the input sequence is longer than the protein, the extra portion of the input is ignored.

A new sequence can be pasted in its entirety by clicking to the left of the first character of the displayed sequence, then typing ctrl-v or the equivalent "paste" shortcut in your environment.

Alternately, you can clear the input field (via ctrl-x or the equivalent) then copy and paste the new sequence on a "blank slate".

The recipe also references the "select all" shortcut (ctrl-a or the equivalent). In general, this does not seem necessary in a Foldit textbox. For example, clicking anywhere the textbox and typing ctrl-c copies the entire contents of the textbox. Clicking anywhere in the textbox and typing ctrl-x clears the entire textbox. Use "select all" if your environment exhibits different behavior. Thanks to Bertro for pointing out the nuances of copy-and-paste in Foldit.

See also print protein 2.4 for a recipe which captures more information about the protein.