Back to Recipes Homepage
recipe picture
Recipe: Report on Structures v0.03
5
Your rating: None Average: 5 (1 vote)
Used 116 times with an average impact of 11982 points.

Profile

Name: Report on Structures v0.03
ID: 16511
Created on: Wed, 11/17/2010 - 11:21
Updated on: Wed, 11/17/2010 - 19:21
Description:

detail report on total score or part score for each segment and summary (total points / average) over each loop, helix and sheet



Best For


Comments

Joined: 08/11/2010
source code

-- Report on Structures, by John McLeod
-- detail report on total score or one part score for each segment
-- and summary (total points / average) over each successive structure
-- (loop, helix and sheet) in the puzzle
--
-- v0.01 -- November 15, 2010
-- v0.02 -- November 16, 2010 -- ugly but nearly usable
-- v0.03 -- November 17, 2010 -- lines now double up so report fits in Recipe Window
-- and it now doesn't crash for ligand puzzles;
-- Amino Acid types list added at end of report

-- USER MODIFIES

local select_score_type = 0 -- total score <-- change this to select a part score

-- 1) clashing, 2) packing, 3) hiding, 4) bonding, 5) backbone, 6) sidechain,
-- 7) reference, 8) disulfides, 9) other

-- Funky variable with fragile calculation

-- This will work as long as puzzle ligands are of structure type "M"
-- and occur at the end of the puzzle. If this changes then the following will
-- require manual setting
local puzzle_num_ligands = 0
do -- start constructor for variable puzzle_num_ligands
local seg_no = get_segment_count()
while get_ss(seg_no) == "M" do -- M structures are ligands, and they happen at the end
puzzle_num_ligands = puzzle_num_ligands + 1
seg_no = seg_no - 1
end
end -- end of constructor for variable puzzle_num_ligands

-- TABLES

-- Table attr

local attr = { -- refer to the documentation for "Get segment score part" in the Foldit Wiki
[0] = "total score", -- 0 -- total score
"clashing", -- 1 -- clashing
"packing", -- 2 -- packing
"hiding", -- 3 -- hiding
"bonding", -- 4 -- bonding
"backbone", -- 5 -- backbone
"sidechain", -- 6 -- sidechain
"reference", -- 7 -- reference
"disulfides", -- 8 -- disulfides
"other" -- 9 -- other
}

--[[ table attr: IMPORTANT CLARIFICATION ON "REFERENCE" PART SCORE

beta_helix's comment dated Nov 2, 2010 under this post http://fold.it/portal/node/987935 ...

These [reference] values do not have anything to do with the hydrophobicity of the different
amino acids, they are actually weights that only affect the score when mutating from one
sidechain to another (so they have nothing to do with prediction puzzles).

For example, when you mutate from a smaller sidechain to a big one (such as Tryptophan) you
are going to have a lot more interactions that will be reflected in the score function, so
Trp is penalized with -9.1 Phe, His & Tyr all have similar penalties as well.

These reference weights were set after careful optimizations on a large benchmark
of native proteins.
]]--

-- Table PuzzleStructsTab

local PuzzleStructsTab = {} -- consecutive elements are of the form { start_seg, end_seg, structure_code }
local PuzzleStructs_start_ind = 1
local PuzzleStructs_end_ind = 2
local PuzzleStructs_ss_ind = 3
local PuzzleStructs_num_structs = 0

do -- constructor for PuzzleStructsTab

local puzzle_last_seg = get_segment_count() - puzzle_num_ligands
local current_struct = ''
local current_start_seg = 0
local current_struct_ind = 0

current_struct = get_ss(1)
current_struct_ind = 1
current_start_seg = 1
PuzzleStructsTab[current_struct_ind] = {}
PuzzleStructsTab[current_struct_ind][PuzzleStructs_start_ind] = current_start_seg
PuzzleStructsTab[current_struct_ind][PuzzleStructs_ss_ind] = current_struct
for x=2,puzzle_last_seg do
if get_ss(x) ~= current_struct then
current_struct = get_ss(x)
current_struct_ind = current_struct_ind + 1
current_start_seg = x
PuzzleStructsTab[current_struct_ind] = {}
PuzzleStructsTab[current_struct_ind][PuzzleStructs_start_ind] = current_start_seg
PuzzleStructsTab[current_struct_ind][PuzzleStructs_ss_ind] = current_struct
PuzzleStructsTab[current_struct_ind - 1][PuzzleStructs_end_ind] = x - 1
end
end
PuzzleStructsTab[current_struct_ind][PuzzleStructs_end_ind] = puzzle_last_seg
PuzzleStructs_num_structs = current_struct_ind

