Icon representing a recipe

Recipe: Rebuild-Remix Selection 2.51 98Rebuild

created by marsfan

Profile


Name
Rebuild-Remix Selection 2.51 98Rebuild
ID
103608
Shared with
Public
Parent
Rebuild-Remix Selection 2.51
Children
Created on
June 18, 2020 at 04:47 AM UTC
Updated on
June 18, 2020 at 04:47 AM UTC
Description

Allows to Remix or Rebuild selections. You may choose between high quality and fast speed execution.

The only change that I have made is the sliders now go up to 98, so that you can utilize even more remix slots!

Best for


Code


--[[ Note from marsfan: I shrunk the size of the file from 1500 lines to 705 lines using regex replace in visual studio code The search string was (\n *^)\n The replacement string was \n I then added a newline before the start of each funcction, to add some spacing between functions ]]-- version = "2.5" --service functions function ScoreReturn() x = current.GetEnergyScore() return roundX(x) end function roundX(x)--cut all afer 3-rd place return x-x%0.1 end function ScoreBBReturn() x = 0 for i=1, proteinLength do x = x + current.GetSegmentEnergySubscore(i, "Clashing") --x = x + current.GetSegmentEnergySubscore(i, "Backbone") + current.GetSegmentEnergySubscore(i, "Bonding") + current.GetSegmentEnergySubscore(i, "Ideality") + current.GetSegmentEnergySubscore(i, "Pairwise") + current.GetSegmentEnergySubscore(i, "Packing") + current.GetSegmentEnergySubscore(i, "Hiding") -- no: -- print (i, "subscore:",x) end x = current.GetEnergyScore() - x return x-x%1 end --Dialog function RequestOptions() ask=dialog.CreateDialog("Options: Rebuild/Remix selected v"..version) ask.maxRebuildCount = dialog.AddSlider("Solutions to search",15,1,98,0) --up to 98 slots possible (change 36 to 98 if needed) ask.slotsToFuze = dialog.AddSlider("Slots to fuze",slotsToFuze,1,maxRebuildCount,0) ask.remixNotRebuild=dialog.AddCheckbox("Remix instead of Rebuild", remixNotRebuild) --ask.remixNotRebuild.value=false ask.convertLoop=dialog.AddCheckbox("Convert to Loop", convertLoop) --selections --ask.s1 = dialog.AddLabel("Selections") ask.selectionStart1 = dialog.AddSlider("Start segment",selectionStartArr[1],0,proteinLength,0) ask.selectionEnd1 = dialog.AddSlider("End segment",selectionEndArr[1],1,proteinLength,0) if selDialog>1 then if selNum < 2 then selectionStartArr[2]=7 selectionEndArr[2]=10 end ask.s2 = dialog.AddLabel("Selection2") ask.selectionStart2 = dialog.AddSlider("Selection2 Start",selectionStartArr[2],1,proteinLength,0) ask.selectionEnd2 = dialog.AddSlider("Selection2 End",selectionEndArr[2],1,proteinLength,0) end if selDialog>2 then if selNum < 3 then selectionStartArr[3]=12 selectionEndArr[3]=15 end ask.s3 = dialog.AddLabel("Selection3") ask.selectionStart3 = dialog.AddSlider("Selection3 Start",selectionStartArr[3],1,proteinLength,0) ask.selectionEnd3 = dialog.AddSlider("Selection3 End",selectionEndArr[3],1,proteinLength,0) end if selDialog>3 then if selNum < 4 then selectionStartArr[4]=12 selectionEndArr[4]=15 end ask.s4 = dialog.AddLabel("Selection4") ask.selectionStart4 = dialog.AddSlider("Selection4 Start",selectionStartArr[4],1,proteinLength,0) ask.selectionEnd4 = dialog.AddSlider("Selection4 End",selectionEndArr[4],1,proteinLength,0) end if selDialog>4 then if selNum < 5 then selectionStartArr[5]=12 selectionEndArr[5]=15 end ask.s5 = dialog.AddLabel("Selection5") ask.selectionStart5 = dialog.AddSlider("Selection5 Start",selectionStartArr[5],1,proteinLength,0) ask.selectionEnd5 = dialog.AddSlider("Selection5 End",selectionEndArr[5],1,proteinLength,0) end if selDialog>5 then ask.s6 = dialog.AddLabel("(not showing more than 5 selections, but Rebuilding)") end --fuze options ask.l1 = dialog.AddLabel("Fuze:") ask.shakeOnRank=dialog.AddCheckbox("Shake each solution on Rebuild (longer)", shakeOnRank) ask.forceChange=dialog.AddCheckbox("Force Changes (loss)", forceChange) ask.turboMode=dialog.AddCheckbox("Turbo Mode (no Fuze, so very fast)", turboMode) --ask.fastFuze2=dialog.AddCheckbox("Fuze longer", fastFuze2) --ask.fastFuze2.value=false --ask.l2 = dialog.AddLabel("How much to report") ask.reportLevel = dialog.AddSlider("Report detalization", reportLevel,1,4,0) ask.fullProtein=dialog.AddCheckbox("Full protein Rebuild (selections ignored)", fullProtein) ask.infiniteExecution=dialog.AddCheckbox("Infinite Execution", infiniteExecution) ask.OK = dialog.AddButton("OK",1) ask.addSelections = dialog.AddButton("AddSelection",2) ask.selectLoops = dialog.AddButton("SelLoops",3) ask.Cancel = dialog.AddButton("Cancel",0) returnVal=dialog.Show(ask) if returnVal > 0 then if returnVal==1 then maxRebuildCount=ask.maxRebuildCount.value end remixNotRebuild=ask.remixNotRebuild.value infiniteExecution=ask.infiniteExecution.value turboMode=ask.turboMode.value fullProtein=ask.fullProtein.value slotsToFuze=ask.slotsToFuze.value selectionStartArr[1]=ask.selectionStart1.value selectionEndArr[1]=ask.selectionEnd1.value if (selectionStartArr[1]==0) and not (fullProtein) then selectionStartArr[1]=1 end if selDialog>1 then selectionStartArr[2]=ask.selectionStart2.value selectionEndArr[2]=ask.selectionEnd2.value end if selDialog>2 then selectionStartArr[3]=ask.selectionStart3.value selectionEndArr[3]=ask.selectionEnd3.value end if selDialog>3 then selectionStartArr[4]=ask.selectionStart4.value selectionEndArr[4]=ask.selectionEnd4.value end if selDialog>4 then selectionStartArr[5]=ask.selectionStart5.value selectionEndArr[5]=ask.selectionEnd5.value end --selNum=selDialog forceChange=ask.forceChange.value shakeOnRank=ask.shakeOnRank.value reportLevel=ask.reportLevel.value if turboMode then --force very simple fuze settings in Turbo Mode shakeOnRank=false slotsToFuze=1 if (reportLevel>2) then print ("(fuze settings are ignored in Turbo Mode)") end end if remixNotRebuild then action="Remix" end --if Full Protein Rebuild/Remix is pressed then rebuilding the whole protein: markup selections and run as OK button was pressed if fullProtein then if (remixNotRebuild) and (selectionEndArr[1]>9) then selectionEndArr[1]=9 if reportLevel>1 then print ("Max selection length for Remix is 9 segs") end end --cut selection length to max (9 residues) when Remix is choosen selectionLength=selectionEndArr[1] overlap=selectionStartArr[1] if overlap>=selectionLength then overlap=selectionLength-1 end if reportLevel>1 then print ("Full Protein "..action..". Length and overlap from selection 1") print (action.." Length "..selectionLength..", Overlap "..overlap) end SelectProteinOverlap() end if slotsToFuze==1 then shakeOnRank=false end else print ("Canceled") end return returnVal end --script content functions --selection function FindSelection() selNum=0 for k=1, proteinLength do if selection.IsSelected(k) then --find for selection start if k==1 then selNum=selNum+1 selectionStartArr[selNum]=k else if not selection.IsSelected(k-1) then selNum=selNum+1 selectionStartArr[selNum]=k end end --find the selection end if k==proteinLength then selectionEndArr[selNum]=k else if not selection.IsSelected(k+1) then selectionEndArr[selNum]=k end end end end --if no selection, select residues 3-6 if selNum==0 then --print ("aaa") selectionStartArr[1]=math.min(5,proteinLength) selectionEndArr[1]=math.min(13,proteinLength) end end function SetSelection() selection.DeselectAll() for k=1, proteinLength do if (k>=selectionStart) and (k<=selectionEnd) then selection.Select (k) end end end function SelectLoops() selection.DeselectAll() looplength=0 --select all loops with length >= 3 for k=1, proteinLength do --print (structure.GetSecondaryStructure(k)) if structure.GetSecondaryStructure(k) == 'L' then looplength=looplength+1 selection.Select (k) else if (looplength>0) and (looplength<3) then --deselect if loop is too short for j=1, looplength do selection.Deselect (k-j) end end looplength=0 end if (k==proteinLength) and (looplength==1) then selection.Deselect (k) end end end --markup selection of the full protein with some overlap function SelectProteinOverlap () k=0 -- used here as selection number activeAA=startingAA --startingAA is set in main when running this function if (overlap>=selectionLength) or (overlap<0) then overlap=selectionLength-1 end if (startingAA+selectionLength-1 <= 1) then startingAA=1 end -- reset selection markup position counter (startingAA) to 1st protein residue if it is too low --make first selections while (activeAA<1) do if (activeAA+selectionLength-1>=3) then --if next selection length is >=3 k=k+1 selectionStartArr[k]=1 selectionEndArr[k]=activeAA+selectionLength-1 end activeAA=activeAA+selectionLength-overlap end --make further selections while activeAA+selectionLength-1 < proteinLength do k=k+1 selectionStartArr[k]=activeAA selectionEndArr[k]=activeAA+selectionLength-1 activeAA=selectionEndArr[k]-overlap+1 end --make last selections while (proteinLength-activeAA+1>=3) do --if next selection length is >=3 k=k+1 selectionStartArr[k]=activeAA selectionEndArr[k]=proteinLength activeAA=activeAA+selectionLength-overlap end selNum=k end function SetAllSelections() selection.DeselectAll() for j=1, selNum do selectionStart=selectionStartArr[j] selectionEnd=selectionEndArr[j] if (selectionEnd-selectionStart < 0) then temp = selectionStart selectionStart = selectionEnd selectionEnd = temp end if (reportLevel>3) then print ("Setting selection"..j.."/"..selNum..": ", selectionStart.."-"..selectionEnd) end for k=1, proteinLength do if (k>=selectionStart) and (k<=selectionEnd) then selection.Select (k) end end end end function SelectionSphere() --dump selection to array selectedSegs={} for k=1, proteinLength do if selection.IsSelected(k) then selectedSegs[k]=1 else selectedSegs[k]=0 end end for k=1, proteinLength do for j=1, proteinLength do dist_str = structure.GetDistance(k, j) if (selectedSegs[j] == 1) and (dist_str < sphereRadius) then selection.Select(k) end end end end function printSelections() strOutput2="" print ("Found "..selNum.." selections") for j=1, selNum do if (selNum>5) then strOutput2=strOutput2.." "..selectionStartArr[j].."-"..selectionEndArr[j] if (math.fmod(j, 7)==6) then strOutput2=strOutput2.."\n" end else print (selectionStartArr[j].."-"..selectionEndArr[j]) end end if (selNum>5) then print(strOutput2) end end --Fuze function TinyFuze() SelectionSphere() behavior.SetClashImportance(0.05) structure.ShakeSidechainsSelected(1) behavior.SetClashImportance(1) SetSelection() end function FastFuze() SelectionSphere() behavior.SetClashImportance(CI) structure.LocalWiggleSelected (2, 0, 1) SetSelection() structure.WiggleAll(5) behavior.SetClashImportance(1) structure.LocalWiggleAll(3, 0, 1) --wiggle sidechains undo.SetUndo(true) --disable undo for everything except fuze structure.WiggleAll(5) undo.SetUndo(false) end function Fuze() currentScore1=ScoreReturn() CI=0.05 behavior.SetClashImportance(0.05) structure.ShakeSidechainsAll (1) structure.WiggleAll (2) if reportLevel>3 then print ("CI = "..CI..". Score is "..ScoreReturn(), "Backbone score "..ScoreBBReturn()) end CI=0.25 behavior.SetClashImportance(0.25) structure.WiggleAll (2, 0, 1) structure.WiggleAll (2) if reportLevel>3 then print ("CI = "..CI..". Score is "..ScoreReturn(), "Backbone score "..ScoreBBReturn()) end CI=1 behavior.SetClashImportance(1) structure.ShakeSidechainsAll (1) undo.SetUndo(true) structure.WiggleAll (5, 1, 0) if reportLevel>3 then print ("CI = "..CI..". Score is "..ScoreReturn(), "Backbone score "..ScoreBBReturn()) end undo.SetUndo(false) if ScoreReturn() > currentScore1 then save.Quicksave(bestSlot) currentScore1=ScoreReturn() end CI=0.07 if reportLevel>3 then print ("...last shake") end behavior.SetClashImportance(0.07) structure.ShakeSidechainsAll (1) CI=1 behavior.SetClashImportance(1) undo.SetUndo(true) structure.WiggleAll (20) if reportLevel>3 then print ("CI = "..CI..". Score is "..ScoreReturn(), "Backbone score "..ScoreBBReturn()) end undo.SetUndo(false) if ScoreReturn() > currentScore1 then save.Quicksave(bestSlot) else save.Quickload(bestSlot) end end --Rebuild/Remix function SortByBackbone() bestEnergySlot=0 --add few best energy score for solutions table.sort(remixBBScores, function(a,b) return a.score > b.score end) for i, remixBBScores in ipairs(remixBBScores) do if i <= bestSelectNum then remixBBScores.rank=(bestSelectNum-i)/energy2BBScoreRatio end --add rank points to top energy solutions half to bb points by default end --add few best backbone score solutions table.sort(remixBBScores, function(a,b) return a.scoreBB > b.scoreBB end) for i, remixBBScores in ipairs(remixBBScores) do if i <= bestSelectNum then remixBBScores.rank=remixBBScores.rank+bestSelectNum+1-i end --add rank points to best backbone solutions end --sort by rank table.sort(remixBBScores, function(a,b) return a.rank > b.rank end) for i, remixBBScores in ipairs(remixBBScores) do if (i<=bestSelectNum) then if reportLevel>3 then print("Backbone score", remixBBScores.scoreBB, "from slot", remixBBScores.id, "score: "..remixBBScores.score, "/"..remixBBScores.rank) end end end end function CheckRepeats() currentScore=ScoreReturn() isDuplicate=false remixNum=#rebuildScores for k=1, remixNum do if rebuildScores[k] == currentScore then isDuplicate=true end end if not isDuplicate then solutionsFound = solutionsFound+1 rebuildScores[solutionsFound] = currentScore save.Quicksave(solutionsFound) if shakeOnRank then TinyFuze() end --makes a small shake before ranking energy score of rebuild (if checkbox was selected). currentScore=ScoreReturn() remixBBScores[solutionsFound-1] = {id = solutionsFound, scoreBB=ScoreBBReturn(), score=currentScore, rank=0} if reportLevel>2 then print ( "Slot", solutionsFound, "backbone", ScoreBBReturn(), "score", currentScore) end --if reportLevel==2 then io.write(".") end else if reportLevel>2 then print (currentScore, "is duplicated to already found.") end end return isDuplicate end function RebuildToSlots() j=0 rebuildIter=1 while (j<maxRebuildCount) and (rebuildIter<7) do j=j+1 structure.RebuildSelected(rebuildIter) if CheckRepeats() then j=j-1 rebuildIter = rebuildIter+1 else rebuildIter=1 save.Quicksave(j+1) end --print (k, remixNum, currentScore) save.Quickload(100) end --if reportLevel==2 then io.write("\n") end --print (maxRebuildCount, rebuildIter, j) end function remixBBscoreList() for i=1, remixNum do save.Quickload(i+1) if shakeOnRank then --makes a small shake before ranking energy score of rebuild (if checkbox was selected). TinyFuze() save.Quicksave(i+1) end currentScore=ScoreReturn() if reportLevel>2 then print ( "Slot", i+1, "score", currentScore, "backbone", ScoreBBReturn()) end --if reportLevel==2 then io.write(".") end remixBBScores[i] = {id = i, scoreBB=ScoreBBReturn(), score=currentScore, rank=0} end --if reportLevel==2 then io.write("\n") end end function RebuildRemixSelected() if remixNotRebuild then remixNum = structure.RemixSelected(2, maxRebuildCount) if (remixNum>0) then remixBBscoreList() end else RebuildToSlots() remixNum=#rebuildScores-1 end end function Cleanup() currentScore=ScoreReturn() undo.SetUndo(true) if (currentScore > startScore) then save.Quicksave(100) else save.Quickload(100) end currentScore=ScoreReturn() if (currentScore > initScore) then print ("Total gain:", roundX(currentScore-initScore)) else save.Quickload(1) print("No improve. Restored to "..ScoreReturn()) end if not infiniteExecution then SetAllSelections() end if convertLoop then save.LoadSecondaryStructure() end end -----------------------------------------------------------------------------------------------init maxRebuildCount=98 sphereRadius=8 reportLevel=2 slotsToFuze=4 shakeOnRank=true turboMode=false fullProtein=false CI=0.1 energy2BBScoreRatio=2 selectionLength=10 overlap=5 startingAA=1 bestScore=-999999 rebuildScores = {} remixBBScores = {}, {} rebuildScores[1]=bestScore rebuildRetryNo=0 bestSelectNum=0 solutionsFound = 1 remixNum = #rebuildScores undo.SetUndo(false) remixNotRebuild = false infiniteExecution = false selectionPresent=false convertLoop=true forceChange=false bestSlot=0 bestEnergySlot=0 selectionEnd=0 selectionStart=0 selNum=0 selDialog=selNum selectionStartArr={} selectionEndArr={} structureSS={} action="Rebuild" proteinLength=structure.GetCount () startScore=ScoreReturn() initScore=ScoreReturn() --the real start score that doesn't changes print ("+++Starting score "..startScore.." saved to slot 1") save.Quicksave(1) recentbest.Save() -----------------------------------------------------------------------------------------------main function main() FindSelection() tempSelNum=selNum if selNum==0 then selNum=1 end selDialog=selNum --Request options from user while requestResult~=1 do requestResult = RequestOptions() if requestResult == 0 then return end -- cancel button pressed by user if requestResult == 2 then selDialog=selDialog+1 end if requestResult == 3 then SelectLoops() FindSelection() --print (selNum,selDialog) selDialog=selNum end if selDialog>5 then selDialog=5 end end selNum=math.max(tempSelNum, selDialog, selNum) SetAllSelections() if convertLoop then save.SaveSecondaryStructure() structure.SetSecondaryStructureSelected("L") end save.Quicksave(100) --Report settings in output window strOutput=action..": "..maxRebuildCount.." /"..slotsToFuze if turboMode then strOutput=strOutput.." TURBO" end if fullProtein then strOutput=strOutput..", full protein" end if forceChange then strOutput=strOutput..", force changes" end if infiniteExecution then strOutput=strOutput..", infinite" end if shakeOnRank then strOutput=strOutput..", shake" end if reportLevel>2 then strOutput=strOutput..". ReportLevel="..reportLevel end if (reportLevel>1) then print (strOutput) end if (reportLevel>1) and (selNum>0) then printSelections() end loopIter=1 while loopIter>0 do --for Infinite execution option startScore2=ScoreReturn() --used in Turbo Mode only loopIter=loopIter + 1 if not infiniteExecution then loopIter=0 end --break while if not infinite execution print ("-------------------------------------------------") if (infiniteExecution) and (reportLevel>1) then print("Iteration", (loopIter-1)..".") end if fullProtein and (loopIter>2) then startingAA=startingAA-1 if reportLevel>1 then --print ("Overlap changed to "..overlap) end SelectProteinOverlap() end for m=1, selNum do bestScore=-999999 bestSlot=0 selectionStart=selectionStartArr[m] selectionEnd=selectionEndArr[m] startScore=ScoreReturn() solutionsFound = 1 print(m.."/"..selNum..": "..action.."ing segs: "..selectionStart.."-"..selectionEnd..". Score "..ScoreReturn().." bb "..ScoreBBReturn()) --switch selectionStart and selectionEnd SetSelection() if (selectionEnd-selectionStart > 8) and (remixNotRebuild) then print("Selections larger 9 segments not allowed for Remix") remixNum=0 else RebuildRemixSelected() end bestSelectNum = slotsToFuze if bestSelectNum > remixNum then bestSelectNum=remixNum end if reportLevel>1 then print(remixNum, "solutions found on "..action..". Ranking best "..bestSelectNum) end --if there are some solutions then rebuild, else go to the next iteration on 'for' loop if remixNum > 0 then SortByBackbone() --Fuze slots and score best for i, remixBBScores in ipairs(remixBBScores) do if i <=bestSelectNum then save.Quickload(remixBBScores.id) if turboMode then --save solution in Undo stack when in Turbo Mode undo.SetUndo(true) undo.SetUndo(false) end if bestSelectNum>1 then --fuze on scoring stage only when 'slotsToFuze' setting is >1 FastFuze() end save.Quicksave(remixBBScores.id) currentScore=ScoreReturn() improve = roundX(currentScore-startScore) textBest="" if (currentScore > bestScore) then bestScore=currentScore bestSlot=remixBBScores.id textBest="*" if (improve > 0) or (turboMode) then save.Quicksave(100) end --just accept and save best (and the only) rebuild solution when in Turbo Mode end if reportLevel>1 then print ("Stabilized slot", remixBBScores.id, " to bb "..ScoreBBReturn()," score", currentScore, textBest) end end end end --continue previous 'if' but with new condition: turboMode is here to enter this fuze section when 0 solutions found on last Remix in Turbo Mode. if (remixNum > 0) or turboMode then -- Finalize save.Quickload(bestSlot) if (not turboMode) or (m==selNum) then --Run full Fuze if not in Turbo Mode or after last selection rebuild in Turbo Mode if reportLevel>2 then print("Fuzing best solution from slot", bestSlot) end currentScore=ScoreReturn() Fuze() if currentScore < ScoreReturn() then --accept Fuze results if score is improved save.Quicksave(bestSlot) else save.Quickload(bestSlot) end if turboMode then startScore=startScore2 end currentScore=ScoreReturn() improve = roundX(currentScore-startScore) if (improve > 0) or (forceChange) then if reportLevel>0 then print ("Gained ", improve.." points. New score: "..currentScore) end if reportLevel>1 then print ("Total gain:", roundX(currentScore-initScore)) end save.Quicksave(100) if turboMode then save.Quicksave(1) end else currentScore=ScoreReturn() save.Quickload(100) if turboMode then save.Quickload(1) save.Quicksave(100) end if reportLevel>2 then print("No improve ("..currentScore.."). Restored to "..ScoreReturn()) end end if reportLevel>1 and (m==selNum) and (improve<=0) then --print 'Total gain' at the end of the round but prevent double print it when improve>0 currentScore=ScoreReturn() if (currentScore-initScore)>0 then print ("Change: ", improve.." points. Restored "..currentScore) print ("Total gain:", roundX(currentScore-initScore)) end end end --if for full Fuze end --if remixNum>0 print ("-------------------------------------------------") end --for end --while Cleanup() end -- function main() xpcall ( main , Cleanup )

Comments