Icon representing a recipe

Recipe: nbl_hinge_v1.2

created by nicobul

Profile


Name
nbl_hinge_v1.2
ID
48965
Shared with
Public
Parent
None
Children
Created on
April 26, 2014 at 08:22 AM UTC
Updated on
April 26, 2014 at 08:22 AM UTC
Description

Freezes the surrounds of a segment, then proceeds to wiggles with bands

Best for


Code


--[[------------------------------------------------------------------------------------------------ NBL_hinge Author: Nicobul2 - april 2014 Contributors: Ch Garnier, Yoyo, Bruno Kestemont Original recipe: Glycine hinge by Tlaloc (LUA v1) Converted from v1 lua by Rav3n_pl v1 to v2 converter Copyright (C) 2011 tlaloc <http://fold.it/portal/user/57765> Copyright (C) 2011 rav3n_pl <http://fold.it/portal/user/174969> Copyright (C) 2011 Seagat2011 <http://fold.it/port/user/1992490> Copyright (C) 2011 thom001 <http://fold.it/port/user/172510> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. --]] local _options = { --- User Options Begin ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ wiggle_count = 1, -- #iters (flex) wiggle_out_count = 30, -- #iters (unflex) band_strength = 0.25, -- band strength allow_float_wiggle_count = false, -- allows "floating" via random number generation of wiggle_count wiggle_count_upper = wiggle_count, -- max possible #iters. iff allow_float_wiggle_count, then this value must be defined. (disabled by default) wiggle_count_lower = wiggle_count, -- min possible #iters. iff allow_float_wiggle_count, then this value must be defined. (disabled by default) wiggle_count_bounds = wiggle_count, -- allowed variance for #iters. iff allow_float_wiggle_count, then this value must be defined. (disabled by default) global_wiggle = true, -- perform wa. iff false, then perform lws (local_wiggle) freeze_backbone = true, -- freeze bb freeze_sidechains = false, -- freeze sc (disabled by default) ci = 0.30, -- clashing importance allow_ci_float = false, -- allows "floating" via random number generation of ci. Iff true, ci_upper and ci_lower must be defined. (disabled by default) ci_upper = ci, -- U_ci_value. iff allow_ci_float == true, then this value must be defined. (disabled by default) ci_lower = ci, -- L_ci_value. iff allow_ci_float == true, then this value must be defined. (disabled by default) ci_bounds = ci, -- allowed variance for ci. ff allow_ci_float == true, then this value must be defined. (disabled by default) qs_recent_best = 3, -- iff exploratory == true, then recent best is saved into this saveslot freeze_hinge_instead = false, -- allows for the hinge to be frozen instead of the rods. (disabled by default) --- User Options End ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ score = 0, ranked_score = 0, multiplier = 0, } flag = {selected = false, mutate = false} uo = {mutateAlways = false} function SegmentListToSet(list) -- retirer doublons local result={} local f=0 local l=-1 table.sort(list) for i=1,#list do if list[i] ~= l+1 and list[i] ~= l then -- note: duplicates are removed if l>0 then result[#result+1]={f,l} end f=list[i] end l=list[i] end if l>0 then result[#result+1]={f,l} end --print("list to set") --SegmentPrintSet(result) return result end function SegmentSetToList(set) -- faire une liste a partir d'une zone local result={} for i=1,#set do --print(set[i][1],set[i][2]) for k=set[i][1],set[i][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 i=1,#list do if list[i]==s then return true elseif list[i]>s then return false end end return false end function SegmentInSet(set,s) --verifie si segment est dans la zone for i=1,#set do if s>=set[i][1] and s<=set[i][2] then return true elseif s<set[i][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 i=1,#list2 do result[#result+1]=list2[i] 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 i=1,#list1 do while list2[j]<list1[i] do j=j+1 if j>#list2 then return result end end if list1[i]==list2[j] then result[#result+1]=list1[i] 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 SegmentPrintListToSet(list) -- NEW BK 14/04/2014 prints a list in a set format SegmentPrintSet(SegmentListToSet(list)) end function SegmentSetToString(set) -- pour pouvoir imprimer local line = "" for i=1,#set do if i~=1 then line=line..", " end line=line..set[i][1].."-"..set[i][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 i=1,#sub do if not SegmentRangeInSet(set,sub[i]) 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 b=range[1] local e=range[2] for i=1,#set do if b>=set[i][1] and b<=set[i][2] then return (e<=set[i][2]) elseif e<=set[i][1] then return false end end return false end function SegmentSetToBool(set) -- vrai ou faux pour chaque segment utilisable ou non local result={} for i=1,structure.GetCount() do result[i]=SegmentInSet(set,i) end return result end --- End of Segment Set module function InitWORKONbool() WORKONbool=SegmentSetToBool(WORKON) end function Zone(zStart, zEnd, hw, prot, options) -- seg start & segend are not necesserally first and last segments for i=zStart, zEnd do j=WORKONBIS[i] -- NEW 24/9/2013 to be able to treat segments in any order defined in WORKON nbl_hinge(j, hw, prot, options) --SaveBestMaaa() end end function ShuffleTable(tab) --randomize order of elements local cnt=#tab for i=1,cnt do local r=math.random(cnt) tab[i],tab[r]=tab[r],tab[i] end return tab end local function _floor ( n ) return n - n%0.01 end local function _floor2 ( n,c ) return n - n%c end local _math = { _random = random, _random2 = random, _floor = _floor, _floor2 = _floor2, } local _saveslots = { max = 10, --#savelots available } local function get_value ( m, l, u ) --> mean, lower, upper local upper local lower upper = m+u lower = m-l return math._random (lower,upper) end local function get_value2 ( m, b ) --> mean, bounds (symmetrical) local upper local lower upper = m+b lower = m-b return math._random (lower,upper) end local _prot = { -- READ ONLY L_idx = 1, -- end of left-hand side rod L_idx2 = 1, -- beginning of left-hand side rod R_idx = 1, -- beginning of right-hand side rod R_idx2 = 1, -- end of right-hand side rod n = 1, -- local index (SS temp) k = 1, -- segment_count next_group = 0, -- local index rebuild_forward = true, -- direction indicator. true = right-side; false = left-side bands_enabled = true, } local function get_ss_group(r) local tmp while ( 1 ) do if r.rebuild_forward == true then tmp = structure.GetSecondaryStructure(r.R_idx2) else tmp = structure.GetSecondaryStructure(r.L_idx) end if tmp == r.n then if r.rebuild_forward == true then if r.R_idx2 < r.k then r.R_idx2 = r.R_idx2 + 1 else r.R_idx2 = r.k break end else if r.L_idx > 1 then r.L_idx = r.L_idx - 1 else r.L_idx = 1 break end end else if r.rebuild_forward == true then r.next_group = r.R_idx2 r.R_idx2 = r.R_idx2 - 1 else r.next_group = r.L_idx r.L_idx = r.L_idx + 1 end break end end -- while ( 1 ) return r end local function build_hinge(prot,options,i,hw) local glycine_idx prot.k = structure.GetCount() glycine_idx = i -- (internally) focus on the right side.. prot.R_idx2 = glycine_idx + 1 + hw prot.R_idx = glycine_idx + hw prot.rebuild_forward = true prot.n = structure.GetSecondaryStructure(glycine_idx + 1 ) prot = get_ss_group(prot ) -- (internally) focus on the left side.. prot.L_idx = glycine_idx - 2 prot.L_idx2 = glycine_idx - 1 prot.rebuild_forward = false prot.n = structure.GetSecondaryStructure(glycine_idx - 1 ) prot = get_ss_group(prot ) return prot end local function save_recent_best(options ) -- if ( options.exploratory == true ) then -- save.Quicksave(options.qs_recent_best ) -- else recentbest.Save() -- end end local function recall_recent_best(options ) -- if ( options.exploratory == true ) then -- save.Quickload(options.qs_recent_best ) -- else recentbest.Restore() -- end end function ncWiggle(zone, iters, iter) how = "wa" iters = iters or 1 iter = iter or 1 local step = .001 local ws = 0 --if flag.selected then ws = ws+1 end if uo.mutateAlways or flag.mutate then ws = ws+10 end function wShake() if ws==0 then structure.ShakeSidechainsAll(1) --elseif ws==1 then structure.ShakeSidechainsSelected(1) elseif ws==10 then structure.MutateSidechainsAll(1) --elseif ws==11 then structure.MutateSidechainsSelected(1) end end function wWiggle() local b, s = true, true if how=='wb' then s = false end --if ws==1 then --structure.WiggleSelected(iters, b, s) --else if zone=='a' then structure.WiggleAll(iters, b, s) else structure.LocalWiggleAll(iters, b, s) end --end end if how=='s' then local sp = current.GetScore() wShake() if (current.GetScore()-sp)>(step*(1+iter)) then wShake() end else local sp = current.GetScore() wWiggle() if (current.GetScore()-sp)>(step*(1+iter)) then ncWiggle(how, iters+1, iter+1) end end end local function wiggle(prot,options ) local do_wiggle local iter -- establish if this is a global or local operation if ( options.global_wiggle == true ) then do_wiggle = ncWiggle('a') else do_wiggle = ncWiggle('l') end -- establish how to execute wiggle if ( options.allow_float_wiggle_count == true ) then local mean local upper local lower local bounds mean = options.wiggle_count upper = options.wiggle_count_upper lower = options.wiggle_count_lower bounds = options.wiggle_count_bounds iter = get_value2(mean,bounds ) --iter = get_value ( mean, lower, upper ) else if ( prot.bands_enabled ) then -- are we flexing ? iter = options.wiggle_count else iter = options.wiggle_out_count end end if ( options.verbose == true ) then -- print ( "Performing Wiggle | iters = ", iter ) end ncWiggle('a', iters, iter) end local function show_score(options ) local s local gn gn = "" if ( options.exploratory == true ) then s = current.GetScore() local n = { [true] = "Yes", [false] = "No", } print ( "Stabilization Score = ", current.GetEnergyScore()) print ( "Ranking score = ", current.GetScore()) print ( "Multiplier: ", current.GetExplorationMultiplier() ) print ( "Conditions met: ", n [current.AreConditionsMet()] ) if ( s > options.ranked_score ) then save.Quicksave(options.qs_recent_best ) if ( options.ranked_score ~= 0 ) then local gain = s-options.ranked_score gn = " + "..gain end options.score = current.GetEnergyScore() options.ranked_score = s options.multiplier = current.GetExplorationMultiplier() end print ( "Ranking Score = ", s..gn ) print ("") else s = current.GetEnergyScore() if ( s > options.score ) then if ( options.score ~= 0 ) then local gain = s-options.score gn = " + "..gain end options.score = s end print ( "Score = ", s..gn ) --print ("") end return options end local function freeze_rods(prot,options ) local r_idx local r_idx2 local l_idx local l_idx2 local freeze_sc local freeze_bb selection.DeselectAll() r_idx = prot.R_idx r_idx2 = prot.R_idx2 l_idx = prot.L_idx l_idx2 = prot.L_idx2 freeze_sc = options.freeze_sidechains freeze_bb = options.freeze_backbone selection.SelectRange(r_idx,r_idx2 ) selection.SelectRange(l_idx,l_idx2 ) if ( options.verbose == true ) then local _s = { [true] = "true", [false] = "false", } -- print ( "Freezing backbone.." ) -- print ( "backbone = ", _s [freeze_bb] ) -- print ( "sidechains = ", _s [freeze_sc] ) end freeze.FreezeSelected(freeze_bb, freeze_sc ) selection.SelectAll() end local function rod_add_bands(prot,options ) local idx local idx2 local str local k idx = prot.R_idx idx2 = prot.L_idx2 k = structure.GetCount() + 1 str = options.band_strength if ( options.verbose == true ) then -- print ( "Placing bands.." ) -- print ( "Setting band strength: ", str ) end for i = 0,3 do local n local n2 n = idx + i n2 = idx2 - i if (( n < k ) and ( n2 > 0 )) then band.AddBetweenSegments(n,n2 ) band.SetStrength(i+1,str ) end end end local function set_clash_importance(options ) local ci if ( options.allow_ci_float == true ) then local mean local upper local lower local bounds mean = options.ci upper = options.ci_upper lower = options.ci_lower bounds = options.ci_bounds ci = get_value2(mean,bounds ) --ci = get_value(mean, lower, upper ) else ci = options.ci end if ( options.verbose == true ) then --print ( "Setting clash importance: ", ci ) end behavior.SetClashImportance(ci ) end local function reset_clash_importance(options ) if ( options.verbose == true ) then -- print ( "Resetting clash importance: ", 1 ) end behavior.SetClashImportance(1) end local function turn_bands_on(prot, options ) if ( options.verbose == true ) then --print ( "Enabling bands.." ) end band.EnableAll() prot.bands_enabled = true set_clash_importance(options ) return prot end local function turn_bands_off(prot, options ) if ( options.verbose == true ) then --print ( "Disabling bands.." ) end band.DisableAll() prot.bands_enabled = false reset_clash_importance ( options ) return prot end local function unfreeze_rods(prot,options ) freeze.UnfreezeAll() end local function freeze_hinge(prot,options ) local glycine_idx local freeze_bb local freeze_sc selection.DeselectAll() glycine_idx = glycine_locator(prot,options ) freeze_sc = options.freeze_sidechains freeze_bb = options.freeze_backbone selection.Select(glycine_idx ) freeze.FreezeSelected(freeze_bb,freeze_sc ) selection.SelectAll() end local function unfreeze_hinge(prot,options ) freeze.UnfreezeAll() end local function check_preconditions(prot, options ) if options.freeze_hinge_instead == true then turn_bands_on(options ) wiggle(prot,options ) turn_bands_off(options ) unfreeze_rods(prot,options ) freeze_hinge(prot,options ) end end function nbl_hinge(seg, hw, prot, options) if (hw==1) then print ("Segment: " .. seg) else print ("Segments: " .. seg .. "-" .. seg+hw-1) end prot = build_hinge(prot, options, seg, hw) freeze_rods(prot, options ) rod_add_bands(prot, options ) save_recent_best(options ) check_preconditions(prot, options ) prot = turn_bands_on(prot, options ) wiggle(prot, options ) prot = turn_bands_off(prot, options ) wiggle(prot, options ) recall_recent_best(options ) options = show_score(options ) freeze.UnfreezeAll() band.DeleteAll() end function Checknums(nums) -- Now checking if #nums%2 ~= 0 then print("Not an even number of segments found") return false end for i=1,#nums do if nums[i]==0 or nums[i]>structure.GetCount() then print("Number "..nums[i].." is not a segment") return false end end return true end function ReadSegmentSet(data) local nums = {} local NoNegatives='%d+' -- - is not part of a number local result={} for v in string.gfind(data,NoNegatives) do table.insert(nums, tonumber(v)) end if Checknums(nums) then for i=1,#nums/2 do result[i]={nums[2*i-1],nums[2*i]} end result=SegmentCleanSet(result) else Errfound=true result={} end return result end function bkh(hinge_width, prot, options) --print ("Segs aleatoires") print ("Random segs") compteur=0 -- intialise le compteur de WORKONBIS p=print --"quicker" print segCnt=structure.GetCount() --segCnt=segCnt-1 -- for lingard puzzles only! sera initialise par seglock flagligand=false segCnt2=segCnt -- cas de ligands segStart = range_min segEnd = range_max while structure.GetSecondaryStructure(segCnt2)=="M" do segCnt2=segCnt2-1 flagligand=true end WORKON={{1,segCnt2}} --BK16/04/2014 WORKONBIS={} for i = segStart, segEnd do compteur=compteur+1 WORKONBIS[compteur]=i end ShuffleTable(WORKONBIS) -- NEW 24/9/2013 mix the segment table randomly si=current.GetScore() --print ("Score initial: " .. si) print ("Starting score: " .. si) for run = 1, nbrun do print() --print ("Boucle " .. run .. " sur " .. nbrun) print ("Loop " .. run .. " of " .. nbrun) Zone(1, #WORKONBIS, hinge_width, prot, options) end end function nblh(hinge_width, prot, options) for run = 1, nbrun do if (run > 1) then rci = math.random() / 5 options.ci = ici + rci - 0.1 rbs = math.random() / 10 options.band_strength = ibs + rbs - 0.05 end print() --print ("Boucle " .. run .. " sur " .. nbrun) print ("Loop " .. run .. " of " .. nbrun) print ("CI " .. options.ci) print ("Band strength " .. options.band_strength) si=current.GetScore() --print ("Score initial: " .. si) print ("Starting score: " .. si) for i=range_min, range_max do nbl_hinge(i, hinge_width, prot, options) end print ("Gain: " .. current.GetScore()-si) --print ("Gain total: " .. current.GetScore()-startscore) print ("Total gain: " .. current.GetScore()-startscore) end end do local prot local options print ( "NBL_hinge v1.1" ) options = _options prot = _prot ici = options.ci ibs = options.band_strength math.randomseed(os.time()%1000000) math.random(100) freeze.UnfreezeAll() band.DeleteAll() startscore=current.GetScore() sc = structure.GetCount() range_min = 3 range_max = sc-3 local ask = dialog.CreateDialog("nbl_hinge") --ask.hinge_width = dialog.AddSlider("Taille charnieres: ",1,1,2,0) ask.hinge_width = dialog.AddSlider("Hinges size: ",1,1,2,0) --ask.keep_trying = dialog.AddCheckbox("Toute la nuit ", true) ask.keep_trying = dialog.AddCheckbox("Keep trying ", true) --ask.random = dialog.AddCheckbox("Segs aleatoires ", false) ask.random = dialog.AddCheckbox("Random ", false) --ask.range = dialog.AddTextbox("Zone forcee", "") ask.range = dialog.AddTextbox("Range ", "") ask.OK = dialog.AddButton("OK",1) ask.Cancel = dialog.AddButton("Cancel",0) if (dialog.Show(ask) > 0) then hinge_width = ask.hinge_width.value keep_trying = ask.keep_trying.value random = ask.random.value if (ask.range.value ~= "") then local rangetext=ask.range.value local rangelist=ReadSegmentSet(rangetext) if not Errfound then range_min = rangelist[1][1] if (range_min<3) then range_min = 3 end range_max = rangelist[1][2] if (range_max > sc-3) then range_max = sc-3 end else print ("Error in range, using default") end end else Exit() end if keep_trying then nbrun = 100 else nbrun=1 end if random then bkh(hinge_width, prot, options) else nblh(hinge_width, prot, options) end end

Comments