end -- constructor for PuzzleStructsTab

-- Table PuzzleStructsKillList

local PuzzleStructsKillList = { } -- structs that print with next structs to conserve lines

do -- constructor for PuzzleStructsKillList
local max_structs_to_print = 45 -- this is the max capacity of the Recipe Output Window
-- reduced by the number of other lines this report prints

local good_list = {} -- structs available to defer printing (not last)
do -- constructor for table good_list
for x=1,(PuzzleStructs_num_structs - 1) do
good_list[x] = true
end
end -- constructor for table good_list

for x=1,(PuzzleStructs_num_structs - max_structs_to_print) do
new_shortest=1
while good_list[new_shortest] == false do
new_shortest = new_shortest + 1
end
for y=new_shortest,(PuzzleStructs_num_structs - 1) do
if (good_list[y] == true) and
(
(
PuzzleStructsTab[y][PuzzleStructs_end_ind] -
PuzzleStructsTab[y][PuzzleStructs_start_ind]
)
<
(
PuzzleStructsTab[new_shortest][PuzzleStructs_end_ind] -
PuzzleStructsTab[new_shortest][PuzzleStructs_start_ind]
)
)
then
new_shortest = y
end
end
good_list[new_shortest] = false
PuzzleStructsKillList[new_shortest] = true
end

end -- constructor for PuzzleStructsKillList

-- Tables UpByLow and LowByUp

local UpByLow = { -- a table of uppercase letters indexed by lowercase letters
['a']='A',['b']='B',['c']='C',['d']='D',['e']='E',
['f']='F',['g']='G',['h']='H',['i']='I',['j']='J',
['k']='K',['l']='L',['m']='M',['n']='N',['o']='O',
['p']='P',['q']='Q',['r']='R',['s']='S',['t']='T',
['u']='U',['v']='V',['w']='W',['x']='X',['y']='Y',
['z']='Z'
}

local LowByUp = { -- a table of lowercase letters indexed by uppercase letters
['A']='a',['B']='b',['C']='c',['D']='d',['E']='e',
['F']='f',['G']='g',['H']='h',['I']='i',['J']='j',
['K']='k',['L']='l',['M']='m',['N']='n',['O']='o',
['P']='p',['Q']='q',['R']='r',['S']='s',['T']='t',
['U']='u',['V']='v',['W']='w',['X']='x',['Y']='y',
['Z']='z'
}

-- Table NATO_Phonetic_Alphabet

local NATO_Phonetic_Alphabet = { -- to give distinctive names to the first 26 structures
'Alfa', 'Bravo', 'Charlie', 'Delta', 'Echo',
'Foxtrot', 'Golf', 'Hotel', 'India', 'Juliet',
'Kilo', 'Lima', 'Mike', 'November', 'Oscar',
'Papa', 'Quebec', 'Romeo', 'Sierra', 'Tango',
'Uniform', 'Victor', 'Whiskey', 'Xray', 'Yankee', 'Zulu'
}

-- Table lua_char

local lua_char = { -- the LUA character set
[0] = '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\008', '\009',
'\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\018', '\019',
'\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', '\028', '\029',
'\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', '\038', '\039',
'\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', '\048', '\049',
'\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', '\058', '\059',
'\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', '\068', '\069',
'\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', '\078', '\079',
'\080', '\081', '\082', '\083', '\084', '\085', '\086', '\087', '\088', '\089',
'\090', '\091', '\092', '\093', '\094', '\095', '\096', '\097', '\098', '\099',
'\100', '\101', '\102', '\103', '\104', '\105', '\106', '\107', '\108', '\109',
'\110', '\111', '\112', '\113', '\114', '\115', '\116', '\117', '\118', '\119',
'\120', '\121', '\122', '\123', '\124', '\125', '\126', '\127', '\128', '\129',
'\130', '\131', '\132', '\133', '\134', '\135', '\136', '\137', '\138', '\139',
'\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', '\148', '\149',
'\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\158', '\159',
'\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\168', '\169',
'\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', '\178', '\179',
'\180', '\181', '\182', '\183', '\184', '\185', '\186', '\187', '\188', '\189',
'\190', '\191', '\192', '\193', '\194', '\195', '\196', '\197', '\198', '\199',
'\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207', '\208', '\209',
'\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217', '\218', '\219',
'\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\228', '\229',
'\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\238', '\239',
'\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247', '\248', '\249',
'\250', '\251', '\252', '\253', '\254', '\255'
}

-- Table AminoAcidTable

