Overview

Needing to recompile every time you change a variable value in a simulation is not ideal and can make it difficult to track what values you had when you got specific data. Instead, you can have a file of these values that your code references so that you can change values at run time. The use of a configuration file is very common and slightly annoying to setup, so Empirical provides a set of tools through the ArgManager class that handles both a configuration file for settings as well as support for overriding those values at the command line and URL when using a GUI.

Basic Learning Objectives

Before class, you should be able to:

  • Explain the functionality that the Empirical ArgManager provides

Advanced Learning Objectives

After class, you should be able to:

  • Implement a configuration manager using the ArgManager functionality
  • Display a configuration panel on a web GUI

Resources

Read the following introductory documentation.

(Note: This reading is a work in progress and there may be typos, please let me know if you find any!)

Include

The ArgManager is in the config directory of Empirical and so you need the following include statement:

#include "emp/config/ArgManager.hpp"

Creating your config object

Empirical provides a way to make a class at compile time for your configuration manager. The macro EMP_BUILD_CONFIG is what does this. Outside of any function in your native.cpp file, you would put:

EMP_BUILD_CONFIG(MyConfigType,
    VALUE(SEED, int, 10, "What value should the random seed be?"), 
    VALUE(START_PROB, double, 0.5, "What cooperation probability value should the starting organism have?"),
    VALUE(FILE_NAME, std::string, "_data.dat", "Root output file name")
)

This creates the type MyConfigType and gives it three instance variables, SEED, START_PROB, and FILE_NAME with the respective types and default values.

In your main function in your native.cpp file, you can then declare your configuration object:

MyConfigType config;

And have it read in all the settings from a file in the top level of your project’s directory:

config.Read("MySettings.cfg");

It’d be nice to check if the file is read in successfully, and if not, write out the default configuration file. You can do so like this:

bool success = config.Read("MySettings.cfg");
if(!success) config.Write("MySettings.cfg");

Accessing config values

Getter methods are automatically created for each of the instance variables in your configuration object, so to access and use the random seed number for example, you would type:

emp::Random random(config.SEED());

You can also pass this configuration object to your organisms so that they can access all the settings directly, which can lead to much cleaner code!

Command line arguments

You can also easily override the settings in your settings file with command line arguments, which is very useful when you want to automatically run a range of parameter settings.

To get command line arguments to override your config settings along with a helpful error message, you type:

auto args = emp::cl::ArgManager(argc, argv);
if (args.ProcessConfigOptions(config, std::cout, "MySettings.cfg") == false) {
cerr << "There was a problem in processing the options file." << endl;
exit(1);
}
if (args.TestUnknown() == false) {
cerr << "Leftover args no good." << endl;
exit(1);
}

To then enter a command line argument for one of your settings such as your FILE_NAME, you should type:

./evo-algo -FILE_NAME "hi"