LOOS  v2.3.2
Frequently Asked Questions


Building LOOS (and building with LOOS)

I am having trouble building LOOS with Boost 1.52 (or later)

There was a change in Boost at version 1.52 that breaks the build of LOOS. We recommend upgrading to either LOOS 2.0.4 or downgrading your version of Boost to 1.51

SCons is not finding the right compiler/swig/doxygen

For LOOS, SCons will use your shell's $PATH veriable to look for tools. You will need to make sure the missing tool is in your path. Some care may be necessary in the order directories appear in your path to make sure you are finding the intended version of the tool. You can explicitly specify a C++ compiler to use with the CXX variable (either in your environment or from a custom.py file). This will take precedence over your path.

SCons is not finding my installation of Boost.

If you need to point SCons to a non-standard location of Boost, use the BOOST variable on the command-line or within your custom.py file. If you need to override either the include directory or the library directory, use the BOOST_INCLUDE and BOOST_LIBPATH variables respectively.

SCons cannot find a Boost library.

SCons will try to determine the correct naming variant for your Boost install. It will start by looking for "libboost_foo-mt.suff", followed by "libboost_foo.suff" where suff is either "dylib" (MacOS/Darwin), "so" (Linux), and "dll.a" (Cygwin). Failing that, it will look for any file matching "libboost_foo-*-mt.suff" followed by the non-threaded version. Of the list of filenames found, SCons will take the shortest one.

If necessary, override the libraries linked to for Boost by setting the BOOST_LIBS variable to a space-separated list of libraries. Note that you will need to include all of the ones required by LOOS, at a minimum,

BOOST_LIBS="boost_regex boost_program_options boost_system boost_thread"

Note that the libraries will be linked in with the same order they appear in the BOOST_LIBS variable.

I'm getting undefined reference or other link errors that appear to be related to Boost

This can happen if you have multiple versions of Boost installed. SCons may use include files from one version, but link with the libraries from another. Check the path to BOOST and the name of the libraries linked against.

I get a build error that says expected threaded libraries or non-threaded libraries, but some library is the opposite?

This is probably a failure of SCons to figure out the appropriate library name. Use the BOOST_LIBS variable (described above) to manually set the libraries used.

I get an error that says I must have some kind of blas installed

This means that SCons could find neither the versions of blas included with Atlas nor the typical system blas. You will need to make sure one or the other is installed. Double check your ATLAS_LIBPATH. In a worst case, you may need to explicitly list the libraries to use by setting the ATLAS_LIBS variable.

I get an error that says SCons could not figure out how to build

As part of the build, SCons will try to compile and link a test program to see whether ATLAS/LAPACK works and if there are any additional libraries needed. For some reason, this step failed. Double-check your Atlas/lapack installation. You may want to try building a small test program with Atlas, and use that to set ATLAS_LIBS or CCFLAGS appropriately.

How do I compile my own, separate tool with debugging?

If you copied the example SConstruct/SConscript, then change the LOOS_CCFLAGS environment variable before building your tool(s).

Using LOOS Tools

What units does LOOS use for coordinates?

LOOS uses Angstroms as the output unit of distance, even when the input coordinates are in other units (e.g. nanometers for GROMACS files are converted into Angstroms).

How does LOOS write out the connectivity information?

LOOS places the model's connectivity into the CONECT records of the output PDB. Connectivity is written out for all atoms for which there is connectivity present.

Using LOOS tools with large systems

LOOS should have no problem with large systems, although some care is required when using PDB files. There are several different approaches to reading and writing PDB files that contain more than 100,000 atoms or 10,000 residues. LOOS uses the Hybrid-36 scheme for encoding large numbers in the atom serial numbers (atomids) and residue id's (resids). While LOOS can read PDB's written in other conventions, it is best to canonicalize them into LOOS's hybrid-36 scheme. One way to do this is to use the renum-pdb tool,

renum-pdb bigmodel.pdb all 1 1 >loos_bigmodel.pdb

Alternatively, stick with a PSF. If you need coordinates in a model, you can extract the first frame of your trajectory using frame2pdb,

frame2pdb bigmodel.psf bigmodel.dcd 0 >loos_bigmodel.pdb

Alternatively, since PSF files are space delimited, field overflow is not an issue. You can convert a PDB+PSF to a PDB without renumbering by using the convert2pdb tool, i.e.

convert2pdb --coords bigmodel.pdb bigmodel.psf >loos_bigmodel.pdb

My DCD says it has 0 frames (or too many frames)

LOOS relies on the DCD header to know how may frames are in a trajectory, but sometimes the header may be incorrect. For example, a ptraj conversion my result in a 0 frame count in the header, or if a write to a trajectory was interrupted, the header may list more frames than were actually written. Two tools can be used to check the integrity of a trajectory: trajinfo and dcdinfo. Both tools will scan the trajectory and count the number of frames actually present. The latter will also dump the inctrl block from the DCD header. If there is a problem with the frame count in the DCD header, use the fixdcd tool to correct it.

