Icon representing a recipe

Recipe: CM - Compressor - V2.03 nc

created by Bruno Kestemont

Profile


Name
CM - Compressor - V2.03 nc
ID
48005
Shared with
Public
Parent
CM - Compressor - V2.03
Children
None
Created on
March 21, 2014 at 23:36 PM UTC
Updated on
March 21, 2014 at 23:36 PM UTC
Description

Based on Rav3en_pl's compressor code. Added random bands for de-novo Monte-Carlo folding as well as autodetection of mutate puzzles to use mutation code. When script cancelled - it restores the recent best score. Now with some dialog settings.
New feature is Experimental bands that select all outermost segments and bands them together.
Added feature is Hydrophobe Modulation that decreases the band length if it is between two hydrophobic segments or increase a band length if it is between two hydrophilic segments.

Best for


Code


--[[ Rav3n_pl Compressor v2.03nc ComputerMage - converted to V2.0 script. trying to compress/decompress protein accepting loss of points between pulls with some aditions. BK optimized for New Chapter 06/02/2014 ]]-- ----------- options below VVVVV --------------------- cLoops = 1500 --<<< SET NUMBER OF LOOPS decomp = false --true --true for DeCompression instead of compression modualtor = false --changing compression/decompression each loop randomModulation = true hydrophobicModulation = false useRegions = { --set regions that have to be used in all bands --{1,20}, --there are exaples, uncomment and edit --{25,55}, --{100,210}, } compressFrac = 15 --make bands shorter by that much percents compressFracMin = 5 -- if this parameter set it will randomly select pecentage between this parameter and compressFrac minSkip = 15 --minimum segment distance between banded segments minBands = 3 -- if minBands less than 1 then it uses fixed amount of bands -- defined in numBands, otherwise it generates random number of bands beween minBands and numBands for each iteration. numBands = 13 --how many bands use at once fastQstab = true --false --true --only 1 shake and 1 wiglle when true useFuze = true -- use Fuze after qStab fuzeScore = 10 --how close we have to be to run Fuze allLoop = false --work in all-loop mode. sometimes work better than structure mode :) S2H = false --all bands are between sheets and helixes useStructure = false --all bands have at least one end on structure (not loop) noLoops=false --band can`t have any end on loop minBandStrength = 0.3 -- 0.3 --starting band str maxBandStrength = 1.5 -- 1.0 -- max band strenght minDist = 3 --minimum band length slowBands = false --bands strength are raised few times till score drops by % percLoss = 1 --pulling stops when score drops by that percent (ie 2=200pts when 10k pts) repeatGood = true --repeating good bands if true pullingCI = 0.3 --0.6--clash impotrance during pull maxLoss = 30 --maximum acceptable LOSS after Fuze. also lowering fuzeScore reloadBest = 5 --reload best solution after that many worst ones normal = true -- checks if this is exploration puzzle mutate = false mutateIterations = 2 experimentalCompress = false ------------ end of options ^^^^^^ segCnt = 0 function table.sort(x,comp) local j local v if comp == nil then comp=function(x,y) return x<y end end for i = #x-1,1,-1 do v=x[i] j=i while (j<#x) and (comp(x[j+1],v)) do x[j]=x[j+1] j=j+1 end x[j]=v end end function GetSortedDistances() local distances = {} for segment = 1, structure.GetCount() do totalDistance = 0 for otherSegment = 1, structure.GetCount() do if segment ~= otherSegment then totalDistance = totalDistance + structure.GetDistance(segment, otherSegment) end end distances[#distances + 1] = {segment, totalDistance} end table.sort(distances, function(x,y) return x[2] < y[2] end) print ('#distances=', #distances, '\n') return distances end function GetSortedDistancesFromSegment(segment) local distances = {} for otherSegment = 1, structure.GetCount() do if segment ~= otherSegment then distances[#distances + 1] = {otherSegment, structure.GetDistance(segment, otherSegment)} end end table.sort(distances, function(x,y) return x[2] < y[2] end) return distances end function GetSortedDistancesFromSegmentList(segmentsList) local distances = {} for segment = 1, structure.GetCount() do totalDistance = 0 for idx = 1, #segmentsList do local otherSegment = segmentsList[idx] if segment ~= otherSegment then totalDistance = totalDistance + structure.GetDistance(segment, otherSegment) end end distances[#distances + 1] = {segment, totalDistance} end table.sort(distances, function(x,y) return x[2] < y[2] end) return distances end function GetSortedDistancesFromSegmentListForSegment(seg, segmentsList) local distances = {} for idx = 1, #segmentsList do local otherSegment = segmentsList[idx] if segment ~= otherSegment then distances[#distances + 1] = {otherSegment, structure.GetDistance(seg, otherSegment)} end end table.sort(distances, function(x,y) return x[2] < y[2] end) return distances end function SetupBandBetweenSegmentsWithParameters(seg1, seg2, goalLength, strength) local bandNo = band.AddBetweenSegments(seg1, seg2) if bandNo > 0 then local bandLength = band.GetLength(bandNo) if goalLength ~= nil then if type(goalLength) == 'string' and string.sub(goalLength, -1) == '%' then local val = tonumber(string.sub(goalLength, 1, -2)) if val ~= nil then bandLength = bandLength * (val / 100) end else bandLength = goalLength end if bandLength < 3 then --not make shorter band, useless bandLength = 3 end if bandLength > 20 then --not make longer band, useless bandLength = 20 end band.SetGoalLength(bandNo, bandLength) end if strength ~= nil then band.SetStrength(bandNo, strength) end end end -- Module Find Segment Types function FindMutablesList() local result={} for i=1,segCnt2 do if structure.IsMutable(i) then result[#result+1]=i end end return result end function FindMutables() return SegmentListToSet(FindMutablesList()) end function FindFrozenList() local result={} for i=1,segCnt2 do if freeze.IsFrozen(i) then result[#result+1]=i end end return result end function FindFrozen() return SegmentListToSet(FindFrozenList()) end function FindLockedList() local result={} for i=1,segCnt2 do if structure.IsLocked(i) then result[#result+1]=i end end return result end function FindLocked() return SegmentListToSet(FindLockedList()) end function FindSelectedList() local result={} for i=1,segCnt do if selection.IsSelected(i) then result[#result+1]=i end end return result end function FindSelected() return SegmentListToSet(FindSelectedList()) end function FindAAtypeList(aa) local result={} for i=1,segCnt2 do if structure.GetSecondaryStructure(i)== aa then result[#result+1]=i 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 i=1,segCnt2 do if structure.GetAminoAcid(i) == at then result[#result+1]=i end end return result end -- end Module Find Segment Types -- Start of module for bridgechecking Cyslist={} savebridges=false --default no bridgechecking nrofbridges=0 function setCyslist() Cyslist=FindAminotype("c") nrofbridges=CountBridges() end function IsBridge(i) return ''..current.GetSegmentEnergySubscore(i,'disulfides') ~= '-0' end function CountBridges() local count = 0 for i = 1,#Cyslist do if IsBridge(Cyslist[i]) then count = count + 1 end end return count end function BridgesBroken() return savebridges == true and CountBridges() < nrofbridges end function Bridgesave() if savebridges then PushPosition() end end function Bridgerestore() if savebridges then if BridgesBroken() then PopPosition() else ClrTopPosition() end end end -- End module bridgechecking function Score() local s=0 if normal==true then s=current.GetEnergyScore() else s=current.GetScore() end return s end function round(x)--cut all afer 3-rd place return x-x%0.001 end function abs(x) if x<0 then x=-x end return x end function round(x)--cut all afer 3-rd place return x-x%0.001 end function down(x) return x-x%1 end function Wiggle(how, iters, minppi) --score conditioned recursive wiggle/shake if how==nil then how="wa" end if iters==nil then iters=6 end if minppi==nil then minppi=0.1 end if iters>0 then iters=iters-1 local sp=Score() if how == "s" then structure.ShakeSidechainsAll(1) elseif how == "wb" then structure.WiggleAll(1, true, false) elseif how == "ws" then structure.WiggleAll(1, false, true) elseif how == "wa" then structure.WiggleAll(1, true, true) end if Score()-sp > minppi then return Wiggle(how, iters, minppi) end end end SAVEDstructs=false function AllLoop() --turning entire structure to loops local anychange=false for i=1,segCnt do if structure.GetSecondaryStructure(i)~="L" then anychange=true break end end if anychange then save.SaveSecondaryStructure() SAVEDstructs=true selection.SelectAll() structure.SetSecondaryStructureSelected("L") end end function qStab() behavior.SetClashImportance(0.1) Wiggle("s",1) if mutate == true then structure.MutateSidechainsSelected(mutateIterations) SaveBest(); end selection.SelectAll() if fastQstab==false then behavior.SetClashImportance(0.4) Wiggle("wa",1) behavior.SetClashImportance(1) Wiggle("s",1) end behavior.SetClashImportance(1) Wiggle() end function FuzeEnd() behavior.SetClashImportance(1) if mutate == true then structure.MutateSidechainsSelected(mutateIterations) end Wiggle("wa",1) Wiggle("s",1) Wiggle() SaveBest() end function Fuze1(ci1,ci2) behavior.SetClashImportance(ci1) Wiggle("s",1) behavior.SetClashImportance(ci2) Wiggle("wa",1) end function Fuze2(ci1,ci2) behavior.SetClashImportance(ci1) Wiggle("wa",1) behavior.SetClashImportance(1) Wiggle("wa") behavior.SetClashImportance(ci2) Wiggle("wa",1) end function reFuze(scr,slot) local s=Score() if s<scr then save.Quickload(slot) else scr=s save.Quicksave(slot) end return scr end function Fuze(slot) local scr=Score() save.Quicksave(slot) selection.SelectAll() Fuze1(0.3,0.6) FuzeEnd() scr=reFuze(scr,slot) Fuze2(0.3,1) SaveBest() scr=reFuze(scr,slot) Fuze1(0.05,1) SaveBest() scr=reFuze(scr,slot) Fuze2(0.7,0.5) FuzeEnd() scr=reFuze(scr,slot) Fuze1(0.07,1) SaveBest() reFuze(scr,slot) end --[[ Tlaloc`s math library ------------------------------------------------------------------------ The original random script this was ported from has the following notices: Copyright (c) 2007 Richard L. Mueller Hilltop Lab web site - http://www.rlmueller.net Version 1.0 - January 2, 2007 You have a royalty-free right to use, modify, reproduce, and distribute this script file in any way you find useful, provided that you agree that the copyright owner above has no warranty, obligations, or liability for such use. ------------------------------------------------------------------------ ]]-- local lngX = 1000 local lngC = 48313 local function _random(m,n) local A_Hi = 63551 local A_Lo = 25354 local M = 4294967296 local H = 65536 function _MWC() local S_Hi = math.floor(lngX / H) local S_Lo = lngX - (S_Hi * H) local C_Hi = math.floor(lngC / H) local F1 = A_Hi * S_Hi local F2 = (A_Hi * S_Lo) + (A_Lo * S_Hi) + C_Hi lngX = ((F2 - (math.floor(F2 / H) * H)) * H) + (A_Lo * S_Lo) + lngC - (C_Hi * H) lngX = lngX - (math.floor(lngX / M) * M) lngC = math.floor((F2 / H) + F1) return lngX end if n == nil and m ~= nil then n = m m = 1 end if (m == nil) and (n == nil) then return _MWC() / M else if n < m then return nil end return math.floor((_MWC() / M) * (n - m + 1)) + m end end local function _abs(value) if value < 0 then return -value else return value end end local function _floor(value) return value - (value % 1) end local function _randomseed(s) if s==nil then s=math.abs(Score()) s=s%0.001 s=1/s while s<10000000 do s=s*10 end s=s-s%1 end lngX = s end math= { abs = _abs, floor = _floor, random = _random, randomseed = _randomseed, } math.randomseed() --[[ End math library ]]-- bestScore=Score() function SaveBest() local g=Score()-bestScore if g>0 then print("Gained another ",round(g)," pts.") bestScore=Score() save.Quicksave(3) end end function MakeBands() local num = 0 if minBands > 0 then if minBands > numBands then minBands = 1 end num = math.random(minBands, numBands) else num = numBands end if minBands < 1 then print("Make "..num.." bands") else print("Make "..num.." bands, where min is "..minBands.." and max is "..numBands) end InternalMakeBands(num) end function InternalMakeBands(num) local done=false local s1=math.random(segCnt) local s2=math.random(segCnt) if s1>s2 then s1,s2=s2,s1 end local d=structure.GetDistance(s1,s2) if s2-s1>=minSkip and d>=minDist then done=true end if (done and #useRegions>0) then done=false for a=1,#useRegions do local ss=useRegions[a][1] local se=useRegions[a][2] if (s1>=ss and s1<=se) or (s2>=ss and s2<=se) then done=true break end end end local ss1=structure.GetSecondaryStructure(s1) local ss2=structure.GetSecondaryStructure(s2) if (done and noLoops) then if ss1=="L" or ss2=="L" then done=false end end if (done and useStructure) then if ss1=="L" and ss2=="L" then done=false end end if (done and S2H) then if (ss1=="E" or ss2=="E") and (ss1=="H" or ss2=="H") and (ss1~=ss2) then done=true else done=false end end if done then num=num-1 mkBand(s1,s2) bands[#bands+1]={s1,s2} end if num>0 then return InternalMakeBands(num) end --tail call end function mkBand(s1,s2) band.AddBetweenSegments(s1,s2) local len = structure.GetDistance(s1,s2) local frac = compressFrac if compressFracMin ~= nil then frac = math.random(compressFracMin, compressFrac) end if hydrophobicModulation == true then local s1hydrophobic = structure.IsHydrophobic(s1) local s2hydrophobic = structure.IsHydrophobic(s2) if s1hydrophobic == true and s2hydrophobic == true then frac = 1 - frac / 100; elseif s1hydrophobic == false and s2hydrophobic == false then frac = 1 + frac / 100; end else if randomModulation == false then if decomp == true then frac = 1 + frac / 100; else frac = 1 - frac / 100; end else if math.random(1,10) > 5 then frac = 1 + frac / 100; else frac = 1 - frac / 100; end end end frac = tostring(frac * 100) .. "%" SetupBandBetweenSegmentsWithParameters(s1, s2, frac) end bands={} function Repeat_bands(bands) band.DeleteAll() for i=1,#bands do local s1=bands[i][1] local s2=bands[i][2] mkBand(s1,s2) end end function ExperimentalBands() local idx, idx1, idx2 = 1,1,1 local distances = GetSortedDistances() local centerSegment = distances[1][1] distancesFromCenter = GetSortedDistancesFromSegment(centerSegment) local axes = {distancesFromCenter[#distancesFromCenter][1]} for idx=1, structure.GetCount() do distances = GetSortedDistancesFromSegmentList(axes) axes[#axes + 1] = distances[#distances][1] end temp = {} for idx=1, #axes do temp[axes[idx]] = 1 end axes = {} for seg, t in pairs(temp) do axes[#axes+1] = seg end bandSegPairs = {} bands = {} for idx1=1, #axes do local seg1 = axes[idx1] distances = GetSortedDistancesFromSegmentListForSegment(seg1, axes) for idx2=1, math.floor(#distances/2,1) do local seg2 = distances[idx2][1] if bandSegPairs[seg1..'|'..seg2] == nil or bandSegPairs[seg2..'|'..seg1] == nil then bandSegPairs[seg1..'|'..seg2] = 1 if seg1 ~= seg2 and math.abs(seg1 - seg2) > 2 then SetupBandBetweenSegmentsWithParameters(seg1, seg2, "95%", 1.1) bands[#bands+1]={seg1,seg2} end end end end end function SetBandsStrength(str) --set all band strengt if str<0.1 then str=0.1 end if str>10 then str=10 end for i=1, band.GetCount() do band.SetStrength(i, str) end end function RandomBandStrength() --set all band strengt if minBandStrength<0.1 then BandStrength=0.1 end if maxBandStrength>10 then maxBandStrength=10 end for i=1, band.GetCount() do band.SetStrength(i, math.random(minBandStrength, maxBandStrength)) end end function SaveRB(slot) save.Quicksave(slot) recentbest.Restore() SaveBest() save.Quickload(slot) end function Cleanup(err) print("Restoring CI, best result and structures") behavior.SetClashImportance(1) save.Quickload(3) if SAVEDstructs then save.LoadSecondaryStructure() end print(err) end sscore=Score() --starting score function Compressor() print("Starting Compressor v2, ",cLoops," loops.") if normal==false then print("Using exploration options.") end if mutate==true then print("Puzzle has mutable segments. Enabling mutations.") end if allLoop then AllLoop() end save.Quicksave(3) save.Quicksave(7) --save state for losing badOnes=0 recentbest.Save() local best=false for i=1,cLoops do loss=Score()*percLoss/100 --pulling till we lost some points band.DeleteAll() if best==true and repeatGood==true then print("Repeating last bands.") if modualtor==true then --switch decomp= not decomp end Repeat_bands(bands) elseif experimentalCompress then ExperimentalBands() else bands={} MakeBands() end local ls=Score() local tx="compressing." if randomModulation == false then if hydrophobicModulation == true then tx = "Hydrophobic Modulation" else if decomp==true then tx="Dec"..tx else tx="C"..tx end end else tx = "Random modulation" end print("Loop ",i," of ",cLoops," started. ", tx) print(" Current score: ",round(ls)) behavior.SetClashImportance(pullingCI) selection.SelectAll() recentbest.Save() if slowBands then for str=minBandStrength,maxBandStrength,0.07 do--search enough band strenght to move recentbest.Restore() --because sometimes it makes points during pull :D local ss=Score() SetBandsStrength(str) Wiggle("wb",1) if ss-Score()>loss then break end end else RandomBandStrength(bandStr) Wiggle("wb",1) end SaveRB(4) --because sometimes it missing fractions structure.ShakeSidechainsAll(1) --06/02/2014 Wiggle(2)--06/02/2014 band.DeleteAll() SaveBest() if mutate == true then structure.MutateSidechainsSelected(mutateIterations) end SaveBest() qStab() if useFuze and Score()> (bestScore-fuzeScore) then SaveBest() if mutate == true then structure.MutateSidechainsSelected(mutateIterations) end Fuze(4) if mutate == true then structure.MutateSidechainsSelected(mutateIterations) end else SaveBest() end if maxLoss>0 then if Score()>bestScore-maxLoss then save.Quicksave(7) --save actual "best" solution else badOnes=badOnes+1 if badOnes >=reloadBest then badOnes=0 save.Quickload(3) else save.Quickload(7) --load "second best" end end else save.Quickload(3) end local es=Score() if es>ls then best=true else best=false end --repeating all bands making points print("Loop ",i," gain ",round(es-ls)," ;total gain ",round(bestScore-sscore)) if modualtor==true then --switch decomp= not decomp end end save.Quickload(3) if allLoop then save.LoadSecondaryStructure() end print("Total gain: ",round(Score()-sscore)) end --main call segCnt = structure.GetCount() while structure.GetSecondaryStructure(segCnt)=="M" do segCnt=segCnt-1 end if current.GetExplorationMultiplier() ~= 0 then normal = false end for idx = 1,segCnt do if structure.IsMutable(idx) then mutate=true break end end -- Settings code local dlg = dialog.CreateDialog("Compressor Settings:") dlg.cLoops = dialog.AddSlider("Loops to work:", cLoops, 0, 3000, 0) dlg.decomp = dialog.AddCheckbox("Use Decompress instead?", decomp) dlg.modulator = dialog.AddCheckbox("Modulate loops?", modulator) dlg.randomModulation = dialog.AddCheckbox("Random modulation?", randomModulation) dlg.experimentalCompress = dialog.AddCheckbox("Experimental Compression?", experimentalCompress) dlg.hydrophobicModulation = dialog.AddCheckbox("Hydrophobic Modulation?", hydrophobicModulation) dlg.l1 = dialog.AddLabel("Compression rate:") dlg.compressFracMin = dialog.AddSlider("Minimum %", compressFracMin, 0, 100, 0) dlg.compressFrac = dialog.AddSlider("Maximum %", compressFrac, 0, 100, 0) dlg.l2 = dialog.AddLabel("Bands:") dlg.minBands = dialog.AddSlider("Minimum", minBands, 0, segCnt, 0) dlg.numBands = dialog.AddSlider("Maximum", numBands, 1, segCnt, 0) dlg.l3 = dialog.AddLabel("Segments between band endpoints:") dlg.minSkip = dialog.AddSlider("Minimum", minSkip, 3, segCnt, 0) dlg.l4 = dialog.AddLabel("Band strength:") dlg.minBandStrength = dialog.AddSlider("Minimum", minBandStrength, 0, 10, 1) dlg.maxBandStrength = dialog.AddSlider("Maximum", maxBandStrength, 0, 10, 1) dlg.minDist = dialog.AddSlider("Min band length", minDist, 0, 20, 0) dlg.slowBands = dialog.AddCheckbox("Slow Bands", slowBands) dlg.repeatGood = dialog.AddCheckbox("Repeat good bands", repeatGood) dlg.pullingCI = dialog.AddSlider("Pulling CI", pullingCI, 0, 1.0, 4) if mutate == true then dlg.mutateIterations = dialog.AddSlider("Mutate iterations", mutateIterations, 0, 100, 0) end dlg.OK = dialog.AddButton("OK",1) dlg.Cancel = dialog.AddButton("Cancel",0) -- percLoss = 1 --pulling stops when score drops by that percent (ie 2=200pts when 10k pts) if dialog.Show(dlg) > 0 then -- Set modified values cLoops = dlg.cLoops.value decomp = dlg.decomp.value modulator = dlg.modulator.value randomModulation = dlg.randomModulation.value experimentalCompress = dlg.experimentalCompress.value hydrophobicModulation = dlg.hydrophobicModulation.value compressFracMin = dlg.compressFracMin.value compressFrac = dlg.compressFrac.value numBands = dlg.numBands.value minBands = dlg.minBands.value minSkip = dlg.minSkip.value minBandStrength = dlg.minBandStrength.value maxBandStrength = dlg.maxBandStrength.value minDist = dlg.minDist.value slowBands = dlg.slowBands.value repeatGood = dlg.repeatGood.value pullingCI = dlg.pullingCI.value if mutate == true then mutateIterations = dlg.mutateIterations.value end if hydrophobicModulation == true then experimentalCompress = false randomModulation = false elseif experimentalCompress == true then hydrophobicModulation = false randomModulation = false elseif randomModulation == true then hydrophobicModulation = false experimentalCompress = false end xpcall(Compressor,Cleanup) else print("Dialog cancelled.") end --end of scipt

Comments