diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..28b7e10 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,193 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = python -m sphinx +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + @rm -rf $(BUILDDIR)/* + @rm -rf $(PNGs) + @rm -f source/spectroscopies/common_parameters.inc + @rm -f source/spectroscopies/ped/ped_parameters.inc + @rm -f source/spectroscopies/eig/eig_parameters.inc + @rm -f source/downloads.rst + + + +PNGs = $(shell find source/ -type f -name '*.svg'|sed s/\.svg/\.png/) +PNGs += $(shell find source/ -type f -name '*.gif'|sed s/\.gif/\.png/) + +foo: + @echo ${PNGs} + + +%.png: %.svg + @echo converting $< to PNG + @convert -background none -density 150 $< $@ + +%.png: %.gif + @echo converting $< to PNG + @convert -background none -density 150 $<[0] $@ + + +$(BUILDDIR)/html/sitemap.xml: $(BUILDDIR)/html/index.html + @echo "Generating sitemap file..." + @python source/sitemap-generate.py --url https://msspec.cnrs.fr --path $(BUILDDIR)/html $@ + +ownership: source/google*.html + @echo "Copying the ownership file for Google." + @cp $< $(BUILDDIR)/html + +images: $(PNGs) + +banner: + @echo "Creating banner..." + @cd source && python -c "import custom; custom.modify_banner()" + +html0: banner images + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +html: html0 ownership $(BUILDDIR)/html/sitemap.xml + @echo + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/MsSpec-ASE.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/MsSpec-ASE.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/MsSpec-ASE" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/MsSpec-ASE" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: banner images + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/source/apple_icon.png b/doc/source/apple_icon.png new file mode 100644 index 0000000..ce314c4 Binary files /dev/null and b/doc/source/apple_icon.png differ diff --git a/doc/source/comingsoon.png b/doc/source/comingsoon.png new file mode 100644 index 0000000..9a46a4c Binary files /dev/null and b/doc/source/comingsoon.png differ diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..783e4cb --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,267 @@ +# -*- coding: utf-8 -*- +# +# MsSpec-ASE documentation build configuration file, created by +# sphinx-quickstart on Mon Jan 18 10:59:09 2016. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('../../src')) +sys.path.insert(0, os.path.abspath('../../src/msspec')) +#sys.path.insert(0, os.path.abspath('../')) + + +import custom + + + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', + 'sphinx.ext.viewcode', 'sphinx.ext.mathjax'] +#extensions += ['sphinx-prompt'] +todo_include_todos = True + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'MsSpec-python' +copyright = u'2016, Rennes Institute of Physics' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version, dev_version = custom.get_package_version() +# The full version, including alpha/beta/rc tags. +#release = custom.get_package_version() +release = '{}.post{}'.format(version, dev_version).strip('.post') + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +rst_prolog = """ +.. |kalpha| replace:: :math:`K_\\alpha` +""" + + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'pyramid' + + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = ['./mytheme/'] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'MsSpec-doc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'MsSpec-python.tex', u'MsSpec-python Documentation', + u'D. Sebilleau, S. Tricot', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'msspec', u'MsSpec-python Documentation', + [u'D. Sebilleau, S. Tricot'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'MsSpec-ASE', u'MsSpec-ASE Documentation', + u'D. Sebilleau', 'MsSpec-ASE', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +custom.generate_download_page() +custom.generate_parameters() +custom.generate_parameters(spectroscopy='PED') +custom.generate_parameters(spectroscopy='EIG') diff --git a/doc/source/contributors.rst b/doc/source/contributors.rst new file mode 100644 index 0000000..c919cb0 --- /dev/null +++ b/doc/source/contributors.rst @@ -0,0 +1,81 @@ +############ +Contributors +############ + + +MsSpec has benefited from the help of many people. Its core results from the long-term +collaboration of D. Sébilleau (Université de Rennes-1, France) with C. R. Natoli (LNFINFN, +Italy). More specifically, cluster gen.f and the various versions of spec.f have been +written by D. Sébilleau1 while phagen scf.f is due to C. R. Natoli. Other contributions have +been made possible through several joint CNRS/Chinese Academy of Sciences projects with Z.- +Y. Wu's group at the Beijing Synchrotron Radiation Facility and at the National Synchrotron +Radiation Laboratory in Hefei (China). MsSpec has also benefited from the post-doctoral grant +awarded to K. Hatada by the Région Bretagne, and from the four year LighTnet European +network. Currently, MsSpec is part of the FP7-funded European network MSNano and of the +COST-funded European action EUSpec. + +The other contributors are: + +* D. Agliz (Université Ibnou-Zohr, Agadir, Morocco): contribution to the + implementation of the Rehr-Albers method +* M. Gavaza (City University, Hong Kong): symmetrized form of the multiple + scattering series +* F. Da Pieve (Università di Roma 3): implementation of the Auger case into + phagen scf.f and contribution to the implementation of the APECS cross-section +* K. Hatada (LNF-INFN, Italy): help to write up the makefile that generates the + spec.f code and implementation of the parallel version. Implementation of the + non muffin-tin routines into phagen scf.f and into spec.f. +* H.F. Zhao (BSRF, Beijing, China and Université de Rennes-1, France): correlation + expansion. +* J.-Y. Wang (BSRF, Beijing, China): Graphical User Interface. +* E.-R. Li (BSRF, Beijing, China): Graphical User Interface. +* L. Frein (Université de Rennes-1, France): artwork for the Graphical User + Interface. +* A. Carré (Université de Rennes-1, France): + previous Website +* P. Le Meur (Université de Rennes-1, France): + Python interface +* S. Tricot (Université de Rennes-1, France): Python interface, website, + online tutorials and documentation +* P. Schieffer (Université de Rennes-1, France): XPD related + improvements + +The package has also benefited from many users and colleagues who pointed out bugs or +suggested improvements or new features. Among them, S. Ababou-Girard, B. Lépine, Y. Lu, +T. Jaouen and P. Schieffer (Université de Rennes-1, France), F. Scheurer (Université Louis +Pasteur, Strasbourg, France), P. Wetzel (Université de Haute-Alsace, Mulhouse, France), R. +Belkhou (SOLEIL, France), M. Zanouni (Université de Tanger, Maroc), A. Souissi (Université +de Bizerte, Tunisie), R. Gunnella (Università di Camerino, Italy) and J. Osterwalder (Université +de Zürich, Switzerland). +The empty sphere features have been tested with the help of K. Kuroda and S. Tadano +(Chiba university, Japan). + +Work on the next version (version 2.0) is currently under development by: + +* D. Sébilleau (Université de Rennes-1, France): + lead development +* C. R. Natoli (LNF-INFN, Italy): new features in phagen scf.f (scalar-relativistic, impact + parameter representation, EELS and (e,2e) radial integrals, ...) and interface with + VASP electronic structure code +* K. Hatada (Université de Rennes-1, France): BEEM spectroscopy, interface with VASP + electronic structure code +* H.-F. Zhao (BSRF, Beijing, China): REXS + spectroscopy +* J.-Q. Xu (NSRL, Hefei, China): EELS spectroscopy, interface with VASP electronic + structure code +* W.-S. Chu (NSRL, Hefei, China): portage to Windows operating system + (through Cygwin) +* R. Choubisa (BITS, Pilani, India): (e,2e) + spectroscopy +* P. Krüger (Chiba university, Japan): interface with VASP electronic + structure code +* A. Calvez (Université de Rennes-1, France): + optimization loop +* T. Balège and L. Strafella (Université de Rennes-1, France): + portage to Fortran 90 +* S. Tricot (Université de Rennes-1, France): Python interface, website, online + tutorials and documentation, graphical user interface +* P. Schieffer (Université de Rennes-1, France): XPD related + improvements +* G. Raffy ( Université de Rennes-1, France): Graphical user + interface diff --git a/doc/source/custom.py b/doc/source/custom.py new file mode 100644 index 0000000..1822edb --- /dev/null +++ b/doc/source/custom.py @@ -0,0 +1,118 @@ +# coding: utf8 +# vim: set et ts=4 sw=4 sts mouse=a fdm=indent: + +import os +import sys +import subprocess +import re +import numpy as np +from lxml import etree + + +def get_package_version(): + p = subprocess.run(["git describe|sed 's/-/.post/'|cut -d'-' -f1"], shell=True, stdout=subprocess.PIPE) + full_version = p.stdout.decode('utf-8').strip() + versions = full_version.split('.post') + version = versions[0] + dev_version = "" + if len(versions) > 1: + dev_version = versions[1] + return version, dev_version + +def generate_download_page(): + full_version = '.post'.join(get_package_version()).strip('.post') + setupfile_path = '../../package/MsSpec-{}.setup'.format(full_version) + docfile_path = '../../package/MsSpec-{}.pdf'.format(full_version) + + with open('downloads.rst', 'w') as fd: + content=""" +########################## +Download and install notes +########################## + +click :download:`here <{}>` to download the last version of MsSpec and +:download:`here <{}>` for this website as a single pdf file + + +.. include:: install_notes.inc +""".format(setupfile_path, docfile_path) + fd.write(content) + +def modify_banner(): + version, dev_version = get_package_version() + xml = etree.parse('./title.svg') + old_content = etree.tostring(xml) + svg = xml.getroot() + elements = svg.findall(".//{http://www.w3.org/2000/svg}tspan") + + for element in elements: + tid = element.get('id') + if tid.startswith('msspec_version'): + element.text = version + if tid.startswith('dev_version'): + if dev_version: + element.text = "post release: " + dev_version + else: + element.text = "" + + new_content = etree.tostring(xml).decode('utf-8') + if new_content != old_content: + with open('./title.svg', 'w') as fd: + fd.write(new_content) + +def generate_parameters(spectroscopy=None): + def get_content(all_parameters): + content = "" + for p in all_parameters: + content += ".. _{0}-{1}:\n\n".format(group.lower(), p.name) + content += "{0}\n{1}\n\n".format(p.name, "-"*len(p.name)) + content += ".. admonition:: details\n\n" + + table = ("\n.. csv-table::\n" + "\t:widths: 100, 100\n\n") + table += "\t\"*Types*\", \"{}\"\n".format(', '.join([_.__name__ for _ in p.allowed_types])) + table += "\t\"*Limits*\", \"{} <= value <= {}\"\n".format(str(p.low_limit), str(p.high_limit)) + table += "\t\"*Unit*\", \"{}\"\n".format(str(p.unit)) + if type(p.allowed_values) in (tuple, list, np.ndarray): + table += "\t\"*Allowed values*\", \"{}\"\n".format(', '.join([str(_) for _ in p.allowed_values])) + else: + table += "\t\"*Allowed values*\", \"{}\"\n".format(str(p.allowed_values)) + table += "\t\"*Default*\", \"{}\"\n".format(str(p.default)) + table += "\n\n\n\n" + + content += table.replace('\n', '\n\t') + content += "{}\n\n\n\n".format(p.docstring) + return content + + content = "" + from msspec.calculator import MSSPEC + c = MSSPEC(spectroscopy='PED' if spectroscopy==None else spectroscopy) + c.shutdown() + + allp = {} + for p in c.get_parameters(): + if p.group not in allp.keys(): + allp[p.group] = [] + if not(p.private): + allp[p.group].append(p) + + + common_groups = ("GlobalParameters", "MuffintinParameters", "TMatrixParameters", "SourceParameters", + "DetectorParameters", "ScanParameters", "CalculationParameters") + + if spectroscopy == None: + groups = common_groups + fn = 'spectroscopies/common_parameters.inc' + for group in groups: + title = "{}".format(group) + content += "{1}\n{0}\n\n".format("=" * len(title), title) + content += get_content(allp[group]) + else: + group = spectroscopy + 'Parameters' + fn = 'spectroscopies/{0}/{0}_parameters.inc'.format(spectroscopy.lower()) + title = "{}".format(group) + content += "{1}\n{0}\n\n".format("=" * len(title), title) + content += get_content(allp[group]) + + with open(fn, 'w') as fd: + fd.write(content) diff --git a/doc/source/download_btn.svg b/doc/source/download_btn.svg new file mode 100644 index 0000000..ed13f48 --- /dev/null +++ b/doc/source/download_btn.svg @@ -0,0 +1,217 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + DOWNLOAD + + + + + + + diff --git a/doc/source/faq/hemispherical_cluster/CsCl_cluster.png b/doc/source/faq/hemispherical_cluster/CsCl_cluster.png new file mode 100644 index 0000000..bbd341d Binary files /dev/null and b/doc/source/faq/hemispherical_cluster/CsCl_cluster.png differ diff --git a/doc/source/faq/hemispherical_cluster/Fe_clusters.png b/doc/source/faq/hemispherical_cluster/Fe_clusters.png new file mode 100644 index 0000000..2d9f8fa Binary files /dev/null and b/doc/source/faq/hemispherical_cluster/Fe_clusters.png differ diff --git a/doc/source/faq/hemispherical_cluster/hemispherical_cluster.rst b/doc/source/faq/hemispherical_cluster/hemispherical_cluster.rst new file mode 100644 index 0000000..5440d10 --- /dev/null +++ b/doc/source/faq/hemispherical_cluster/hemispherical_cluster.rst @@ -0,0 +1,74 @@ +.. _hemispherical_cluster_faq: + + +The hemispherical_cluster function +---------------------------------- + +A the :py:func:`hemispherical_cluster` takes one mandatory argument and 4 keyword arguments. +The first required argument is an ASE Atoms object. This object will be the base pattern used to create a cluster. +It is usually a primitive cell of a structure. The 4 keywords arguments describe the dimensions of the cluster and +the location of the emitter atom: + +- emitter_tag: is an integer which is the tag of the emitter atom +- emitter_plane: is an integer to tell in which plane to put the emitter +- diameter: is the diameter of the hemispherically shaped cluster (in angströms) +- planes: is the total number of planes + +Three simple example are shown in the figure 1 below. These are cut view in the (xOz) plane of the clusters. the +clusters were created with those commands: + +.. code-block:: python + + from msspec.utils import hemispherical_cluster + from ase.build import bulk + + iron = bulk('Fe', cubic=True) # The base cell to be repeated to shape a cluster + # The cluster 1a, with an emitter on the surface + cluster1a = hemispherical_cluster(iron, diameter=25, emitter_plane=0) + # The cluster 1c, with an emitter in the second plane + cluster1b = hemispherical_cluster(iron, diameter=25, emitter_plane=1) + # The cluster 1c, with an emitter in the third plane and with just one plane below + # the emitter + cluster1c = hemispherical_cluster(iron, diameter=25, emitter_plane=2, planes=4) + + +.. figure:: Fe_clusters.png + :align: center + :width: 80% + + Figure 1. + +The *emitter_tag* keyword is used to specify the emitter in a multielemental structure or if two atoms of the same +kind exist in the primitive cell with different chemical or geometrical environment. For example, the CsCl structure +is also *bcc* like the iron above, but the chlorine atom is at the center of a cube with 4 Caesium atoms on the apex. +To get a Cl emitter in the desired plane, we should first tag it in the cell: + +.. code-block:: python + + from msspec.utils import hemispherical_cluster + from ase.spacegroup import crystal + + # Definition of this cubic cell + a0 = 2.05 + a = b = c = a0 + alpha = beta = gamma = 90 + cellpar = [a, b, c, alpha, beta, gamma] + # Create the CsCl structure with the crystal function + CsCl = crystal(['Cs', 'Cl'], basis=[(0,0,0),(0.5,0.5,0.5)], spacegroup=221, cellpar=cellpar) + # by default, all atoms tags are 0 + # set the Cl tag to 1 + CsCl[1].tag = 1 + # Create a cluster with the Cl emitter + cluster = hemispherical_cluster(CsCl, emitter_tag=1, emitter_plane=3, diameter=25) + +The resulting cluster is shown in the figure 2 below + +.. figure:: CsCl_cluster.png + :align: center + :width: 80% + + Figure 2. A cut view in the (xOz) plane of a CsCl cluster with a Cl emitter atom in the third plane + + + + diff --git a/doc/source/faq/index.rst b/doc/source/faq/index.rst new file mode 100644 index 0000000..f46ebfb --- /dev/null +++ b/doc/source/faq/index.rst @@ -0,0 +1,9 @@ +.. _faq: + +### +FAQ +### + +.. toctree:: + + hemispherical_cluster/hemispherical_cluster diff --git a/doc/source/full_picture.svg b/doc/source/full_picture.svg new file mode 100644 index 0000000..86954c0 --- /dev/null +++ b/doc/source/full_picture.svg @@ -0,0 +1,2644 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + K + L1 + L2,3 + M + + + 1s + 2s + 2p + 3s + 3p + 3d + + + core hole + + Photoelectron + vacuum level + valence band + work function ΦWF  + + + + + Ek + photon ħω + + + + + + + + + + + + + + + + + + + + + + K + L1 + L2,3 + M + + + 1s + 2s + 2p + 3s + 3p + 3d + + + initialcore hole + + Photoelectron + vacuum level + valence band + work function ΦWF  + + + + + photon ħω + + + + Auger electron + 1st + 2nd + 3rd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + X-Ray source + sample + + + + + + + + + Analyzer + θ + φ + Photoelectrons + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Direct signal + singly scatterd wave + doubly scatterd wave + + + + e- + + + + e- + + + + e- + + sample atoms + (a) + (b) + (c) + Standard Photoelectron Diffraction (PED mode)  + Auger Photoelectron Diffraction(AED mode)  + photon ħω + photon ħω + + + diff --git a/doc/source/google2c86b0817b98582b.html b/doc/source/google2c86b0817b98582b.html new file mode 100644 index 0000000..db2cfee --- /dev/null +++ b/doc/source/google2c86b0817b98582b.html @@ -0,0 +1 @@ +google-site-verification: google2c86b0817b98582b.html \ No newline at end of file diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 0000000..a513ef5 --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,159 @@ +.. MsSpec-ASE documentation master file, created by + sphinx-quickstart on Mon Jan 18 10:59:09 2016. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + + +.. image:: download_btn.png + :scale: 0% + +.. image:: title.png + :scale: 0% + + + +.. raw:: html + + + + + + + + + + + + + + +################# +Table of Contents +################# + +.. toctree:: + :maxdepth: 1 + + intro + downloads + spectroscopies/spectro + parameters + tutorials/index + contributors + faq/index + todo + + + + +.. only:: html + + ################## + Indices and tables + ################## + + * :ref:`genindex` + * :ref:`modindex` + * :ref:`search` + + +.. only:: latex + + ################################# + Application Programming Interface + ################################# + + .. toctree:: + :glob: + + modules/* \ No newline at end of file diff --git a/doc/source/install_notes.inc b/doc/source/install_notes.inc new file mode 100644 index 0000000..44ce1fe --- /dev/null +++ b/doc/source/install_notes.inc @@ -0,0 +1,124 @@ +************ +Installation +************ + +.. |logowin| image:: windows_icon.png + :height: 96px + :target: `win10_install_notes`_ + +.. |logolinux| image:: linux_icon.png + :height: 96px + :target: `linux_install_notes`_ + +.. |logomac| image:: apple_icon.png + :height: 96px + :target: `mac_install_notes`_ + + + +.. admonition:: Select your Operating System to view specific installation instructions + + |logowin| |logolinux| |logomac| + + +.. _common_install_notes: + +In a terminal window, execute the setup program you've just downloaded. + +.. code-block:: console + + $ sh ./MsSpec-version.setup + +Once the install process has competed, you can launch the MsSpec environnement by typing:: + + msspec + + + + +.. _win10_install_notes: + +For Windows 10 +============== + +Windows users can install MsSpec through the Windows Subsystem for Linux +(also known as bash Ubuntu). + +Below is a short description of the steps to enable this feature. You can +have more details `here `_. + +Install the Windows Subsystem for Linux +--------------------------------------- + +1. Turn on Developer Mode + Open **Settings -> Update and Security -> For developers** + +.. figure:: win_step1.png + :align: center + :width: 70% + + Select the Developer Mode radio button + +2. Open a command prompt. Run:: + + bash + +.. figure:: win_step2.png + :align: center + :width: 70% + + Type "y" to accept the license. An Ubuntu system will be installed. + + +3. Launch a new Ubuntu shell by running *bash* from the command prompt. + If this is the first time that the Windows Subsystem for Linux is installed, + you will be prompted to create a UNIX user. Simply follow the instructions. + This UNIX username and password may be different from your Windows username + and password. + +Install an X server +------------------- + +To allow graphical windows to popup in this Linux environnement, you need to install +an X server. **Xming** is a good choice. Go to `this website `_ +and download and install the public version 6.9.0.31. + +Don't forget to start the server after the install. You can configure it to always run automatically at +the startup. + +Install MsSpec +-------------- + +Open a Windows command prompt and launch *bash*. For the Xming server to work, you need to modify +the DISPLAY environnement variable. Enter this command:: + + echo "export DISPLAY=:0" >> ~/.bashrc && source ~/.bashrc + +Then you can launch the setup program:: + + cd /where/the/setup/program/was/downloaded + sh ./MsSpec-version.setup + +where *version* is the actual version number + + + +.. _linux_install_notes: + +For Linux +========= + +Ubuntu and Mageia based dstributions are supported by the installer, but any Linux +flavour should be able to run MsSpec as long as you have permissions to install +all requirements. + +You just need to open a terminal window and execute the setup program. + + +.. _mac_install_notes: + +For Mac 0S +========== + +.. note:: + to be written... diff --git a/doc/source/intro.rst b/doc/source/intro.rst new file mode 100644 index 0000000..7fb8c17 --- /dev/null +++ b/doc/source/intro.rst @@ -0,0 +1,99 @@ +############ +Introduction +############ + +Spectroscopies are among the most widely used techniques to study the physical +and chemical properties of materials. They are now extensively present in many +fields of science such as physics, chemistry or biology. The term +“spectroscopy” which was still characterizing the study of light by means of a +prism in the 19th century, has now, since the advent of quantum theory, a much +wider meaning. Indeed, according to the 15th edition of The New Encyclopaedia +Britannica, “spectroscopy is the study of the absorption and emission of light +and other radiation, as related to the wavelength of the radiation”. If we add +scattering to the two previous physical processes, the quantum nature of +particles makes this definition cover most types of experiment that can be +performed nowadays. Such a typical experiment is sketched below. It should +be noted that the incoming and outgoing particles are not necessarily the same. +When they are of an identical nature, the corresponding technique can be +performed either in the reflection or in the transmission mode. + +.. figure:: intro_fig1.png + :align: center + :width: 50% + + Typical spectroscopic experiment + +The idea behind these spectroscopies is that information about the sample can +be obtained from the analysis of the outgoing particles. Depending on the type +of spectroscopy, this information can be related to the crystallographic +structure, to the electronic structure or to the magnetic structure of the +sample. Or it can be about a reaction that takes place within the sample. With +this in mind, the type and energy of the detected particles will directly +determine the region of the sample from which this information can be traced +back, and therefore the sensitivity of the technique to the bulk or the +surface. For instance, low-energy electrons or ions will not travel much more +than ten interatomic distances in a solid while electromagnetic radiations will +be able to emerge from much deeper layers. In diffraction techniques using +significantly penetrating particles, surface sensitivity can nevertheless be +achieved with grazing incidence angles. Note also that the counterpart to +detecting particles with a small mean free path is the necessity to work under +ultra high vacuum conditions so that the outgoing particles can effectively +reach the detector. The figure below gives the variation of the electron mean free path +:math:`\lambda_e` in solids as a function of the electron kinetic energy. We see +clearly here that in the range 10–1000 eV, electrons coming from within a +sample do not originate from much deeper than 5 to 20 Angströms. +As a consequence, spectroscopies detecting +electrons in this energy range will be essentially sensitive to the surface structure +as the particle detected will carry information from the very topmost +layers. + +.. figure:: intro_fig2.png + :align: center + :width: 80% + + The electron mean free path as a function of the energy + +Although, as we have just seen, many techniques can provide information +on a sample and its surface (if any), we will mainly restrict ourselves here +to some of them specifically related to synchrotron radiation: x-ray spectroscopies. +X-ray spectroscopies are characterized by the fact that the incoming +beam is composed of photons in the range of about 100 eV to 10 keV. Higher +energies, in the :math:`\gamma`-ray region, will not be considered here as in this latter range +photons will be scattered significantly not only by the electrons but also by +the nuclei [2] giving rise to entirely different spectroscopies such as Mössbauer +spectroscopy. The next, taken from [3], gives a sketch of the electromagnetic +spectrum with some common photon sources and the spectroscopies corresponding +to the various energy ranges. + +.. figure:: intro_fig3.png + :align: center + :width: 70% + + The electromagnetic spectrum, along with the common photon sources and + some spectroscopies based on photons. + + +.. seealso:: + + *This introduction is taken from:* + + X-ray and Electron Spectroscopies: An Introduction + Didier Sébilleau, Lect. Notes Phys. **697**, p15–57 (2006) + `[doi] `__ + + *For a more complete theoretical background about multiple scattering, see (and references herein):* + + Multiple-scattering approach with complex potential in the interpretation of electron and photon spectroscopies + D. Sebilleau, R. Gunnella, Z-Y Wu, S Di Matteo and C. R. Natoli, + J. Phys.: Condens. Matter **18**, R175-228 (2006) + `[doi] `__ + + *For a description of the MsSpec code package, see:* + + MsSpec-1.0: A multiple scattering package for electron spectroscopies in material science + D. Sébilleau, C. R. Natoli, G. M.Gavaza, H. Zhao, F. Da Pieve and K. Hatada, + Comput. Phys. Commun., **182** (12), p2567-2579 (2011) + `[doi] `__ + + + diff --git a/doc/source/intro_fig1.png b/doc/source/intro_fig1.png new file mode 100644 index 0000000..978a2ea Binary files /dev/null and b/doc/source/intro_fig1.png differ diff --git a/doc/source/intro_fig2.png b/doc/source/intro_fig2.png new file mode 100644 index 0000000..157f9da Binary files /dev/null and b/doc/source/intro_fig2.png differ diff --git a/doc/source/intro_fig3.png b/doc/source/intro_fig3.png new file mode 100644 index 0000000..a454721 Binary files /dev/null and b/doc/source/intro_fig3.png differ diff --git a/doc/source/linux_icon.png b/doc/source/linux_icon.png new file mode 100644 index 0000000..19d2bb2 Binary files /dev/null and b/doc/source/linux_icon.png differ diff --git a/doc/source/modules/calcio.rst b/doc/source/modules/calcio.rst new file mode 100644 index 0000000..0663b46 --- /dev/null +++ b/doc/source/modules/calcio.rst @@ -0,0 +1,6 @@ +.. .. :orphan: + +.. automodule:: calcio + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/modules/calculator.rst b/doc/source/modules/calculator.rst new file mode 100644 index 0000000..a05c6e9 --- /dev/null +++ b/doc/source/modules/calculator.rst @@ -0,0 +1,5 @@ +:orphan: + +.. automodule:: calculator + :members: MSSPEC, _MSCALCULATOR, _PED, _EIG + :show-inheritance: diff --git a/doc/source/modules/config.rst b/doc/source/modules/config.rst new file mode 100644 index 0000000..7ae9e81 --- /dev/null +++ b/doc/source/modules/config.rst @@ -0,0 +1,6 @@ +:orphan: + +.. automodule:: config + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/doc/source/modules/electron_be.rst b/doc/source/modules/electron_be.rst new file mode 100644 index 0000000..bdae779 --- /dev/null +++ b/doc/source/modules/electron_be.rst @@ -0,0 +1,6 @@ +:orphan: + +.. automodule:: data.electron_be + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/doc/source/modules/iodata.rst b/doc/source/modules/iodata.rst new file mode 100644 index 0000000..ea0da00 --- /dev/null +++ b/doc/source/modules/iodata.rst @@ -0,0 +1,6 @@ +:orphan: + +.. automodule:: iodata + :members: Data, DataSet, _DataSetView + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/doc/source/modules/misc.rst b/doc/source/modules/misc.rst new file mode 100644 index 0000000..cda4527 --- /dev/null +++ b/doc/source/modules/misc.rst @@ -0,0 +1,6 @@ +:orphan: + +.. automodule:: misc + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/doc/source/modules/parameters.rst b/doc/source/modules/parameters.rst new file mode 100644 index 0000000..9efcb17 --- /dev/null +++ b/doc/source/modules/parameters.rst @@ -0,0 +1,6 @@ +:orphan: + +.. automodule:: parameters + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/source/modules/utils.rst b/doc/source/modules/utils.rst new file mode 100644 index 0000000..170f02a --- /dev/null +++ b/doc/source/modules/utils.rst @@ -0,0 +1,5 @@ +:orphan: + +.. automodule:: utils + :members: + :show-inheritance: diff --git a/doc/source/parameters.rst b/doc/source/parameters.rst new file mode 100644 index 0000000..b088971 --- /dev/null +++ b/doc/source/parameters.rst @@ -0,0 +1,23 @@ +.. _allparameters: + +############################# +All the simulation parameters +############################# + + +.. contents:: Contents + :depth: 2 + :local: + +Common parameters +***************** + +.. include:: spectroscopies/common_parameters.inc + +Spectroscopy parameters +*********************** + + +.. include:: spectroscopies/ped/ped_parameters.inc + +.. include:: spectroscopies/eig/eig_parameters.inc \ No newline at end of file diff --git a/doc/source/sitemap-generate.py b/doc/source/sitemap-generate.py new file mode 100644 index 0000000..a3509f3 --- /dev/null +++ b/doc/source/sitemap-generate.py @@ -0,0 +1,73 @@ +# coding: utf8 + +import os, fnmatch +from datetime import datetime +from pytz import timezone +import re +from lxml import etree +import argparse + + +opt_defaults = {'include': ".*\.html|.*\.pdf", + 'exclude': "google.*\.html", + 'timezone': 'Europe/Paris'} + + +parser = argparse.ArgumentParser(description="Create an XML sitemap file from a source html folder.") +parser.add_argument("--url", help="The website address.") +parser.add_argument("--path", help="The root folder to explore.") +parser.add_argument("--include", help="The include regexp pattern.", default=opt_defaults['include']) +parser.add_argument("--exclude", help="The exclude regexp pattern.", default=opt_defaults['exclude']) +parser.add_argument("--timezone", help="The time zone.", default=opt_defaults['timezone']) +parser.add_argument("--priority", help="The page priority.", type=float, default=.8) +parser.add_argument("--changefreq", help="How often the page is likely to change.", default="monthly", + choices=["always", "hourly", "daily", "weekly", "monthly", "yearly", "never"]) +parser.add_argument("output", help="The output file name.") + +opts = parser.parse_args() + +defaults = {'loc': '', 'lastmod': '', 'priority': "{:.1f}".format(opts.priority), 'changefreq': opts.changefreq} +results = [] + +for root, dirs, files in os.walk(opts.path): + for fn in files: + if re.match(opts.include, fn) and not re.match(opts.exclude, fn): + fullfn = os.path.join(root, fn) + loc = os.path.join(opts.url, fn) + dt = datetime.fromtimestamp(os.stat(fullfn).st_ctime, tz=timezone(opts.timezone)) + tzd = dt.strftime("%z") + tzd = tzd[:-2] + ":" + tzd[-2:] + lastmod = dt.strftime("%Y-%m-%dT%H:%M") + tzd + + data = defaults.copy() + data.update(loc=loc, lastmod=lastmod) + + results.append(data) + + +# convert to xml +class NameSpace: + xsi = "http://www.w3.org/2001/XMLSchema-instance" + + +root = etree.Element("urlset", xmlns="http://www.sitemaps.org/schemas/sitemap/0.9", nsmap={'xsi': NameSpace.xsi}) +root.attrib[etree.QName(NameSpace.xsi, 'schemaLocation')]= ("http://www.sitemaps.org/schemas/sitemap/0.9 " + "http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd") + + +comment = etree.Comment("Auto-generated on {}".format(datetime.now().ctime())) +root.insert(1, comment) + +for data in results: + url_el = etree.SubElement(root, "url") + loc_el = etree.SubElement(url_el, "loc") + lastmod_el = etree.SubElement(url_el, "lastmod") + changefreq_el = etree.SubElement(url_el, "changefreq") + priority_el = etree.SubElement(url_el, "priority") + loc_el.text = data['loc'] + lastmod_el.text = data['lastmod'] + priority_el.text = data['priority'] + changefreq_el.text = data['changefreq'] + +with open(opts.output, 'w') as fd: + fd.write(etree.tostring(root, encoding='UTF-8', xml_declaration=True, pretty_print=True).decode('utf8')) diff --git a/doc/source/sitemap.xml b/doc/source/sitemap.xml new file mode 100644 index 0000000..958a29d --- /dev/null +++ b/doc/source/sitemap.xml @@ -0,0 +1,222 @@ + + + + + + + https://msspec.cnrs.fr/ + 2018-12-29T10:40:37+00:00 + 1.00 + + + https://msspec.cnrs.fr/genindex.html + 2018-12-29T10:40:38+00:00 + 0.80 + + + https://msspec.cnrs.fr/py-modindex.html + 2018-12-29T10:40:38+00:00 + 0.80 + + + https://msspec.cnrs.fr/intro.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/downloads.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/spectroscopies/spectro.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/parameters.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/tutorials/index.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/contributors.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/faq/index.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/todo.html + 2018-12-29T10:40:37+00:00 + 0.80 + + + https://msspec.cnrs.fr/search.html + 2018-12-29T10:40:38+00:00 + 0.80 + + + https://msspec.cnrs.fr/index.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/iodata.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/calculator.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/parameters.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/misc.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/calcio.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/utils.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/config.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/modules/electron_be.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/_downloads/MsSpec-1.2rc3.post154.pdf + 2018-12-29T10:38:59+00:00 + 0.64 + + + https://msspec.cnrs.fr/spectroscopies/ped/ped.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/spectroscopies/aed/aed.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/spectroscopies/apecs/apecs.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/spectroscopies/exafs/exafs.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/spectroscopies/leed/leed.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/spectroscopies/eig/eig.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/tutorials/copper/tuto_ped_copper.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/tutorials/nickel_chain/tuto_ped_nickel_chain.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/tutorials/RhO/tuto_ped_RhO.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/tutorials/temperature/tuto_ped_temperature.html + 2018-12-29T10:40:38+00:00 + 0.64 + + + https://msspec.cnrs.fr/tutorials/AlN/tuto_cluster.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/faq/hemispherical_cluster/hemispherical_cluster.html + 2018-12-29T10:40:37+00:00 + 0.64 + + + https://msspec.cnrs.fr/_modules/iodata.html + 2018-12-29T10:40:38+00:00 + 0.51 + + + https://msspec.cnrs.fr/_modules/calculator.html + 2018-12-29T10:40:38+00:00 + 0.51 + + + https://msspec.cnrs.fr/_modules/parameters.html + 2018-12-29T10:40:38+00:00 + 0.51 + + + https://msspec.cnrs.fr/_modules/misc.html + 2018-12-29T10:40:38+00:00 + 0.51 + + + https://msspec.cnrs.fr/_modules/calcio.html + 2018-12-29T10:40:38+00:00 + 0.51 + + + https://msspec.cnrs.fr/_modules/utils.html + 2018-12-29T10:40:38+00:00 + 0.51 + + + https://msspec.cnrs.fr/_modules/config.html + 2018-12-29T10:40:38+00:00 + 0.51 + + + https://msspec.cnrs.fr/_modules/index.html + 2018-12-29T10:40:38+00:00 + 0.41 + + + + \ No newline at end of file diff --git a/doc/source/spectroscopies/aed/aed.rst b/doc/source/spectroscopies/aed/aed.rst new file mode 100644 index 0000000..3a4b151 --- /dev/null +++ b/doc/source/spectroscopies/aed/aed.rst @@ -0,0 +1,5 @@ +******************************** +Auger Electron Diffraction (AED) +******************************** + +.. include:: ../not_available.rst \ No newline at end of file diff --git a/doc/source/spectroscopies/apecs/apecs.rst b/doc/source/spectroscopies/apecs/apecs.rst new file mode 100644 index 0000000..9d187a0 --- /dev/null +++ b/doc/source/spectroscopies/apecs/apecs.rst @@ -0,0 +1,5 @@ +****************************************************** +Auger Photo-Electron Conincidence Spectroscopy (APECS) +****************************************************** + +.. include:: ../not_available.rst diff --git a/doc/source/spectroscopies/eig/eig.rst b/doc/source/spectroscopies/eig/eig.rst new file mode 100644 index 0000000..17db12a --- /dev/null +++ b/doc/source/spectroscopies/eig/eig.rst @@ -0,0 +1,5 @@ +****************************** +Eigen values calculation (EIG) +****************************** + +.. include:: ../not_available.rst diff --git a/doc/source/spectroscopies/exafs/exafs.rst b/doc/source/spectroscopies/exafs/exafs.rst new file mode 100644 index 0000000..69b9d7e --- /dev/null +++ b/doc/source/spectroscopies/exafs/exafs.rst @@ -0,0 +1,5 @@ +************************************************ +Extended X-Ray Absorption Fine Structure (EXAFS) +************************************************ + +.. include:: ../not_available.rst diff --git a/doc/source/spectroscopies/leed/leed.rst b/doc/source/spectroscopies/leed/leed.rst new file mode 100644 index 0000000..5e22516 --- /dev/null +++ b/doc/source/spectroscopies/leed/leed.rst @@ -0,0 +1,5 @@ +************************************** +Low-Energy Electron Diffraction (LEED) +************************************** + +.. include:: ../not_available.rst diff --git a/doc/source/spectroscopies/not_available.rst b/doc/source/spectroscopies/not_available.rst new file mode 100644 index 0000000..c69ab13 --- /dev/null +++ b/doc/source/spectroscopies/not_available.rst @@ -0,0 +1,6 @@ +.. warning:: + + For the moment, this spectroscopy mode is not available with the Python interface. + + You have to run the classical version of MsSpec to perform such a calculation. + Please see ??? for the details on how to run MsSpec like this. \ No newline at end of file diff --git a/doc/source/spectroscopies/ped/MgO.gif b/doc/source/spectroscopies/ped/MgO.gif new file mode 100644 index 0000000..80500d7 Binary files /dev/null and b/doc/source/spectroscopies/ped/MgO.gif differ diff --git a/doc/source/spectroscopies/ped/MgO.py b/doc/source/spectroscopies/ped/MgO.py new file mode 100644 index 0000000..9d13e65 --- /dev/null +++ b/doc/source/spectroscopies/ped/MgO.py @@ -0,0 +1,24 @@ +# coding: utf8 + +from ase.build import bulk +from msspec.utils import * + +a = 4.21 # The lattice parameter +epsilon = 0.01 # a small usefull value +MgO = bulk('MgO', a=a, crystalstructure='rocksalt', cubic=True) # ASE magic here + +# shaping the cluster in half sphere +MgO = MgO.repeat((10, 10, 10)) +center_cluster(MgO) +MgO = cut_plane(MgO, z=epsilon) +MgO = cut_sphere(MgO, radius=3.*a + epsilon) + +print len(MgO) +raise + +from ase.io import write +MgO.rotate(-65, 'x') +for a in range(0, 360, 5): + write('img_{:03d}.pov'.format(a), MgO, camera_type='perspective', display=False, rotation='{:d}y'.format(a), + transparent=True) + diff --git a/doc/source/spectroscopies/ped/ped.rst b/doc/source/spectroscopies/ped/ped.rst new file mode 100644 index 0000000..fb92be7 --- /dev/null +++ b/doc/source/spectroscopies/ped/ped.rst @@ -0,0 +1,197 @@ +******************************** +Photo-Electron Diffraction (PED) +******************************** + +Introduction +============ +In PhotoElectron Diffraction, an incoming photon, with an energy in the X-ray range is absorbed by +an atom of the sample. A core electron of the absorbing atom is emitted and will eventually escape +from the sample after many scattering events toward a detector. This photo-electron is detected at +a given kinetic energy and for a given position (polar angle and azimutal angle) of the detector with +respect to the sample (see figure below). The distribution of electrons as a function of the sample +polar or azimutal angles contains chemically resolved informations about the crystallography in the +immediate proximity of the surface sample. This spectroscopy can also be done on Auger electrons. In +this case, the technique is named Auger Electron Diffraction. + +.. _ped_full_picture: + +.. figure:: ../../full_picture.png + :align: center + :width: 80% + + The Full picture of a photoelectron diffraction process. a) The geometry of + the experiment. b) A view of the multiple scattering process and c) Atomic + energy level sketch of the normal and Auger photoemission process. + + +Quick reference +=============== + +To quickly start with MsSpec and Python, the easiest way is to read the :ref:`tutorials` section. +Here we summurize all the steps to perform a PED simulation: + + 1. :ref:`Build your cluster ` (thanks to the ASE python package) + 2. :ref:`Create a calculator ` with :py:func:`MSSPEC` + 3. :ref:`Set the parameters ` of your calculation. + 4. :ref:`Attach ` your cluster to the calculator + 5. :ref:`Choose the absorber ` + 6. :ref:`Compute ` a scan + 7. :ref:`Plot ` the results + + +.. _step1: + +Build your cluster +------------------ + +Building a cluster means creating a list of atoms with their given positions in x, y, z coordinates. +It is easily done thanks to the `ase Python package `_. + +Because most of spectroscopies have a source and a detector in the same hemispherical space, a cluster +is often shaped as an half sphere. To create such atomic arrangements, special helper functions are provided +in the :py:mod:`utils` module. + +For example to create an MgO cluster: + + .. literalinclude:: MgO.py + :linenos: + :lines: 1-15 + +.. only:: html + + will produce a cluster of 519 atoms like this: + + .. figure:: MgO.gif + :align: center + :width: 60% + + The shape of a typical (yet quite large) cluster used for a calculation (519 atoms of MgO). + + +.. only:: latex + + will produce a cluster of 519 atoms like this: + + .. figure:: MgO.png + :align: center + :width: 60% + + The shape of a typical (yet quite large) cluster used for a calculation (519 atoms of MgO). + + +.. _step2: + +Create a calculator +------------------- + +To create a claculator, you will use the :py:func:`calculator.MSSPEC` function. This function takes 4 +keyword arguments: + + - **spectroscopy**, to specify the kind of spectroscopy. This is a string and + can be one of 'PED' for PhotoElectron Diffraction, 'AED' for Auger Electron + Diffraction, 'APECS' for Auger PhotoElectron Coincidence Spectroscopy or + 'EXAFS' for Extended X-Ray Absorption Fine Structure. + - **algorithm**, to choose between the matrix inversion method with the string + 'inversion' (best suited for lower kinetic energies < 100 eV), or the series + expansion technique with 'expansion' or the correlation-expansion with + 'correlation'. + - **polarization** to specify the light polarization. 'linear_qOz' or 'linear_xOy' + for a linearly polarized light with the polarization vector in the :math:`(\vec{q}Oz)` + or in the :math:`(xOy)` plane respectively. Finally choose 'circular' for circularly + polarized light. + - **folder**. Enter here the name of the folder used for temporary files. + +The function returns a calculator object, so for example. To create a calculator for PhotoElectron +Diffraction with the matrix inversion method: + +.. code-block:: python + + calc = MSSPEC(spectroscopy = 'PED', algorithm = 'inversion') + + +.. _step3: + +Set the parameters +------------------ + +A calculator has many parameters. They fall into 4 categories: + + * Muffin-tin parameters, to tweak the potential used for the phase shifts calculation + * T-Matrix parameters, to control the T-matrix calculation + * Calculation parameters, to tune the multiple scattering calculation: add atomic vibrations, + add some filters to speed up the process, control the parameters of the series expansion method... + * Spectroscopy dependent parameters. These parameters control -- for example -- the light source, + the detector... + +Each set of parameters is accessible through properties of the calculator object. For example, to tweak +the interstitial value of the Muffin Tin potential, use: + + >>> calc.muffintin_parameters.interstitial_potential = 12.1 + +To change the source energy, use: + + >>> calc.source_parameters.energy = 1253.0 + +All options are detailed in :ref:`this section ` + + +.. _step4: + +Attach your cluster +------------------- + +Very easy! Juste use the :py:func:`set_atoms` function like this: + +.. code-block:: python + + calc.set_atoms(cluster) + +.. _step5: + +Choose the absorber +------------------- + +Set the absorber attribute of your cluster to the index of the atom you want it to be the absorber. +For example if the first atom of your cluster is the absorber + +.. code-block:: python + + cluster.absorber = 0 + +The best way is to use a function to find the index based on the xyz coordinates of the atom. For +example to choose the closest atom of the origin: + +.. code-block:: python + + cluster.absorber = get_atom_index(cluster, 0, 0, 0) + +:py:func:`get_atom_index` is in the :py:mod:`utils` package so do not forget to import it. The +first argument is the cluster you will look for and the 3 next parameters are the x, y and z +coordinates. + +.. _step6: + +Compute +------- + +You can compute 5 kinds of scans in PED spectroscopy: + + * A polar scan, with the :py:func:`get_theta_scan` method of the calculator object + * An azimutal scan, with the :py:func:`MSSPEC.get_phi_scan` method + * A stereographic scan, with the :py:func:`MSSPEC.get_theta_phi_scan` method + * An energy scan, with the :py:func:`MSSPEC.get_energy_scan` method + * The scattering factor, with the :py:func:`MSSPEC.get_scattering_factors` method + +All these functions are used and detailed in the :ref:`tutorials `. + +.. _step7: + +Plot the results +---------------- + +Normally, the output of the previous functions is a :py:class:`iodata.Data` object. You can see +the results by typing: + +>>> data = calc.get_theta_scan(...) # a polar scan for example +>>> data.view() # will popup a graphical window + diff --git a/doc/source/spectroscopies/spectro.rst b/doc/source/spectroscopies/spectro.rst new file mode 100644 index 0000000..02ddd5f --- /dev/null +++ b/doc/source/spectroscopies/spectro.rst @@ -0,0 +1,19 @@ +############## +Spectroscopies +############## + + + +.. toctree:: + :maxdepth: 1 + + ped/ped + aed/aed + apecs/apecs + exafs/exafs + leed/leed + eig/eig + + + + diff --git a/doc/source/title.svg b/doc/source/title.svg new file mode 100644 index 0000000..027ecd7 --- /dev/null +++ b/doc/source/title.svg @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1.6 + 1.6 + + + MsSpec + MsSpec + + A multiple scattering package for spectroscopiesusing electrons to probe materials + post release: 11 + + + + + \ No newline at end of file diff --git a/doc/source/todo.rst b/doc/source/todo.rst new file mode 100644 index 0000000..899ea9b --- /dev/null +++ b/doc/source/todo.rst @@ -0,0 +1,5 @@ +#### +TODO +#### + +.. todolist:: \ No newline at end of file diff --git a/doc/source/tutorials/AlN/AlN.py b/doc/source/tutorials/AlN/AlN.py new file mode 100644 index 0000000..bcc5fe5 --- /dev/null +++ b/doc/source/tutorials/AlN/AlN.py @@ -0,0 +1,181 @@ +# coding: utf-8 + +from msspec.utils import * +from ase.build import bulk +from ase.visualize import view +import numpy as np +from msspec.calculator import MSSPEC, XRaySource +from msspec.iodata import Data +from itertools import product + +DATA = None + +def AlN_cluster(emitter_tag, emitter_plane, diameter=0, planes=0, term_anion=True, tetra_down=True): + """ + This function is a kind of overload of the hemispherical_cluster function with specific attributes + to the AlN structure + + :param emitter_tag: An integer that allows to identify the kind of atom to use as the emitter + :param emitter_plane: The plane where the emitter is. 0 means the surface. + :param diameter: The diameter of the cluster (in Angstroms). + :param planes: The total number of planes. + :param term_anion: True if the surface plane is anion terminated, False otherwise + :param tetra_down: The orientation of the tetrahedral + :return: + """ + + # create the initial cluster of AlN + cluster = bulk('AlN', crystalstructure='wurtzite', a=3.11, c=4.975) + + # tag each atom in the unit cell because they are all in a different chemical/geometrical environment + # (0 and 2 for Aluminum's atoms and 1 and 3 for Nitride's atoms) + [atom.set('tag', i) for i, atom in enumerate(cluster)] + + # change the orientation of the tetrahedron + if not tetra_down: + cluster.rotate(180, 'y') + + # From this base pattern, creat an hemispherically shaped cluster + cluster = hemispherical_cluster(cluster, emitter_tag=emitter_tag, emitter_plane=emitter_plane, diameter=diameter, + planes=planes) + + # Depending on the number of planes above the emitter, the termination may not be the one you wish, + # we test this and raise an exception in such a case + + # Get the termination by finding the kind of one atom located at the topmost z coordinate + termination = cluster[np.argsort(cluster.get_positions()[:, 2])[-1]].symbol + + # test if the combination of parameters is possible + assert (termination == 'N' and term_anion) or (termination == 'Al' and not term_anion), ( + "This termination isn't compatible with your others parameters, you must change the tag of " + "your emitter, the plane of your emitter or your termination") + + return cluster + +def create_clusters(side='Al', emitter='Al', diameter=15, planes=6): + clusters = [] + if side == 'Al': + term_anion = tetra_down = False + elif side == 'N': + term_anion = tetra_down = True + + if emitter == 'Al': + tags = (0, 2) + level = '2p' + ke = 1407. + elif emitter == 'N': + tags = (1, 3) + level = '1s' + ke = 1083. + + for emitter_tag, emitter_plane in product(tags, range(0, planes)): + nplanes = emitter_plane + 2 + try: + cluster = AlN_cluster(emitter_tag, emitter_plane, diameter=diameter, planes=nplanes, term_anion=term_anion, + tetra_down=tetra_down) + except AssertionError: + continue + cluster.absorber = get_atom_index(cluster, 0, 0, 0) + cluster.info.update({'emitter_plane': emitter_plane, + 'emitter_tag': emitter_tag, + 'emitter': emitter, + 'side': side, + 'level': level, + 'ke': ke}) + clusters.append(cluster) + + return clusters + +def compute_polar_scans(clusters, theta=np.arange(-20., 80., 1.), phi=0., data=DATA): + for ic, cluster in enumerate(clusters): + # select the spectroscopy of the calculation and create a new folder for each calculation + side, emitter, tag, plane, level, ke = [cluster.info[k] for k in ('side', 'emitter', 'emitter_tag', + 'emitter_plane', 'level', 'ke')] + calc = MSSPEC(spectroscopy='PED', folder='calc{:0>3d}_S{}_E{}_T{:d}_P{:d}'.format(ic, side, emitter, tag, + plane)) + calc.calculation_parameters.scattering_order = max(1, min(4, plane)) + calc.source_parameters.energy = XRaySource.AL_KALPHA + calc.source_parameters.theta = -35 + calc.detector_parameters.angular_acceptance = 4. + calc.detector_parameters.average_sampling = 'medium' + calc.calculation_parameters.path_filtering = 'forward_scattering' + calc.calculation_parameters.off_cone_events = 1 + [a.set('forward_angle', 30.) for a in cluster] + calc.calculation_parameters.vibrational_damping = 'averaged_tl' + [a.set('mean_square_vibration', 0.006) for a in cluster] + calc.set_atoms(cluster) + + data = calc.get_theta_scan(level=level, theta=theta, phi=phi, kinetic_energy=ke, data=data) + dset = data[-1] + dset.title = 'Polar scan {emitter:s}({level:s} tag {tag:d}) in plane #{plane:d}'.format(emitter=emitter, + level=level, tag=tag, + plane=plane) + for name, value in cluster.info.items(): + dset.add_parameter(group='AlnTuto', name=name, value=str(value), unit="") + #data.save('all_polar_scans.hdf5', append=True) + data.save('all_polar_scans.hdf5') + +def analysis(filename='all_polar_scans.hdf5'): + data=Data.load(filename) + # create datasets to store the sum of all emitter + tmp_data = {} + for dset in data: + # retrieve some info + side = dset.get_parameter(group='AlnTuto', name='side')['value'] + emitter = dset.get_parameter(group='AlnTuto', name='emitter')['value'] + try: + key = '{}_{}'.format(side, emitter) + tmp_data[key] += dset.cross_section + except KeyError: + tmp_data[key] = dset.cross_section.copy() + + # get the index of theta = 0; + it0 = np.where(dset.theta == 0)[0][0] + for key, cs in tmp_data.items(): + tmp_data[key + '_norm'] = cs / cs[it0] + + tmp_data['Al_side'] = tmp_data['Al_Al_norm'] / tmp_data['Al_N_norm'] + tmp_data['N_side'] = tmp_data['N_Al_norm'] / tmp_data['N_N_norm'] + + # now add all columns + substrate_dset = data.add_dset('Total substrate signal') + substrate_dset.add_columns(theta=dset.theta.copy()) + substrate_dset.add_columns(**tmp_data) + + view = substrate_dset.add_view('Al side', + title=r'AlN Polar scan in the (10$\bar{1}$0) azimuthal plane - Al side polarity', + xlabel=r'$\Theta (\degree$)', + ylabel='Signal (a.u.)') + view.select('theta', 'Al_Al_norm', legend='Al 2p') + view.select('theta', 'Al_N_norm', legend='N 1s') + view.set_plot_options(autoscale=True) + + view = substrate_dset.add_view('N side', + title=r'AlN Polar scan in the (10$\bar{1}$0) azimuthal plane - N side polarity', + xlabel=r'$\Theta (\degree$)', + ylabel='Signal (a.u.)') + view.select('theta', 'N_Al_norm', legend='Al 2p') + view.select('theta', 'N_N_norm', legend='N 1s') + view.set_plot_options(autoscale=True) + + view = substrate_dset.add_view('Ratios', + title=r'Al(2p)/N(1s) ratios on both polar sides of AlN in the (10$\bar{1}$0) ' + r'azimuthal plane', + xlabel=r'$\Theta (\degree$)', + ylabel='Intenisty ratio') + view.select('theta', 'Al_side', legend='Al side', where="theta >= 0 and theta <=70") + view.select('theta', 'N_side', legend='N side', where="theta >= 0 and theta <=70") + view.set_plot_options(autoscale=True) + + data.save('analysis.hdf5') + data.view() + + +DIAMETER = 10 +PLANES = 4 +clusters = create_clusters(side='Al', emitter='Al', diameter=DIAMETER, planes=PLANES) + \ + create_clusters(side='Al', emitter='N', diameter=DIAMETER, planes=PLANES) + \ + create_clusters(side='N', emitter='Al', diameter=DIAMETER, planes=PLANES) + \ + create_clusters(side='N', emitter='N', diameter=DIAMETER, planes=PLANES) +compute_polar_scans(clusters, phi=0.) +analysis() diff --git a/doc/source/tutorials/AlN/figures/AL_N_ratios.png b/doc/source/tutorials/AlN/figures/AL_N_ratios.png new file mode 100644 index 0000000..06686ed Binary files /dev/null and b/doc/source/tutorials/AlN/figures/AL_N_ratios.png differ diff --git a/doc/source/tutorials/AlN/figures/AlN_3D.png b/doc/source/tutorials/AlN/figures/AlN_3D.png new file mode 100644 index 0000000..3745f44 Binary files /dev/null and b/doc/source/tutorials/AlN/figures/AlN_3D.png differ diff --git a/doc/source/tutorials/AlN/figures/AlN_polar_scans.png b/doc/source/tutorials/AlN/figures/AlN_polar_scans.png new file mode 100644 index 0000000..7dd1610 Binary files /dev/null and b/doc/source/tutorials/AlN/figures/AlN_polar_scans.png differ diff --git a/doc/source/tutorials/AlN/figures/AlN_projections.png b/doc/source/tutorials/AlN/figures/AlN_projections.png new file mode 100644 index 0000000..e16a06c Binary files /dev/null and b/doc/source/tutorials/AlN/figures/AlN_projections.png differ diff --git a/doc/source/tutorials/AlN/figures/Al_side.png b/doc/source/tutorials/AlN/figures/Al_side.png new file mode 100644 index 0000000..fe33568 Binary files /dev/null and b/doc/source/tutorials/AlN/figures/Al_side.png differ diff --git a/doc/source/tutorials/AlN/figures/N_side.png b/doc/source/tutorials/AlN/figures/N_side.png new file mode 100644 index 0000000..54b695a Binary files /dev/null and b/doc/source/tutorials/AlN/figures/N_side.png differ diff --git a/doc/source/tutorials/AlN/figures/figures.pptx b/doc/source/tutorials/AlN/figures/figures.pptx new file mode 100644 index 0000000..9f8ee1c Binary files /dev/null and b/doc/source/tutorials/AlN/figures/figures.pptx differ diff --git a/doc/source/tutorials/AlN/figures/ratios.png b/doc/source/tutorials/AlN/figures/ratios.png new file mode 100644 index 0000000..beb5ff4 Binary files /dev/null and b/doc/source/tutorials/AlN/figures/ratios.png differ diff --git a/doc/source/tutorials/AlN/tuto_cluster.rst b/doc/source/tutorials/AlN/tuto_cluster.rst new file mode 100644 index 0000000..1eb50dc --- /dev/null +++ b/doc/source/tutorials/AlN/tuto_cluster.rst @@ -0,0 +1,81 @@ +Computing a substrate XPD signal: the AlN polarity example +========================================================== + +.. |AlN4| replace:: AlN\ :sub:`4` + + +In this tutorial, we will see how to compute the full XPD signal of a substrate. In a photoelectron diffraction +experiment, the collected electrons come from a lot of emitters that are located in different planes of the structure +at different depths. + +Simply put, getting the total signal from a substrate from a given type of emitter is computing the signal for the +emitter at the surface, at the subsurface, in the 3rd plane... etc, and summing all together. + +This task can be tedious since it requires to create as many clusters as needed by the number of planes to compute. +Clusters may be different from one to another because you do not need all the planes if the emitter is at the surface +for example and also because the emitter has to be located at the center of the surface to preserve as much as possible +the symmetry. + +A function called :py:func:`hemispherical_cluster` is very handy for that purpose. Before diving into a the more +realistic example of aluminium nitride, you may read more about how to use this function in the FAQ section +:ref:`hemispherical_cluster_faq`. + +In a work published in 1999, Lebedev *et al.* demonstrated that Photoelectron diffraction can be used as a non +invasive tool to unambiguously state the polarity of an AlN surface. Aluminium nitride cristallizes in an hexagonal +cell and the authors experimentally showed that the polarity of the surface can be controlled by the annealing +temperature during the growth. Both polarities are sketched in the figure 1 below. + +.. figure:: figures/AlN_3D.png + :align: center + :width: 80% + + Figure 1. AlN hexagonal lattice in the left) N polarity with nitrogen terminated surface and |AlN4| + tetrahedrons pointing downward and right) Al polarity with aluminium terminated surface and |AlN4| + + +In this work, the authors studied the Al(2p) and N(1s) diffraction patterns for both polarities and they demonstrated +that the Al(2p)/N(1s) ratio exhibits 2 clear peaks at 32° and 59° polar angle in the (10-10) azimuthal plane only for +the aluminium side. + +We will attempt to reproduce these results in the multiple scattering approach. In the AlN cell there are 2 Al atoms +and 2 Nitrogen atoms that are non equivalent. To compute the polar scan of a bulk AlN with those 2 variants, we need +to create one cluster for each non equivalent emitter in each plane. We chose to work with 8 planes, so we have to +compute the polar scan for 32 AlN clusters. The total signal for a polar scan will be the sum of all the scans with +the same kind of emitter in each plane. + +The code is splitted in different functions. The function :py:func:`AlN_cluster` allows to create an AlN cluster +through the use of the :py:func:`hemispherical_cluster` function by specifing the surface termination and the +direction of the |AlN4| tetrahedrons. This function is used by the second function called :py:func:`create_clusters` +which returns a list of clusters to use for the calculation of a substrate with the desired polarity and emitter +chemical symbol. The function :py:func:`compute_polar_scans` does the calculation of a polar scan for a list of +clusters and save all results in a file called all_polar_scans.hdf5. Finally, the :py:func:`analysis` function performs +the sum of all the data and add a new dataset with the 3 figures reported in figures 2 and 3 below. + +.. figure:: figures/AlN_polar_scans.png + :align: center + :width: 80% + + Figure 2. Polar scans in the (10-10) azimuthal plane of AlN for Al polarity (left) and N polarity (right). + + +.. figure:: figures/ratios.png + :align: center + :width: 80% + + Figure 3. Al(2p)/N(1s) intensity ratio for both polarities. + +As can be seen in figure 3, the peaks at 32° and 58.5° are well reproduced by the calculation for an Al polarity. +Some discreapancies arise between the experimental work and this simulation especially for large polar angles. This +may be due to the use of a too small cluster in diameter for the deeper emitters. + +The full code of this tutorial can be downloaded :download:`here` + + + +.. seealso:: + + The polarity of AlN films grown on Si(111) + V. Lebedev, B. Schröter, G. Kipshidze & W Richter, J. Cryst. Growth **207** p266 (1999) + `[doi] `__ + + diff --git a/doc/source/tutorials/Ge/Ge.py b/doc/source/tutorials/Ge/Ge.py new file mode 100644 index 0000000..d1240b8 --- /dev/null +++ b/doc/source/tutorials/Ge/Ge.py @@ -0,0 +1,107 @@ +# -*- encoding: utf-8 -*- +# vim: set fdm=indent ts=4 sw=4 sts=4 et ai tw=80 cc=+0 mouse=a nu : # + +from msspec.calculators import PED, XRaySource +from msspec.utils import * + +from ase.build import bulk +from ase.build import fcc111, add_adsorbate +from ase.visualize import view +from ase.data import reference_states, atomic_numbers + +from matplotlib import pyplot as plt +import numpy as np +import sys + + +n = 1 +symbol = 'Ge' +cluster = bulk(symbol, cubic = True) +cluster = cluster.repeat((10, 10, 10)) +center_cluster(cluster) +a0 = reference_states[atomic_numbers[symbol]]['a'] +cluster = cut_sphere(cluster, radius = a0 * (n+ .01)) +cluster = cut_plane(cluster, z = 0.1) +view(cluster) +#sys.exit(0) +#cluster.absorber = 12 +#cluster.absorber = get_atom_index(cluster, 0,0,-1*n*a0) + + +calc = PED(folder = './Ge') +calc.set_atoms(cluster) + +calc.set_calculation_parameters(scattering_order = 3,RA_cut_off = 1, + mean_square_vibration = 0.0) +#calc.set_source_parameters(theta = -55., phi = 0.) + +calc.set_source_parameters(energy = 100.) +calc.set_muffintin_parameters(interstitial_potential = 0) + + +if False: + level = '3d' + all_be = np.linspace(27., 32., 5) + all_theta = 76. + data = [] + + for be in all_be: + theta, Xsec, dirsig = calc.get_theta_scan(theta = 76., level = level, + binding_energy = be) + print '<'*80 + print Xsec + data.append(Xsec - dirsig) + + data = np.array(data).flatten() + print data + ax = plt.subplot(111) + ax.plot(all_be, data) + plt.show() + +if True: + ax = plt.subplot(111) + for V in [0., 15.]: + level = '3d' + all_theta = np.arange(0., 80., 1.) + phi = 0. + + calc.set_muffintin_parameters(interstitial_potential = V) + + cluster.absorber = 18 + surface_data = calc.get_theta_scan(theta = all_theta, level = level, + phi = phi)#, plane = -1) + + cluster.absorber = 12 + bulk_data = calc.get_theta_scan(theta = all_theta, level = level, + phi = phi)#, plane = -1) + + theta0, Xsec0, dirsig0 = surface_data + theta1, Xsec1, dirsig1 = bulk_data + #plt.plot(theta0, Xsec0, label = 'surface') + #plt.plot(theta1, Xsec1, label = 'bulk') + plt.plot(theta1, Xsec0/Xsec1, label = 'Vint = {:.2f} eV'.format(V)) + + plt.ylim(None, 8) + plt.legend() + plt.show() + + +if False: + # compute + level = '2s' + ke = 156.5 + + all_theta = np.arange(0.,91.) + theta, phi, Xsec, dirsig = calc.get_stereo_scan(theta = all_theta, level = level, + kinetic_energy = ke) + + + + # plot + X, Y = np.meshgrid(np.radians(phi), theta) + ax = plt.subplot(111, projection = 'polar') + ax.pcolormesh(X, Y, Xsec, cmap='gray') + #plt.title(r'z_0 = %.3f $\AA$' % z0) + + plt.show() + diff --git a/doc/source/tutorials/MgO/MgO.py b/doc/source/tutorials/MgO/MgO.py new file mode 100644 index 0000000..2c27f8a --- /dev/null +++ b/doc/source/tutorials/MgO/MgO.py @@ -0,0 +1,68 @@ +# coding: utf-8 + +from msspec.calculators import PED +from msspec.utils import * + +from ase.build import bulk +from ase.visualize import view + +from matplotlib import pyplot as plt +import sys + +a0 = 4.21 # The lattice parameter in angstroms +n = 2 # An integer useful to tweak the size of + # the cluster + +#all_n = (1., 1.5, 2.) +all_n = (1., 1.5) +level = '2p3/2' + +if False: + for n_idx, n in enumerate(all_n): + # Create the copper cubic cell + cluster = bulk('MgO', crystalstructure = 'rocksalt', a = a0, cubic = True) + # Repeat the cell many times along x, y and z + x = int(4*n) + cluster = cluster.repeat((x, x, x)) + # Put the center of the structure at the origin + center_cluster(cluster) + # Keep atoms inside a given radius + cluster = cut_sphere(cluster, radius = n*a0 + .01) + # Keep only atoms below the plane z <= 0 + cluster = cut_plane(cluster, z = 0.1) + + # Set the absorber (for example the deeper atom in z, + # centered in the x-y plane) + cluster.absorber = get_atom_index(cluster, 0,0,-a0) + #view(cluster) + #continue + # Create a calculator for the PhotoElectron Diffration + calc = PED(folder = 'calc' + str(n_idx)) + # Set the cluster to use for the calculation + calc.set_atoms(cluster) + + # Run the calculation + calc.get_theta_scan(level = level) + + calc.save('data%s.msp' % str(n_idx)) + + +#import sys +#sys.exit() + +calc = PED() +ax = plt.subplot(111) + +for i, n in enumerate(all_n): + calc.load('data{:d}.msp'.format(i)) + x, y, _ = calc.get_results() + #y = y/max(y) + ax.plot(x, y, label = '{:d} atoms (n = {:.1f})'.format(len(calc.get_atoms()), n) ) + +ax.legend() +ax.grid(True) +ax.set_xlabel(r'$\theta$ ($\degree$)') +ax.set_ylabel(r'Normalized intensity') +ax.set_title(r'Polar scan of Mg({}) @ {:.2f} eV'.format(level, calc.parameters['kinetic_energy'][0])) +plt.show() + diff --git a/doc/source/tutorials/MgO/MgO_fig1.png b/doc/source/tutorials/MgO/MgO_fig1.png new file mode 100644 index 0000000..af09f01 Binary files /dev/null and b/doc/source/tutorials/MgO/MgO_fig1.png differ diff --git a/doc/source/tutorials/MgO/MgO_fig2.png b/doc/source/tutorials/MgO/MgO_fig2.png new file mode 100644 index 0000000..d9ccc07 Binary files /dev/null and b/doc/source/tutorials/MgO/MgO_fig2.png differ diff --git a/doc/source/tutorials/MgO/MgO_fig3_n1.png b/doc/source/tutorials/MgO/MgO_fig3_n1.png new file mode 100644 index 0000000..e4a544f Binary files /dev/null and b/doc/source/tutorials/MgO/MgO_fig3_n1.png differ diff --git a/doc/source/tutorials/RhO/RhO.py b/doc/source/tutorials/RhO/RhO.py new file mode 100644 index 0000000..e719c43 --- /dev/null +++ b/doc/source/tutorials/RhO/RhO.py @@ -0,0 +1,54 @@ +# -*- encoding: utf-8 -*- +# vim: set fdm=indent ts=4 sw=4 sts=4 et ai tw=80 cc=+0 mouse=a nu : # + +from msspec.calculator import MSSPEC, XRaySource +from msspec.utils import * + +from ase.build import fcc111, add_adsorbate +from ase.visualize import view +from msspec.iodata import cols2matrix + +from matplotlib import pyplot as plt +import numpy as np +import sys + +data = None +all_z = np.arange(1.10, 1.50, 0.02) +all_z=(1.1,) +for zi, z0 in enumerate(all_z): + # construct the cluster + cluster = fcc111('Rh', size = (2,2,1)) + add_adsorbate(cluster, 'O', z0, position = 'fcc') + cluster.pop(3) + #cluster.rotate('z',np.pi/3.) + #view(cluster) + + cluster.absorber = len(cluster) - 1 + + calc = MSSPEC(spectroscopy = 'PED', folder = './RhO_z') + calc.set_atoms(cluster) + calc.calculation_parameters.scattering_order = 3 + calc.calculation_parameters.RA_cutoff = 1 + calc.source_parameters.energy = XRaySource.AL_KALPHA + + # compute + level = '1s' + ke = 723. + + + data = calc.get_theta_phi_scan(level=level, kinetic_energy=ke, data=data) + + # OPTIONAL, this will create an image of the data that you can combine + # in an animated gif + dset = data[-1] + theta, phi, Xsec = cols2matrix(dset.theta, dset.phi, dset.cross_section) + X, Y = np.meshgrid(np.radians(phi), 2*np.tan(np.radians(theta/2.))) + fig = plt.figure() + ax = fig.add_subplot(111, projection='polar') + im = ax.pcolormesh(X, Y, Xsec) + theta_ticks = np.arange(0, 91, 15) + plt.yticks(2 * np.tan(np.radians(theta_ticks/2.)), theta_ticks) + plt.title(r"$z_0 = {:.2f} \AA$".format(z0)) + plt.savefig('image{:03d}.png'.format(zi)) + +data.view() diff --git a/doc/source/tutorials/RhO/RhO_fig0.svg b/doc/source/tutorials/RhO/RhO_fig0.svg new file mode 100644 index 0000000..f13eeaf --- /dev/null +++ b/doc/source/tutorials/RhO/RhO_fig0.svg @@ -0,0 +1,499 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + X-Ray source + photon ħω + + + + + Backscattering + Oxygen + Rhodium + + Surface + + + + + + + Interferences + + + diff --git a/doc/source/tutorials/RhO/RhO_fig1.svg b/doc/source/tutorials/RhO/RhO_fig1.svg new file mode 100644 index 0000000..eb6cece --- /dev/null +++ b/doc/source/tutorials/RhO/RhO_fig1.svg @@ -0,0 +1,1789 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + Atom of Muffin-Tinradius = 1.5 A + + + Backward scattering + Forward scattering + + + + + diff --git a/doc/source/tutorials/RhO/RhO_fig2a.svg b/doc/source/tutorials/RhO/RhO_fig2a.svg new file mode 100644 index 0000000..f443d1e --- /dev/null +++ b/doc/source/tutorials/RhO/RhO_fig2a.svg @@ -0,0 +1,252 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + Rhodium + Oxygen atom on fcc site + + + + + + + + z + 0 + + side view + + + diff --git a/doc/source/tutorials/RhO/RhO_fig2b.gif b/doc/source/tutorials/RhO/RhO_fig2b.gif new file mode 100644 index 0000000..4c46e2d Binary files /dev/null and b/doc/source/tutorials/RhO/RhO_fig2b.gif differ diff --git a/doc/source/tutorials/RhO/sf.py b/doc/source/tutorials/RhO/sf.py new file mode 100644 index 0000000..02e2fca --- /dev/null +++ b/doc/source/tutorials/RhO/sf.py @@ -0,0 +1,31 @@ +# -*- encoding: utf-8 -*- +# vim: set fdm=indent ts=4 sw=4 sts=4 et ai tw=80 cc=+0 mouse=a nu : # + +from msspec.calculator import MSSPEC, XRaySource +from msspec.utils import * + +from ase import Atoms + +import numpy as np + +# Defining global variables +a0 = 6.0 +symbols = ('Rh', 'O') +ke = 723. +level = '1s' + +data = None +for symbol in symbols: + cluster = Atoms(symbol*2, positions = [(0,0,0), (0,0,a0)]) + [a.set('mt_radius', 1.5) for a in cluster] + + # Create the calculator + calc = MSSPEC(spectroscopy = 'PED') + calc.source_parameters.energy = XRaySource.AL_KALPHA + calc.set_atoms(cluster) + cluster.absorber = 0 + + # compute + data = calc.get_scattering_factors(level=level, kinetic_energy=ke, data=data) + +data.view() diff --git a/doc/source/tutorials/RhO/tuto_ped_RhO.rst b/doc/source/tutorials/RhO/tuto_ped_RhO.rst new file mode 100644 index 0000000..5247145 --- /dev/null +++ b/doc/source/tutorials/RhO/tuto_ped_RhO.rst @@ -0,0 +1,98 @@ +Playing with the scattering factor +---------------------------------- + +In this tutorial we will play with an important parameter of any multiple +scattering calculation: the *scattering factor*. When a electron wave is +scattered by an atom, the electron trajectory is modified after this event. The +particle will most likely continue its trajectory in the same direction +(forward scattering), but, to a lesser extent and depending on the atom and on +the electron energy, the direction of the scattered electron can change. The +electron can even be backscattered. The angular distribution of the electron +direction after the scattering event is the scattering factor. + +In a paper published in 1998, T. Gerber *et al.* used the quite high +backscattering factor of Rhodium atoms to probe the distance of Oxygen atoms +adsorbed on a Rhodium surface. Some electrons coming from Oxygen atoms are +ejected toward the Rhodium surface. They are then backscattered and interfere +with the direct signal comming from Oxygen atoms (see the figure below). They +demonstrated both experimentally and numerically with a sinle scattering +computation that this lead to a very accurate probe of adsorbed species that +can be sensitive to bond length changes of the order of :math:`\pm 0.02 \mathring{A}`. + +.. figure:: RhO_fig0.png + :align: center + :width: 30% + + Interferences produced by the backscattering effect. + + +First, compute the scattering factor of both chemical species, Rh and O. + +.. literalinclude:: sf.py + :linenos: + +Running the above script should produce this polar plot. You can see that for Rhodium, +the backscattering coefficient is still significant even at quite high kinetic energy +(here 723 eV). + +.. figure:: RhO_fig1.png + :align: center + :width: 80% + + Polar representation of the scattering factor + +Let an Oxygen atom being adsorbed at a distance :math:`z_0` of an fcc site of +the (111) Rh surface. and compute the :math:`\theta-\phi` scan for different +values of :math:`z_0`. You can see on the stereographic projection 3 bright +circles representing fringes of constructive interference between the direct +O(1s) photoelectron wave and that backscattered by the Rhodium atoms. The +center of these annular shapes changes from bright to dark due to the variation +of the Oxygen atom height above the surface which changes the path difference. + +.. image:: RhO_fig2a.png + :align: center + :height: 200px + + +.. only:: html + + .. figure:: RhO_fig2b.gif + :align: center + :width: 80% + + Stereographic projections of O(1s) emission at :math:`E_k` = 723 eV for an + oxygen atom on top of a fcc site of 3 Rh atoms at various altitudes + :math:`z_0` + +.. only:: latex + + .. figure:: RhO_fig2b.png + :align: center + :width: 80% + + Stereographic projections of O(1s) emission at :math:`E_k` = 723 eV for an + oxygen atom on top of a fcc site of 3 Rh atoms at various altitudes + :math:`z_0` + + + + +Here is the script for the computation. (:download:`download `) + +.. literalinclude:: RhO.py + :linenos: + +.. note:: + After runing this script, you will get 20 images in your folder. You can merge them in one animated gif image + like this: + + .. code-block:: bash + + convert -delay 50 -loop 0 image*.png animation.gif + +.. seealso:: + + X-Ray Photoelectron Diffraction in the Backscattering Geometry: A Key to Adsorption Sites and Bond Lengths at Surfaces + T. Gerber, J. Wider, E. Welti & J. Osterwalder, Phys. Rev. Lett. **81** (8) p1654 (1998) + `[doi] `__ + diff --git a/doc/source/tutorials/copper/Cu_fig1.png b/doc/source/tutorials/copper/Cu_fig1.png new file mode 100644 index 0000000..5fe7ad6 Binary files /dev/null and b/doc/source/tutorials/copper/Cu_fig1.png differ diff --git a/doc/source/tutorials/copper/Cu_fig2.svg b/doc/source/tutorials/copper/Cu_fig2.svg new file mode 100644 index 0000000..9dc24c2 --- /dev/null +++ b/doc/source/tutorials/copper/Cu_fig2.svg @@ -0,0 +1,222 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + (a) + (b) + (c) + + absorber + + + + diff --git a/doc/source/tutorials/copper/Cu_fig3.png b/doc/source/tutorials/copper/Cu_fig3.png new file mode 100644 index 0000000..79245c2 Binary files /dev/null and b/doc/source/tutorials/copper/Cu_fig3.png differ diff --git a/doc/source/tutorials/copper/Cu_simple.py b/doc/source/tutorials/copper/Cu_simple.py new file mode 100644 index 0000000..9801b03 --- /dev/null +++ b/doc/source/tutorials/copper/Cu_simple.py @@ -0,0 +1,34 @@ +# coding: utf-8 + +from msspec.calculator import MSSPEC +from msspec.utils import * + +from ase.build import bulk +from ase.visualize import view + +a0 = 3.6 # The lattice parameter in angstroms + +# Create the copper cubic cell +cluster = bulk('Cu', a=a0, cubic=True) +# Repeat the cell many times along x, y and z +cluster = cluster.repeat((4, 4, 4)) +# Put the center of the structure at the origin +center_cluster(cluster) +# Keep atoms inside a given radius +cluster = cut_sphere(cluster, radius=a0 + .01) +# Keep only atoms below the plane z <= 0 +cluster = cut_plane(cluster, z=0.1) + +# Set the absorber (the deepest atom centered in the xy-plane) +cluster.absorber = get_atom_index(cluster, 0, 0, -a0) +# Create a calculator for the PhotoElectron Diffration +calc = MSSPEC(spectroscopy='PED') +# Set the cluster to use for the calculation +calc.set_atoms(cluster) + +# Run the calculation +data = calc.get_theta_scan(level='2p3/2') + +# Show the results +data.view() +#calc.shutdown() diff --git a/doc/source/tutorials/copper/log.log b/doc/source/tutorials/copper/log.log new file mode 100644 index 0000000..9f405a2 --- /dev/null +++ b/doc/source/tutorials/copper/log.log @@ -0,0 +1,302 @@ +INFO:msspec:Getting the TMatrix... + _________________________________________________________________ + + PHAGEN + _________________________________________________________________ + + parameters for this xpd calculation: + ----------------------------------------------------------------- + edge= k + potype= hedin norman= stdcrm absorber= 1 + coor= angs emin= 13.52 Ry emax= 13.52 Ry + delta= 0.300 Ry gamma= 0.03 Ry eftri= 0.000 Ry + ionization state : neutral + final state potential generated internally + + + Computes the T-matrix and radial matrix elements + + + coordinates in angstroms Radii + ----------------------------------------------------------------- + Cu 29 0.0000 0.0000 -3.6000 0.0000 0.0000 + Cu 29 -1.8000 -1.8000 0.0000 0.0000 0.0000 + Cu 29 -1.8000 0.0000 -1.8000 0.0000 0.0000 + Cu 29 -3.6000 0.0000 0.0000 0.0000 0.0000 + Cu 29 -1.8000 1.8000 0.0000 0.0000 0.0000 + Cu 29 0.0000 -1.8000 -1.8000 0.0000 0.0000 + Cu 29 0.0000 -3.6000 0.0000 0.0000 0.0000 + Cu 29 1.8000 -1.8000 0.0000 0.0000 0.0000 + Cu 29 0.0000 1.8000 -1.8000 0.0000 0.0000 + Cu 29 1.8000 0.0000 -1.8000 0.0000 0.0000 + Cu 29 0.0000 0.0000 0.0000 0.0000 0.0000 + Cu 29 1.8000 1.8000 0.0000 0.0000 0.0000 + Cu 29 0.0000 3.6000 0.0000 0.0000 0.0000 + Cu 29 3.6000 0.0000 0.0000 0.0000 0.0000 + ----------------------------------------------------------------- + + + ** enter calphas ** + --- + total energy for atom in ground state + total energy for atom with a hole in k edge + calculated ionization energy for edge k = 8994.86914 eV + --- + calculated ionization potential (ryd) = 661.387451 + --- + + + symmetrizing coordinates... + + + symmetrized atomic coordinates of cluster + + position + atom no. x y z eq + + 1 osph 0 0.0000 0.0000 0.0000 0 + 2 Cu 29 0.0000 0.0000 -5.3452 0 + 3 Cu 29 -3.4015 -3.4015 1.4578 0 + 4 Cu 29 -3.4015 0.0000 -1.9437 0 + 5 Cu 29 -6.8030 0.0000 1.4578 0 + 6 Cu 29 0.0000 0.0000 1.4578 0 + 7 Cu 29 -3.4015 3.4015 1.4578 3 + 8 Cu 29 3.4015 -3.4015 1.4578 3 + 9 Cu 29 3.4015 3.4015 1.4578 3 + 10 Cu 29 0.0000 -3.4015 -1.9437 4 + 11 Cu 29 0.0000 3.4015 -1.9437 4 + 12 Cu 29 3.4015 0.0000 -1.9437 4 + 13 Cu 29 0.0000 -6.8030 1.4578 5 + 14 Cu 29 0.0000 6.8030 1.4578 5 + 15 Cu 29 6.8030 0.0000 1.4578 5 + + computing muffin tin potential and phase shifts + generating core state wavefunction + generating final potential (complex hedin-lundqvist exchange) + MT radii for Hydrogen atoms determined by stdcrm unless other options are specified + + ----------------------------------------------------------------- + i rs(i) i=1,natoms + 1 9.28 2 2.50 3 2.46 4 2.35 5 2.48 6 2.33 7 2.46 8 2.46 + 9 2.46 10 2.35 11 2.35 12 2.35 13 2.48 14 2.48 15 2.48 + N.B.: Order of atoms as reshuffled by symmetry routines + ----------------------------------------------------------------- + + input value for coulomb interst. potential = -0.699999988 + and interstitial rs = 3.00000000 + lower bound for coulomb interst. potential = -0.290025890 + and for interst. rs = 2.54297900 + + lmax assignment based on l_max = r_mt * k_e + 2 + where e is the running energy + optimal lmax chosen according to the running energy e for each atom + + + number of centers= 14 + + starting potentials and/or charge densities written to file 13 + symmetry information generated internally + symmetry information written to file 14 + + + core initial state of type: 1s1/2 + + fermi level = -0.17690 + + generating t_l (for030) and atomic cross section (for050) + + gamma = 0.030000 rsint = 3.944844 + + check in subroutine cont + order of neighb. -- symb. -- dist. from absorber + + 3 Cu 4.81045771 + 5 Cu 6.80301476 + 2 Cu 8.33195782 + 4 Cu 9.62091541 + ----------------------------------------------------------------- + 1 Cu 0.000000 + 3 Cu 4.810458 + 5 Cu 6.803015 + 2 Cu 8.331958 + 4 Cu 9.620915 + 1 Cu 0.000000 + 3 Cu 4.810458 + 5 Cu 6.803015 + 2 Cu 8.331958 + 4 Cu 9.620915 + + irho = 2 entering vxc to calculate energy dependent exchange + energy dependent vcon = (-0.181322575,0.183172509) at energy 13.5235996 + calculating atomic t-matrix elements atm(n) + check orthogonality between core and continuum state + scalar product between core and continuum state = (0.215178907,-7.336383685E-03) + sqrt(xe/pi) = (1.08555424,-3.627028549E-03) + check ionization potential: 661.387451 + + + value of the mean free path: + ----------------------------------------------------------------- + average mean free path due to finite gamma: mfp = 8.81667 angstrom at energy 13.52360 + + average mean free path in the cluster : mfp = 8.71420 angstrom at energy 13.52360 + + total mean free path due to Im V and gamma: mfp = 4.38257 angstrom at energy 13.52360 + ----------------------------------------------------------------- + + + + ** phagen terminated normally ** + + +INFO:msspec:Getting the TMatrix... + _________________________________________________________________ + + PHAGEN + _________________________________________________________________ + + parameters for this xpd calculation: + ----------------------------------------------------------------- + edge= k + potype= hedin norman= stdcrm absorber= 1 + coor= angs emin= 13.52 Ry emax= 13.52 Ry + delta= 0.300 Ry gamma= 0.03 Ry eftri= 0.000 Ry + ionization state : neutral + final state potential generated internally + + + Computes the T-matrix and radial matrix elements + + + coordinates in angstroms Radii + ----------------------------------------------------------------- + Cu 29 0.0000 0.0000 -3.8000 0.0000 0.0000 + Cu 29 -1.9000 -1.9000 0.0000 0.0000 0.0000 + Cu 29 -1.9000 0.0000 -1.9000 0.0000 0.0000 + Cu 29 -3.8000 0.0000 0.0000 0.0000 0.0000 + Cu 29 -1.9000 1.9000 0.0000 0.0000 0.0000 + Cu 29 0.0000 -1.9000 -1.9000 0.0000 0.0000 + Cu 29 0.0000 -3.8000 0.0000 0.0000 0.0000 + Cu 29 1.9000 -1.9000 0.0000 0.0000 0.0000 + Cu 29 0.0000 1.9000 -1.9000 0.0000 0.0000 + Cu 29 1.9000 0.0000 -1.9000 0.0000 0.0000 + Cu 29 0.0000 0.0000 0.0000 0.0000 0.0000 + Cu 29 1.9000 1.9000 0.0000 0.0000 0.0000 + Cu 29 0.0000 3.8000 0.0000 0.0000 0.0000 + Cu 29 3.8000 0.0000 0.0000 0.0000 0.0000 + ----------------------------------------------------------------- + + + ** enter calphas ** + --- + total energy for atom in ground state + total energy for atom with a hole in k edge + calculated ionization energy for edge k = 8994.86914 eV + --- + calculated ionization potential (ryd) = 661.387451 + --- + + + symmetrizing coordinates... + + + symmetrized atomic coordinates of cluster + + position + atom no. x y z eq + + 1 osph 0 0.0000 0.0000 0.0000 0 + 2 Cu 29 0.0000 0.0000 -5.6422 0 + 3 Cu 29 -3.5905 -3.5905 1.5388 0 + 4 Cu 29 -3.5905 0.0000 -2.0517 0 + 5 Cu 29 -7.1810 0.0000 1.5388 0 + 6 Cu 29 0.0000 0.0000 1.5388 0 + 7 Cu 29 -3.5905 3.5905 1.5388 3 + 8 Cu 29 3.5905 -3.5905 1.5388 3 + 9 Cu 29 3.5905 3.5905 1.5388 3 + 10 Cu 29 0.0000 -3.5905 -2.0517 4 + 11 Cu 29 0.0000 3.5905 -2.0517 4 + 12 Cu 29 3.5905 0.0000 -2.0517 4 + 13 Cu 29 0.0000 -7.1810 1.5388 5 + 14 Cu 29 0.0000 7.1810 1.5388 5 + 15 Cu 29 7.1810 0.0000 1.5388 5 + + computing muffin tin potential and phase shifts + generating core state wavefunction + generating final potential (complex hedin-lundqvist exchange) + MT radii for Hydrogen atoms determined by stdcrm unless other options are specified + + ----------------------------------------------------------------- + i rs(i) i=1,natoms + 1 9.80 2 2.64 3 2.60 4 2.44 5 2.61 6 2.46 7 2.60 8 2.60 + 9 2.60 10 2.44 11 2.44 12 2.44 13 2.61 14 2.61 15 2.61 + N.B.: Order of atoms as reshuffled by symmetry routines + ----------------------------------------------------------------- + + input value for coulomb interst. potential = -0.699999988 + and interstitial rs = 3.00000000 + lower bound for coulomb interst. potential = -0.232031077 + and for interst. rs = 2.76609278 + + lmax assignment based on l_max = r_mt * k_e + 2 + where e is the running energy + optimal lmax chosen according to the running energy e for each atom + + + number of centers= 14 + + starting potentials and/or charge densities written to file 13 + symmetry information generated internally + symmetry information written to file 14 + + + core initial state of type: 1s1/2 + + fermi level = -0.16924 + + generating t_l (for030) and atomic cross section (for050) + + gamma = 0.030000 rsint = 4.292365 + + check in subroutine cont + order of neighb. -- symb. -- dist. from absorber + + 3 Cu 5.07770586 + 5 Cu 7.18096018 + 2 Cu 8.79484367 + 4 Cu 10.1554117 + ----------------------------------------------------------------- + 1 Cu 0.000000 + 3 Cu 5.077706 + 5 Cu 7.180960 + 2 Cu 8.794844 + 4 Cu 10.155412 + 1 Cu 0.000000 + 3 Cu 5.077706 + 5 Cu 7.180960 + 2 Cu 8.794844 + 4 Cu 10.155412 + + irho = 2 entering vxc to calculate energy dependent exchange + energy dependent vcon = (-0.151319593,0.168841615) at energy 13.5235996 + calculating atomic t-matrix elements atm(n) + check orthogonality between core and continuum state + scalar product between core and continuum state = (0.217915282,-9.193832986E-03) + sqrt(xe/pi) = (1.08495688,-3.348779166E-03) + check ionization potential: 661.387451 + + + value of the mean free path: + ----------------------------------------------------------------- + average mean free path due to finite gamma: mfp = 8.81667 angstrom at energy 13.52360 + + average mean free path in the cluster : mfp = 9.13179 angstrom at energy 13.52360 + + total mean free path due to Im V and gamma: mfp = 4.48573 angstrom at energy 13.52360 + ----------------------------------------------------------------- + + + + ** phagen terminated normally ** + + diff --git a/doc/source/tutorials/copper/tuto_ped_copper.rst b/doc/source/tutorials/copper/tuto_ped_copper.rst new file mode 100644 index 0000000..ed7037c --- /dev/null +++ b/doc/source/tutorials/copper/tuto_ped_copper.rst @@ -0,0 +1,227 @@ +Your first XPD pattern +---------------------- +In this small example, you will learn how to produce a polar scan, *ie* you +will plot the number of photo-electrons as a function of the :math:`\theta` +angle. We will do this calculation for a bulk copper (001) surface. + +This is a small script of roughly 15 lines (without comments) just to show you +how to start with the msspec package. For this purpose we will detail all steps +of this first hands on as much as possible. + +Start your favorite text editor to write this Python script. + +Begin by typing: + +.. code-block:: python + :linenos: + :lineno-start: 1 + + # coding: utf-8 + + from msspec.calculator import MSSPEC + from msspec.utils import * + + +Every line starting by a '#' sign is considered as a comment in Python and thus +is ignored... except the first line with the word 'coding' right after the '#' +symbol. It allows you to specify the encoding of your text file. It is not +mandatory but highly recommended. You will most likeley use an utf-8 encoding +as in this example. + +For an MsSpec calculation using ASE, msspec modules must be imported first. +Thus, line 3 you import the MSSPEC calculator from the *calculator* module of the +*msspec* package. MSSPEC is a class. + +We will also need some extra stuff that we load from the *utils* module (line +4). + +We need to create a bulk crystal of copper atoms. We call this a *cluster*. +This is the job of the *ase* module, so load the module + +.. code-block:: python + :linenos: + :lineno-start: 6 + + from ase.build import bulk + from ase.visualize import view + + a0 = 3.6 + cluster = bulk('Cu', a = a0, cubic = True) + view(cluster) + +In line 6 we load the :py:func:`bulk` function to create our atomic object and, +in line 7, we load the :py:func:`view` function to actually view our cluster. + +The creation of the cluster is done line 10. The :py:func:`bulk` needs one +argument which are the chemical species ('Cu' in our example). We also pass 2 +keyword (optional) arguments here: + + * The lattice parameter *a* in units of angströms. + * The *cubic* keyword, to obtain a cubic cell rather than the fully + reduced one which is not cubic + +From now on, you can save your script as 'Cu.py' and open a terminal window in +the same directory as this file. Launch your script using python: + +.. code-block:: bash + + python2 Cu.py + +and a graphical window (the ase-gui) should open with a cubic cell of copper +like this one: + +.. figure:: Cu_fig1.png + :align: center + :width: 40% + + Figure 1. + + +Obviously, multiple scattering calculations need more atoms to be accurate. Due +to the forward focusing effect in photo-electron diffraction, the best suited +geometry for the cluster is hemispherical. Obtaining such a cluster is a +straightforward process: + + 1. Repeat the previous cell in all 3 directions + 2. center the structure + 3. Keep only atoms within a given radius from center + 4. Keep only atoms within one halh of the sphere. + +Modify your script like this and run it again. + +.. literalinclude:: Cu_simple.py + :linenos: + :lineno-start: 1 + :lines: 1-21 + + +Don't forget to add the line to view the cluster at the end of the script and run +the script again. + +.. figure:: Cu_fig2.png + :align: center + :width: 60% + + Figure 2. The different steps to output a cluster. + a) After repeat, b) after cut_sphere, c) after cut_plane + + +Once you a cluster is built the next step is to define which atom in the cluster +will absorbe the light. This atom is called the *absorber*. + +To specify which atom is the absorber, you need to understand that the cluster +object is like a list of atoms. Each member of this list is an atom with its +own position. You need to locate the index of the atom in the list that you want +it to be the absorber. Then, put that number in the *cluster.absorber* attribute + +For example, suppose that you want the first atom of the list to be the +absorber. You should write: + +.. code-block:: python + + cluster.absorber = 0 + +To find what is the index of the atom you'd like to be the absorber, you can +either get it while you are visualizing the structure within the ase-gui +program. Or, you can use :py:func:`get_atom_index` function. This function takes +4 arguments: the cluster to look the index for, and the x, y and z coordinates. +It will return the index of the closest atom to these coordinates. In our +example, to get the deepest atom centered in the xy-plane, we write: + +.. literalinclude:: Cu_simple.py + :linenos: + :lineno-start: 22 + :lines: 22-23 + + +That's all for the cluster part. We now need to create a calculator for that +object. This is a 2 lines procedure: + +.. literalinclude:: Cu_simple.py + :linenos: + :lineno-start: 24 + :lines: 24-28 + +When creating a new calculator, you must choose the kind of spectroscopy you +will work with. In this example we choose 'PED' for *PhotoElectron Diffraction*. +Other types of spectroscopies are: + + - 'AED' for *Auger Electron Spectroscopy* + - 'APECS' for *Auger PhotoElectron Coincidence Spectroscopy* + - 'EXAFS' for *Extended X-Ray Absorption Fine Structure* + - 'LEED' for *Low Energy Electron Diffraction* + + + +Now that everything is ready you can actually perform a calculation. The 2 lines +below will produce a polar scan of the Cu(2p3/2) level with default parameters, +store the results in the data object and display it in a graphical window. + +.. literalinclude:: Cu_simple.py + :linenos: + :lineno-start: 29 + :lines: 29-33 + +running this script will produce the following output + +.. figure:: Cu_fig3.png + :align: center + :width: 80% + + Figure 3. Polar scan of copper (2p3/2) + +You can clearly see the modulations of the signal and the peak at :math:`\theta += 0°` and :math:`\theta = 45°`, which are dense directions of the crystal. + +By default, the program computes for :math:`\theta` angles in the -70°..+70° +range. This can be changed by using the *angles* keyword. + +.. code-block:: python + :linenos: + + #For a polar scan between 0° and 60° with 100 points + import numpy as np + data = calc.get_theta_scan(level = '2p3/2', theta = np.linspace(0,60,100)) + + # For only 0° and 45° + data = calc.get_theta_scan(level = '2p3/2', theta = [0, 45]) + + +You probably also noticed that we did not specify any kinetic energy for our +photoelectron in this example. By default, the programm tries to find the binding +energy (:math:`E_b`) of the choosen level in a database and assume a +kinetic energy (:math:`E_k`) of + +.. math:: + E_k = \hbar\omega - E_b - \Phi_{WF} + +where :math:`\hbar\omega` is the photon energy, an :math:`\Phi_{WF}` is the +work function of the sample, arbitrary set to 4.5 eV. + +Of course, you can choose any kinetic energy you'd like: + +.. code-block:: python + :linenos: + + # To set the kinetic energy... + data = calc.get_theta_scan(level = '2p3/2', kinetic_energy = 300) + + + +Below is the full code of this example. You can download it :download:`here +` + +.. literalinclude:: Cu_simple.py + :linenos: + +.. seealso:: + + Atomic Simulation Environnment + `Documentation `_ + of the ASE module to create your clusters much more. + X-Ray data booklet + `Electron binding energies `_ are + taken from here. + + + diff --git a/doc/source/tutorials/index.rst b/doc/source/tutorials/index.rst new file mode 100644 index 0000000..7efd61e --- /dev/null +++ b/doc/source/tutorials/index.rst @@ -0,0 +1,16 @@ +.. _tutorials: + +#################### +Learn from tutorials +#################### + +...About Photodiffraction +========================= + +.. toctree:: + + copper/tuto_ped_copper + nickel_chain/tuto_ped_nickel_chain + RhO/tuto_ped_RhO + temperature/tuto_ped_temperature + AlN/tuto_cluster diff --git a/doc/source/tutorials/nickel_chain/Ni_chain.py b/doc/source/tutorials/nickel_chain/Ni_chain.py new file mode 100644 index 0000000..321ebd2 --- /dev/null +++ b/doc/source/tutorials/nickel_chain/Ni_chain.py @@ -0,0 +1,77 @@ +# coding: utf-8 + +# import all we need and start by msspec +from msspec.calculator import MSSPEC + +# we will build a simple atomic chain +from ase import Atom, Atoms + +# we need some numpy functions +import numpy as np + + +symbol = 'Ni' # The kind of atom for the chain +orders = (1, 5) # We will run the calculation for single scattering + # and multiple scattering (5th diffusion order) +chain_lengths = (2,3,5) # We will run the calculation for differnt lengths + # of the atomic chain +a = 3.5 # The distance bewteen 2 atoms + +# Define an empty variable to store all the results +all_data = None + +# 2 for nested loops over the chain length and the order of diffusion +for chain_length in chain_lengths: + for order in orders: + # We build the atomic chain by + # 1- stacking each atom one by one along the z axis + chain = Atoms([Atom(symbol, position = (0., 0., i*a)) for i in + range(chain_length)]) + # 2- rotating the chain by 45 degrees with respect to the y axis + chain.rotate('y', np.radians(45.)) + # 3- setting a custom Muffin-tin radius of 1.5 angstroms for all + # atoms (needed if you want to enlarge the distance between + # the atoms while keeping the radius constant) + [atom.set('mt_radius', 1.5) for atom in chain] + # 4- defining the absorber to be the first atom in the chain at + # x = y = z = 0 + chain.absorber = 0 + + # We define a new PED calculator + calc = MSSPEC(spectroscopy = 'PED') + calc.set_atoms(chain) + # Here is how to tweak the scattering order + calc.calculation_parameters.scattering_order = order + # This line below is where we actually run the calculation + all_data = calc.get_theta_scan(level='3s', kinetic_energy=1000., + theta=np.arange(0., 80.), data=all_data) + + # OPTIONAL, to improve the display of the data we will change the dataset + # default title as well as the plot title + t = "order {:d}, n = {:d}".format(order, chain_length) # A useful title + dset = all_data[-1] # get the last dataset + dset.title = t # change its title + # get its last view (there is only one defined for each dataset) + v = dset.views()[-1] + v.set_plot_options(title=t) # change the title of the figure + + + +# OPTIONAL, set the same scale for all plots +# 1. iterate over all computed cross_sections to find the absolute minimum and +# maximum of the data +min_cs = max_cs = 0 +for dset in all_data: + min_cs = min(min_cs, np.min(dset.cross_section)) + max_cs = max(max_cs, np.max(dset.cross_section)) + +# 2. for each view in each dataset, change the scale accordingly +for dset in all_data: + v = dset.views()[-1] + v.set_plot_options(ylim=[min_cs, max_cs]) + +# Pop up the graphical window +all_data.view() +# You can end your script with the line below to remove the temporary +# folder needed for the calculation +calc.shutdown() diff --git a/doc/source/tutorials/nickel_chain/Ni_fig1.svg b/doc/source/tutorials/nickel_chain/Ni_fig1.svg new file mode 100644 index 0000000..b439391 --- /dev/null +++ b/doc/source/tutorials/nickel_chain/Ni_fig1.svg @@ -0,0 +1,757 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + 45° + z + x + Absorber + + q + + + + + + + + 45° + z + x + Absorber + + q + + + + + 45° + z + x + Absorber + + q + + + diff --git a/doc/source/tutorials/nickel_chain/tuto_ped_nickel_chain.rst b/doc/source/tutorials/nickel_chain/tuto_ped_nickel_chain.rst new file mode 100644 index 0000000..27f04b6 --- /dev/null +++ b/doc/source/tutorials/nickel_chain/tuto_ped_nickel_chain.rst @@ -0,0 +1,44 @@ +From single scattering to multiple scattering effects +----------------------------------------------------- + +In this tutorial we will observe one of the main difference between a single +and a multiple scatteirng process: the *defocusing effect*. + +We will reproduce a calculation performed by M.-L Xu, J.J. Barton and M.A. Van Hove +in their paper of 1989 (see :ref:`below ` ) +In the spirit of figure 3 of their paper, We create 3 atomic chains of Ni +atoms (2, 3 and 5 atoms) tilted by 45° and we compare the intensity of the forward scattering +peak as a function of the scattering order: for single scattering and for a multiple +scattering at the 5th order. + +Below is a commented version of this example. You can download it :download:`here +` + +.. literalinclude:: Ni_chain.py + :linenos: + + +The resulting ouput is reported below. We added a sketch of the atomic chains +on the left hand side of the figure. You can see that for the single scattering +computation (left column), the forward peak is growing with increasing the +number of atoms in the chain, while it is clearly damped when using the +multiple scattering approach. Electrons are focused by the second atom in the +chain and *over* focused again by the third atom leading to a diverging +trajectory for this electron which in turn lowers the signal. + +.. figure:: Ni_fig1.png + :align: center + :width: 80% + + Figure 4. Polar scan of a Ni chain of 2-5 atoms for single and mutliple (5th order) + scattering. + + +.. _refTuto2: + +.. seealso:: + + Electron scattering by atomic chains: Multiple-scattering effects + M.-L Xu, J.J. Barton & M.A. Van Hove, Phys. Rev. B **39** (12) p8275 (1989) + `[doi] `__ + diff --git a/doc/source/tutorials/temperature/Cu_temperature.py b/doc/source/tutorials/temperature/Cu_temperature.py new file mode 100644 index 0000000..4120366 --- /dev/null +++ b/doc/source/tutorials/temperature/Cu_temperature.py @@ -0,0 +1,153 @@ +# coding: utf-8 + +from msspec.calculator import MSSPEC, XRaySource +from msspec.utils import * +from msspec.iodata import Data +from ase.build import bulk + +import numpy as np +import sys + +a0 = 3.6 # The lattice parameter in angstroms +phi = np.arange(0, 100) # An array of phi angles +all_T = np.arange(300, 1000, 100) # All temperatures used for the calculation +all_theta = np.array([45, 83]) # 2 polar angles, 83° is grazing detection +eps = 0.01 # a useful small value + +DATA_FNAME = 'all_data.hdf5' # Where to store all the data +ANALYSIS_FNAME = 'analysis.hdf5' + + +def compute(filename): + """Will compute a phi scan for an emitter in the first, second and third plane + of a copper substrate for various polar angles and temperatures. + In a second step (outside this function), intensities from all these emitters + are added to get the signal of a substrate.""" + calc = MSSPEC(spectroscopy='PED') + calc.source_parameters.energy = XRaySource.AL_KALPHA + calc.muffintin_parameters.interstitial_potential = 14.1 + + calc.calculation_parameters.vibrational_damping = 'averaged_tl' + calc.calculation_parameters.use_debye_model = True + calc.calculation_parameters.debye_temperature = 343 + calc.calculation_parameters.vibration_scaling = 1.2 + + calc.detector_parameters.average_sampling = 'high' + calc.detector_parameters.angular_acceptance = 5.7 + + filters = ['forward_scattering', 'backward_scattering'] + calc.calculation_parameters.path_filtering = filters + + calc.calculation_parameters.RA_cutoff = 3 + + # You can also choose a real potential and manually define the + # electron mean free path + # + # calc.tmatrix_parameters.exchange_correlation = 'hedin_lundqvist_real' + # calc.calculation_parameters.mean_free_path = 10. + + data = None # init an empty data object + for temperature in all_T: + for plane in range(3): + # We create a cylindrical cluster here with one plane below the emitter + # and 0, 1 or to planes above the emitter + cluster = bulk('Cu', a=a0, cubic=True) + cluster = cluster.repeat((20, 20, 8)) + center_cluster(cluster) + cluster = cut_cylinder(cluster, radius=1.5 * a0 + eps) + cluster = cut_plane(cluster, z=-( a0/2 + eps)) + cluster = cut_plane(cluster, z=(plane) * a0 / 2 + eps) + cluster.absorber = get_atom_index(cluster, 0, 0, 0) + + calc.calculation_parameters.temperature = temperature + # the scattering order depends on the number of planes above + # the emitter to speed up calculations + calc.calculation_parameters.scattering_order = 1 + plane + + calc.set_atoms(cluster) + # Here starts the calculation + data = calc.get_phi_scan(level='2p3/2', theta=all_theta, phi=phi, + kinetic_energy=560, data=data) + + data.save(filename) + +def process_data(datafile, outputfile): + """Will create another Data file with some phi-scans corresponding to 3 + planes at different temperatures and the anisotropy curve for 45° and + grazing detection. + """ + def get_signal(datafile, T=300, theta=45): + data = Data.load(datafile) + total = None + for dset in data: + p = {_['group'] + '.' + _['name']: _['value'] for _ in dset.parameters()} + temperature = np.float(p['CalculationParameters.temperature']) + if temperature != T: continue + i = np.where(dset.plane == -1) + j = np.where(dset.theta[i] == theta) + signal = dset.cross_section[i][j] + try: + total += signal + except: + total = signal + phi = dset.phi[i][j] + return phi, total + + analysis = Data('Temperature tutorial') + scans_dset = analysis.add_dset('Phi scans') + scans_view = scans_dset.add_view('Figure 1', + title=r'Cu(2p) Azimuthal scan for $\theta = 83\degree$', + xlabel=r'$\Phi (\degree$)', + ylabel='Signal (a.u.)') + anisotropy_dset = analysis.add_dset('Anisotropies') + anisotropy_view = anisotropy_dset.add_view('Figure 2', + title='Relative anisotropies for Cu(2p)', + marker='o', + xlabel='T (K)', + ylabel=r'$\frac{\Delta I / I_{max}(T)}{\Delta I_{300} / I_{max}(300)} (\%)$') + for theta in all_theta: + for T in all_T: + PHI, SIGNAL = get_signal(datafile, T=T, theta=theta) + for phi, signal in zip(PHI, SIGNAL): + scans_dset.add_row(phi=phi, signal=signal, theta=theta, temperature=T) + + middleT = all_T[np.abs(all_T - np.mean(all_T)).argmin()] + if theta == 83 and T in [np.min(all_T), middleT, np.max(all_T)]: + scans_view.select('phi', 'signal', + where='temperature == {:f} and theta == {:f}'.format(T, theta), + legend='{:.0f} K'.format(T)) + + PHI, SIGNAL0 = get_signal(datafile, T=np.min(all_T), theta=theta) + Imax = np.max(SIGNAL) + Imax0 = np.max(SIGNAL0) + dI = Imax - np.min(SIGNAL) + dI0 = Imax0 - np.min(SIGNAL0) + ani = (dI / Imax) / (dI0 / Imax0) + anisotropy_dset.add_row(temperature=T, anisotropy=ani, theta=theta) + + anisotropy_view.select('temperature', 'anisotropy', + where='theta == {:f}'.format(theta), + legend=r'$\theta = {:.0f} \degree$'.format(theta)) + + analysis.save(outputfile) + + +# A convenient way to run the script, just specify one or more of these calc, analyse or +# view keywords as arguments +# ... to calculate all the data, analyse the data and view the results, run +# python Cu_temperature.py calc analyse view +# ... to just view the results, simply run +# python Cu_temperature.py view + +if 'calc' in sys.argv: + compute(DATA_FNAME) +if 'analyse' in sys.argv: + process_data(DATA_FNAME, ANALYSIS_FNAME) +if 'view' in sys.argv: + data = Data.load(ANALYSIS_FNAME) + data.view() + + + + + diff --git a/doc/source/tutorials/temperature/fig1.png b/doc/source/tutorials/temperature/fig1.png new file mode 100644 index 0000000..3156272 Binary files /dev/null and b/doc/source/tutorials/temperature/fig1.png differ diff --git a/doc/source/tutorials/temperature/fig2.png b/doc/source/tutorials/temperature/fig2.png new file mode 100644 index 0000000..b4d7d0c Binary files /dev/null and b/doc/source/tutorials/temperature/fig2.png differ diff --git a/doc/source/tutorials/temperature/tuto_ped_temperature.rst b/doc/source/tutorials/temperature/tuto_ped_temperature.rst new file mode 100644 index 0000000..0e0998e --- /dev/null +++ b/doc/source/tutorials/temperature/tuto_ped_temperature.rst @@ -0,0 +1,54 @@ +Let's raise the temperature +--------------------------- + +In this tutorial we will learn how to introduce lattice vibrations in the calculation. Indeed, vibrational +damping can greatly change the result of a calculation since it adds incoherence that will damp the modulations +of the signal. + +This was experimentally shown back to 1986 for example by R. Trehan and S. Fadley (see reference below). In their +work, they performed azimutal scans of a copper(001) surface at 2 different polar angles: one at grazing incidence +and one at 45° for incresing temperatures from 298K to roughly 1000K. + +For each azimutal scan, they looked at the *anisotropy* of the signal, that is: + +:math:`\frac{\Delta I}{I_{max}}` + +This value is representative of how clear are the modulations of the signal. As it was shown by their +experiments, this anisotropy decreases when the temperature is increased due to the increased disorder +in the structure coming from thermal agitation. They also showed that this variation in anisotropy is more +pronounced for grazing incidence angles. This is related to the fact that surface atoms are expected to +vibrate more than bulk ones. They also proposed single scattering calculations that reproduced well these +results. + +We propose here to reproduce this kind of calculation to introduce the parameters that control the +vibrational damping. + + +.. figure:: fig1.png + :align: center + :width: 80% + + Azimutal scans for Cu(2p) at grazing incidence and at 45°. + + + +.. figure:: fig2.png + :align: center + :width: 80% + + Variation of anisotropy as a function of temperature and polar angle. + + + +.. literalinclude:: Cu_temperature.py + :linenos: + + +Here is the full script used to generate those data (:download:`download `) + +.. seealso:: + + Temperature dependence x-ray photoelectron diffraction from copper: Surface and bulk effects + R. Trehan & C. S. Fadley, Phys. Rev. B **34** (10) p1654 (1986) + `[doi] `__ + diff --git a/doc/source/win_step1.png b/doc/source/win_step1.png new file mode 100644 index 0000000..43b3d38 Binary files /dev/null and b/doc/source/win_step1.png differ diff --git a/doc/source/win_step2.png b/doc/source/win_step2.png new file mode 100644 index 0000000..5c3ac53 Binary files /dev/null and b/doc/source/win_step2.png differ diff --git a/doc/source/windows_icon.png b/doc/source/windows_icon.png new file mode 100644 index 0000000..f8d6179 Binary files /dev/null and b/doc/source/windows_icon.png differ