Co lapse's Settle, as seen in the Foldit recipe editor. (The command numbers were added in a photo editor.)

Co lapse's Settle is an early GUI recipe, released 14 June 2009. It uses local wiggle, and is useful late in the game.

GUI recipes are easy to write, but come with some serious limitations. Foldit also supports recipes written in Lua, which have far fewer limitations. The tradeoff is the increased complexity of working in a full programming language.

This article looks at the 17 commands that make up Co lapse's Settle, showing how they can be adapted into Lua.

Commands[edit | edit source]

The commands in a GUI recipe occupy one line in the recipe editor. When the recipe runs, each statement is executed in order. The to[p image on this page shows how the recipe looks in the Foldit recipe editor.

The 17 commands are:

  1. Freeze Segments by stride every 4th segment starting at index 2
  2. Local Wiggle Sequence Segments by stride every 4th segment starting at index 1 for 3 iterations
  3. Unfreeze All segments
  4. Freeze Segments by stride every 2nd segment starting at index 1
  5. Local Wiggle Sequence Segments by stride every 2nd segment starting at index 2 for 3 iterations
  6. Freeze All segments
  7. Unfreeze Segments by stride every 2nd segment starting at index 1
  8. Local Wiggle Sequence Segments by stride every 2nd segment starting at index 1 for 3 iterations
  9. Unfreeze All segments
  10. Freeze Segments by stride every 3rd segment starting at index 2
  11. Local Wiggle Sequence Segments by stride every 3rd segment starting at index 1 for 3 iterations
  12. Unfreeze All segments
  13. Freeze Segments by stride every 2nd segment starting at index 1
  14. Wiggle for 25 iterations
  15. Unfreeze All segments
  16. Shake for 1 iterations
  17. Wiggle for 25 iterations

Unlike Lua and other programming languages, GUI recipes don't have a "source code" format, so you can't just paste the lines above into a text editor. Instead, you select each command and its "ingredients" in the Foldit recipe editor.

For Co lapse's Settle, the equivalent Lua commands are described below. See GUI commands Lua V2 equivalents for a full list of all GUI commands.

Command 1 - Freeze[edit | edit source]

Freeze Segments by stride every 4th segment starting at index 2

The GUI Freeze command takes one "ingredient", which specifies the segments to be frozen. The equivalent Lua statement is freeze.Freeze.

The "by stride" option freezes only certain segments. We'll use a "for loop" to do the same thing.

Also, we'll need to know when to stop. The GUI recipe does this for us. InLua, we'll need structure.GetCount to tell us how many segments the current protein has.

Without getting in too deep, here's the Lua equivalent for command 1:

segCnt = structure.GetCount () -- get number of segments, save in "segCnt"

for ii = 2, segCnt, 4 do                    -- statement 1
    freeze.Freeze ( ii, true, true )        -- statement 1
end                                         -- statement 1

The good news is that we only need to do the first line once. It stores the number of segments in a variable called "segCnt". We'll use segCnt throughout the rest of the recipe. Variable names are case-sensitive, and can't be the same as certain words Lua uses, such as "for", "do", and "end". Otherwise, you have lots of options when picking a name. The name "segCnt" is used in many Foldit recipes for the same purpose.

The for loop is the next three lines. These lines are the equivalent of statement 1 in the GUI recipe. The part between the "for" and the "do" is similar to the by "by stride" options in the GUI version.

The name "ii" is just a another variable name. It will change each time the statements in the loop get run. The variable ii will start with the value 2, corresponding to segment 2 in the protein. It will increase each time the loop executes, until it reaches the value of segCnt. The third value, 4, is the amount that will be added to ii each time.

The body of the loop is the one line containing freeze.Freeze. It's an example of calling a Lua function (freeze.Freeze), and passing arguments or parameters. Here the arguments are ii, the segment number to freeze, and two "boolean" arguments that tell whether to freeze the backbone and the sidechain. The GUI version doesn't let you specify the backbone and sidechain separately, it just freezes both.

Bottom line, the for loop will freeze segments 2, 6, 10, 14, and so on, until it reaches the value in segCnt. Once ii is greater than segCnt, the loop stops.

That's a lot for one statement, but we'll use the same type of for loop for several of the other GUI commands.

A few notes are in order for users familiar with other languages. First, Lua likes to start counting things at one, where other languages prefer to start at zero. So the first segment in a protein is segment 1.

Second, Lua variables don't have a fixed type. Instead the type is determined by what you put in them. Here, we're only putting numbers in segCnt and ii, so they're both type number, but this could change later on. Other languages require you decide up front what type of data you'll put in a variable, and generate an error if you try to store something different.

Third, the variable ii is used in the for loop. That's a holdover from FORTRAN and related ancient languages, where variables like i, j, and k were commonly used in similar spots. The advantage of ii over i is that it looks less funny to write "the variable ii is..." versus "the variable i is". Also, on a more serious note, ii is automatically assigned "local" scope in this example. The variable on the ii for loop is valid only for the for loop. It disappears after the for loop finishes. Unlike other languages, variables in Lua have "global" scope by default, meaning your entire Lua program can use them. In this example, we could add "local" to segCnt:

local segCnt = structure.GetCount ()

This would have no practical effect, however.

Statement 2 - Local Wiggle Sequence[edit | edit source]

Local Wiggle Sequence Segments by stride every 4th segment starting at index 1 for 3 iterations

This command also uses the "by stride" option to specify its segments, so another for loop is in order. We'll use the variable segCnt that was created in the first step.

Here the key Lua function is structure.LocalWiggleSelected. Since this function works on "selected" segments, we'll need selection.Select to set that up. We'll also use selection.DeselectAll to clear any existing selections.

 
for ii = 1, segCnt, 4 do                    -- statement 2
    selection.DeselectAll ()                -- statement 2      
    selection.Select ( ii )                 -- statement 2 
    structure.LocalWiggleSelected ( 3 )     -- statement 2 
end

The selection.DeselectAll () clears all existing selections. The () means that selection.DeselectAll doesn't require any arguments. It's similar to structure.GetCount in that way.

The statement selection.Select ( ii ) selects the segment indicated by ii.

The statement structure.LocalWiggleSelected ( 3 ) does local wiggle on the selected segments, which is going to be only one segment in this case. The "3" is the number of iterations that the local wiggle tool runs. We don't know a lot about iterations, except that more is better, but more takes longer. After a certain point, additional iterations typically don't matter, but the iterations generally go by faster when they're not doing much.

Statement 3 - Unfreeze[edit | edit source]

Unfreeze All segments

Where the first two statements were kind of complex, this one is easy:

freeze.UnfreezeAll ()                       -- statement 3

The Lua function is freeze.UnfreezeAll. There are many other "all" functions, and they tend to be easy to understand. It's the statements that only do part of something that get complicated.

In case you haven't figured it out, the "-- statement 3" part of the line is a comment, and gets ignored when the recipe runs. Anything after "--" on a line is a comment.

Statement 4 - Freeze[edit | edit source]

Freeze Segments by stride every 2nd segment starting at index 1

Once again, we'll need a for loop. We can just adapt the one from the first statement:

for ii = 1, segCnt, 2 do                    -- statement 4
    freeze.Freeze ( ii, true, true )        -- statement 4
end                                         -- statement 4                                        

As before, we can reuse the variable segCnt. This time the loop starts on segment 1, and freezes that and every other segment, so 1, 3, 5, 7, and so on.

Experience programmers might notice that since statements 1 and 4 are very similar, we could create a "function" to handle the differences. This would allow 1 and 4 to be one-liners in the Lua version, just like in the GUI. We'll get into that additional complexity in a later version of the recipe.

Statement 5 - Local Wiggle Sequence[edit | edit source]

Local Wiggle Sequence Segments by stride every 2nd segment starting at index 2 for 3 iterations

This time we can just adapt statement 2:

for ii = 2, segCnt, 2 do                    -- statement 5
    selection.DeselectAll ()                -- statement 5      
    selection.Select ( ii )                 -- statement 5 
    structure.LocalWiggleSelected ( 3 )     -- statement 5 
end                                         -- statement 5

So the result is local wiggle is applied to segment

Statement 6 - Freeze[edit | edit source]

Freeze All segments

Once again, a one-liner:

<pre>
freeze.FreezeAll ()                         -- statement 6

The Lua function is freeze.FreezeAll. Like the other "all" functions, you don't need to worry about any arguments.

Statement 7 - Unfreeze[edit | edit source]

Unfreeze Segments by stride every 2nd segment starting at index 1

We're back to using "by stride", so we'll need another for loop.

This time, the function is freeze.Unfreeze. Like freeze.Freeze, you need to supply two true/false "booleans" telling it whether to unfreeze the backbone and sidechain.

We'll just adapt the for loop from statement 4, changing freeze to unfreeze.

for ii = 1, segCnt, 2 do                    -- statement 7
    freeze.Unfreeze ( ii, true, true )      -- statement 7
end                                         -- statement 7

Once again, we start at segment 1, and do segments 1, 3, 5, 7, and so on. The only difference is that we're unfreezing instead of freezing.

Statement 8 - Local Wiggle Sequence[edit | edit source]

Local Wiggle Sequence Segments by stride every 2nd segment starting at index 1 for 3 iterations

Yet again, we can just adapt statements 2 and 5:

for ii = 1, segCnt, 2 do                    -- statement 8
    selection.DeselectAll ()                -- statement 8      
    selection.Select ( ii )                 -- statement 8 
    structure.LocalWiggleSelected ( 3 )     -- statement 8 
end                                         -- statement 8

Yet again, we could create a function and reduce the number of lines of code. But we're getting close to the end, only one local wiggle to go, so we'll stay the course.

Statement 9 - Unfreeze[edit | edit source]

Unfreeze All segments

We did this one on statement 3, now it's back:

freeze.UnfreezeAll ()                       -- statement 9

Statement 10 - Freeze[edit | edit source]

Freeze Segments by stride every 3rd segment starting at index 2

Statement 4 can be adjusted to handle this one:

for ii = 2, segCnt, 3 do                    -- statement 10
    freeze.Freeze ( ii, true, true )        -- statement 10
end                                         -- statement 10                                     

This time, we have arguments "2, segCnt, 3", so we'll start at segment 2, and go until we pass segCnt. We'll add 3 to the previous segment number each time, so it's 2, 5, 8, 11, and so on that wind up frozen.

Statement 11 - Local Wiggle Sequence[edit | edit source]

Local Wiggle Sequence Segments by stride every 3rd segment starting at index 1 for 3 iterations

We are repeating ourselves yet again, but this is the last time for this one:

for ii = 1, segCnt, 3 do                    -- statement 11
    selection.DeselectAll ()                -- statement 11      
    selection.Select ( ii )                 -- statement 11
    structure.LocalWiggleSelected ( 3 )     -- statement 11 
end                                         -- statement 11

The only change from statement 8 is the "3" of as the increment for the for loop.

The increment defaults to 1 if you don't specify it. Many for loops are happy with an increment of 1. A negative increment is also possible, to you can specify -1 as the increment if you want your loop to count down instead of up.

Statement 12 - Unfreeze[edit | edit source]

Unfreeze All segments

Repetition is the sincerest form of monotony.

freeze.UnfreezeAll ()                       -- statement 12

Statement 13 - Freeze[edit | edit source]

Freeze Segments by stride every 2nd segment starting at index 1

This should be easy by now:

for ii = 1, segCnt, 2 do                    -- statement 13
    freeze.Freeze ( ii, true, true )        -- statement 13
end                                         -- statement 13

Freezes 1, 3, 5, 7, and so on.

Statement 14 - Wiggle[edit | edit source]

Wiggle for 25 iterations

This time we're doing "regular" wiggle, not local wiggle. The command is structure.WiggleAll. It's another "all" command, but you do have to tell it how many iterations you want. Still, it's relatively straightforward:

structure.WiggleAll ( 30 )                  -- statement 14

This is an "all" function, so everything gets wiggled...except the parts that were frozen in the previous step. The frozen bits don't move around during wiggle, or at least not much. (They're not frozen to absolute zero, however.)