fixdcd simulation.dcd

Using the LOOS Library

How does LOOS handle connectivity/bonds?

Bonds are represented in LOOS by a list of atom id's that are bound to a given atom. This means that connectivity can be maintained even when the bound atoms are no longer stored. However, it also means that atom id's are assumed to be unique. If you are having trouble with connectivity because of fragmenting groups of atoms, you can use AtomicGroup::clearBonds() to remove all connectivity in a group, or AtomicGroup::pruneBonds() to remove bonds to any atom not contained in the given group.

How do I make a copy of an AtomicGroup? Why do changes in one group affect another?

Atoms are typically shared between AtomicGroup's in LOOS. For example, select just the alpha-carbons from a model,

AtomicGroup model = createSystem("protein.pdb");
AtomicGroup ca = selectAtoms(model, "name == 'CA'");

The atoms in ca will be shared with the corresponding atoms in model. Changes to an atom in one group will result in changes to the other group because the atoms are shared.

ca[0]->coords(ca[0]->coords() + translation_vector);

Will translate the first alpha-carbon in both ca and model. Making a copy of an AtomicGroup,

AtomicGroup duplicate = model;
AtomicGroup duplicate(model);

results in the copy sharing the same atoms. Also of note here are the two idioms for making a copy of a group. Both result in what is called a "shallow copy" of model. The atoms are shared, but the lists of atoms in the group are different. For example,


will remove all alpha-carbons from the list of atoms in duplicate, but they will still be present in model.

In order to make a copy of an AtomicGroup where the atoms are not shared, a "deep copy" must be made. Here, each atom is copied into a new, separate atom, and then stored in the copy of the group. The AtomicGroup::copy() function does this,

AtomicGroup duplicate = ca.copy();

Now, not only are the lists of atoms distinct, but so are the atoms...

duplicate[0]->coords(duplicate[0]->coords() + translation_vector);

Here, the changes to the first alpha-carbon in duplicate does not change the coordinates of the first alpha-carbon in ca since they are no longer shared.

What's the difference between an atom index and an atom id?

When working with a trajectory, the ordering of the atoms in the corresponding model is important. The ith coordinate in a frame of the trajectory belongs to the ith atom in the model. When a model is read in by LOOS, the associated atoms are assigned an index based on their position within the file/model. In general, this approach should just work and you will not need to worry about atom indices.

In contrast, LOOS treats the atom id (atomid) as an atom identifier (metadata) and assumes that atomid's are unique. They are important for connectivity since bonds are stored as a list of atomid's that are connected to a given atom. Also, atomid's can be non-contiguous to indicate logical groupings, for example, nor are they required to begin with 1.

How have atomid's changed in LOOS in release 2.1.0?

Previously, LOOS treated atomid's as special when reading a trajectory. The atomid was the index into the trajectory frame for the corresponding atom. This required models to have contiguous atomid's that began with 1. This is no longer the case. Atomid's should still be unique, otherwise features like searching for atoms and following bonds may give erroneous results.

Additionally, some trajectory format classes have special cases of

If the number of atoms in g is the same as the trajectory frame, then the coordinates are copied in order into g, irrespective of the atomid's. This is no longer the case. Atom indices will always be honored.

What if I need to renumber the atom indices?

This should rarely happen. If it does, you can set the indices directly by using Atom::index(), or use AtomicGroup::resetAtomIndices() which will make all indices in a given group sequential and beginning with 0.


NOTE: This FAQ is specific to the Python interface to LOOS (PyLOOS). Please report any bugs found to "loos.maintainer [at] gmail.com". Similarly, please feel free to contact us regarding new functionality or better implementations.

Building PyLOOS

What operating systems support PyLOOS?

PyLOOS currently supports Linux and MacOS. For specific versions and installation instructions, see the INSTALL file.

How do I build PyLOOS?

You will need to install a recent version of Swig. For details specific to your OS, please see the INSTALL file.

I'm getting errors from Swig (about missing files)

On a few test systems, we found that there is an older version of swig present (e.g. /usr/bin) in addition to a newer version (e.g. in /sw/bin). Make sure that your shell's path has the newever location first, i.e. /sw/bin appears to the left of /usr/bin

I'm seeing a lot of warnings messages from the PyLOOS build

We have seen this in some instances (MacOS 10.9, for example), and believe they can be safely ignored.

SCons is trying to build PyLOOS even though it's unsupported, or the build is breaking with PyLOOS

You can disable the auto-build of PyLOOS by using the pyloos command-line flag with scons: scons pyloos=0

How do I use PyLOOS?

