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
print protein 2.1 - 2016/03/23 - LociOiling
+ add ruler
print protein 2.2 - 2016/04/18 - LociOiling
+ fix crash in normal ligand case
+ add mean score to subscore display
print protein 2.3 - 2016/10/27 - LociOiling
+ add density analysis for ED puzzles
* density by amino acid
* density by aromatic vs. non-aromatic
* density by aliphatic vs. non-aliphatic
* density by hydrophobic vs. hydrophilic
* density deviation, showing whether each segment is
above or below mean density for the segment's amino acid type
+ move less-used parms to second screen to avoid screen overflow
]]--
--
-- globals section
--
Recipe = "print protein"
Version = "2.3"
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
kDensity = false -- density report
jDensity = false -- true if density component present
--
-- 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
--
-- 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
--
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" } ,
}
--
-- amino acid types
--
Aromatic = {
f = { "phenylalanine", },
h = { "histidine", },
w = { "tryptophan", },
y = { "tyrosine", },
}
Aliphatic = {
i = { "isoleucine", },
l = { "leucine", },
v = { "valine", },
}
Hydrophobic = {
a = { "alanine", },
c = { "cysteine", },
f = { "phenylalanine", },
i = { "isoleucine", },
l = { "leucine", },
m = { "methionine", },
p = { "proline", },
v = { "valine", },
w = { "tryptophan", },
y = { "tyrosine", },
}
--
-- 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 [ 1 ] [ 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 [ 1 ] [ STRCTSTR ] ..
", end = "
.. ligandList [ 1 ] [ STRCTEND ] ..
", score = "
.. round ( ligandList [ 1 ] [ 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 ()
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
function makeruler ( segments )
local onez = ""
local tenz = ""
local hunz = ""
local numz = 1
for ii = 1, segments do
onez = onez .. numz % 10
if ii % 10 == 0 then
local ff = ii
if ff >= 100 then
ff = ff % 100
end
tenz = tenz .. ( ff - ( ff % 10 ) ) / 10
if ii >= 100 then
local ff = ii
if ff >= 1000 then
ff = ff % 1000
end
hunz = hunz .. ( ff - ( ff % 100 ) ) / 100
else
hunz = hunz .. " "
end
else
tenz = tenz .. " "
hunz = hunz .. " "
end
numz = numz + 1
if numz > 10 then
numz = 1
end
end
local ruler = ""
if segments >= 100 then
ruler = hunz .. "\n"
end
if segments >= 10 then
ruler = tenz .. "\n"
end
ruler = ruler .. onez
return ruler
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
local ruler = makeruler ( segCnt2 )
print ( "sequence with single-letter amino acid codes for searching PDB" )
print ( ruler )
print ( seqstring )
print ( "" )
print ( "sequence with i if hydrophobic" )
print ( ruler )
print ( hydrostring )
print ( "" )
print ( "sequence of structure" )
print ( ruler )
print ( strucstring )
print ( "" )
print ( "--" )
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
--
-- print density analysis
--
function DensityRat ( table )
local tReport = ""
local headStr =
"\"AA code\""
.. delim ..
"\"AA name\""
.. delim ..
"\"segment count\""
.. delim ..
"\"total density\""
.. delim ..
"\"% total density\""
.. delim ..
"\"mean density\""
.. delim ..
"\"worst density\""
.. delim ..
"\"worst density seg\""
.. delim ..
"\"best density\""
.. delim ..
"\"best density seg\""
.. delim
--
-- AA density table - keyed by AA code
--
DENCOUNT = 1
DENTOTAL = 2
DENMEAN = 3
DENBEST = 4
DENBESTS = 5
DENWORST = 6
DENWORSTS = 7
--
-- density by amino acid
--
local tAA = {}
--
-- binary (true/false) tables for density by AA type
--
--
-- density of aromatics - true => aromatic
--
local tAromatic = {}
tAromatic [ true ] = { 0, 0, 0, -999, 0, 999, 0, }
tAromatic [ false ] = { 0, 0, 0, -999, 0, 999, 0, }
--
-- density of aliphatics - true => alphatic
--
local tAliphatic = {}
tAliphatic [ true ] = { 0, 0, 0, -999, 0, 999, 0, }
tAliphatic [ false ] = { 0, 0, 0, -999, 0, 999, 0, }
--
-- density of hydrophobics - true => hydrophobic
--
local tHydrophobic = {}
tHydrophobic [ true ] = { 0, 0, 0, -999, 0, 999, 0, }
tHydrophobic [ false ] = { 0, 0, 0, -999, 0, 999, 0, }
local function denUpdate ( tDen, segDensity, segindx )
tDen [ DENCOUNT ] = tDen [ DENCOUNT ] + 1
tDen [ DENTOTAL ] = tDen [ DENTOTAL ] + segDensity
if segDensity > tDen [ DENBEST ] then
tDen [ DENBEST ] = segDensity
tDen [ DENBESTS ] = segindx
end
if segDensity < tDen [ DENWORST ] then
tDen [ DENWORST ] = segDensity
tDen [ DENWORSTS ] = segindx
end
end
local tSegDensity = 0
for ii = 1, segCnt2 do
local aaCode = table [ ii ] [ 1 ]
if tAA [ aaCode ] == nil then
tAA [ aaCode ] = { 0, 0, 0, -999, 0, 999, 0, }
end
--
-- update table of density by amino acid
--
local segDensity = current.GetSegmentEnergySubscore ( ii, "Density" )
tSegDensity = tSegDensity + segDensity
local aaDen = tAA [ aaCode ]
if aaDen ~= nil then
denUpdate ( aaDen, segDensity, ii )
else
print ( "ERROR: AA density table entry for " .. aaCode .. " is nil" )
end
--
-- update table of density by aromatic vs. non-aromatic
--
local aromDen = tAromatic [ Aromatic [ aaCode ] ~= nil ]
if aromDen ~= nil then
denUpdate ( aromDen, segDensity, ii )
else
print ( "ERROR: Aromatic density table entry for " .. aaCode .. " is nil" )
end
--
-- update table of density by aliphatic vs. non-aliphatic
--
local alipDen = tAliphatic [ Aliphatic [ aaCode ] ~= nil ]
if alipDen ~= nil then
denUpdate ( alipDen, segDensity, ii )
else
print ( "ERROR: Aliphatic density table entry for " .. aaCode .. " is nil" )
end
--
-- update table of density by hydrophobic vs. non-hydrophobic
--
local phobDen = tHydrophobic [ Hydrophobic [ aaCode ] ~= nil ]
if phobDen ~= nil then
denUpdate ( phobDen, segDensity, ii )
else
print ( "ERROR: hydrophobic density table entry for " .. aaCode .. " is nil" )
end
end
print ( "--" )
print ( "\"density by AA\"" )
print ( headStr )
tReport = tReport .. "\"density by AA\"\n" .. headStr .. "\n"
for aac, aaDen in pairs ( tAA ) do
if aaDen [ DENCOUNT ] > 0 then
aaDen [ DENMEAN ] = aaDen [ DENTOTAL ] / aaDen [ DENCOUNT ]
end
local denline =
aac
.. delim ..
AminoAcids [ aac ] [ AALONG ]
.. delim ..
aaDen [ DENCOUNT ]
.. delim ..
round ( aaDen [ DENTOTAL ] )
.. delim ..
round ( ( aaDen [ DENTOTAL ] / tSegDensity ) * 100 )
.. delim ..
round ( aaDen [ DENMEAN ] )
.. delim ..
round ( aaDen [ DENWORST ] )
.. delim ..
aaDen [ DENWORSTS ]
.. delim ..
round ( aaDen [ DENBEST ] )
.. delim ..
aaDen [ DENBESTS ]
print ( denline )
tReport = tReport .. denline .. "\n"
end
local footstr =
"totals"
.. delim ..
segCnt2
.. delim ..
round ( tSegDensity )
.. delim
.. delim ..
round ( tSegDensity / segCnt2 )
print ( footstr )
tReport = tReport .. footstr .. "\n"
headStr =
"\"aromatic AA\""
.. delim ..
""
.. delim ..
"\"segment count\""
.. delim ..
"\"total density\""
.. delim ..
"\"% total density\""
.. delim ..
"\"mean density\""
.. delim ..
"\"worst density\""
.. delim ..
"\"worst density seg\""
.. delim ..
"\"best density\""
.. delim ..
"\"best density seg\""
.. delim
print ( "--" )
print ( "\"density by aromatic vs. non-aromatic\"" )
print ( headStr )
tReport = tReport .. "\"density by aromatic vs. non-aromatic\"\n" .. headStr .. "\n"
for aac, aaDen in pairs ( tAromatic ) do
if aaDen [ DENCOUNT ] > 0 then
aaDen [ DENMEAN ] = aaDen [ DENTOTAL ] / aaDen [ DENCOUNT ]
end
local denline =
tostring ( aac )
.. delim ..
""
.. delim ..
aaDen [ DENCOUNT ]
.. delim ..
round ( aaDen [ DENTOTAL ] )
.. delim ..
round ( ( aaDen [ DENTOTAL ] / tSegDensity ) * 100 )
.. delim ..
round ( aaDen [ DENMEAN ] )
.. delim ..
round ( aaDen [ DENWORST ] )
.. delim ..
aaDen [ DENWORSTS ]
.. delim ..
round ( aaDen [ DENBEST ] )
.. delim ..
aaDen [ DENBESTS ]
print ( denline )
tReport = tReport .. denline .. "\n"
end
headStr =
"\"aliphatic AA\""
.. delim ..
""
.. delim ..
"\"segment count\""
.. delim ..
"\"total density\""
.. delim ..
"\"% total density\""
.. delim ..
"\"mean density\""
.. delim ..
"\"worst density\""
.. delim ..
"\"worst density seg\""
.. delim ..
"\"best density\""
.. delim ..
"\"best density seg\""
.. delim
print ( "--" )
print ( "\"density by aliphatic vs. non-aliphatic\"" )
print ( headStr )
tReport = tReport .. "\"density by aliphatic vs. non-aliphatic\"\n" .. headStr .. "\n"
for aac, aaDen in pairs ( tAliphatic ) do
if aaDen [ DENCOUNT ] > 0 then
aaDen [ DENMEAN ] = aaDen [ DENTOTAL ] / aaDen [ DENCOUNT ]
end
local denline =
tostring ( aac )
.. delim ..
""
.. delim ..
aaDen [ DENCOUNT ]
.. delim ..
round ( aaDen [ DENTOTAL ] )
.. delim ..
round ( ( aaDen [ DENTOTAL ] / tSegDensity ) * 100 )
.. delim ..
round ( aaDen [ DENMEAN ] )
.. delim ..
round ( aaDen [ DENWORST ] )
.. delim ..
aaDen [ DENWORSTS ]
.. delim ..
round ( aaDen [ DENBEST ] )
.. delim ..
aaDen [ DENBESTS ]
print ( denline )
tReport = tReport .. denline .. "\n"
end
headStr =
"\"hydrophobic AA\""
.. delim ..
""
.. delim ..
"\"segment count\""
.. delim ..
"\"total density\""
.. delim ..
"\"% total density\""
.. delim ..
"\"mean density\""
.. delim ..
"\"worst density\""
.. delim ..
"\"worst density seg\""
.. delim ..
"\"best density\""
.. delim ..
"\"best density seg\""
.. delim
print ( "--" )
print ( "\"density by hydrophobic vs. non-hydrophobic\"" )
print ( headStr )
tReport = tReport .. "\"density by hydrophobic vs. non-hydrophobic\"\n" .. headStr .. "\n"
for aac, aaDen in pairs ( tHydrophobic ) do
if aaDen [ DENCOUNT ] > 0 then
aaDen [ DENMEAN ] = aaDen [ DENTOTAL ] / aaDen [ DENCOUNT ]
end
local denline =
tostring ( aac )
.. delim ..
""
.. delim ..
aaDen [ DENCOUNT ]
.. delim ..
round ( aaDen [ DENTOTAL ] )
.. delim ..
round ( ( aaDen [ DENTOTAL ] / tSegDensity ) * 100 )
.. delim ..
round ( aaDen [ DENMEAN ] )
.. delim ..
round ( aaDen [ DENWORST ] )
.. delim ..
aaDen [ DENWORSTS ]
.. delim ..
round ( aaDen [ DENBEST ] )
.. delim ..
aaDen [ DENBESTS ]
print ( denline )
tReport = tReport .. denline .. "\n"
end
print ( "--" )
print ( "\"density deviation (above/below mean density by AA)\"" )
local dendeviate = ""
for ii = 1, segCnt2 do
local aaCode = table [ ii ] [ 1 ]
local segDensity = current.GetSegmentEnergySubscore ( ii, "Density" )
local jDenMean = tAA [ aaCode ] [ DENMEAN ]
if round ( segDensity ) == round ( jDenMean ) or tAA [ aaCode ] [ DENCOUNT ] == 1 then
dendeviate = dendeviate .. "="
elseif segDensity < jDenMean then
dendeviate = dendeviate .. "-"
else
dendeviate = dendeviate .. "+"
end
end
local ruler = makeruler ( segCnt2 )
print ( ruler )
print ( dendeviate )
print ( "" )
return tReport, dendeviate
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, dReport, seq, struc, dendev )
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 )
if kDensity then
ask.l50 = dialog.AddLabel ( "---- density analysis ----" )
ask.dens = dialog.AddTextbox ( "density:", dReport )
end
ask.SEQN = dialog.AddLabel ( "---- primary (sequence) and secondary structure detail ----" )
ask.seq = dialog.AddTextbox ( "AA sequence:", seq )
ask.struc = dialog.AddTextbox ( "secondary:", struc )
if kDensity then
ask.l70 = dialog.AddLabel ( "---- density deviation from mean AA density ----" )
ask.dev = dialog.AddTextbox ( "deviation:", dendev )
end
ask.OK = dialog.AddButton ( "OK", 1 )
dialog.Show ( ask )
end
function GetParms ( scrParts, ligands )
local selParts = {}
local ask = dialog.CreateDialog ( ReVersion )
local kRet = 0
repeat
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 ] )
.. " (" ..
round ( scrParts [ ii ] [ 2 ] / segCnt2 )
.. " / seg) ",
true )
end
ask.SECT = dialog.AddLabel ( "---- report sections ----" )
ask.kContact = dialog.AddCheckbox ( "mini contact table", kContact )
ask.kMutDet = dialog.AddCheckbox ( "mutable details", kMutDet )
if jDensity then
ask.kDensity = dialog.AddCheckbox ( "density analysis", kDensity )
end
ask.OK = dialog.AddButton ( "OK", 1 )
ask.more = dialog.AddButton ( "More", 2 )
ask.Cancel = dialog.AddButton ( "Cancel", 0 )
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
kContact = ask.kContact.value
kMutDet = ask.kMutDet.value
if jDensity then
kDensity = ask.kDensity.value
end
if kRet == 2 then
GetMoreParms ()
end
end
until kRet < 2
if kRet == 1 then
return true, selParts
end
return false, scrParts
end
function GetMoreParms ( )
local ask = dialog.CreateDialog ( ReVersion )
ask.DETAIL = dialog.AddLabel ( "---- additional columns ----" )
ask.kHydro = dialog.AddCheckbox ( "hydropathy index", kHydro )
ask.kAtom = dialog.AddCheckbox ( "atom count", kAtom )
ask.kRotamer = dialog.AddCheckbox ( "rotamer count", kRotamer )
ask.FORMAT = dialog.AddLabel ( "---- formatting options ----" )
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.OK = dialog.AddButton ( "OK", 1 )
ask.Cancel = dialog.AddButton ( "Cancel", 0 )
local kRet = dialog.Show ( ask )
if kRet > 0 then
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
return true
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 )
--
-- special check for "Density" subscore
--
for ii = 1, #subScores do
if subScores [ ii ] [ 1 ] == "Density" then
jDensity = true -- density present
kDensity = true -- select density report by default
break
end
end
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 )
--
-- print density analysis
--
local dReport = nil
local dendev = nil
if jDensity then
dReport, dendev = DensityRat ( segTable )
end
--
-- 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 reports for copy and paste
--
ShowReport ( tReport, dReport, seq, struc, dendev )
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