Icon representing a recipe

Recipe: print protein 2.0

created by LociOiling

Profile


Name
print protein 2.0
ID
101034
Shared with
Public
Parent
print protein lua2 V0
Children
Created on
May 26, 2015 at 19:38 PM UTC
Updated on
May 26, 2015 at 19:38 PM UTC
Description

Updated version of "print protein lua2 V0" by marie_s.

Best for


Code


--[[ print protein info on the protein - Concatenation of recipes, part of recipes or functions by: Tlaloc, spvincent, seagate, John McLeod, Crashguard303, Gary Forbis and authors on wiki Now with code from Timo van der Laan and and more code from spvincent. Borrowed HerobrinesArmy's idea for copy-and-paste on the segment score table, plus option for including atom and rotamer counts. Intended use: 1. Run 2. Open the script log (scriptlog.default.xml) in a text editor. 3. Strip off the start and end lines and save it as a text file with another name. 4. Import that into Excel as a comma-delimited text file. Alternately: 3. Select and copy the lines containing the score detail. 4. Paste into a spreadsheet or other program that accepts CSV (comma-separated values) format. Yet another alternative: 3. Select and copy the "score report" from the new "copy-and-paste" dialog. 4. Paste into the spreadsheet of your choice. version history --------------- print protein lua v0 - 2011/08/15 - marie_s (Marie Suchard) print protein 2.0 - 2015/05/13 - LociOiling + add dialog + use active subscores + restrict scope of most variables + convert amino acid table to keyed format + added kludges specific to puzzle 879 (hope they are never needed) + add adjustable rounding, eliminate existing "no trunc" logic + made tab the default delimiter, with comma or semicolon as alternates + add detailed scoring information + add "modifiable sections" report, make original "mutable" report optional + make "mini contact table" optional + in subscores report, add option for atom and rotamer counts, make hydropathy index optional + add warnings for unknown amino acid or secondary structure codes, subtotal mismatches, suspect ligands + and copy-and-paste dialog for subscores, primary and secondary structure ]]-- -- -- globals section -- Recipe = "print protein" Version = "2.0" ReVersion = Recipe .. " " .. Version segCnt = structure.GetCount() segCnt2 = segCnt isLigand = false subScores = {} -- subscore table gTotal = 0 -- grand total all subscores BoxScore = { tSubScores = 0, -- total of active subscores, all segments tSegScores = 0, -- total of segment scores tScoreFilt = 0, -- total score, filters on tScoreFOff = 0, -- total score, filters off tScoreNrgy = 0, -- total energy score tScoreBonus = 0, -- total filter bonus tScoreForm = 0, -- subscores + filter bonus + 8000 tScoreDark = 0, -- total "dark" score } kHydro = false -- include hydropathy index kAtom = false -- include atom count kRotamer = false -- include rotamer count kRound = 3 -- number of digits for rounding kFax = 10 ^ -kRound -- initial rounding factor dtab = true delim = "\t" -- default delimiter is tab character dcomma = false -- allow user to select comma dsemic = false -- allow user to select semicolon kMutDet = false -- detailed mutable report kContact = false -- contact table -- -- indexes for helixList, sheetList, structList -- STRCTTYP = 1 --structure type STRCTSTR = 2 --starting segment STRCTEND = 3 --ending segment STRCTUSE = 4 --use flag (boolean) STRCTSCR = 5 --score -- -- end of globals section -- -- -- function print score by spvincent -- function round ( x ) if x == nil then return "nil" end return x - x % kFax end -- -- Segment set and list module -- Notice that most functions assume that the sets are well formed -- (=ordered and no overlaps) -- 02-05-2012 TvdL Free to use for non commercial purposes -- function SegmentListToSet ( list ) -- retirer doublons local result = {} local f = 0 local l = -1 table.sort ( list ) for ii = 1, #list do if list [ ii ] ~= l + 1 and list [ ii ] ~= l then -- note: duplicates are removed if l > 0 then result [ #result + 1 ] = { f, l } end f = list [ ii ] end l = list [ ii ] end if l > 0 then result [ #result + 1 ] = { f, l } end return result end function SegmentSetToList ( set ) -- faire une liste a partir d'une zone local result = {} for ii = 1, #set do for k = set [ ii ] [ 1 ], set [ ii ] [ 2 ] do result [ #result + 1 ] = k end end return result end function SegmentCleanSet ( set ) -- Makes it well formed return SegmentListToSet ( SegmentSetToList ( set ) ) end function SegmentInvertSet ( set, maxseg ) -- Gives back all segments not in the set -- maxseg is added for ligand local result={} if maxseg == nil then maxseg = structure.GetCount () end if #set == 0 then return { { 1, maxseg } } end if set [ 1 ] [ 1 ] ~= 1 then result [ 1 ] = { 1, set [ 1 ] [ 1 ] - 1 } end for i = 2, #set do result [ #result + 1 ] = { set [ i - 1 ] [ 2 ] + 1, set [ i ] [ 1 ] - 1} end if set [ #set ] [ 2 ] ~= maxseg then result [ #result + 1 ] = { set [ #set ] [ 2 ] + 1, maxseg } end return result end function SegmentInList ( s, list ) -- verifier si segment est dans la liste table.sort ( list ) for ii = 1, #list do if list [ ii ] == s then return true elseif list [ ii ] > s then return false end end return false end function SegmentInSet ( set, s ) --verifie si segment est dans la zone for ii = 1, #set do if s >= set [ ii ] [ 1 ] and s <= set [ ii ] [ 2 ] then return true elseif s < set [ ii ] [ 1 ] then return false end end return false end function SegmentJoinList ( list1, list2 ) -- fusionner 2 listes de segments local result = list1 if result == nil then return list2 end for ii = 1, #list2 do result [ #result + 1 ] = list2 [ ii ] end table.sort ( result ) return result end function SegmentJoinSet ( set1, set2 ) --fusionner (ajouter) 2 zones return SegmentListToSet ( SegmentJoinList ( SegmentSetToList ( set1 ), SegmentSetToList ( set2 ) ) ) end function SegmentCommList ( list1, list2 ) -- chercher intersection de 2 listes local result = {} table.sort ( list1 ) table.sort ( list2 ) if #list2 == 0 then return result end local j = 1 for ii = 1, #list1 do while list2 [ j ] < list1 [ ii ] do j = j + 1 if j > #list2 then return result end end if list1 [ ii ] == list2 [ j ] then result [ #result + 1 ] = list1 [ ii ] end end return result end function SegmentCommSet ( set1, set2 ) -- intersection de 2 zones return SegmentListToSet ( SegmentCommList ( SegmentSetToList ( set1 ), SegmentSetToList ( set2 ) ) ) end function SegmentSetMinus ( set1, set2 ) return SegmentCommSet ( set1, SegmentInvertSet ( set2 ) ) end function SegmentPrintSet ( set ) print ( SegmentSetToString ( set ) ) end function SegmentSetToString ( set ) -- pour pouvoir imprimer local line = "" for ii = 1, #set do if ii ~= 1 then line = line .. ", " end line = line .. set [ ii ] [ 1 ] .. "-" .. set [ ii ] [ 2 ] end return line end function SegmentSetInSet ( set, sub ) if sub == nil then return true end -- Checks if sub is a proper subset of set for ii = 1, #sub do if not SegmentRangeInSet ( set, sub [ ii ] ) then return false end end return true end function SegmentRangeInSet ( set, range ) --verifier si zone est dans suite if range == nil or #range == 0 then return true end local bb = range [ 1 ] local ee = range [ 2 ] for ii = 1, #set do if bb >= set [ ii ] [ 1 ] and bb <= set [ ii ] [ 2 ] then return ( ee <= set [ ii ] [ 2 ] ) elseif ee <= set [ ii ] [ 1 ] then return false end end return false end function SegmentSetToBool ( set ) --vrai ou faux pour chaque segment utilisable ou non local result = {} for ii = 1, structure.GetCount () do result [ ii ] = SegmentInSet ( set, ii ) end return result end --- End of Segment Set module -- Module Find Segment Types function FindMutablesList () local result = {} for ii = 1, segCnt2 do if structure.IsMutable ( ii ) then result [ #result + 1 ] = ii end end return result end function FindMutables() return SegmentListToSet ( FindMutablesList () ) end function FindFrozenList () local result = {} for ii = 1, segCnt2 do if freeze.IsFrozen ( ii ) then result [ #result + 1 ] = ii end end return result end function FindFrozen () return SegmentListToSet ( FindFrozenList () ) end function FindLockedList () local result = {} for ii = 1, segCnt2 do if structure.IsLocked ( ii ) then result [ #result + 1 ] = ii end end return result end function FindLocked () return SegmentListToSet ( FindLockedList () ) end function FindZeroScoreList () local result = {} for ii = 1, segCnt do local sub = 0 for jj = 1, #subScores do sub = sub + current.GetSegmentEnergySubscore ( ii, subScores [ jj ] [ 1 ] ) end if sub == 0 then result [ #result + 1 ] = ii end end return result end function FindZeroScore () return SegmentListToSet ( FindZeroScoreList () ) end function FindSelectedList () local result = {} for ii = 1, segCnt do if selection.IsSelected ( ii ) then result [ #result + 1 ] = ii end end return result end function FindSelected() return SegmentListToSet ( FindSelectedList () ) end function FindAAtypeList ( aa ) local result = {} for ii = 1, segCnt2 do if structure.GetSecondaryStructure ( ii ) == aa then result [ #result + 1 ] = ii end end return result end function FindAAtype ( aa ) return SegmentListToSet ( FindAAtypeList ( aa ) ) end function FindAminotype ( at ) --NOTE: only this one gives a list not a set local result={} for ii = 1, segCnt2 do if structure.GetAminoAcid ( ii ) == at then result [ #result + 1 ] = ii end end return result end -- -- end Module Find Segment Types -- -- -- count segments, check for ligand -- function GetSeCount () segCnt = structure.GetCount() -- -- ultra-paranoid method for detecting ligands -- 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, segment " .. segCnt .. ", score = " .. round ( ligandList [ 1 ] [ STRCTSCR ] ) ) segCnt2 = segCnt - 1 if ligandList [ 1 ] [ STRUCTSCR ] ~= 0 then print ( "WARNING: normal ligand with non-zero score" ) end elseif ligandList [ 1 ] [ STRCTEND ] == segCnt then print ( "normal ligand, segments " .. ligandList [ 1 ] [ STRCTSTR ] .. "-" .. ligandList [ 1 ] [ STRCTEND ] .. ", score = " .. round ( ligandList [ jj ] [ STRCTSCR ] ) ) if ligandList [ 1 ] [ STRUCTSCR ] ~= 0 then print ( "WARNING: suspect multi-segment ligand with non-zero score, segment count not adjusted" ) else segCnt2 = ligandList [ 1 ] [ STRCTSTR ] - 1 end else print ( "WARNING: non-standard ligand, ligand not at end" ) print ( "most ligand-aware recipes will not work correctly" ) print ( "ligand # 1, start = " .. ligandList [ jj ] [ STRCTSTR ] .. ", end = " .. ligandList [ jj ] [ STRCTEND ] .. ", score = " .. round ( ligandList [ jj ] [ STRCTSCR ] ) ) print ( "WARNING: suspect ligand, segment count not adjusted" ) end else print ( "WARNING: non-standard ligands, " .. #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 print ( "WARNING: suspect ligands, segment count not adjusted" ) end end if segCnt2 == segCnt then print ( "segment count = " .. segCnt ) else print ( "original segment count = " .. segCnt ) print ( "adjusted segment count = " .. segCnt2 ) end return ligandList end -- -- build segments table, without any ligand segments -- function tablesegment () -- -- indexes for amino acid table -- AASHORT = 1 -- three-letter code AALONG = 2 -- full name AAPOLARITY = 3 -- polarity (text) AAACIDITY = 4 -- acidity (text) AAHYDROPATHY = 5 -- hydropathy index -- -- residues with -- in front (commented) are not in Foldit (as of Nov 15, 2010) -- one-letter amino acid code is the table key -- local AminoAcids = { a = { "Ala", "Alanine", "nonpolar", "neutral", 1.8 }, -- b = { "Asx", "Asparagine or Aspartic acid" }, c = { "Cys", "Cysteine", "nonpolar", "neutral", 2.5 }, d = { "Asp", "Aspartate", "polar", "negative", -3.5 }, e = { "Glu", "Glutamate", "polar", "negative", -3.5 }, f = { "Phe", "Phenylalanine", "nonpolar", "neutral", 2.8 }, g = { "Gly", "Glycine", "nonpolar", "neutral", -0.4 }, h = { "His", "Histidine", "polar", "neutral", -3.2 }, i = { "Ile", "Isoleucine", "nonpolar", "neutral", 4.5 }, -- j = { "Xle", "Leucine or Isoleucine" }, k = { "Lys", "Lysine", "polar", "positive", -3.9 }, l = { "Leu", "Leucine", "nonpolar", "neutral", 3.8 }, m = { "Met", "Methionine ", "nonpolar", "neutral", 1.9 }, n = { "Asn", "Asparagine", "polar", "neutral", -3.5 }, -- o = { "Pyl", "Pyrrolysine" }, p = { "Pro", "Proline", "nonpolar", "neutral", -1.6 }, q = { "Gln", "Glutamine", "polar", "neutral", -3.5 }, r = { "Arg", "Arginine", "polar", "positive", -4.5 }, s = { "Ser", "Serine", "polar", "neutral", -0.8 }, t = { "Thr", "Threonine", "polar", "neutral", -0.7 }, -- u = { "Sec", "Selenocysteine" }, v = { "Val", "Valine", "nonpolar", "neutral", 4.2 }, w = { "Trp", "Tryptophan", "nonpolar", "neutral", -0.9 }, x = { "Xaa", "Unspecified/unknown", "", "", 0 }, -- kludge for puzzle 879 y = { "Tyr", "Tyrosine", "polar", "neutral", -1.3 }, -- z = { "Glx", "Glutamine or glutamic acid" } , } local table = { {} } for ii = 1, segCnt2 do table [ ii ] = {} local aac = structure.GetAminoAcid ( ii ) if AminoAcids [ aac ] == nil then -- bizarro kludge code "unk" used -- for segment 134, puzzle 879 print ( "WARNING: unknown amino acid \'" .. aac .. "\' at segment " .. ii .. ", code \'x\' substituted" ) aac = "x" end table [ ii ] [ 1 ] = aac table [ ii ] [ 2 ] = AminoAcids [ aac ] [ AASHORT ] table [ ii ] [ 3 ] = AminoAcids [ aac ] [ AALONG ] table [ ii ] [ 4 ] = AminoAcids [ aac ] [ AAHYDROPATHY ] table [ ii ] [ 5 ] = structure.GetSecondaryStructure ( ii ) if table [ ii ] [ 5 ] ~= "H" and table [ ii ] [ 5 ] ~= "E" and table [ ii ] [ 5 ] ~= "L" and table [ ii ] [ 5 ] ~= "M" then print ( "WARNING: unknown secondary structure code \'" .. table [ ii ] [ 5 ] .. "\' at segment " .. ii ) end end return table end -- -- tlaloc functions to print sequence of letter -- function BuildSequence ( table ) local seqstring = "" local hydrostring = "" local strucstring = "" for ii = 1, segCnt2 do seqstring = seqstring .. table [ ii ] [ 1 ] if structure.IsHydrophobic ( ii ) then hydrostring = hydrostring .. "i" else hydrostring = hydrostring .. "e" end strucstring = strucstring .. table [ ii ] [ 5 ] end print ( "sequence with single-letter amino acid codes for searching PDB" ) print ( seqstring ) print ( "sequence with i if hydrophobic" ) print ( hydrostring ) print ( "sequence of structure" ) print ( strucstring ) return seqstring, hydrostring, strucstring end -- -- find modifiable sections -- function FindModifiable () -- local flocked = FindLocked () --print ( #flocked .. " locked sections" ) for kk = 1, #flocked do print ( "locked section " .. kk .. ": " .. flocked [ kk ] [ 1 ] .. "-" .. flocked [ kk ] [ 2 ] ) end -- local funlocked = SegmentInvertSet ( flocked ) --print ( #funlocked .. " unlocked sections" ) for kk = 1, #funlocked do print ( "unlocked section " .. kk .. ": " .. funlocked [ kk ] [ 1 ] .. "-" .. funlocked [ kk ] [ 2 ] ) end -- local zeroScore = FindZeroScore () --print ( #zeroScore .. " zero score sections" ) for kk = 1, #zeroScore do print ( "zero score section " .. kk .. ": " .. zeroScore [ kk ] [ 1 ] .. "-" .. zeroScore [ kk ] [ 2 ] ) end -- if #flocked == 1 and #zeroScore > 0 then local LockedNZ = SegmentInvertSet ( zeroScore, flocked [ 1 ] [ 2 ] ) for kk = 1, #LockedNZ do print ( "locked, non-zero score section " .. kk .. ": " .. LockedNZ [ kk ] [ 1 ] .. "-" .. LockedNZ [ kk ] [ 2 ] ) end if flocked [ 1 ] [ 1 ] == 1 then segStart = math.min ( flocked [ 1 ] [ 2 ] + 1, segCnt2 ) end end -- local mutables = FindMutables () --print ( #mutables .. " mutable sections" ) for kk = 1, #mutables do print ( "mutable section " .. kk .. ": " .. mutables [ kk ] [ 1 ] .. "-" .. mutables [ kk ] [ 2 ] ) end -- local lockmut = SegmentCommSet ( flocked, mutables ) --print ( #lockmut .. " locked, mutable sections" ) for kk = 1, #lockmut do print ( "locked, mutable section " .. kk .. ": " .. lockmut [ kk ] [ 1 ] .. "-" .. lockmut [ kk ] [ 2 ] ) end end -- -- find mutable segments -- function FindMutable ( table ) local mutable = {} local mutablestring = '' for ii = 1, segCnt2 do if structure.IsMutable ( ii ) == true then mutable [ #mutable + 1 ] = ii end end print ( #mutable .. " mutables found" ) if #mutable > 0 then print ( "n" .. delim .. "segment" .. delim .. "aacode" .. delim .. "aaname" ) end for ii = 1, #mutable do print ( ii .. delim .. mutable[ii] .. delim .. table [ mutable [ ii ] ] [ 1 ] .. delim .. table [ mutable [ ii ] ] [ 3 ] ) mutablestring = mutablestring .. "'" .. table [ mutable [ ii ] ] [ 1 ] .. "'," end print ( mutablestring ) --- for copy paste on other recipe return mutable end -- -- function FindActiveSubscores adapted from EDRW by Timo van der Laan -- function FindActiveSubscores ( show ) local result = {} local gTotal = 0 -- grand total all subscores local gTotalS = 0 -- grand total all segment subscores local Subs = puzzle.GetPuzzleSubscoreNames () for ii = 1, #Subs do local total = 0 local abstotal = 0 local part for jj = 1, segCnt2 do part = current.GetSegmentEnergySubscore ( jj, Subs [ ii ] ) total = total + part abstotal = abstotal + math.abs ( part ) end if abstotal > 10 then result [ #result + 1 ] = { Subs [ ii ], total } gTotal = gTotal + total if show then print ( "active subscore " .. #result .. ": " .. Subs [ ii ] .. ", total = " .. round ( total ) ) end end end for ii = 1, segCnt2 do gTotalS = gTotalS + current.GetSegmentEnergyScore ( ii ) end if show then print ( #result .. " active subscores" ) end if show then print ( "total of all subscores: " .. round ( gTotal ) ) end if show then print ( "total of all segment scores: " .. round ( gTotalS ) ) end if ( round ( gTotal ) ~= round ( gTotalS ) ) then print ( "WARNING: total subscores " .. round ( gTotal ) .. " not equal total segment scores " .. round ( gTotalS ) ) end return result, gTotal, gTotalS end -- -- print segment scores in spreadsheet format -- function SegScores ( table, subScores ) local tReport = "" local headStr = "n" .. delim .. "ID" .. delim .. "SS" .. delim if kHydro then headStr = headStr .. "Hyd" .. delim end if kAtom then headStr = headStr .. "atoms" .. delim end if kRotamer then headStr = headStr .. "rotamers" .. delim end headStr = headStr .. "score" .. delim for ii = 1, #subScores do headStr = headStr .. subScores [ ii ] [ 1 ] .. delim end print ( "--" ) print ( "\"segment scores\"" ) print ( headStr ) tReport = tReport .. "\"segment scores\"\n" .. headStr .. "\n" local tSegEnergy = 0 for ii = 1, segCnt2 do local segEnergy = current.GetSegmentEnergyScore ( ii ) tSegEnergy = tSegEnergy + segEnergy local segScore = ii .. delim .. table [ ii ] [ 1 ] .. delim .. table [ ii ] [ 5 ] .. delim if kHydro then segScore = segScore .. round ( table [ ii ] [ 4 ] ) .. delim end if kAtom then segScore = segScore .. structure.GetAtomCount ( ii ) .. delim end if kRotamer then segScore = segScore .. rotamer.GetCount ( ii ) .. delim end segScore = segScore .. round ( segEnergy ) .. delim for jj = 1, #subScores do segScore = segScore .. round ( current.GetSegmentEnergySubscore ( ii, subScores [ jj ] [ 1 ] ) ) .. delim end print ( segScore ) tReport = tReport .. segScore .. "\n" end local footstr = "totals" .. delim .. "" .. delim .. "" .. delim if kHydro then footstr = footstr .. delim -- no totals for hydropathy end if kAtom then footstr = footstr .. delim -- no totals for atoms end if kRotamer then footstr = footstr .. delim -- no totals for rotamers end footstr = footstr .. round ( tSegEnergy ) .. delim for ii = 1, #subScores do footstr = footstr .. round ( subScores [ ii ] [ 2 ] ) .. delim end print ( footstr ) tReport = tReport .. footstr .. "\n" return tReport 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 structScr = 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 structScr = 0 end structLast = ii structScr = structScr + current.GetSegmentEnergyScore ( ii ) elseif ( within_struct == true ) then -- end of a struct within_struct = false structList [ #structList + 1 ] = { structT, structStart, structLast, false, structScr } end end if ( within_struct == true ) then structList [ #structList + 1 ] = { structT, structStart, structLast, false, structScr } end return structList end -- -- function to print a little contact table -- function contact ( structs ) local head = delim .. delim local first = true for s = 1, #structs do if structs [ s ] [ STRCTTYP ] == "H" or structs [ s ] [ STRCTTYP ] == "E" then local string = structs [ s ] [ STRCTTYP ] .. delim .. structs [ s ] [ STRCTSTR ] .. delim .. structs [ s ] [ STRCTEND ] for s2 = 1, #structs do if structs [ s2 ] [ STRCTTYP ] == "H" or structs [ s2 ] [ STRCTTYP ] == "E" then if first then head = head .. delim .. structs [ s2 ] [ STRCTTYP ] end local mean = 0 local nb = 0 for i = structs [ s ] [ STRCTSTR ], structs [ s ] [ STRCTEND ] do local min = 999999 for j = structs [ s2 ] [ STRCTSTR ], structs [ s2 ] [ STRCTEND ] do dist = structure.GetDistance ( i, j ) if dist < min then min = dist end end mean = mean + min nb = nb + 1 end mean = mean / nb local c = " " if structure.GetDistance ( structs [ s ] [ STRCTSTR ], structs [ s2 ] [ STRCTEND ] ) < structure.GetDistance ( structs [ s ] [ STRCTSTR ], structs [ s2 ] [ STRCTSTR ] ) then if mean < 5 then c = 'X' elseif mean < 10 then c = 'x' end else if mean < 5 then c = 'O' elseif mean < 10 then c = 'o' end end string = string .. delim .. c end end if first then print ( "--" ) print ( "\"mini contact table\"" ) print ( head ) first = false end print ( string ) end end end function ShowReport ( tReport, seq, struc ) local ask = dialog.CreateDialog ( ReVersion .. " copy-and-paste" ) ask.l15 = dialog.AddLabel ( "Click inside the one of the text boxes, then" ) ask.l16 = dialog.AddLabel ( "use ctrl+a (command+a on Mac) to select all," ) ask.l20 = dialog.AddLabel ( "and control+c or command+c to copy, then" ) ask.l30 = dialog.AddLabel ( "paste into spreadsheet" ) ask.l10 = dialog.AddLabel ( "---- segment subscores report ----" ) ask.rep = dialog.AddTextbox ( "subscores:", tReport ) ask.SEQN = dialog.AddLabel ( "---- primary (sequence) and secondary structure detail ----" ) ask.seq = dialog.AddTextbox ( "AA sequence:", seq ) ask.struc = dialog.AddTextbox ( "secondary:", struc ) ask.OK = dialog.AddButton ( "OK", 1 ) dialog.Show ( ask ) end function GetParms ( scrParts, ligands ) local selParts = {} local ask = dialog.CreateDialog ( ReVersion ) if segcnt == segcnt2 then ask.segcnt = dialog.AddLabel ( segCnt2 .. " segments" ) else ask.segcnt = dialog.AddLabel ( segCnt .. " segments" ) ask.segcnt2 = dialog.AddLabel ( segCnt2 .. " segments, adjusted for ligands" ) end if #ligands > 0 then ask.ligands = dialog.AddLabel ( #ligands .. " ligand section(s), see scriptlog for details" ) end ask.NRGE = dialog.AddLabel ( "---- score information ----" ) --[[ BoxScore = { tSubScores = 0, -- total of active subscores, all segments tSegScores = 0, -- total of segment scores tScoreFilt = 0, -- total score, filters on tScoreFOff = 0, -- total score, filters off tScoreNrgy = 0, -- total energy score tScoreBonus = 0, -- total filter bonus tScoreForm = 0, -- subscores + filter bonus + 8000 tScoreDark = 0, -- total "dark" score } ]]-- ask.active = dialog.AddLabel ( #scrParts .. " active subscores" ) ask.tSubScores = dialog.AddLabel ( "total of all subscores = " .. round ( BoxScore.tSubScores ) ) ask.tScoreFilt = dialog.AddLabel ( "current score = " .. round ( BoxScore.tScoreFilt ) ) if BoxScore.tScoreBonus ~= 0 then ask.tScoreBonus = dialog.AddLabel ( "filter bonus = " .. round ( BoxScore.tScoreBonus ) ) else ask.tScoreBonus = dialog.AddLabel ( "no filter bonus" ) end ask.tScoreForm = dialog.AddLabel ( "subscores + filter bonus + 8000 = " .. round ( BoxScore.tScoreForm ) ) ask.tScoreDark = dialog.AddLabel ( "\"dark\" points = " .. round ( BoxScore.tScoreDark ) ) ask.DETAIL = dialog.AddLabel ( "---- subscore reporting options ----" ) for ii = 1,#scrParts do ask [ scrParts [ ii ] [ 1 ] ] = dialog.AddCheckbox ( scrParts [ ii ] [ 1 ] .. ": " .. round ( scrParts [ ii ] [ 2 ] ), true ) end ask.kHydro = dialog.AddCheckbox ( "hydropathy index", kHydro ) ask.kAtom = dialog.AddCheckbox ( "atom count", kAtom ) ask.kRotamer = dialog.AddCheckbox ( "rotamer count", kRotamer ) ask.kRound = dialog.AddSlider ( "decimal places:", kRound, 1, 8, 0 ) ask.ddlm = dialog.AddLabel ( "delimiters (last selected wins)" ) ask.dtab = dialog.AddCheckbox ( "tab", dtab ) ask.dcomma = dialog.AddCheckbox ( "comma", dcomma ) ask.dsemic = dialog.AddCheckbox ( "semicolon", dsemic ) ask.SECT = dialog.AddLabel ( "---- report sections ----" ) ask.kContact = dialog.AddCheckbox ( "mini contact table", kContact ) ask.kMutDet = dialog.AddCheckbox ( "mutable details", kMutDet ) ask.OK = dialog.AddButton ( "OK", 1 ) ask.Cancel = dialog.AddButton ( "Cancel", 0 ) local kRet = dialog.Show ( ask ) if kRet > 0 then for ii = 1, #scrParts do if ask [ scrParts [ ii ] [ 1 ] ].value then selParts [ #selParts + 1 ] = scrParts [ ii ] end end -- -- select all if nothing selected -- if #selParts == 0 then for ii = 1, #scrParts do selParts [ #selParts + 1 ] = scrParts [ ii ] end end kHydro = ask.kHydro.value kAtom = ask.kAtom.value kRotamer = ask.kRotamer.value kRound = ask.kRound.value kFax = 10 ^ -kRound dtab = ask.dtab.value if dtab then delim = "\t" end dcomma = ask.dcomma.value if dcomma then delim = "," end dsemic = ask.dsemic.value if dsemic then delim = ";" end kContact = ask.kContact.value kMutDet = ask.kMutDet.value return true, selParts end return false, scrParts end function main () print ( "--" ) print ( ReVersion ) print ( "Puzzle: " .. puzzle.GetName () ) print ( "Track: " .. ui.GetTrackName () ) -- -- count segments and search for ligand -- local ligands = GetSeCount () -- -- determine which subscores are active -- print ( "--" ) print ( "score information" ) --[[ BoxScore = { tSubScores = 0, -- total of active subscores, all segments tSegScores = 0, -- total of segment scores tScoreFilt = 0, -- total score, filters on tScoreFOff = 0, -- total score, filters off tScoreNrgy = 0, -- total energy score tScoreBonus = 0, -- total filter bonus tScoreForm = 0, -- subscores + filter bonus + 8000 tScoreDark = 0, -- total "dark" score } ]]-- subScores, BoxScore.tSubScores, BoxScore.tSegScores = FindActiveSubscores ( true ) behavior.SetFiltersDisabled ( false ) BoxScore.tScoreFilt = current.GetEnergyScore () behavior.SetFiltersDisabled ( true ) BoxScore.tScoreFOff = current.GetEnergyScore () BoxScore.tScoreBonus = BoxScore.tScoreFilt - BoxScore.tScoreFOff if fBonus ~= 0 then print ( "current filter bonus = " .. round ( BoxScore.tScoreBonus ) ) end behavior.SetFiltersDisabled ( false ) BoxScore.tScoreForm = BoxScore.tSubScores + BoxScore.tScoreBonus + 8000 print ( "subscores + filter bonus + 8000 = " .. round ( BoxScore.tScoreForm ) ) BoxScore.tScoreDark = BoxScore.tScoreFilt - BoxScore.tScoreForm print ( "current score = " .. round ( BoxScore.tScoreFilt ) ) print ( "\"dark\" points = " .. round ( BoxScore.tScoreDark ) ) print ( "--" ) print ( "sequence information" ) -- -- build table of non-ligand segments -- local segTable = tablesegment () -- -- sequence of letters, hydrophobes, structures -- local seq, hydro, struc = BuildSequence ( segTable ) -- -- find modifiable sections -- print ( "--" ) print ( "modifiable sections" ) FindModifiable () -- -- get details for subscore report -- local go, selScores = GetParms ( subScores, ligands ) if go then -- -- print segment scores -- local tReport = SegScores ( segTable, selScores ) -- -- detect structures -- local helixList = GetStruct ( "H" ) local sheetList = GetStruct ( "E" ) local structList = {} for ii = 1, #helixList do structList [ #structList + 1 ] = helixList [ ii ] end for ii = 1, #sheetList do structList [ #structList + 1 ] = sheetList [ ii ] end if kContact then -- -- mini contact table -- contact ( structList ) end -- -- find mutable segments and print them -- if kMutDet then print ( "--" ) print ( "mutable segments" ) FindMutable ( segTable ) end -- -- show report for copy and paste -- ShowReport ( tReport, seq, struc ) end -- -- 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

This update to "print protein lua2 V0" by marie_s adds some new reports and a dialog with many new options for controlling the output. A new "copy-and-paste" dialog simplifies getting the segment subscore report, the primary sequence, and the secondary structure. As before, detailed information can be found in the recipe's scriptlog.

Thanks to spvincent, Timo van der Laan, and HerobrinesArmy for code and ideas used in this version. Thanks to brgreening for helping to illuminate the mystery of the total score.

ligands and segment count

The recipe first does detailed checking for ligand sections, looking for any segments with a secondary structure code of "M". The recipe calculates the total score for each range of ligands found. For a "normal" ligand, one "M" segment at the end of the protein, the recipe reduces the segment count by one. The recipe issues a warning message to the scriptlog for any other ligands found. The recipe also issues a warning if the "normal" ligand has a non-zero score, but this may in fact be "normal". A current bug is that the "auto structures" tool may incorrectly convert the last segment to a ligand, which inspired these checks.

scoring information

New in this version, the recipe detects active subscores using the logic found in "Tvdl enhanced DRW". In some cases, this logic may suppress certain subscores, such as disulfides, when they have a low total value across all segments. The recipe reports the active subscores in the main dialog and the scriptlog.

The recipe calculates the "filter bonus" by toggling filters off and on, and then checks the total score. In theory, the total score is 8000 points plus the total of all segment subscores, plus the filter bonus. There's is usually a discrepancy, which is reported as "dark" score.

sequence information

As in previous versions, the recipe reports the primary sequence as a string of single-letter amino acid codes, and the secondary structure as a string with "H" for helix, "E" for sheet, and "L" for loop. The recipe also reports hydrophobicity as a string with "i" for if hydrophobic, and "e" if not hydrophobic.

New in this version, the primary sequence and secondary structure are available in the cut-and-paste dialog at the end.

The recipe issues warning messages to the scriptlog if a non-standard amino acid code or secondary structure code is found. The code "x" is substituted for a non-standard amino acid code. (One previous puzzle had a segment with an amino acid code of "unk", which caused problems.)

modifiable sections

New in this version, the recipe reports on modifiable sections, including locked and unlocked sections, zero-score sections, and mutable sections. The "mutable segments" report is now optional.

Some puzzles have locked sections with movable sidechains or locked sections that are mutable. Some recipes incorrectly assume that "locked" means not modifiable in any way. Locked sections with zero subscores are likely the only truly non-modifiable sections.

segment subscore report

New in this version, the main dialog appears before the segment subscore report is produced. Along with reporting other information, the dialog lets you select which subscores are to be included in the report. The hydropathy index (a fixed value based on the AA code), atom count, and rotamer count can optionally be included.

The main dialog lets you select the delimiter character, with the tab character as the default. The number of decimal places reported is also now adjustable.

The segment subscore report is now available in the cut-and-paste dialog, or in the scriptlog as previously. The report now includes a total line reflecting the column totals for the scoring components.

The fixed-width option found in previous versions, for example reporting "12389" instead of "123.89" or "123,89" has been eliminated.

other report sections

The mini contact table and detailed mutable reports are now optional. These are available in the scriptlog only.

cut-and-paste dialog

When you click "OK" in the main dialog, the segment subscore report and other selected reports are produced. The cut-and-paste dialog then appears, with text boxes for the subscore report, and the primary and secondary structures of the protein. These fields can be copied and pasted into a spreadsheet or another tool.

To copy a given field, click in its text box. Then use ctrl+a on Windows or command+a on Mac to "select all". Then use ctrl-c or command-c to copy. The selected text can then be pasted into the tool of your choice.

The use of the tab character as the default delimiter produces more legible scriptlog output (in most tools), and also simplifies pasting data into most spreadsheets, such as Excel and Open Office Calc. At least US English versions, spreadsheets typically recognize the comma-separated value (CSV) format automatically when pasting, and offer the tab character as the default delimiter.

scriptlog

In this version, key outputs, such as the segment score report and the primary and secondary structures, are available through dialogs.

As before, certain outputs, such as the mini-contact table and the detailed mutable report, and available only in the scriptlog.

The scriptlog file has the name "scriptlog.trackname.xml" where trackname is the current trackname, or "default" for the default track. The scriptlog file is located in the foldit installation folder, for example c:\Foldit in a Windows environment.

Although the scriptlog is nominally an XML file, with XML tags at the beginning and end, the recipe output is normally just plain text. (A few recipes create XML tags in their output, however.) A normal text editor, such as notepad on Windows, can be used to view the scriptlog. In some cases, you may need to manually select a tool to open the "XML" type. For example, in Windows, right-click the scriptlog file and select "Open with", then "Notepad".

Bruno Kestemont Lv 1

The windows is too long for a laptop 15". Impossible to click on the "ok" button. Could you divide the dialog in 2 ?