local AminoAcidTable = { -- { 'short', 'long' } by lowercase letter code
['a'] = { 'Ala', 'Alanine' },
['b'] = { 'Asx', 'Asparagine or Aspartic acid' }, -- not in Foldit (as of Nov 15, 2010)
['c'] = { 'Cys', 'Cysteine' },
['d'] = { 'Asp', 'Aspartic acid' },
['e'] = { 'Glu', 'Glutamic acid' },
['f'] = { 'Phe', 'Phenylalanine' },
['g'] = { 'Gly', 'Glycine' },
['h'] = { 'His', 'Histidine' },
['i'] = { 'Ile', 'Isoleucine' },
['j'] = { 'Xle', 'Leucine or Isoleucine' }, -- not in Foldit (as of Nov 15, 2010)
['k'] = { 'Lys', 'Lysine' },
['l'] = { 'Leu', 'Leucine' },
['m'] = { 'Met', 'Methionine' },
['n'] = { 'Asn', 'Asparagine' },
['o'] = { 'Pyl', 'Pyrrolysine' }, -- not in Foldit (as of Nov 15, 2010)
['p'] = { 'Pro', 'Proline' },
['q'] = { 'Gln', 'Glutamine' },
['r'] = { 'Arg', 'Arginine' },
['s'] = { 'Ser', 'Serine' },
['t'] = { 'Thr', 'Threonine' },
['u'] = { 'Sec', 'Selenocysteine' }, -- not in Foldit (as of Nov 15, 2010)
['v'] = { 'Val', 'Valine' },
['w'] = { 'Trp', 'Tryptophan' },
['x'] = { 'Xaa', 'Unspecified or unknown amino acid' }, -- not in Foldit (as of Nov 15, 2010)
['y'] = { 'Tyr', 'Tyrosine' },
['z'] = { 'Glx', 'Glutamine or glutamic acid' } -- not in Foldit (as of Nov 15, 2010)
}
local AminoAcidTable_short_ind = 1
local AminoAcidTable_long_ind = 2

-- FUNCTIONS

function Round_to_10ths(num_in_arg) -- returns string num_string, number len
-- Rounds number input to nearest tenth and returns a table with rounded number
-- as a string in the first element and the length of the string as the second

local num_in = 0
local num_out_str = ''
local num_out_len = 0
local whole_part = 0 -- whole number part of num
local frac_part = 0 -- fractional part of num
local dec_part = 0 -- will be 0,1,..., or 9

if num_in_arg == nil then -- no input, return as if zero
return "0.0", 3
else
num_in = num_in_arg + 0
end

-- round up or down to nearest tenth
if (num_in % 0.1) < 0.05 then
num_in = num_in - (num_in % 0.1) -- round down
else
num_in = num_in + (0.1 - (num_in % 0.1)) -- round up
end

if num_in < 0 then
-- flip to absolute value, place minus sign in output string
num_out_str = num_out_str .. '-'
num_out_len = num_out_len + 1
num_in = -num_in
end

num_in = num_in + 0.00001 -- add salt to defend against small arithmetic errors
frac_part = num_in % 1 -- is (about) .0 .1, .2, ... or .9 since we've already rounded
whole_part = num_in - frac_part

num_out_str = num_out_str .. whole_part -- put whole number part in as string
num_out_len = num_out_len + 1 -- always have ones place

-- determine additional places to the left of ones place
local scale = 10
while scale <= whole_part do
num_out_len = num_out_len + 1
scale = scale * 10
end

num_out_str = num_out_str .. '.' -- put in decimal point
num_out_len = num_out_len + 1

dec_part = frac_part * 10
frac_part = dec_part % 1
dec_part = dec_part - frac_part -- remove the salt

num_out_str = num_out_str .. dec_part -- put in tenths digit
num_out_len = num_out_len + 1

return num_out_str, num_out_len

end -- Round_to_10ths

function Desperate_String_Len(string_arg) -- returns length of string_arg
-- mimics function of string.len()
-- until Foldit starts allowing the LUA string library
--
-- requires table lua_char

if string_arg == nil then
return 0
end

local return_val = 0
local compare_str = ''
local search_ind = 0

-- Rebuilds string_arg one bit at a time, counting the number
-- of characters until completion. What's not to love?
while compare_str ~= string_arg do
search_ind = 0
for current_bit=1,8 do
if compare_str .. lua_char[search_ind + 2 ^ (8 - current_bit)] <= string_arg then
search_ind = search_ind + 2 ^ (8 - current_bit)
end
end
compare_str = compare_str .. lua_char[search_ind]
return_val = return_val + 1
end

return return_val

end -- function Desperate_String_Len

