/*! @page pag_concepts_atomscat Atomic scattering

\section sec_atomscat Atomic scattering

\subsection sec_atomscat_intro Introduction

The process of calculating atomic scattering factors (phase shifts) can be customized in several ways.

1. Internal processing.
   Some multiple scattering programs, like EDAC, contain a built-in facility to calculate phase shifts.
   This is the most simple and default behaviour.
2. Automatic calculation in a separate program.
   PMSCO has an interface to run the PHAGEN program from
   the [MsSpec-1.0 package](https://ipr.univ-rennes1.fr/msspec) to calculate scattering factors.
   Note that the PHAGEN code is not included in the public distribution of PMSCO.
3. Manual calculation.
   Scattering files created manually using an external program can be used by providing the file names.
   The files must have the format required by the multiple scattering code,
   and they must be linked to the corresponding atoms of the cluster.

In the case of automatic calculation, the project code can optionally hook into the process
and modify clusters before and after scattering factors are calculated.
For instance, it may provide an extended cluster in order to reduce boundary effects,
or it may modify the assignment of scattering files to cluster atoms
so that the scattering factors of selected atom classes are used
(cf. section \ref sec_atomscat_atomclass).


\subsection sec_atomscat_usage Usage

\subsubsection sec_atomscat_internal Internal processing

This is the default behaviour selected in the inherited pmsco.project.Project class.
Make sure not to override the `atomic_scattering_factory` attribute.
Its default value is pmsco.calculators.calculator.InternalAtomicCalculator.

\subsubsection sec_atomscat_external Automatic calculation in a separate program

To select the atomic scattering calculator,
assign its interface class to the project's `atomic_scattering_factory` attribute.
For example, to use PHAGEN, add the following code to your project's `__init__` constructor:

@code{.py}
    from pmsco.calculators.phagen import PhagenCalculator
    self.atomic_scattering_factory = PhagenCalculator
@endcode

\subsubsection sec_atomscat_manual Manual calculation

If you want to keep the scattering factors constant during an optimization,
you should run PMSCO in _single_ mode and provide the model parameters and cluster
that will return the desired scattering files.
In the `create_params` method of your project,
you should then set the `phase_files` attribute,
which is a dictionary that maps atom classes to the names of the scattering files.
Unless you set specific values in the cluster object, the atom class defaults to the element number.
The file names should include a path relative to the working directory.


\subsection sec_atomscat_implement Implementation

\subsubsection sec_atomscat_atomclass Atom classes

Atomic scattering programs classify atoms based on chemical element, charge state and symmetry of the local environment.
This means that two atoms of the same chemical element may have different scattering factors.
For example, if you have EDAC output the cluster after calculation of the muffin tin potential,
you will find that the chemical element number has been replaced by an arbitrary integer.

By default, PMSCO will do the linking of atom classes and scattering files transparently.
However, if you want to reduce the number of atom classes,
or if you have the scattering factors calculated on a reference cluster,
you will have to provide project code to do the assignment.
This is described further below.


\subsubsection sec_atomscat_calculator Atomic scattering calculator

The project selects the atomic scattering calculation mode by specifying its `atomic_scattering_factory` attributed.
This is the name of a class that inherits from @ref pmsco.calculators.calculator.AtomicCalculator.

The following calculators are currently implemented:

| Class | Description |
| --- | --- |
| pmsco.calculators.calculator.InternalAtomicCalculator | Calculate the atomic scattering factors in the multiple-scattering program. |
| pmsco.calculators.phagen.PhagenCalculator | Calculate the atomic scattering factors in the PHAGEN program. |

An atomic calculator class essentially defines a `run` method that operates on a cluster and scattering parameters object.
It generates the necessary scattering files, updates the cluster with the new atom classes
and updates the parameters with the file names of the scattering files.
Note that the scattering files have to be in the correct format for the multiple scattering calculator.


\subsubsection sec_atomscat_hooks Project hooks

Before and after calculation of the scattering factors,
the project's `before_atomic_scattering` and `after_atomic_scattering` methods are called
with the cluster and input parameters.

The _before_ method provides the cluster to be used for atomic scattering calculations.
It may,
1. just return the original cluster,
2. modify the provided cluster to include additional atoms or modify the charge state of the emitter,
3. create a completely different cluster,
4. return None to suppress the atomic scattering calculation.
The method is called once at the beginning of the PMSCO job with model -1,
where it may return the global reference cluster.
Later on it is called once for each calculation task with the specific task index.

Similarly, the _after_ method collects the results and updates the `phase_files` dictionary of the input parameters.
It is free to consolidate atom classes and remove unwanted atoms.
However, it must make sure that for each atom class in the cluster,
there is a corresponding link to a scattering file.
*/