.. currentmodule:: rotsim2d.pathways
#########################################
Creating and manipulating excitation tree
#########################################
First-order excitation
======================
Create :class:`KetBra` in ground vibrational state
.. ipython:: python
import rotsim2d.pathways as pw
import molspecutils.molecule as mol
kb1 = pw.KetBra(mol.DiatomState(nu=0, j=1), mol.DiatomState(nu=0, j=1))
print(kb1)
and excite it,
.. ipython:: python
pw.excite(kb1, light_name='omg1')
kb1.print_tree()
`kb1` is modified in-place. Use :func:`readout` to simulate measurement and see which
branches will contribute to macroscopic polarization, i.e. would survive
another one-sided application of the dipole operator and taking the trace of the
density matrix.
.. ipython:: python
pw.readout(kb1)
kb1.print_tree()
**********************
Third-order excitation
**********************
Create :class:`KetBra` in ground vibrational state and perform three excitations
with :func:`multi_excite`:
.. ipython:: python
kb2 = pw.KetBra(mol.DiatomState(nu=0, j=1), mol.DiatomState(nu=0, j=1))
kb2 = pw.multi_excite(kb2, light_names=['omg1', 'omg2', 'omg3'],
parts=['ket', 'both', 'both'])
kb2.print_tree()
The excitation tree in this case is very long. We can save it's graphical
representation with :meth:`KetBra.savepng`. This uses
:class:`anytree.exporter.DotExporter` and requires a working installation of
`GraphViz `_.
.. ipython:: python
kb2.savepng('images/kb2.png')
.. image:: /images/kb2.png
:target: ../_images/kb2.png
We can also generate double-sided Feynmann diagrams corresponding to the tree with LaTeX/Tikz:
.. ipython:: python
import rotsim2d.visual as vis
latex_code = vis.tikz_diagrams(kb2)
#vis.latex_compile('images/kb2_tikz.tex', vis.latex_document(latex_code))
See the result: :download:`kb2_tikz.pdf <../images/kb2_tikz.pdf>`. See
:func:`rotsim2d.visual.tikz_diagrams` for more details.
******************
Filtering the tree
******************
`kb2` contains all rephasing and non-rephasing pathways, emitted in all
directions. The tree can be filtered with one of :mod:`rotsim2d.pathways`
functions starting with `remove_` or only `only_`, see
:ref:`tree-filtering-functions`. For example, to obtain only pathways emitted
in :math:`\vec{k}_s = \vec{k}_1 - \vec{k_2} + \vec{k}_3` (non-rephasing
pathways) we can use:
.. ipython:: python
kb2_SII = pw.only_SII(kb2.copy())
kb2_SII = pw.readout(kb2_SII)
kb2_SII.savepng('images/kb2_SII.png')
.. image:: /images/kb2_SII.png
:target: ../_images/kb2_SII.png
For :math:`\vec{k}_s = \vec{k}_1 + \vec{k_2} - \vec{k}_3` direction (rephasing
without double-quantum coherences), we can use:
.. ipython:: python
kb2_SI = pw.only_SI(kb2.copy())
kb2_SI = pw.readout(kb2_SI)
kb2_SI.savepng('images/kb2_SI.png')
.. image:: /images/kb2_SI.png
:target: ../_images/kb2_SI.png
*************************
Multiple excitations tree
*************************
Excitation trees for many initial `j` values can be generated with :func:`gen_pathways`:
.. ipython:: python
from pprint import pprint
js = (0, 1, 2, 3)
kbs = pw.gen_pathways(js, meths=[pw.only_SII, pw.only_twocolor],
rotor='symmetric', kiter_func="range(j+1)")
pprint(kbs)
This call created a list of third-order excitation trees for `j` values in
`js`. Each tree was filtered by :func:`only_SII` and
:func:`only_twocolor`. `meths` argument can contain any callable that takes
:class:`KetBra` instance as its sole argument and returns it, presumably after
filtering it in some way, see :ref:`tree-filtering-functions`.
`rotor='symmetric'` causes the functions to generate
tree for different `k` quantum number values. The range of these values is
determined by `kiter_func` [#f1]_. `kiter_func` is a Python expression evaluated
with `ASTEVAL `_, which should return an
iterable over integers. The expression is evaluated for each `j` value from `js`
argument. The default expression is ``"range(j+1)"``, which iterates from 0 to `j`.
.. rubric:: Footnotes
.. [#f1] This argument could be called more aptly `kiter_expr`.