function Desperate_Left_Fill(string_arg, field_width, fill_char)
-- NOTE: requires function Desperate_String_Len
--
-- returns string_arg with enough instances of fill_char
-- (assumed to be single character) concatenated to the left
-- so that returned string is field_width wide
--
-- fill_char defaults to a space

local return_string = ''
local char_to_add = ''
local num_chars_to_add = 0

if string_arg == nil then
return ''
elseif field_width == nil then
return string_arg
else
return_string = string_arg
end

if fill_char == nil then
char_to_add = ' ' -- space
else
char_to_add = fill_char
end

num_chars_to_add = field_width - Desperate_String_Len(return_string)

for i=1,num_chars_to_add do
return_string = char_to_add .. return_string
end

return return_string

end -- function Desperate_Left_Fill

function Print_Score_in_1000ths(Prefix)
-- NOTE: requires function Desperate_Left_Fill
--
-- Prints the Foldit score truncated to the nearest thousandth,
-- as displayed in the game in the "Advanced GUI"
-- If provided a Prefix string argument will print ahead of the score

local score_str = ''
if Prefix ~= nil then -- concatenate Prefix ahead of score if one provided
score_str = score_str .. Prefix
end

local negative_score = true -- tells get_score to also return negatives
local score_num = get_score(negative_score) -- present game score
local int_part = 0 -- whole number part of score
local dec_part = 0 -- fractional part of score
local dec_part_thousandths = 0 -- truncated thousandths part of fraction: 0 to 999

if score_num < 0 then
-- flip to absolute value, save minus sign in string
score_str = score_str .. '-'
score_num = -score_num
end

dec_part = score_num % 1
int_part = score_num - dec_part
dec_part_thousandths = (dec_part * 1000) - ((dec_part * 1000) % 1)

score_str = score_str .. int_part -- put whole number part in string
score_str = score_str .. '.' -- put in decimal point
score_str = score_str .. Desperate_Left_Fill(dec_part_thousandths .. '', 3, '0') -- put in decimal places

print(score_str)

end -- function Print_Score_in_1000ths

function Struct_Sequential_Name(seq_no)
-- Returns a distinctive "name" string for the seq_no'th structure.
--
-- input argument seq_no = 1, 2, ..., 26 (numbers) yields one of the
-- twenty-six "letters" of the NATO Phonetic Alphabet. Other values
-- for seq_no are just reflected back as strings.
--
-- requires table NATO_Phonetic_Alphabet

if seq_no == nil then -- no input argument at all
return '???' -- huh?
elseif seq_no == '' then -- input argument is empty string
return '???' -- huh?
else
-- NO ACTION: we've at least got an input arg seq_no
end

if NATO_Phonetic_Alphabet[seq_no] == nil then -- input arg out of range of the table
return seq_no .. '' -- return input argument itself (as string)
else -- input arg is in range of table, return table element
return NATO_Phonetic_Alphabet[seq_no]
end

end -- function Struct_Sequential_Name

function To_Upper(char_in)
-- If string input argument char_in is a single lowercase letter than the equivalent uppercase letter is returned.
-- Otherwise char_in is returned (as a string)
--
-- Requires table UpByLow

local char_in_str = ''

if char_in == nil then -- no input argument at all
return ''
else
char_in_str = char_in .. '' -- force input arg to be string
end

if UpByLow[char_in_str] == nil then -- input arg out of range of the table
return char_in_str -- return input argument itself (as string)
else -- input arg is in range of table, return table element
return UpByLow[char_in_str]
end

end -- function To_Upper

function To_Lower(char_in)
-- If string input argument char_in is a single lowercase letter than the equivalent lowercase letter is returned.
-- Otherwise char_in is returned (as a string)
--
-- Requires table LowByUp

local char_in_str = ''

if char_in == nil then -- no input argument at all
return ''
else
char_in_str = char_in .. '' -- force input arg to be string
end

if LowByUp[char_in_str] == nil then -- input arg out of range of the table
return char_in_str -- return input argument itself (as string)
else -- input arg is in range of table, return table element
return LowByUp[char_in_str]
end

end -- function To_Lower

function Amino_Acid_Name(aa_code, long_name_req)
-- Returns the name of the amino acid, the short 3-letter code by default
--
-- argument aa_code is one-letter string, 1-letter amino acid code
-- if long_name_req is present and boolean true then the long name of the aa is returned
--
-- requires table AminoAcidTable
-- requires function To_Lower

local boolean long_name_req_bool = false
local aa_code_char = ''

if aa_code == nil then -- no input argument at all
return '???' -- huh?
else
aa_code_char = To_Lower(aa_code .. '') -- Foldit uses lowercase aa codes
end

