Icon representing a recipe

Recipe: Lig Detector 1.0

created by LociOiling

Profile


Name
Lig Detector 1.0
ID
101024
Shared with
Public
Parent
None
Children
Created on
May 19, 2015 at 19:21 PM UTC
Updated on
May 19, 2015 at 19:21 PM UTC
Description

Detects ligands and flags suspicious ligands. In puzzles such as 1088, the last segment sometimes incorrectly appears to be a ligand. The segment's non-zero score may be one clue that this is a bug, not the intended design.

Best for


Code


--[[ Lig Detector -- detect presence of possibly spurious "ligands" Some foldit puzzles include a "ligand", a non-protein attachment. The foldit convention is that ligands are attached as the last segment of the puzzle, with a structure code "M". On a couple of recent puzzles, a puzzle will sometimes have a ligand in the last position, and sometimes not. This seems to be a defect. The problem is that some recipes detect the ligand and avoid working on it. This is an issue when the segment has a large negative score. For example, on puzzle 1088, segment 141 is sometimes marked as a ligand, and has a starting score of -345.6. Skipping this segment is enough to guarantee a poor finish on the puzzle. This recipe is based in part on "print protein lua v0" by marie_s Thanks to spvincent for the structure detection logic. Lig Detector looks for all possible ligand sections, and reports the position and total score of each one found. The recipes flags multiple ligands or a ligand that is not at the end. Even a "normal" ligand puzzle may note be a bug, not a true ligand. Ligands with a non-zero score are suspect. version history --------------- Lig Detector 1.0 - 2015/05/19 - LociOiling ]]-- -- -- globals section -- Recipe = "Lig Detector" Version = "1.0" ReVersion = Recipe .. " " .. Version -- -- indexes for structure list -- STRCTTYP = 1 --structure type STRCTSTR = 2 --starting segment STRCTEND = 3 --ending segment STRCTSCR = 4 --total score -- -- end of globals section -- local function round ( x ) if x == nil then return "nil" end return x - x % 0.001 end -- -- LigDetector: ultra-paranoid method for detecting ligands -- function LigDetector () local segCnt = structure.GetCount() local ligandList = GetStruct ( "M" ) print ( #ligandList .. " ligands" ) if #ligandList > 0 then if #ligandList == 1 then if ligandList [ 1 ] [ STRCTSTR ] == segCnt and ligandList [ 1 ] [ STRCTEND ] == segCnt then print ( "normal ligand puzzle, segment " .. segCnt .. " represents ligand, score = " .. round ( ligandList [ 1 ] [ STRCTSCR ] ) ) if ligandList [ 1 ] [ STRCTSCR ] ~= 0 then print ( "Caution! Non-zero score may indicate spurious ligand." ) end elseif ligandList [ 1 ] [ STRCTEND ] == segCnt then print ( "normal ligand puzzle, segments " .. ligandList [ 1 ] [ STRCTSTR ] .. "-" .. ligandList [ 1 ] [ STRCTEND ] .. " represent ligand, score = " .. round ( ligandList [ 1 ] [ STRCTSCR ] ) ) if ligandList [ 1 ] [ STRCTSCR ] ~= 0 then print ( "Caution! Non-zero score may indicate spurious ligand." ) end else print ( "non-standard ligand puzzle, ligand section not at end" ) print ( "most ligand-aware recipes will not work correctly" ) print ( "ligand # 1, start = " .. ligandList [ 1 ] [ STRCTSTR ] .. ", end = " .. ligandList [ 1 ] [ STRCTEND ] .. ", score = " .. round ( ligandList [ 1 ] [ STRCTSCR ] ) ) end else print ( "non-standard ligand puzzle, " .. #ligandList .. " ligand sections" ) print ( "most ligand-aware recipes will not work correctly" ) for jj = 1, #ligandList do print ( "ligand # " .. jj .. ", start = " .. ligandList [ jj ] [ STRCTSTR ] .. ", end = " .. ligandList [ jj ] [ STRCTEND ] .. ", score = " .. round ( ligandList [ jj ] [ STRCTSCR ] ) ) end end end return ligandList end -- -- GetStruct -- return a list of structures of a specified type -- -- adapted from spvincent's Helix Rebuild -- function GetStruct ( structT ) local within_struct = false local structList = {} local structStart = 0 local structLast = 0 local structScore = 0 local segCnt = structure.GetCount() -- do our own count, lets us check for ligands for ii = 1, segCnt do if ( structure.GetSecondaryStructure ( ii ) == structT ) then if ( within_struct == false ) then -- start of a new struct within_struct = true structStart = ii structScore = 0 end structLast = ii structScore = structScore + current.GetSegmentEnergyScore ( ii ) elseif ( within_struct == true ) then -- end of a struct within_struct = false structList [ #structList + 1 ] = { structT, structStart, structLast, structScore } end end if ( within_struct == true ) then structList [ #structList + 1 ] = { structT, structStart, structLast, structScore } end return structList end function ShowReport ( ligandList ) local ask = dialog.CreateDialog ( ReVersion ) if #ligandList == 0 then ask.l10 = dialog.AddLabel ( "No ligands detected" ) else local segCnt = structure.GetCount() ask.l05 = dialog.AddLabel ( segCnt .. " segments" ) ask.l10 = dialog.AddLabel ( #ligandList .. " ligand sections found" ) local asterisk = " " local marked = false local suspect = false for jj = 1, #ligandList do if ligandList [ jj ] [ STRCTEND ] ~= segCnt then asterisk = "*" marked = true elseif ligandList [ jj ] [ STRCTSCR ] ~= 0 then asterisk = "!" suspect = true end ask [ "lig" .. jj ] = dialog.AddLabel ( "ligand # " .. jj .. ", start = " .. ligandList [ jj ] [ STRCTSTR ] .. ", end = " .. ligandList [ jj ] [ STRCTEND ] .. ", score = " .. round ( ligandList [ jj ] [ STRCTSCR ] ) .. " " .. asterisk ) asterisk = " " end if marked then ask.l50 = dialog.AddLabel ( "* non-standard ligand, breaks many recipes" ) end if suspect then ask.l60 = dialog.AddLabel ( "! ligand with non-zero score, may be bug" ) end end ask.OK = dialog.AddButton ( "OK", 1 ) dialog.Show ( ask ) end function main () print ( ReVersion ) print ( "Puzzle: " .. puzzle.GetName () ) print ( "Track: " .. ui.GetTrackName () ) -- -- search for ligand -- local ligs = LigDetector () ShowReport ( ligs ) -- -- exit via the cleanup function -- cleanup () end function cleanup ( error ) print ( "---" ) -- -- model 100 - print recipe name, puzzle, track, time, score, and gain -- local reason local start, stop, line, msg if error == nil then reason = "complete" else -- -- model 120 - civilized error reporting, -- thanks to Bruno K. and Jean-Bob -- start, stop, line, msg = error:find ( ":(%d+):%s()" ) if msg ~= nil then error = error:sub ( msg, #error ) end if error: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: \"" .. error .. "\"" ) end end xpcall ( main, cleanup ) --- end of recipe

Comments


LociOiling Lv 1

On puzzle 1088, and previously on puzzle 1073, some clients show the last segment as a ligand…but some clients don't. This is apparently a bug. In puzzle 1088, one clue is that the "ligand" segment has a non-zero score.

Lig Detector identifies all possible ligands in a puzzle. The convention has been that a ligand appears as the last segment or segments of a puzzle, and has a structure code "M". Lig Detector finds all sections with structure code "M", and reports them in a dialog box and the scriptlog. Multiple ligands, ligands not at the end of the protein, and ligands with non-zero scores are noted as being suspect.

See http://fold.it/portal/node/2000613

LociOiling Lv 1

Another way to find a ligand to use the "EnzDes" coloring under view options. Segments marked as a ligand will show in white.

When you select the "ligand", you find that you won't be able to change its secondary structure, for example to helix. In a design puzzle, however, you'll probably be able to mutate the "ligand".

LociOiling Lv 1

Just observed a new wrinkle on puzzle 1091. Initially, the puzzle showed no ligands with "EnzDes" coloring. Then after "select all" and "auto structures", segment 139 turned white, and the Lig Detector recipe shows it as a ligand.

In this case, "undo" was enough to un-ligandize segment 139.