Somewhat like freeze.Freeze and freeze.Unfreeze, structure.WiggleAll also takes two arguments for backbone and sidechains. They boolean true/false arguments, just like on the freeze functions, but the difference here is that they're optional. If you don't specify what you want, both backbone and sidechains get wiggled.

And FYI, structure.LocalWiggleSelected has the same two optional arguments. So now you know.

Statement 15 - Unfreeze[edit | edit source]

Unfreeze All segments

Once more with feeling.

freeze.UnfreezeAll ()                       -- statement 15

Statement 16 - Shake[edit | edit source]

Shake for 1 iterations

Another new function, structure.ShakeSidechainsAll. It's an "all" function, but again you need to tell it how many iterations. The shake does pretty much all it's work on the first iteration, which makes you wonder why it even has iterations.

structure.ShakeSidechainsAll ( 1 )          -- statement 16

Statement 17 - Wiggle[edit | edit source]

Wiggle for 25 iterations

Just like statement 14:

structure.WiggleAll ( 30 )                  -- statement 17

This time, we have unfrozen everything, so everything gets wiggled, backbone, sidechains, and all.

This statement wraps up Co lapse's Settle.

All in one[edit | edit source]

Here are the results of the initial conversion. The 17 statements in the GUI recipe have expanded to 61 lines of Lua, if you count the blank lines.