if long_name_req == nil then -- no second argument, default is short name
long_name_req_bool = false
else
long_name_req_bool = (false or long_name_req)
end

if AminoAcidTable[aa_code_char] == nil then -- table has no aa for this code
return '???' -- huh?
elseif long_name_req_bool then
return AminoAcidTable[aa_code_char][AminoAcidTable_long_ind]
else
return AminoAcidTable[aa_code_char][AminoAcidTable_short_ind]
end

end -- function Amino_Acid_Name

-- MAIN
print("begin Report on Structures v0.03")
print("Score Type: ", attr[select_score_type])

-- quick dirty summary for v0.01, v0.02 and v0.03 release

-- needs work obviously
local Struct_Types = { ["L"] = "Loop", ["E"] = "Sheet", ["H"] = "Helix" }

do -- for loop wrapper
-- current_line goes outside loop because it can accumulate
-- so that a large number of structures won't cause the report
-- to have more lines than the script output window can handle

local current_line = ""

for x=1,PuzzleStructs_num_structs do

local score_sum = 0
tot_score_str = ""
ave_score_str = ""
for y=PuzzleStructsTab[x][PuzzleStructs_start_ind],
PuzzleStructsTab[x][PuzzleStructs_end_ind] do
if select_score_type == 0 then -- total score
score_sum = score_sum + get_segment_score(y)
else
score_sum = score_sum + get_segment_score_part(attr[select_score_type], y)
end
end
tot_score_str = Round_to_10ths(score_sum)
ave_score_str = Round_to_10ths(score_sum / ( ( PuzzleStructsTab[x][PuzzleStructs_end_ind] -
PuzzleStructsTab[x][PuzzleStructs_start_ind] ) + 1) )
-- print(Struct_Types[ PuzzleStructsTab[x][PuzzleStructs_ss_ind] ], " ",
-- Struct_Sequential_Name(x), "(",
-- PuzzleStructsTab[x][PuzzleStructs_start_ind], ",",
-- PuzzleStructsTab[x][PuzzleStructs_end_ind], ") -- tot: ",
-- tot_score_str, " ave: ", ave_score_str
-- )
current_line = current_line .. Struct_Types[ PuzzleStructsTab[x][PuzzleStructs_ss_ind] ] .. " " ..
Struct_Sequential_Name(x) .. "(" ..
PuzzleStructsTab[x][PuzzleStructs_start_ind] .. "," ..
PuzzleStructsTab[x][PuzzleStructs_end_ind] .. ") -- [[tot: " ..
tot_score_str .. " ave: " .. ave_score_str .. "]]"

-- Details here
local detail_score_str = ""
for y=PuzzleStructsTab[x][PuzzleStructs_start_ind],PuzzleStructsTab[x][PuzzleStructs_end_ind] do
if select_score_type == 0 then -- total score
detail_score_str = Round_to_10ths(get_segment_score(y))
else -- part score
detail_score_str =
Round_to_10ths(get_segment_score_part(attr[select_score_type], y))
end
current_line = current_line .. ", " .. y .. ")" ..
Amino_Acid_Name(get_aa(y)) .. " " .. detail_score_str
end

if PuzzleStructsKillList[x] == nil then -- OK to print what we've got
print(current_line)
current_line = ""
else -- print with next line to save space
current_line = current_line .. "; "
end

end -- for loop

end -- for loop wrapper

do -- print a line with all the Amino Acid names
local current_line = "Amino Acids list: "
for x=97,121 do -- those are the decimal ASCII values from 'a' to 'y'
current_line = current_line .. Amino_Acid_Name(lua_char[x]) ..
"(" .. To_Upper(lua_char[x]) .. ") " ..
Amino_Acid_Name(lua_char[x], true) .. ", " -- second parm true for long AA name
end
current_line = current_line .. Amino_Acid_Name(lua_char[122]) .. -- 122 is for 'z'
"(" .. To_Upper(lua_char[122]) .. ") " ..
Amino_Acid_Name(lua_char[122], true) -- no comma after last in list
print(current_line)
end -- print a line with all the Amino Acid names

Print_Score_in_1000ths("Current Game Score: ")
print("end Report on Structures v0.03")

Want to try?
Add to Cookbook!
To download recipes to your cookbook, you need to have the game client running.
Parent
Children

none

Authors
Sitemap

Developed by: UW Center for Game Science, UW Institute for Protein Design, Northeastern University, Vanderbilt University Meiler Lab, UC Davis
Supported by: DARPA, NSF, NIH, HHMI, Amazon, Microsoft, Adobe, RosettaCommons