Icon representing a recipe

Recipe: Bravo Find Terminals With Bands

created by bravosk8erboy

Profile


Name
Bravo Find Terminals With Bands
ID
109119
Shared with
Public
Parent
Test recipe 13 (distance on backbone)
Children
Created on
August 04, 2025 at 00:11 AM UTC
Updated on
August 04, 2025 at 03:21 AM UTC
Description

Best for


Code


-- This is an alternative method to identify terminal segments. works off the idea that you can creat a band on connected atoms. -- correctly identifies seperate proteins, ligands, RNA, and DNA. -- like most things in fold.it this recipe is faster with the window minimized. -- Finds terminal segments using bands between atom 3 of segment i and atom 1 of segment i+1 (adjacent segments) function findTerminalsWithBands() save.Quicksave(80) local segmentCount = structure.GetCount() local distances = {} -- Clear any existing bands to avoid interference band.DeleteAll() for i = 1, segmentCount - 1 do -- minus 1 so that we don't call a non existant segment with (i+1) -- Create a band between atom 3 of segment i and atom 1 of segment i+1 local bandIndex = band.AddBetweenSegments(i, i + 1, 3, 1) end local bandCount = band.GetCount() -- print(" bandCount: " .. bandCount) local Terminals = {} -- first segment and last segment wont have bands but are always terminals table.insert(Terminals, 1) -- table is sorted for i = 1, bandCount do -- minus 1 so that we don't call a non existant segment with (i+1) -- Get the length of the band (i.e., the distance between the atoms) local Base = band.GetResidueBase(i) local End = band.GetResidueEnd(i) -- local length = band.GetLength(i) -- print(string.format(" %.5f" , length)) -- Average distance between atoms on back bone in fold.it 1.330688909 -- Std. Dev. is 0.007942111 -- base before end to keep Terminals sorted table.insert(Terminals, Base) table.insert(Terminals, End) end -- first segment and last segment wont have bands but are always terminals table.insert(Terminals, segmentCount) -- table is sorted Terminals = remove_duplicates(Terminals) -- Print all distances in one line, comma-separated print(" Terminals") print(table.concat(Terminals, ", ")) -- remove bands and return user created bands save.Quickload(80) return Terminals end function remove_duplicates(sorted_table) local unique = {} local last_value = nil for _, value in ipairs(sorted_table) do if value ~= last_value then table.insert(unique, value) last_value = value end end return unique end findTerminalsWithBands()

Comments


NinjaGreg Lv 1

Hey Bravo, you could replace your remove_duplicates function like this:

u=(function(t)table.sort(t)for i=#t,2,-1 do t[i]==t[i-1]and table.remove(t,i)end return t end){"a","b","a","c","b","d"}

If the table is already sorted, you don't need the table.sort(t) call.
Of course, it's much less readable, but I had fun finding it.

NinjaGreg Lv 1

Also, you could remove the need for local variables in this:

    local Base = band.GetResidueBase(i)
    local End =  band.GetResidueEnd(i)
    -- local length = band.GetLength(i)
    -- print(string.format(" %.5f" , length))
    -- Average distance between atoms on back bone in fold.it 1.330688909
    -- Std. Dev. is 0.007942111
    
    -- base before end to keep Terminals sorted
    table.insert(Terminals, Base)
    table.insert(Terminals, End)

with this:

– base before end to keep Terminals sorted
table.insert(Terminals,band.GetResidueBase(i))
table.insert(Terminals,band.GetResidueEnd(i))

Those kinds of changes removes the need for Lua to allocate/deallocate storage for the local variables. Should run a little faster.

bravosk8erboy Lv 1

this code was not properly cleaned up and was just a proof of concept to share. it does contain dead variables and commented out code lol. "local distances = {}" is never actually used…
i am not an expert at lua or coding in general. how much time does it save? i did notice the recipe is a little slow but i figured that was the fold.it environment not the lua side. i run on a low memory computer so memory allocation is a big concern for me so i was just trying to protect that.
copilot AI says "Locals are lexical (block-scoped) and stored in the function’s stack frame, not the heap". they only declare the variable once and just re-assign them not re-declare them at run time.
Garbage cleanup was a big concern for me when developing this function. I will mess around with your suggestions and try out some stuff to make it more efficient.

bravosk8erboy Lv 1

the "band.AddBetweenSegments(i, i + 1, 3, 1)" which is the soul of the recipe seems to be the largest time sink. fold.it is tricky because the os.clock time for this recipe can vary from .05 seconds to 2.1 seconds just rerunning the same code.