Code
min_residue = 1
max_residue = 999
n_residues = 0
best_score = 0
clash_importance_during_mutate = 0.2
target_loss_on_mutate = 150
kMaxIterations = 10 -- Sanity check for the new wiggle loop
mutate_radius = 14
-- Amino acids. Hydrophobics first.
single_letter_codes = { "g","a","v","l","i","m","f","w","p","s","t","c","y","n","q","d","e","k","r","h"}
three_letter_codes = { "Gly","Ala","Val","Leu","Ile","Met","Phe","Trp","Pro","Ser","Thr","Cys","Tyr","Asn","Gln","Asp","Glu","Lys","Arg","His"}
-- Use of quicksave slots
kOriginalStructureOrNewBest = 10
function r3 ( x )
-- Round to 3 decimal places
t = 10 ^ 3
return math.floor ( x*t + 0.5 ) / t
end
function GetScore ()
score = current.GetEnergyScore ()
return score
end
function get_aa3 ( i )
k = structure.GetAminoAcid ( i )
for j = 1, 20 do
if ( k == single_letter_codes [ j ] ) then
return three_letter_codes [ j ]
end
end
return "Unk"
end
function Wiggle ( step , threshold )
n_it = 0
new_score = GetScore ()
repeat
prev_score = new_score
structure.WiggleSelected ( step )
new_score = GetScore ()
n_it = n_it + 1
until ( ( math.abs ( new_score - prev_score ) < threshold ) or ( n_it > kMaxIterations ) )
end
function PostMutate ()
behavior.SetClashImportance ( 0.1 )
structure.ShakeSidechainsSelected ( 1 )
behavior.SetClashImportance ( 1.0 )
selection.SelectAll ()
structure.WiggleSelected ( 1 , false , true ) -- sidechains
Wiggle ( 4 , 0.1 )
end
function MutateResidue ( i )
if ( structure.IsMutable ( i ) ) then
print ( get_aa3 (i) .. " " .. i )
save.Quickload ( kOriginalStructureOrNewBest )
selection.DeselectAll ()
for j = 1 , n_residues do
if ( structure.GetDistance ( i , j ) < mutate_radius ) then
selection.Select ( j )
end
end
behavior.SetClashImportance ( clash_importance_during_mutate )
structure.MutateSidechainsSelected ( 1 )
score = GetScore ()
loss_from_mutate = best_score - score
-- print ( "loss from mutate " .. r3 ( loss_from_mutate ) )
if ( loss_from_mutate > 2*target_loss_on_mutate ) then
clash_importance_during_mutate = clash_importance_during_mutate * ( 1 + 0.2*math.random () )
-- print ( "CI changed to " .. r3 ( clash_importance_during_mutate ) )
elseif ( loss_from_mutate < 0.5*target_loss_on_mutate ) then
clash_importance_during_mutate = clash_importance_during_mutate * ( 1 - 0.2*math.random () )
-- print ( "CI changed to " .. r3 ( clash_importance_during_mutate ) )
end
if ( math.abs ( score - best_score ) > 0.5 ) then
PostMutate()
score = GetScore ()
if ( score > best_score ) then
save.Quicksave ( kOriginalStructureOrNewBest )
best_score = score
print ( "Improvement to " .. r3 ( best_score ) )
end
end
end
end
function MutateAll ()
for i = min_residue , max_residue , 2 do
MutateResidue ( i )
end
for i = min_residue + 1 , max_residue , 2 do
MutateResidue ( i )
end
end
function GetParameters ()
local dlog = dialog.CreateDialog ( "Local Mutate 1.0" )
dlog.min_residue = dialog.AddSlider ( "Min residue" , 1 , 1 , n_residues , 0 )
dlog.max_residue = dialog.AddSlider ( "Max residue" , n_residues , 1 , n_residues , 0 )
dlog.tlom = dialog.AddSlider ( "Target loss" , target_loss_on_mutate , 0 , 500 , 0 )
dlog.mutate_radius = dialog.AddSlider ( "Sphere radius" , mutate_radius , 1 , 30 , 1 )
dlog.ok = dialog.AddButton ( "OK" , 1 )
dlog.cancel = dialog.AddButton ( "Cancel" , 0 )
if ( dialog.Show ( dlog ) > 0 ) then
min_residue = dlog.min_residue.value
max_residue = dlog.max_residue.value
target_loss_on_mutate = dlog.tlom.value
mutate_radius = dlog.mutate_radius.value
return true
else
return false
end
end
function main ()
band.DisableAll ()
n_residues = structure.GetCount ()
save.Quicksave ( kOriginalStructureOrNewBest )
if ( GetParameters () == false ) then
return -- graceful exit
end
print ( "Local Mutate 1.0 : New Chapters" )
max_residue = math.min ( n_residues , max_residue )
min_residue = math.max ( 1 , min_residue )
print ( "Rebuild range " .. min_residue .. " to " .. max_residue )
if ( max_residue < min_residue ) then
print ( "Rebuild range error." )
return
end
best_score = GetScore ()
print ( "Start score : " .. r3 ( best_score ) )
MutateAll ()
band.EnableAll ()
end
function cleanup ()
print ( "Cleaning up" )
behavior.SetClashImportance ( 1.0 )
save.Quickload ( kOriginalStructureOrNewBest )
band.EnableAll ()
end
--main ()
xpcall ( main , cleanup )