*******************
Fragment Conversion
*******************

*A tutorial page written by Thomas John and Rowan Hanson at Cardiff University, with thanks to the Nuffield Foundation and CCP5.*

Overview
========

The `Atomic Simulation Environment <https://wiki.fysik.dtu.dk/ase/>`_ (ASE) is a popular tool for setting up materials simulations.
ChemShell reads and writes chemical data files using the **Fragment** object, whereas ASE reads and writes using the **Atoms** object; thus, a tool has been written that interconvert ChemShell Fragments with the ASE atoms format, allowing structural manipulation in ASE prior to ChemShell use, and for access to additional I/O tools in ASE for saving results.

This page will show you how to convert to *Fragment* from *Atoms* and back by using a ``.cif`` file as the example.

`Convert Fragment to Atoms`_
============================

A ``Fragment`` object can be defined and converted into an ``Atoms`` object. Some of ASE's method will then be used on the ``Atoms`` object.
First, we must import ``ChemShell`` and create a ``Fragment`` of an N_2 molecule:

.. code-block:: python

   from chemsh import *
   nitrogenMolecule = Fragment(znums=[7, 7], coords=[[0, 0, 0], [2.0787, 0, 0]])


Next, we import the ``io.tools`` from *ChemShell*. These are used to call the ``convert_frag_to_atoms`` function, passing the ``Fragment`` object as an argument. The output of the conversion is an ASE ``Atoms`` object, and can be visualised by importing the *view* function from *ASE*

.. code-block:: python

   from chemsh.io.tools import *
   from ase.visualize import view
   atomsObject = convert_frag_to_atoms(nitrogenMolecule)
   view(atomsObject)

The kinetic and potential energies of the system can be calculated using calculators built into *ASE*, such as ``EMT``:

.. code-block:: python

   from ase.calculators.emt import EMT
   print("\nKinetic Energy: " + str(atomsObject.get_kinetic_energy()))
   print("\nPotential Energy: " + str(atomsObject.get_potential_energy()))

.. note:: Other methods found in *ASE* can also be used to manipulate the created Atoms object. Charges associated with the ``Fragment`` are lost on conversion into the *ASE* object


`Convert Atoms to Fragment`_
============================

Simiar to above, an ``Atoms`` object can be defined and converted to a ``Fragment`` object.
To begin, we import the ``Atoms`` object from *ASE* and define a molecule:

.. code-block:: python

   from ase.atoms import Atoms
   nitrogenMolecule = Atoms("N2", positions=[[0, 0, 0], [1.1, 0, 0]])

Next, we import *ChemShell* and the ``io.tools``. This allows a call to the ``convert_atoms_to_fragment`` function, passing the ``Atoms`` object and its connectivity mode (``connect_mode``) as arguments; *connect_mode* can be set as either ``"ionic"`` or ``"covalent"``.

.. code-block:: python

   fragmentObject = convert_atoms_to_frag(nitrogenMolecule)

Performing such an approach with a more native crystal formats, such as ``"cif"``, can allow easy cluster construction and energy calculations from popular formats, and transformation back for model review

.. code-block:: python

   from ase.io import read
   fragmentObject = convert_atoms_to_frag(read("mgo.cif"))
   fragmentObject.addCharges({"Mg":2.0, "O":-2.0})
   cluster = fragmentObject.construct_cluster(origin_atom=0, radius_cluster=20.0, radius_active=10.0, bq_margin=7.0, bq_density=3, adjust_charge='coordination_scaled')
   clusterToAtoms = convert_frag_to_atoms(cluster)
   view(clusterToAtoms)

