1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
================
Labels for atoms
================
**WORK IN PROGRESS**
This proposal describes how to introduce labels for the atoms in an
:class:`~ase.Atoms` object in a backwards compatible way.
Why?
====
Some atoms are special:
* ghost atoms
* atoms with a core hole
* atoms that need a special basis set
* ...
and some atoms are not atoms at all (methyl group, ...).
Proposal
========
Introduce *labels* and *kinds*. A label is a string and a kind is the
combination of these three:
* A chemical symbol or an atomic number. Default: ``None``
(same as ``'X'`` or ``0``)
* A label. Default ``''``
* A mass. Default ``None`` (use standard value)
* An integer tag. Default ``0``
A *kind* can be represented as a ``Kind`` object:
* ``Kind(Z=None, symbol=None, label='', mass=None, tag=0)``
or as a string:
* ``'symbol'`` (``Kind(symbol='symbol')``)
* ``'symbol:label'`` (``Kind(symbol='symbol', label='label')``)
* ``'label'`` (``Kind(label='label')``)
Examples:
* ``Kind(Z=1, label='ghost')`` (same as ``'H:ghost'``)
* ``Kind(symbol='H')`` (same as ``'H'``)
* ``Kind(symbol='H', label='', mass=2.0)``
* ``'methyl'`` (same as ``Kind(label='methyl')``)
We add ``symbols``, ``labels`` and ``kinds`` list-of-string like attributes to
the :class:`~ase.Atoms` object as well as new ``labels`` and ``kinds`` keyword
arguments to the Atoms constructor. Currently, the first argument to the
Atoms constructor (``symbols``) will accept a chemical formula as a string or a
list of chemical symbols or atomic numbers. We extend this to also accept
kinds.
.. note::
Not really related to this label issue, but since we are anyway adding new
attributes, we should also add ``masses``, ``tags``, ``initial_magmoms``,
``momenta``, ``initial_charges`` and ``mass``.
Examples
========
>>> a = Atoms(['N', 'C', Kind(label='methyl', mass=9.0)])
>>> a.positions[:, 0] = [0, 1.2, 2.6]
>>> a.masses[a.labels == 'methyl'] = 10
>>> a.numbers
array([7, 6, 0])
>>> a.symbols # special list-like object tied to a
Symbols(['N', 'C', 'X'])
>>> a.get_chemical_symbols() # simple list
['N', 'C', 'X']
>>> a.labels
Labels(['', '', 'methyl'])
>>> a.kinds
Kinds(['N', 'C', Kind(label='methyl', mass=10.0)])
Here are 50 H-D molecules:
>>> h = Atoms('H100', positions=...)
>>> h.labels[::2] = 'deuterium'
>>> h.masses[h.labels == 'deuterium'] = 2.0
or equivalently:
>>> h.kinds[::2] = Kind(symbol='H', label='deuterium', mass=2.0)
A DFT code could use the kinds to select pseudo-potentials:
>>> n2 = molecule('N2')
>>> n2.labels[0] = 'core-hole'
>>> n2.calc = DFT(xc='LDA',
... pp={'N:core-hole': '~/mypps/N-LDA.core-hole.upf'})
List-like objects
=================
New ``Labels``, ``Kinds`` and ``Symbols`` list-like objects will
be introduced that can handle all the indexing operations in a storage
efficient way. A statement like ``a.symbols[0] = 'He'`` must somehow lead to
``a.numbers[0] == 2`` and other magic.
Atom objects
============
Add ``Atom.label`` and ``Atom.kind``.
I/O
===
???
|