Your environment needs to be setup to allow Python to locate the PyLOOS libraries. LOOS now provides two setup scripts, setup.sh for bash users, and setup.csh for tcsh users. Source the appropriate script, then execute Python and import from loos.

Can I install PyLOOS?

Yes. PyLOOS can be installed alongside the rest of LOOS,

scons install

or to install in a specific location,

scons PREFIX=/home/user/MyLOOS

Be sure to source the appropriate setup.sh or setup.csh file in the install directory prior to using LOOS/PyLOOS.

I get an error about a missing init function when I try to import PyLOOS...

If you built LOOS and then built PyLOOS, the old LOOS shared library may still be around and this can confuse Python. Look for loos.so and remove it, or try a clean rebuild,

scons -c

Using PyLOOS

Setting parameters in LOOS objects

In C++, it is possible to have two different methods for setting a parameter value,

GCoord c;
c.x() = 42;

In both cases, the X-coordinate is set to 42. In Python, however, you must use the second form, c.x(42) .

Making copies of LOOS objects

Remember that in Python, saying "a = b" does not actually copy b. Python has a "copy" package which supports a shallow copy using the copy() function and a deep copy using the deepcopy() function. A shallow copy is similar to how a LOOS object would normally be copied in C++. For example,

AtomicGroup A;
AtomicGroup B = A;
    In this case, B is a shallow copy of A.  That is, the atoms
    are shared between A and B.  However, B can contain a
    different set of atoms from A, e.g.

Now B will have an extra atom that A will be lacking, but existing atoms will still be shared between A and B. In contrast, in the PyLOOS equivalent,

1 A = AtomicGroup()
2 B = A
3 B.append(another_atom)

A and B are the same and now both have the extra atom. To make a copy of A that behaves like the C++ copy, use Python's copy package to make a shallow copy,

1 import copy
2 A = AtomicGroup()
3 B = copy.copy(A)
4 B.append(another_atom)

Now, B has an extra atom and existing atoms are shared. Note that the C++ idiom,

A = AtomicGroup()
B = AtomicGroup(A)

will also work for creating a shallow copy.

Since atoms are shared in a shallow copy of an AtomicGroup, modifying the atom in one group will modify the atom in all groups that contain that atom.

1 import copy
2 an_atom = Atom(1, "CA", GCoord(1,2,3))
3 A = AtomicGroup()
4 A.append(an_atom)
6 B = copy.copy(A)
7 B[0].id(42)

Here, we've created an atom, appended it to AtomicGroup A, then made a shallow copy into AtomicGroup B. However, atoms are shared between AtomicGroups that have been shallow-copied. Therefore, when the atomid of the first atom in B is changed, since the atom is shared between A and B, both groups see the change. Sometimes, it is necessary to have a separate copy of a group so that changes to the atom in group B will not affect group A. This requires a deep copy,

1 import copy
2 an_atom = Atom(1, "CA", GCoord(1,2,3))
3 A = AtomicGroup()
4 A.append(an_atom)
6 B = copy.deepcopy(A)
7 B[0].id(42)

Here, the atoms are no longer shared...each group has its own copy of the atom. Therefore, changing the atomid of the first atom in group B does NOT change the first atom in group A. This is equivalent to using the AtomicGroup::copy() function in C++.

Why are my GCoords changing on me?

See above... Remember that saying "a = b" in Python does NOT copy the GCoord so when you change a, you're also changing b. Use "a = copy(b)" to get a new GCoord that's a copy of the existing one.

What objects support copying?

Currently, Atom, GCoord, and AtomicGroup support copying. For Atom and GCoord, copy() and deepcopy() are functionally equivalent.

Where did pAtoms go in PyLOOS?

Swig maps the boost shared pointer (pAtom) into the name "Atom". So, wherever you would use a pAtom in the C++ version of your code, simply use Atom in PyLOOS.

Are there any examples of using PyLOOS?

Yes. Look in the Packages/PyLOOS directory. We will be adding more examples in future releases.

Where are the matrix operations?

We currently assume that matrix operations are better handled by the appropriate Python package (e.g. numpy). Some matrix-based routines are available, such covariance and subspace overlaps.

Why is PyLOOS so slow?
A frequent problem with PyLOOS performance is a result of looping using Python. For example, to find an Atom in an AtomicGroup, the following will be slow,
1 found = 0
2 for x in range(system.size()):
3  if (system[x] == an_atom):
4  found = 1
5  break
7 if (found):
8  do_something()
    Instead of using loops, try first to get Python to do the
    looping internally, i.e.
1 if (an_atom in system):
2  do_something()
    Alternatively, look for LOOS functions that will perform the
    same operation, such as:
1 if (system.contains(an_atom)):
2  do_something()
    Finally, consider rewriting the loop in C++ and adding it to
    AtomicGroup (remembering to update the SWIG interface file,