integer band.Add(integer segmentOrigin, integer segmentXAxis, integer segmentYAxis, number rho, number theta, number phi, [integer atomIndexOrigin], [integer atomIndexXAxis], [integer atomIndexYAxis])
Add a band to empty space.
V1 Function Name
New to V2
Spherical Coordinates v3

Spherical coordinates. Three segments define the reference plane, highlighted in yellow. Thin bands connect the beta carbons of the plane segments and show the X, Y, and Z axes. A heavy band from from the origin segment has theta (Θ) 45°, relative the Z axis, and phi (Φ) 45°, relative to the X axis. The dotted line shows where the band would fall if theta was 90°. The length of the band is Ρ (rho). (Click for larger image.)

band.Add adds a band from a point on a segment to a point in space. This type of band is called a spaceband or "band in space" (BiS).

Creating a band to empty space requires specifying spherical coordinates. The spherical coordinates involve three different segments, which define a reference plane. The band itself is defined by three Greek-letter arguments: rho (Ρ), the length of the band, and theta (Θ) and phi (Φ), angles of the band. Foldit follows the physics or ISO convention for its definition of the angles theta and phi.

Optionally, atom numbers can be specified for each of the three segments, bringing the count to nine possible arguments for band.Add.

Of all the functions in the Foldit Lua interface, band.Add is probably the most complicated to use. If any of the arguments passed to band.Add are incorrect, the recipe terminates with an error. The Lua function pcall can be used to trap these errors, allowing the recipe to continue. See Using pcall to trap Lua errors for details.

If successful, band.Add returns the band index of the newly added band, which can be used in band.Delete and other band functions. It's possible that band.Add could return a band index of zero, indicating the band couldn't be added for some reason. Callers should always check for a non-zero return code, since a band index of zero will cause an error in other band functions.

The added band has a default goal length of 3.5 Angstroms, and a default strength of 1.0. Goal length can be set and queried by band.SetGoalLength and band.GetGoalLength. Strength can be set and queried by band.SetStrength and band.GetStrength.

The added band's initial actual length is the value of rho (Ρ) specified when adding the band. The actual length changes as the protein moves, and can be queried by band.GetLength.


In the argument list for band.Add, each of the arguments segmentOrigin, segmentXAxis, and segmentYAxis must be a valid segment number, and they must all be different from each other. These three segments define the reference plane, and, in turn, the X, Y, and Z axes.

The new band starts at segmentOrigin.

The argument rho (Ρ) is a distance, and must be a value greater than 0 and less than 10000. Rho is measured in Angstroms, the unit of measure for bands in Foldit.

The argument theta (Θ) is an angle in radians, and must in the range 0 to pi (0° to 180°).

Theta is the "polar angle" between the Z axis (perpendicular to the reference plane) and the band. When theta is less than 90°, the band is above the reference plane. When theta is 90°, the band is in the reference plane. When theta is above 90°, the band is below the reference plane.

The argument phi (Φ) is an angle in radians, and must be in the range 0 to 2pi (0° to 360°).

Phi is the "azimuthal angle", the angle of rotation of the band with respect to the X axis. When phi is 0° or 180°, the band is along the X axis. When phi is 90° or 270°, the band is along the Y axis.

Values for theta and phi are specified in radians, but the examples here use degrees. The Lua function math.rad() converts from degrees to radians. For example, math.rad(45) converts from 45 degrees into the equivalent in radians (0.785).

The optional arguments atomIndexOrigin, atomIndexXAxis, and atomIndexYAxis are atom numbers for the corresponding segments. They range from 1 to structure.GetAtomCount() for the segment. An atom number of 0 is equivalent to the default, which bands to the alpha carbon atom of the backbone, atom number 2.

See protein backbone for a detailed description of backbone atom numbering.


The image on this page shows a reference plane highlighted in yellow. The reference plane was defined using the beta carbons of three segments to make it easier to see. (The beta carbon is always the first "nub" of a the sidechain.)

Thin bands connect the three segments, and show the X, Y, and Z axes.

A heavier band has been drawn using rho = 15, theta = 45°, and phi = 45°. (The band strength is set to 10, making this the thickest possible band in Foldit.)

The image demonstrates these principles:

  • The X axis is defined as the line passing through segmentOrigin and segmentXAxis.
  • The Y axis defined by segmentOrigin, segmentXAxis, and segmentYAxis. These segments define a plane. By default, the plane passes through the alpha carbon atom of each segment.
  • The Y axis is perpendicular to the X axis in the reference plane, passing through segmentOrigin. The positive values on the Y axis will occur on the same side of the X axis as segmentYAxis. The segment you specify as segmentYAxis is not necessarily perpendicular to the X axis.
  • The Z axis is perpendicular to the X and Y axes, passing through segmentOrigin. The positive direction on the Z axis is determined the right-hand rule from X and Y axes.

In the right-hand rule, the Z axis corresponds to the thumb of the right hand, pointing "thumbs up". Phi represents the fingers of the right hand, toward the palm (Y axis).

The segments in the image were carefully selected to give good visual results. The X axis always passes through segmentOrigin and segmentXAxis as shown. The Y axis must be perpendicular ("ortagonal") to the X axis. So while segmentYAxis defines the reference plane, the Y axis doesn't necessarily pass through it. In the image, segmentYAxis was selected so it lies very close to the Y axis, but it's not quite perfect.

With the "cartoon" or "cartoon views" in Foldit, bands sometimes appear to be drawn incorrectly. For example, a band from segmentOrigin to segmentXAxis should coincide with spaceband on the X axis (theta = 90°, phi = 0°). For some combinations of segments, however, this isn't true. It's not clear what produces these distortions, but they disappear in the atom-level view of "stick" or "line".


The example below creates a band to empty space from segment 12, with rho of 20, a theta of 30°, and a phi of 45°. The angles would be relative to the coordinate system established from the segments numbered 12, 49, and 42 in the protein.

local segmentOrigin = 12
local segmentXAxis = 49
local segmentYAxis = 42
local rho = 20
local theta = math.rad ( 30 )
local phi = math.rad ( 45 )
band.Add ( segmentOrigin, segmentXAxis, segmentYAxis, rho, theta, phi )

In practice, most often, segmentXAxis and segmentYAxis will be specified as the segments immediately adjacent to segmentOrigin. So here is possibly the most common usage, creating a band that is 20 units long perpendicular to the backbone at segment 2, and the plane defined by segments 2, 1, and 3.

band.Add ( 2, 1, 3, 20, 0, 0 ) 

To get a perfectly uniformly random direction, use the following snippet (simply using random() won't be perfectly even everywhere):

theta = math.acos ( 2 * math.random () - 1 )
phi = 2 * math.pi * math.random ()
rho = R * math.random () ^ ( 1 / 3 ) + 0.001 -- for a random point in sphere of radius R