LOOS  v2.3.2
loos::OptionsFramework Namespace Reference

Namespace for encapsulating options processing. More...

Classes

class  AggregateOptions
 Combines a set of OptionsPackages. More...
 
class  BasicConvergence
 
class  BasicOptions
 Options common to all tools (including –fullhelp) More...
 
class  BasicSelection
 Provides a single LOOS selection (–selection) More...
 
class  BasicSplitBy
 Provides a mechanism for controlling how to split an AtomicGroup. More...
 
class  BasicTrajectory
 Basic trajectory with a –skip option. More...
 
class  BasicWater
 Options specific to tools that work with water/internal-water. More...
 
class  ModelWithCoords
 Request a model with coordinates. More...
 
class  OptionsPackage
 Base class for options. More...
 
class  OutputPrefix
 Gets a string as prefix for output files (–prefix) More...
 
class  OutputTrajectoryOptions
 
class  OutputTrajectoryTypeOptions
 
class  RequiredArguments
 Provides simple way to add command-line arguments (required options) More...
 
class  TrajectoryWithFrameIndices
 Trajectory with either a –range or –skip. More...
 
class  TwoModelsWithCoords
 Request Two models with coordinates. More...
 

Typedefs

typedef std::vector< OptionsPackage * > vOpts
 

Detailed Description

Namespace for encapsulating options processing.

The OptionsFramework provides a consistent set of "common" options across all LOOS tools. By mixing and matching the subclasses of OptionsPackage, a tool can decide which set of "common" options it will use. Packages may also define their own package-wide set of common options. In addition, subclassing OptionsPackage within a tool is an easy mechanism for providing command-line options that are specific to an individual tool without having to write the support-code that using boost::program_options requires.

The basic pattern for using OptionsFramework is to create a new object that represents the options required by the tool. Once all objects are created, they are added to an AggregateOptions object that is responbile for parsing and validating the command-line as well as generating help messages and serializing the options' state for inclusion in the tool's output. For example, a tool that requires a model (with coordinates) and an output prefix would setup its options as follows:

BasicOptions* bopts = new BasicOptions; // Create basic option (i.e. verbosity & help)
OutputPrefix* popts = new OutputPrefix; // Allow --prefix
ModelWithCoords* mopts = new ModelWithCoords; // Add a model (and ensure coordinates are present)
AggregateOptions options;
options.add(bopts).add(popts).add(mopts); // Combine all options
if (!options.parse(argc, argv)) // If an error occurs, the help message
// will already be printed
exit(-1);

The values of the options are generally stored in the member variables of the appropriate object. Simply use these, or copy them out into the tool. For example, to find the verbosity level in the above example, check bopts->verbosity, and to access the model read in, use mopts->model.

One feature of boost::program_options is that the long-name options may have a single letter short-cut. Since OptionsFramework integrates options from many different sources, there is a possibility of short-cut collisions (i.e. two classes using the same single letter code). We therefore recommend the following convention when providing these short-cuts:

  • LOOS wide common options should use lower-case single letters
  • Package-wide common options should use upper-case single letters
  • Tool specific options should always be long-names, unless the options are frequently used, in which case an upper-case letter should be used.

The full set of command-line options is created by the AggregateOptions class. Using AggregateOptions::add(), different OptionsPackage instances can be combined to build up the full set of command-line options. The order that the OptionsPackage objects are added is important, as it will determine the order of "positional" options as well as how the options are listed in the help. We recommend the following convention in options order:

Frequently, a tool requires a number of command-line arguments that are not optional. The RequiredArguments class can be used to incorporate these, rather than handling it within a tool-specific subclass of OptionsPackage. A RequiredArguments object can build up a command line by passing a string tag and description to RequiredArguments::addArgument() in the same order that the arguments would appear on the command line.

