$darkmode
DENOPTIM
developer_manual

DENOPTIM Developer's Manual

This manual integrates the JavaDoc to provide an overview on the software logic and facilitate understanding, development, and debug of the code. It is a manual meant for developers, not for users. If you are looking for information on how to use DENOPTIM, check the user's manual.


Execution Logic

The Main class is meant to be the only JAVA Main class in the DENOPTIM package and is the execution entry point for all the functionality implemented in the DENOPTIM package. Accordingly, the main() method defines the actual Behavior of the software upon parsing the list of program arguments. The Behavior may correspond to

  • returning an error in case of unacceptable list or program arguments (i.e., a null RunType),
  • terminating, possibly upon printing some information such as the help message (i.e., a DRY RunType),
  • launching the graphical user interface (i.e., a GUI RunType),
  • launching the execution of anyone among the main program tasks (i.e., any other RunType. The specific implementation of ProgramTask for a given RunType is defined within the definitions of a RunType).

The latter occurs by creating an instance of ProgramTask, typically by passing as parameters to the constructor the pathname to a working directory and the pathname to a configuration file defining any settings that control the specifics of the task at hand. Any such implementation of ProgramTask is a callable where the usual call method, in addition to dealing with general-purpose process management tasks, embeds a call to method runProgram(), which is where the main task is coded.

Typically, any parsing of the configuration file occurs at the beginning of the runProgram() and populated an instance of RunTimeParameters. The latter is a class meant to collect program-specific settings and utilities, such as logger and randomizer, that are used in various parts on a program. Therefore, RunTimeParameters are passed around to child methods to make these settings and utilities available where needed.

Implementations of ProgramTasks are collected in sub-packages of the denoptim.programs package together with the corresponding program-specific implementation of RunTimeParameters.


Run types

Run Description
GUI Graphical User Interface
GA Genetic Algorithm
FSE Fragment Space Exploration
FRG Fragmenter
GE Graph Editing
GO Genetic Operation
FIT Fitness Evaluation
B3D Build 3D molecular entities
GI Graph Isomorphism
CLG Comparison of lists of Graph

Genetic Algorithm

The ProgramTask implementation dealing with GA experiments is the GARunner. Besides class EvolutionaryAlgorithm which ultimately performs the evolutionary experiment, besides the settings GARunner creates an ExternalCommandListener in its arguments. Such listener is responsible for the interaction between an ongoing evolutionary experiment and the user (see here).

The specifics of the evolutionary algorithm's implementation are deeply affected by its capability of running two parallelization schemes: synchronous and asynchronous. The synchronous scheme follows the classical evolutionary optimization algorithm where each generation is isolated from the others. In the asynchronous scheme, instead, new candidates are created continuously without stopping the generation of candidates at the end of a generations. Because of this peculiarity, selection of candidates for mutation and crossover is done upon requesting a crossover or mutation event.

Fragment Space Exploration

The ProgramTask implementation dealing with combinatorial experiments is the FragSpaceExplorer, while the algorithm is coded in the CombinatorialExplorerByLayer. Given a graph, i.e., the so-called root graph, all the combinations of fragments that can be attached on the root graph are obtained from the FragsCombinationIterator. Once the combination of fragments to be attached on the root graph is defined, the construction of the resulting graph, or graphs (multiple graphs can result by closing different sets of fundamental rings on the same spanning tree) is done by the GraphBuildingTask.

This type of run has the capability to periodically save CheckPoints that allow to restart the exploration should it be interrupted by any reason.

Graph Editing

The ProgramTask dealing with standalone graph editing tasks is the GraphEditor. This class essentially allows to prepare everything that may be needed to call method DGraph.editGraph.

Genetic Operation

The ProgramTask dealing with standalone genetic operations is GeneOpsRunner. This class essentially allows to prepare everything that may be needed to perform mutations and crossover operations outside a genetic algorithm.

Fitness

The ProgramTask dealing with standalone fitness calculations FitnessRunner. An instance of FPRunner is created to run a task that may use the internal or an external fitness provider. The internal fitness provider uses only functionality available within the DENOPTIM package, while the external fitness provider runs a ProcessHandler to create an external subprocess and retrieve the fitness from the output of such process (NB: not the log or return value).

3D Molecular Models Builder

The ProgramTask dealing with standalone construction of three-dimensional (3D) molecular models is the MolecularModelBuilder. The construction of one or more 3D models for a Candidate is MultiMolecularModelBuilder.

Graph Isomorphism Analyzer

The ProgramTask dealing with standalone detection of graph isomorphism is Isomorphism. Here, two graphs are compared by means of the method DGraph.isIsomorphicTo. his method uses the Vento-Foggia algorithm (see DOI:10.1109/TPAMI.2004.75) implemented in the JGraphT library.

Graph List Comparator

The ProgramTask dealing with standalone comparison of lists of graphs is GraphListsHandler. Here the method isIsomorphicTo is use to compare each member of a list with each member of another list.

Fragmenter

The ProgramTask performing fragmentation tasks and management of fragment libraries is the Fragmenter.

When fragmentation is requires, the ParallelFragmentationAlgorithm can parallelize the work as follows:

  1. Split input structures in N batches.​
  2. Run N fragmentation threads in parallel.​ Each thread contributes creating a molecular weight (MW)-resolved fragment collections. MW is an intrinsic property, and therefore it’s thread-safe.​ Moreover, in case of need to identify isomorphic fragments, a single fragment is used to represent each isomorphic family (i.e., the list of fragments isomorphic to each other).

Also when the task is the extraction of representative geometries, the work can be parallelized. This is done by ParallelConformerExtractionAlgorithm, which runs one thread for each isomorphic family in an asynchronous parallelization scheme.

Graphical User Interface

Contrarily to most of the other run types, the launching of the GUI occurs directly via running GUI without involving any ProgramTask implementation.