Profile
- Name
- Helix Rebuild 2a
- ID
- 108135
- Shared with
- Public
- Parent
- None
- Children
- Created on
- December 12, 2022 at 23:33 PM UTC
- Updated on
- December 12, 2022 at 23:39 PM UTC
- Description
Code got from jeff101's Foldit10g client 9/19/2022 505pm.
Seems Helix Rebuild 2 by spvincent + Random Idealize Subroutine v0.1.0 changes by mirp.
Best for
Code
-- Helix Rebuild 2 by spvincent
--[[
Helix Rebuild 2a (modified by mirp)
- Random Idealize Subroutine added
- Random Idealize Options
- Note added
- Best solution stored in Slot 3
]]--
function noteSegment()
for i=structure.GetCount(),1,-1 do
if structure.GetNote(i) ~= "" then
if i == structure.GetCount() then return(-1) else return(i+1) end
end -- if
end -- for
return(1)
end -- function
note_segment = noteSegment()
initial_score = current.GetScore()
function saveNote(rb)
structure.SetNote(note_segment,string.format("(%s) %.3f + %s (rb %i) %.3f",
user.GetPlayerName(),roundto3(initial_score),"Helix Rebuild 2a",rb,roundto3(current.GetScore())))
end -- function
----- Random Idealize Subroutine v0.1.0
ri_idealizes = 10
ri_max_segments = 8
ri_before_fuze = true
ri_after_fuze = true
ri_fast = false
ri_mutate = false
ri_spacer = 2
function RandomIdealize(i_length,spacer,fast,mutate,max_segments)
-- Random Idealize Subroutine v0.1.0 by mirp
-- Combine Random Idealize with other recipes
-- Defaults
-- number of idealizes
if i_length == nil then i_length = 20 end
-- if spacer < 0 then do not print gain message else insert <spacer> spaces
if spacer == nil then spacer = 0 end
-- if fast then remove "wiggle all iterations after each idealize"
if fast == nil then fast = true end
-- if mutate then mutate after idealize if possible
if mutate == nil then mutate = false end
-- max. number of segments selected for idealize
if max_segments == nil then max_segments = 8 end
p_length = structure.GetCount() -- length of the protein
idealize_wiggle = 5 -- wiggle iterations after idealize
idealize_wiggle_all = 1 -- wiggle all iterations after each idealize
wiggle_all = 10 -- wiggle all iterations after each loop
idealize_mutate_iterations = 1 -- mutate iterations
pre_ci = behavior.GetClashImportance() -- restore CI
score = current.GetScore() -- start score
math.randomseed(os.time())
function puzzleHasMutable()
for i = 1,p_length do
if structure.IsMutable(i) then
return true
end -- if
end -- for
return false
end -- function
function puzzleHasLocked()
for i = 1,p_length do
if structure.IsLocked(i) then
return true
end -- if
end -- for
return false
end -- function
flag_mutable_puzzle = puzzleHasMutable()
flag_locked_puzzle = puzzleHasLocked()
flag_freeze_puzzle = math.max(freeze.GetCount()) > 0
function notLockedAdjacentSegments()
-- idealize requires at least two segments
-- all segments has to be adjacent
if p_length < 2 then return {} end
-- not locked list
not_locked_list = {}
if flag_locked_puzzle or flag_freeze_puzzle then
last_segment = false -- segment i
for i = 1,p_length-1 do
if not freeze.IsFrozen(i) and not structure.IsLocked(i) and
not freeze.IsFrozen(i+1) and not structure.IsLocked(i+1) then
if last_segment then
not_locked_list[#not_locked_list+1] = i+1
else
not_locked_list[#not_locked_list+1] = i
not_locked_list[#not_locked_list+1] = i+1
end -- if/else
last_segment = true
else
last_segment = false
end -- if/else
end -- for
else
for i = 1,p_length do
not_locked_list[#not_locked_list+1] = i
end -- for
end -- if/else
if #not_locked_list == 0 then return {} end
return not_locked_list
end -- function
-- quit when not enough segments
if freeze.GetCount() == p_length then
print("Random Idealize: Puzzle is frozen.")
return
end -- if
not_locked_segments = notLockedAdjacentSegments()
if #not_locked_segments == 0 then
print("Random Idealize: There are not enough segments.")
return
end -- if
function randomAdjacentSegments()
if flag_locked_puzzle or flag_freeze_puzzle then
-- select random start segments
repeat
start_index = math.random(#not_locked_list-1)
until not_locked_list[start_index] + 1 == not_locked_list[start_index+1]
-- random range
segments = math.random(max_segments - 1)
for i = 1,segments do
if start_index + i > #not_locked_list then
end_index = #not_locked_list
else
if not_locked_list[start_index] + i == not_locked_list[start_index+i] then
end_index = start_index + i
else
return {not_locked_list[start_index],not_locked_list[end_index]}
end -- if/else
end -- if/else
end -- for
segment_range = {not_locked_list[start_index],not_locked_list[end_index]}
else
-- select random segments
start_seg = math.random(p_length-1)
segments = math.random(max_segments - 1)
if start_seg + segments > p_length then
end_seg = p_length
else
end_seg = start_seg + segments
end -- if/else
segment_range = {start_seg,end_seg}
end -- if/else
return segment_range
end -- function
----- Main -----
behavior.SetClashImportance(1)
for i = 1,i_length do
random_adjacent_segments = randomAdjacentSegments()
start_seg = random_adjacent_segments[1]
end_seg = random_adjacent_segments[2]
recentbest.Save()
selection.DeselectAll()
selection.SelectRange(start_seg, end_seg)
structure.IdealizeSelected()
if flag_mutable_puzzle and mutate then
selection.DeselectAll()
for i_mutate = start_seg,end_seg do
if structure.IsMutable(i_mutate) then selection.Select(i_mutate) end
end -- for
structure.MutateSidechainsSelected(idealize_mutate_iterations)
end -- if
structure.WiggleSelected(idealize_wiggle)
if not fast then
selection.SelectAll()
structure.WiggleSelected(idealize_wiggle_all)
end -- if
recentbest.Restore()
end -- for
recentbest.Save()
selection.SelectAll()
structure.WiggleSelected(wiggle_all)
recentbest.Restore()
gain = current.GetScore() - score
if gain > 0 then gain_string = "+" else gain_string = "" end
if spacer >= 0 then
spacer_string = ""
if spacer > 0 then
for i = 1,spacer do spacer_string = spacer_string.." " end
end -- if
print(spacer_string.."Random Idealize: "..gain_string..(gain - gain % 0.001))
end -- if
behavior.SetClashImportance(pre_ci)
end -- function
-----
-- Globals
original_secondary_structure = {}
helix_starts = {}
helix_ends = {}
use_helix = {}
n_helices = 0
n_residues = 0
loop_spacer = 3
co_rebuild = false
clash_importance_during_rebuild = 0.3
n_rebuilds = 5
fuze_threshold = 4
-- For design
mutate_not_shake = false
-- Quicksave slots
kOriginalStructureOrNewBest = 1 -- the starting structure, or any subsequent improvement, will be stored in this quicksave slot
kTemp = 5
kQs10 = 10 -- the rebuilt structure that comes closest in score to the original without actually exceeding it
-- will be stored here
function roundto3 ( i )
-- printing convenience
return i - i % 0.001
end
function GetScore ()
score = current.GetEnergyScore ()
return score
end
function IsPuzzleMutable ()
for i = 1 , n_residues do
if ( structure.IsMutable ( i ) ) then
return true
end
end
return false
end
function get_helices ()
within_helix = false
for i = 1, n_residues do
if ( structure.GetSecondaryStructure ( i ) == "H" ) then
if ( within_helix == false ) then
-- start of a new helix
within_helix = true
n_helices = n_helices + 1
helix_starts [ n_helices ] = i
end
elseif ( within_helix == true ) then
-- end of a helix
within_helix = false
helix_ends [ n_helices ] = i -1
end
end -- for i
if ( within_helix == true ) then
helix_ends [ n_helices ] = n_residues
end
end
function IsWithinASelectedHelix ( residue )
-- When
for i = 1 , n_helices do
if ( use_helix [ i ] == true ) then
if ( ( residue >= helix_starts [ i ] ) and ( residue >= helix_ends [ i ] ) ) then
return true
end
end
end
return false
end
function ConvertToLoop ( first , last )
for k = first , last do
if ( original_secondary_structure [ k ] ~= "L" ) then
if ( IsWithinASelectedHelix ( k ) == false ) then
selection.SelectRange ( k , k )
structure.SetSecondaryStructureSelected ( "L" )
end
end
end
end
function pseudorandom ( score )
-- Returns a pseudorandom number >= 0 and < 1.
-- Based on the fractional part of the score
if ( score >= 0 ) then
return score % 1
else
return (-score ) % 1
end
end
function MiniFuse ()
selection.SelectAll ()
score_in_kTemp = GetScore()
save.Quicksave ( kTemp)
selection.SelectAll ()
behavior.SetClashImportance ( 0.07 )
structure.ShakeSidechainsSelected ( 1 )
behavior.SetClashImportance ( 1 )
structure.WiggleSelected ( 8 )
score = GetScore()
if ( score < score_in_kTemp ) then
save.Quickload ( kTemp )
end
end
function nudge ( score )
selection.SelectAll ()
recentbest.Save ()
behavior.SetClashImportance ( 0.2 + 0.2 * pseudorandom ( score ) )
structure.WiggleSelected ( 1 )
behavior.SetClashImportance ( 1 )
structure.WiggleSelected ( 8 )
recentbest.Restore ()
end
function ShakeWiggleShakeNudge ()
-- returns the score after doing a SWSW: short-circuiting if things don't look promising
if ( false ) then
structure.MutateSidechainsSelected ( 1 )
else
structure.ShakeSidechainsSelected ( 2 )
end
score_after_first_shake = GetScore ()
structure.WiggleSelected ( 12 )
score_after_wiggle = GetScore ()
if ( score_after_wiggle - score_after_first_shake < 10 and best_score - score_after_wiggle > 30 ) then
-- The wiggle got stuck and didn't achieve anything
nudge ( score_after_wiggle )
score_after_wiggle = GetScore ()
end
if ( mutate_not_shake == true ) then
structure.MutateSidechainsSelected ( 1 )
else
structure.ShakeSidechainsSelected ( 1 )
end
score_after_second_shake = GetScore ()
if ( score_after_second_shake - score_after_wiggle > 0.5 ) then
nudge ( score_after_second_shake )
score = GetScore ()
return score
else
return score_after_second_shake
end
end
function ConstructSpacers ( start_helix , end_helix )
start_idx = start_helix - loop_spacer
if ( start_idx < 1 ) then
start_idx = 1
end
if ( start_helix > 1 ) then
ConvertToLoop ( start_idx , start_helix - 1 )
end
end_idx = end_helix + loop_spacer
if ( end_idx > n_residues ) then
end_idx = n_residues
end
if ( end_helix < n_residues ) then
ConvertToLoop ( end_helix + 1 , end_idx )
end
return start_idx , end_idx
end
function rebuild_helix ( start_helix , end_helix )
improvement_made = false
save.Quickload ( kOriginalStructureOrNewBest )
rb = rb + 1
best_score = GetScore ()
selection.DeselectAll ()
if ( co_rebuild == true ) then
print ( "rb : " .. rb )
for i = 1 , n_helices do
if ( use_helix [ i ] == true ) then
start_idx , end_idx = ConstructSpacers ( helix_starts [ i ] , helix_ends [ i ] )
selection.SelectRange ( start_idx , end_idx )
end
end
else
print ( "rb : " .. rb .. " (" .. start_helix .. "-" .. end_helix .. ")" )
start_idx , end_idx = ConstructSpacers ( start_helix , end_helix )
selection.SelectRange ( start_idx , end_idx )
end
-- mirp
saveNote(rb)
save.Quicksave(3)
behavior.SetClashImportance ( clash_importance_during_rebuild )
recentbest.Save ()
structure.RebuildSelected ( 1 )
score_after_rebuild = GetScore ()
recentbest.Save ()
if ( math.abs ( score_after_rebuild - best_score ) < 1e-5 ) then
-- If the scores are still equal we probably have a locked segment
return false
end
structure.RebuildSelected ( 5 )
recentbest.Restore ()
behavior.SetClashImportance ( 1.0 )
selection.SelectAll ()
curr_score = ShakeWiggleShakeNudge ()
if ( curr_score > best_score - fuze_threshold ) then
-- mirp
if ri_before_fuze then
RandomIdealize(ri_idealizes,ri_spacer,ri_fast,ri_mutate,ri_max_segments)
end
-- mirp
curr_score = GetScore ()
MiniFuse ()
print ( " Fuze gain : " .. roundto3 ( GetScore () - curr_score ) )
-- mirp
if ri_after_fuze then
RandomIdealize(ri_idealizes,ri_spacer,ri_fast,ri_mutate,ri_max_segments)
end
end
curr_score = GetScore ()
if ( curr_score > best_score ) then
improvement_made = true
best_score = curr_score
save.LoadSecondaryStructure ()
save.Quicksave ( kOriginalStructureOrNewBest )
print ( "Improvement to " .. roundto3 ( best_score ) )
end
curr_score = GetScore ()
if ( curr_score > qs10_best_score and improvement_made == false ) then
qs10_best_score = curr_score
save.Quicksave ( kQs10 )
print ( "Storing " .. roundto3 ( qs10_best_score ) .. " in " .. kQs10 )
end
save.LoadSecondaryStructure ()
return true
end
function get_parameters ()
-- mirp
local dlog = dialog.CreateDialog ( "Helix Rebuild 2a" )
dlog.loop_spacer = dialog.AddSlider ( "Loop spacer" , loop_spacer , 0 , 6 , 0 )
for i = 1 , n_helices do
dlog [ "helix" .. i ] = dialog.AddCheckbox ( helix_starts [ i ] .. "-" .. helix_ends [ i ] , true )
end
dlog.co_rebuild = dialog.AddCheckbox ( "Co-rebuild" , co_rebuild )
dlog.n_rebuilds = dialog.AddSlider ( "Rebuilds" , n_rebuilds , 1 , 20 , 0 )
dlog.ci = dialog.AddSlider ( "Clash importance" , clash_importance_during_rebuild , 0 , 1.0 , 2 )
dlog.fzth = dialog.AddSlider ( "Fuze threshold" , fuze_threshold , 0 , 20 , 0 )
design_puzzle = IsPuzzleMutable ()
if ( design_puzzle == true ) then
dlog.mutate= dialog.AddCheckbox ( "Mutate not shake" , false )
end
-- mirp
dlog.RiLabel = dialog.AddLabel("----- Random Idealize Options -----")
dlog.RiIdealizes=dialog.AddSlider("Idealizes:",ri_idealizes,1,100,0)
dlog.RiMaxSegments=dialog.AddSlider("Max. Segments:",ri_max_segments,2,30,0)
dlog.RiBeFuze = dialog.AddCheckbox("Random Idealize before Fuze",ri_before_fuze)
dlog.RiAfterFuze = dialog.AddCheckbox("Random Idealize after Fuze",ri_after_fuze)
dlog.RiFast = dialog.AddCheckbox("Random Idealize Fast",ri_fast)
if design_puzzle then
dlog.RiMutate = dialog.AddCheckbox("Mutate after idealize",ri_mutate)
end
dlog.ok = dialog.AddButton ( "OK" , 1 )
dlog.cancel = dialog.AddButton ( "Cancel" , 0 )
if ( dialog.Show ( dlog ) > 0 ) then
loop_spacer = dlog.loop_spacer.value
for i = 1 , n_helices do
use_helix [ i ] = dlog [ "helix" .. i ].value
end
co_rebuild = dlog.co_rebuild.value
if ( design_puzzle == true ) then
mutate_not_shake = dlog.mutate.value
end
n_rebuilds = dlog.n_rebuilds.value
clash_importance_during_rebuild = dlog.ci.value
fuze_threshold = dlog.fzth.value
-- mirp
ri_idealizes = dlog.RiIdealizes.value
ri_max_segments = dlog.RiMaxSegments.value
ri_before_fuze = dlog.RiBeFuze.value
ri_after_fuze = dlog.RiAfterFuze.value
ri_fast = dlog.RiFast.value
if design_puzzle then ri_mutate = dlog.RiMutate.value end
return true
else
return false
end
end
function main ()
-- mirp
print ( "Helix Rebuild 2a" )
band.DisableAll ()
n_residues = structure.GetCount ()
for i = 1, n_residues do
original_secondary_structure [ i ] = structure.GetSecondaryStructure ( i )
end
save.SaveSecondaryStructure ()
behavior.SetClashImportance ( 1 )
best_score = GetScore ()
print ( "Start score : " .. roundto3 ( best_score ) )
get_helices ()
for i = 1 , n_helices do
print ( "Helix " .. i .." : " .. helix_starts [ i ] .. "-" .. helix_ends [ i ] )
use_helix [ i ] = false
end
qs10_best_score = 0
if ( get_parameters () == false ) then
print ( "error" )
error ()
end
-- Check that at least one helix was selected
found = false
i = 1
while ( i <= n_helices and found == false ) do
if ( use_helix [ i ] == true ) then
found = true
end
i = i + 1
end
if ( found == false ) then
print ( "No helix selected" )
error ()
end
rb = 0
save.Quicksave ( kOriginalStructureOrNewBest )
while ( true ) do
for i = 1 , n_helices do
if ( use_helix [ i ] == true ) then
rebuild_helix ( helix_starts [ i ] , helix_ends [ i ] )
end
end
end
end
function cleanup ()
print ( "Cleaning up" )
behavior.SetClashImportance ( 1.0 )
save.Quickload ( kOriginalStructureOrNewBest )
band.EnableAll ()
-- mirp
if rb ~= nil then
saveNote(rb)
save.Quicksave(3)
end
end
--main ()
xpcall ( main , cleanup )