The Nanoverse codebase is, in a word, huge. It got a little smaller with the removal of legacy code in September 2015, but it's still a challenge for anyone to navigate (including its inventor). Fortunately, it is reasonably well-organized, meaning that a decent map should help you get your bearings.
Java allows developers to organize code into packages. The following skeleton does not mention every Nanoverse package, but it does mention enough of the important ones to let you find your way around.
Nanoverse's main class is
nanoverse.Nanoverse. It takes a exactly one argument: namely, the path to the project file to be executed. The class constructs a compiler, compiled the project into a Nanoverse project, and then simulates the project.
We are currently interviewing research assistants to help develop an interactive object dictionary. Until then, the user must identify objects by viewing the Nanoverse source code. Perhaps the most important package for doing this is the symbol table hierarchy, which is located at
These symbol tables contain plain-text descriptions of objects and their properties. Starting at the project symbol table, you can actually crawl through the hierarchy of symbol tables to learn about any object desired. The symbol table hierarchy is a nearly exact mirror of the runtime hierarchy.
The next most important package is the the hierarchy of loaders, which build Java objects from internal representation of user code. The loader hierarchy contains information about which parameters are optional, and if so, what defaults are used. This information can be found at:
Like the symbol table hierarchy, the loader hierarchy basically mirrors the runtime hierarchy. (It should mirror it exactly, but it must be maintained manually, so it gets messed up sometimes.) The project loader is found at
nanoverse.compiler package contains all of the logic necessary to read user source code, check it for errors, convert it to an internal representation (with defaults as needed), and translate it into an execution plan.
Nanosyntax.g4 is the Nanoverse language specification. It is written in ANTLR v4, a program for generating parsers from grammars. This file is used to generate the backbone of the interpreter, found in
nanoverse.compiler.pipeline.interpret.nanosyntax.*. You can peruse the
Nanosyntax.g4 file to study the grammar of the language directly.
nanoverse.compiler.error contains error messages supplied to the user during compile time, typically as a result of syntax errors or illegal definitions.
nanoverse.compiler.pipeline contains the sequence of steps involved in converting human-readable Nanoverse source code into a simulation. The compilation pipeline consists of three steps: interpretation, translation, and instantiation. The instantiation step is further divided into two sub-steps: interpolation and loading.
This package contains the logic involved in reading Nanoverse source code and turning into an internal representation known as an abstract syntax tree. The abstract syntax tree has only structural information about the program; semantic information is added in the next step,
Much of the code in this package is computer-generated, and is therefore not subjected to automated tests.
This package contains the logic involved in
understanding the user's specifications in the context of agent-based models. In technical terms, the
Translate step decorates the abstract syntax tree with semantic information. This is accomplished by matching each token to a corresponding symbol table. If the token is not recognized as a well-defined symbol in the current context in which it is used, the compiler halts with an error.
The symbol table hierarchy is an extremely helpful source of information for the user: it can be used as a dictionary for types and their associated classes, as well as for the arguments of each particular class. The symbol table hierarchy can be found at
The last stage of the compilation pipeline is the
Instantiate stage. During this stage, well-defined symbols are converted to Java objects. This process is completed recursively: before an object can be instantiated, its properties must first be instantiated as well.
Thus, at the outset of the
Instantiation stage, the compiler begins to instantiate the simulation itself. In order to do this, the compiler must first instantiate each of the simulation's properties. Why? These properties are used to define the simulation itself. (On the Java side of things, these properties are arguments to the constructors of the simulation's foundational objects.) So these must be instantiated first.
The build sequence for an object called
MyObject is defined in a
Loader object called
MyObjectLoader, in a method called
Loader object should be in a package that mirrors the
nanoverse.runtime hierarchy, rooted in
Loader visited is the
ProjectLoader, located at
The user may omit essential properties from the project definition. If there is a default for that property, Nanoverse attempts to use it automatically. Some defaults are “smart”, in that they attempt to interpolate the most reasonable value based on the user's other input. For an object called
MyObject with loader
MyObjectLoader, interpolation will occur in an object called
MyObjectInterpolator. Defaults are specified in
MyObjectDefaults. The loader, interpolator and defaults are all in the same package.
nanoverse.runtime package contains all of the logic that will be used to actually execute a simulation. The first runtime object,
nanoverse.runtime.control.Runner, is returned by the last step of the compiler. Executing its
run() method begins simulation execution.
nanoverse.runtime.agent package contains classes involved in creating and controlling agents, including agent actions and action targets. the contents of
nanoverse.runtime.cells will soon by migrated to this package as well.
nanoverse.runtime.agent.action package contains the definitions of all actions that can be performed by agents. The
ActionClassSymbolTable (in the
translate package of the compiler) provides human-readable descriptions actions, as well as their names in the Nanoverse language.
nanoverse.runtime.agent.target package contains methods used to specify the affected site(s) of transitive actions relative to the acting agent.
This package contains the control logic for the simulation engine itself, such as the simulation integrator (which moves the simulation forward through time) and halt events (which signal that the simulation is over).
This package contains the so-called “Halt conditions” that cause the simulation to stop running. These are triggered by corresponding
Check processes. There are two special cases:
StepMaxReachedEvent, which occurs when the simulation has reached the maximum time specified in the
parameters section of the project, and
BoundaryReachedEvent, which occurs if an agent touches or passes the boundary while its agent layer is using a
This package contains the lattices, shapes and boundaries that make up the geometry of a simulation. This includes both simulation-wide geometric properties (lattice, shape) and the layer-specific boundary. This package also includes
Coordinate objects and coordinate sets, which are used to specify areas of effect.
This package contains all serializers (output classes), deserializers (input classes), and visualizations for simulations.
This package contains all of the logic for agent and continuum layers, as well as for the linkages between them.
This package contains all classes concerned with managing and updating continuum layers. It includes the Java linkages to the PETSc numerical simulation library, which is used on Mac and UNIX computers to update simulation state quickly. (Windows users must content themselves with Matrix Toolkit Java).
This package contains all classes concerned with managing and updating agent layers. The biology-specific name is a holdover from earlier versions of Nanoverse; expect this to change soon.
This package contains all of the global processes that can take place in a simulation. The
ProcessClassSymbolTable (in the
translate package of the compiler) provides plain-text descriptions of each process, as well as the word used to invoke the process in the Nanoverse programming language.
This package contains utility methods that are used throughout the code base.