6 replies [Last post]
Joined: 08/09/2010

About filters, one thing I do on recipes is disable them with structure functions (wiggle, shake...) and enable them for getting score.
I have written a code for overload the lua classes, so we can set/unset filters for all the functions in a class, and easily modify the old recipes.

The idea is:

MutClass(structure, false): set filters disabled on all the functions in 'structure'
MutClass(band, false): set filters disabled for band functions
MutClass(current, true): set filters enabled on all the functions in 'current' (for example GetEnergyScore

On that way if you are cutting, wiggling, and so on, you change filters only one time, avoiding disable_filters/cut/enable/disable/cut/enable/disable... For example, a sequence of actions:

getScore: filter on
Wiggle: filters off
Shake: nothing
Wiggle: nothing
Shake: nothing
getScore: filters on

For this, the functions:


-- function to copy class/table
function CopyTable(orig)
    local copy = {}
    for orig_key, orig_value in pairs(orig) do
        copy[orig_key] = orig_value  
    end
    return copy
end

-- functions for filters
function FiltersOn()
    if behavior.GetSlowFiltersDisabled() then
        behavior.SetSlowFiltersDisabled(false)
    end
end
function FiltersOff()
    if behavior.GetSlowFiltersDisabled()==false then
        behavior.SetSlowFiltersDisabled(true)
    end
end

-- function to overload a funtion
function mutFunction(func)
    local currentfunc = func
    local function mutate(func, newfunc)
        local lastfunc = currentfunc
        currentfunc = function(...) return newfunc(lastfunc, ...) end
    end
    local wrapper = function(...) return currentfunc(...) end
    return wrapper, mutate
end


-- function to overload a class
-- to do: set the name of function
classes_copied = 0
myclcp = {}
function MutClass(cl, filters)
    classes_copied = classes_copied+1
    myclcp[classes_copied] = CopyTable(cl)
    local mycl =myclcp[classes_copied]
    for orig_key, orig_value in pairs(cl) do
        myfunc, mutate = mutFunction(mycl[orig_key])
        if filters==true then
            mutate(myfunc, function(...)
                print("Mutated function called: filter on")
                FiltersOn()
                if table.getn(arg)>1 then
                    -- first arg is self (function pointer), we pack from second argument
                    local arguments = {}
                    for i=2,table.getn(arg) do
                        arguments[i-1]=arg[i] 
                    end
                    return mycl[orig_key](unpack(arguments))
                else
                    --print("No arguments")
                    return mycl[orig_key]()
                end
            end)   
            cl[orig_key] = myfunc
        else
            mutate(myfunc, function(...)
                print("mutated funcion called: filter off")
                FiltersOff()
                if table.getn(arg)>1 then
                    local arguments = {} 
                    for i=2, table.getn(arg) do
                        arguments[i-1]=arg[i]  
                    end
                    return mycl[orig_key](unpack(arguments))
                else
                    return mycl[orig_key]()
                end
            end)   
            cl[orig_key] = myfunc
        end
           
           
    end    
end


-- how to use:
MutClass(structure, false)
MutClass(band, false)
MutClass(current, true)

On this way class structure and class band will be with no filters, and class current will use filters. Write this code at the start of your recipe.

Joined: 08/09/2010
TODO

To do: set the names of functions. When you run a recipe with classes mutated it shows "?" instead the function name (wiggleselested, shakeAll...) when you run it. I have had investigating (a lot :D) but I have been unable. If anybody find the way please tell me.

Joined: 04/11/2013
can we remove two lines?

print("Mutated function called: filter on")
print("mutated funcion called: filter off")
Not sure it will affect the functions but if not it would be easier to follow drw progress without these lines

Joined: 08/09/2010
of course :)

you can remove prints, thanks for testings :)

Joined: 12/27/2012
Groups: Beta Folders
great idea

I really like this idea of automatically redoing classes.

There may be simpler way to accomplish this in some recipes. Many recipes already have a separate function Score() for collecting the overall score. It's easy to add filter toggling in this case. Some recipes may also get segment scores or subscores. It's easy to add a wrapper function for these as well.

Once the scoring functions toggle filters, all that's needed to disable the filter at the beginning of the recipe.

This approach avoid the issue of having "?" for the function name in the recipe status window. (I suspect the foldit client may construct a table of functions at startup. The question mark may appear when the client can't find one of the modified functions in the table. )

One additional tip is that it's helpful to reenable filters at the end. I suggest using a cleanup routine in all recipes, and resetting the filters there.

Here's sample code for filter-toggling score, segment score, and segment subscore functions:

function Score ()
local foff = behavior.GetSlowFiltersDisabled()
if foff then
behavior.SetSlowFiltersDisabled ( false )
end
local cscor = current.GetEnergyScore ()
if foff then
behavior.SetSlowFiltersDisabled ( true )
end
return cscor
end

function SegScore ( ii )
local foff = behavior.GetSlowFiltersDisabled()
if foff then
behavior.SetSlowFiltersDisabled ( false )
end
local cscor = current.GetSegmentEnergyScore ( ii )
if foff then
behavior.SetSlowFiltersDisabled ( true )
end
return cscor
end

function SegSubScore ( ii, subs )
local foff = behavior.GetSlowFiltersDisabled()
if foff then
behavior.SetSlowFiltersDisabled ( false )
end
local cscor = current.GetSegmentEnergySubscore ( ii, subs )
if foff then
behavior.SetSlowFiltersDisabled ( true )
end
return cscor
end

Joined: 09/24/2012
Groups: Go Science
excellent !

Thanks for this generic solution !

It works well on heavy puzzles. An order of magnitude more speed (see recipes by porkythepundit).

I still wonder if it's better to disable filter when wiggling or not. See http://fold.it/portal/node/2000171

I noticed that wiggling with filters enabled takes much more time ... but finds more points.

Disabling filters during most operations with your generic script makes much more attempts (loops) in a given time. After a certain time, the yield is better than running less loops with filters enabled.

I suppose that there should be a kind of "best compromise", like running with filters off on start design (trying to rise filter bonus), and running with filter off (unless current actions) at the end, when maximum filter bonus is achieved?

Joined: 06/17/2010
I go leazy way,

and only enable filters when scoring :P
My 1st script that do this: https://fold.it/portal/recipe/100580
Will try to update rest of my main scripts to do same thing.
Those filters are REALLY slow.

Sitemap

Developed by: UW Center for Game Science, UW Institute for Protein Design, Northeastern University, Vanderbilt University Meiler Lab, UC Davis
Supported by: DARPA, NSF, NIH, HHMI, Amazon, Microsoft, Adobe, RosettaCommons