Another common command line format is to have an argument that can appear one or more times. This can also be handled by RequiredArguments by using the RequiredArguments::addVariableArguments() method. If this feature is used, the specified argument will appear after all other required arguments. Since the final argument can appear one or more times, it will consume all remaining command-line arguments. This means that if you use RequiredArguments, it should be the last OptionsPackage included in the AggregateOptions object.

Which OptionsPackage subclasses to use in a tool depends on what the tool needs. All tools, however, should include BasicOptions to provide a help message and optional full-help message. While verbosity is defined in BasicOptions, tools do not need to support it. If a tool needs an output prefix, then include OutputPrefix. Similarly, if a tool needs a single selection to determine which atoms to operate on, include a BasicSelection. If the tool needs multiple selections, then you will need to handle this explicitly with a tool-specific subclass of OptionsPackage or via RequiredArguments.

For tools that work with a model only, we recommend that you use ModelWithCoords. This will guarantee that the generatic AtomicGroup has coordinates (e.g. the user specified a PSF file rather than a PDF). Tools that iterate over all frames in a trajectory should use BasicTrajectory. This class does provide a –skip option that lets the user skip the first n-frames of a trajectory (presumably, the equilibration stage). The trajectory it creates will be "primed" so that the first read will be the n+1'th frame. Finally, tools that can operate on a range of a trajectory, or an arbitrary set of frames, should use TrajectoryWithFrameIndices. The TrajectoryWithFrameIndices::frameList() method returns a vector of unsigned integers that specify which frames of the trajectory a tool should use. For example:

pTraj traj = trajectory_options->trajectory;
vector<uint> indices = trajectory_options->frameList();
for (vector<uint>::iterator i = indices.begin(); i != indices.end(); ++i)
processTrajectoryFrame(traj->readFrame(*i));

Writing a ToolOption class

The common idiom to add tool-specific options not covered by the existing objects is to subclass OptionsPackage. The virtual memberfunctions (e.g. addGeneric(), addHidden(), etc) mimic the steps you would normally take to use boost::program_options. It is only necessary to override the functions required speficially for the tool.

As a trivial example, here is a class that will add a bool option to the command line,

namespace po = loos::OptionsFramewokr::po;
class ToolOptions : public opts::OptionsPackage {
public:
void addGeneric(po::options_description& o) {
o.add_options()
("flag", po::value<bool>(&flag)->default_value(false), "Set a flag");
}
// print() included for completeness. It's not necessary, but good form to
// include...
string print() const {
std::ostringstream oss;
oss << boost::format("flag=%d") % flag;
return(oss.str());
}
bool flag;
};

This class can then be used as follows,

BasicOptions* bopts = new BasicOptions;
ModelWithCoords* mopts = new ModelWithCoords;
ToolOptions* topts = new ToolOptions;
AggregateOptions options;
options.add(bopts).add(mopts).add(topts);
if (!options.parse(argc, argv))
exit(-1);

In more complex cases, check() can be used to validate the command-line and postConditions() can be used to implement any necessary post-processing of command-line options but still within the context of the parser. This means that an error will result in a help message being printed. For example, if a file is required for input, the ifstream can be opened here. If it fails, then postConditions() will report the error and a help message will be printed out.


Notes:

  • Model and Trajectory options classes will create the appropriate model and trajectory objects which can be copied out of the respective options object for use in a tool.
  • Pointers to OptionsPackage subclasses are used within the OptionsFramework. Unlike most of LOOS, these are not shared pointers so the tool is responsible for managing them. However, we anticipate that most will only use a small amount of memory and will need to exist for the life of a tool anyway, so deletion of the objects should not be a problem.
  • OptionsPackages cannot be combined multiple times, e.g. using two BasicTrajectory objects because the tool needs to read from two different trajectories. We anticipate these cases as being infrequent, and as such, there is no direct support for it in OptionsPackages. Use a tool-specific OptionsPackage that handles the required args (matching as closely as possible the existing OptionsPackage options).