With a few added comments, this recipe has been shared as Co lapse's Settle Lua version a.

Another article will look into ways to make the Lua recipe shorter.

segCnt = structure.GetCount () -- get number of segments, save in "segCnt"

for ii = 2, segCnt, 4 do                    -- statement 1
    freeze.Freeze ( ii, true, true )        -- statement 1
end                                         -- statement 1

for ii = 1, segCnt, 4 do                    -- statement 2
    selection.DeselectAll ()                -- statement 2
    selection.Select ( ii )                 -- statement 2
    structure.LocalWiggleSelected ( 3 )     -- statement 2
end                                         -- statement 2

freeze.UnfreezeAll ()                       -- statement 3

for ii = 1, segCnt, 2 do                    -- statement 4
    freeze.Freeze ( ii, true, true )        -- statement 4
end                                         -- statement 4

for ii = 2, segCnt, 2 do                    -- statement 5
    selection.DeselectAll ()                -- statement 5
    selection.Select ( ii )                 -- statement 5
    structure.LocalWiggleSelected ( 3 )     -- statement 5
end                                         -- statement 5

freeze.FreezeAll ()                         -- statement 6

for ii = 1, segCnt, 2 do                    -- statement 7
    freeze.Unfreeze ( ii, true, true )      -- statement 7
end                                         -- statement 7

for ii = 1, segCnt, 2 do                    -- statement 8
    selection.DeselectAll ()                -- statement 8
    selection.Select ( ii )                 -- statement 8
    structure.LocalWiggleSelected ( 3 )     -- statement 8
end                                         -- statement 8

freeze.UnfreezeAll ()                       -- statement 9

for ii = 2, segCnt, 3 do                    -- statement 10
    freeze.Freeze ( ii, true, true )        -- statement 10
end                                         -- statement 10

for ii = 1, segCnt, 3 do                    -- statement 11
    selection.DeselectAll ()                -- statement 11
    selection.Select ( ii )                 -- statement 11
    structure.LocalWiggleSelected ( 3 )     -- statement 11
end                                         -- statement 11

freeze.UnfreezeAll ()                       -- statement 12

for ii = 1, segCnt, 2 do                    -- statement 13
    freeze.Freeze ( ii, true, true )        -- statement 13
end                                         -- statement 13

structure.WiggleAll ( 30 )                  -- statement 14

freeze.UnfreezeAll ()                       -- statement 15

structure.ShakeSidechainsAll ( 1 )          -- statement 16

structure.WiggleAll ( 30 )                  -- statement 17
Community content is available under CC-BY-SA unless otherwise noted.