8.10.1. Architecture Quick Reference
************************************


8.10.1.1. Diagram
=================

The following diagram is intended as a quick reference to aid in
building or debugging personal workflows with ParAMS, listing main
input-output interactions between classes. Boxes on the left are
inputs to the ones on the right. For more information about a specific
class, see its respective section.

   +--------------------+--------------------+--------------------+--------------------+
   |  plams.Settings()  |                    |                    |                    |
   +--------------------+     JCEntry()      |   JobCollection()  |                    |
   |  plams.Molecule()  |                    |                    |                    |
   +--------------------+--------------------+--------------------|                    |
                                             |                    |                    |
                        +--------------------+     DataSet()      |                    |
                        |   extractor.py     |                    |                    |
                        +--------------------+--------------------|                    |
                                             |                    |                    |
                                             |ParameterInterface()|                    |
                                             |                    |                    |
                                             +--------------------|    Optimization()  |
                                             |                    |                    |
                                             |     Optimizer()    |                    |
                                             |                    |                    |
                                             +--------------------|                    |
                                             |                    |                    |
                                             |  ParallelLevels()  |                    |
                                             |                    |                    |
                                             +--------------------|                    |
                                             |                    |                    |
                                             |       Loss()       |                    |
                                             |                    |                    |
                                             +--------------------|                    |
                        +--------------------+--------------------+--------------------+
                        |  plams.Settings()  |                    |                    |
                        +--------------------+      Engine()      | EngineCollection() |
                                             |                    |                    |
                                             +--------------------+--------------------+


8.10.1.2. Simple usage of some classes
======================================

Launch "$AMSBIN/amspython", and import all modules from "scm.params":

>>> from scm.params import *

There are three main components to the package:

* The Job Collection, which represents a set of chemical systems
  stored as plams.Molecule objects alongside AMS settings specific to
  each system. The combination of system and settings clearly defines
  a computational *job*. An example for a job could be a geometry
  optimization of a methane molecule.

* A Data Set, which holds the definition of all properties that are
  relevant for the parameter optimization. These could be forces,
  energy, and geometry of the aforementioned methane job. The Data Set
  is responsible for the extraction and comparison of all properties
  to their reference values, providing a *loss value* metric.

* A parameter interface, which serves as a translation layer between
  an AMS engine and a list of parameters. Any available parameter
  interface in ParAMS can be used for reparameterization.

Components interact with each other as follows:

>>> print(jc) # jc is a JobCollection instance
---
ID: Water01
ReferenceEngineID: None
AMSInput: |
   properties
     gradients
   End
   system
     Atoms
                 O      0.0000000000      0.0000000000      0.5937200000
                 H      0.0000000000     -0.7654400000     -0.0083600000
                 H      0.0000000000      0.7654400000     -0.0083600000
     End
   End
   task geometryoptimization
...

>>> print(ds) # ds is a DataSet instance
---
Expression: energy('Water01')
Weight: 1.0
ReferenceValue: -0.09210963293745549
---
Expression: forces('Water01')
Weight: 1.0
ReferenceValue: |
   array([[-4.41310133e-11,  1.24966204e-10, -1.38738596e-05],
          [-2.19091605e-11, -2.01034720e-05,  6.93698245e-06],
          [-2.19091605e-11,  2.01036055e-05,  6.93698245e-06]])
...

>>> params = LennardJonesParameters() # params is a ParameterInterface instance
>>> params.names # parameter names
['eps', 'rmin']
>>> print(params.x) # parameter values
[0.0003, 3.0]
>>> jobresults = jc.run(params) # calculate all jobs in `jc` with our parameters
>>> loss       = ds.evaluate(jobresults)
>>> print(loss) # How close are the results calculated with `params` to their reference values?
2082.088800689759

>>> params.x   = [0.0004, 4.] # change the parameter values ...
>>> jobresults = jc.run(params) # ... re-calculate ...
>>> loss       = ds.evaluate(jobresults) # ... and re-evaluate.
2066.4096600168773

Note how in the above code block we are manually assigning different
parameter values to our *params* instance. This is the entry point to
the fourth component in ParAMS - the optimizer. Piecing it all
together is a top-level Optimization class, which is managing the
parameter fitting process based on user-defined settings. A simplified
overview of the ParAMS parameterization loop is depicted in the figure
below.

   [image]

For a hands-on dive into the workings of the package, we recommend
checking out the Tutorials: Getting Started section (and trying them
yourself). If at any point you stumble upon a class, whose
functionality is not entirely clear, make sure to look it up in the
respective Python Classes and Functions subsection. Most of these
provide additional examples on the component's functionality on top of
introducing the complete API.
