Skip to content

Commit

Permalink
v0.2: structure manipulation (#5)
Browse files Browse the repository at this point in the history
* Initial commit for the baseline package

This package includes the code that was used in the publication of :
L. P. René de Cotret and B. J. Siwick, A general method for
baseline-removal in ultrafast electron powder diffraction data using the
dual-tree complex wavelet transform, Struct. Dyn. 4 (2016)

* Initial documentation for the baseline package

* Removed links to PyUp and saythanks

* Added installation of NumPy before setup.py can be run on Appveyor

* Revert "Added installation of NumPy before setup.py can be run on Appveyor"

This reverts commit dd4ab54.

* FIX: appveyor builds failing fue to numpy not being

* Removed TOX dependency in Appveyor CI

* FIX: Install numpy & friends from conda on appveyor CI

* FIX: remove optional installation of conda

* FIX: typo in appveyor.yml

* FIX: Escape characters

* FIX: Yet another typo

* f

* Installation of skimage through conda

* UTF-8 encoding

* appveyor.yml typo

* build_sphinx command

* Not installign the right python version

* f

* 23rd time's the charm

* Refactoring of the baseline package

Iterative baseline functions are pretty similar, and they now share a
common implementation for the 1D case.

* Documentation setup based on SHAMPOO

* DOC: updated documentation to reflect the pywavelets dependency

* Sphinx RTD theme added

* Appveyor testing via unittest

* FIX: appveyor.yml typo

* FIX: Python 3.5 install from Miniconda3s

* FIX: Appveyor.yml typo

* CI overhaul

- Removed travis CI
- switched Appveyor testing to a modified version of Astropy's
CI-Helpers

* FIX: appveyor os not found

* FIX: code climate and readme

* Angular average and tutorial (#3)

* Continuous integration and documentation (#2)

* Initial commit for the baseline package

This package includes the code that was used in the publication of :
L. P. René de Cotret and B. J. Siwick, A general method for
baseline-removal in ultrafast electron powder diffraction data using the
dual-tree complex wavelet transform, Struct. Dyn. 4 (2016)

* Initial documentation for the baseline package

* Removed links to PyUp and saythanks

* Added installation of NumPy before setup.py can be run on Appveyor

* Revert "Added installation of NumPy before setup.py can be run on Appveyor"

This reverts commit dd4ab54.

* FIX: appveyor builds failing fue to numpy not being

* Removed TOX dependency in Appveyor CI

* FIX: Install numpy & friends from conda on appveyor CI

* FIX: remove optional installation of conda

* FIX: typo in appveyor.yml

* FIX: Escape characters

* FIX: Yet another typo

* f

* Installation of skimage through conda

* UTF-8 encoding

* appveyor.yml typo

* build_sphinx command

* Not installign the right python version

* f

* 23rd time's the charm

* Refactoring of the baseline package

Iterative baseline functions are pretty similar, and they now share a
common implementation for the 1D case.

* Documentation setup based on SHAMPOO

* DOC: updated documentation to reflect the pywavelets dependency

* Sphinx RTD theme added

* Appveyor testing via unittest

* FIX: appveyor.yml typo

* FIX: Python 3.5 install from Miniconda3s

* FIX: Appveyor.yml typo

* CI overhaul

- Removed travis CI
- switched Appveyor testing to a modified version of Astropy's
CI-Helpers

* FIX: appveyor os not found

* FIX: code climate and readme

* Initial commit

* pseudo-voigt and friends

* DOC: angular_average tutorial

* DOC: References

* DOC: baseline tutorial

* API: angular_average returns intensity and radius

* DOC: angular_average tutorial

* Plot utils: spectrum (rainbow) colors

* Parallel utils: pmap

Parallel map that reduces to the use of map() for a single process.

* Structure package (#4)

* Affine transforms module

First commit for the affine transforms module, containing functions to
create affine transforms and transform points and other transforms.

* Initial commit for the core structure package

* Atom class tutorial

* structure tutorial enhancements

Added an example of crystal potential
  • Loading branch information
LaurentRDC committed Apr 27, 2017
1 parent 878a514 commit ea27d46
Show file tree
Hide file tree
Showing 46 changed files with 3,268 additions and 102 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ __pycache__/
# Visual studio cache
*.vs/

# Protein DataBank cache folder
pdb_cache/

# Distribution / packaging
.Python
env/
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ environment:

- PYTHON_VERSION: "3.6"
CONDA_DEPENDENCIES: "numpy scipy cython scikit-image"
PIP_DEPENDENCIES: "pywavelets"
PIP_DEPENDENCIES: "pywavelets spglib pycifrw"

- PYTHON_VERSION: "3.5"
CONDA_DEPENDENCIES: "numpy scipy cython scikit-image"
PIP_DEPENDENCIES: "pywavelets"
PIP_DEPENDENCIES: "pywavelets spglib pycifrw"

matrix:
fast_finish: true
Expand Down
3 changes: 2 additions & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ nose==1.3.7
coverage==4.3.1
codecov==2.0.5
Sphinx>=1.5.1
cython>=0.25
cython>=0.25
matplotlib
24 changes: 23 additions & 1 deletion docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@
Reference/API
*************

.. automodapi:: scikit-ued
Plot Utilities
==============
.. automodule:: skued.plot_utils

Voigt Profile
=============
.. automodule:: skued.voigt

Affine Transforms
=================
.. automodule:: skued.transformations

Structure
=========
.. autoclass:: skued.structure.Lattice

Baseline-determination
======================
.. autofunction:: skued.baseline.baseline_dt

.. autofunction:: skued.baseline.baseline_dwt

Image Analysis
==============
.. automodule:: skued.image_analysis.symmetry
5 changes: 4 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@
'sphinx.ext.todo',
'sphinx.ext.intersphinx',
'sphinx.ext.autodoc',
'sphinx.ext.napoleon']
'sphinx.ext.napoleon',
'matplotlib.sphinxext.plot_directive']

intersphinx_mapping = {'numpy': ('http://docs.scipy.org/doc/numpy/', None)}

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down
39 changes: 28 additions & 11 deletions docs/source/tutorials/baseline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,45 @@
Baseline Tutorials
************************

Due to the high electron cross-section, background signals (or baseline) are
much more of a problem for electron diffraction than equivalent X-ray experiments.

Contents
========

* :ref:`dual_tree_baseline`

.. _dual_tree_baseline:

Iterative Baseline Determination using the Dual-Tree Complex Wavelet Transform
==============================================================================
Due to the high electron cross-section, background signals (or baseline) are
much more of a problem for electron diffraction than equivalent X-ray experiments.

In the case of polycrystalline samples (i.e. 1D diffraction signals),
the definite way of removing background signals is to use an iterative
approach based on the dual-tree complex wavelet transform.

First, we load an example dataset::
import numpy as np
import matplotlib.pyplot as plt

# TODO: this
import matplotlib.pyplot as plt
import numpy as np

s, intensity = np.load('powder.py')

.. plot :: tutorials/plots/powder_plot.py
We can add a background typical of silicon nitride substrates, as well
as inelastic scattering effects::

from skued import gaussian
background = 75 * np.exp(-7 * s) + 55 * np.exp(-2 * s)
substrate1 = 0.8 * gaussian(s, center = s.mean(), fwhm = s.mean()/4)
substrate2 = 0.9 * gaussian(s, center = s.mean()/2.5, fwhm = s.mean()/4)

.. plot:: tutorials/plots/powder_w_background.py

Scikit-ued offers two ways of removing the background.

.. _dual_tree_baseline:

Iterative Baseline Determination using the Dual-Tree Complex Wavelet Transform
==============================================================================

.. plot:: tutorials/plots/powder_dt_baseline_progression.py

:ref:`Return to Top <baseline_tutorial>`
111 changes: 111 additions & 0 deletions docs/source/tutorials/image_analysis.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
.. include:: ../references.txt

.. _image_analysis_tutorial:

***********************
Image Analysis Tutorial
***********************

Due to the high electron cross-section, background signals (or baseline) are
much more of a problem for electron diffraction than equivalent X-ray experiments.

Contents
========

* :ref:`symmetry`

.. _symmetry:

Angular average of polycrystalline diffraction patterns
=======================================================

First, we create a test image::

import numpy as np
import matplotlib.pyplot as plt
from skued import gaussian

image = np.zeros( (256, 256) )
xc, yc = image.shape[0]/2, image.shape[1]/2 # center

extent = np.arange(0, image.shape[0])
xx, yy = np.meshgrid(extent, extent)
image += gaussian([xx, yy], center = [xc, yc], fwhm = 200)
image /= image.max() # Normalize max to 1
image += np.random.random(size = image.shape)

plt.imshow(image)
plt.show()

.. plot::

import numpy as np
import matplotlib.pyplot as plt
from skued import gaussian
image = np.zeros( (256, 256) )
xc, yc = image.shape[0]/2, image.shape[1]/2 # center
extent = np.arange(0, image.shape[0])
xx, yy = np.meshgrid(extent, extent)
image += gaussian([xx, yy], center = [xc, yc], fwhm = 100)
image /= image.max()
image += np.random.random(size = image.shape)
plt.imshow(image)
plt.show()


... and we can easily compute an angular average::
from skued.image_analysis import angular_average

radius, intensity = angular_average(image, (xc, yc))

plt.plot(radius, intensity)

.. plot::

from skued.image_analysis import angular_average
from skued import gaussian
import numpy as np
import matplotlib.pyplot as plt
from skued import gaussian
image = np.zeros( (256, 256) )
xc, yc = image.shape[0]/2, image.shape[1]/2 # center
extent = np.arange(0, image.shape[0])
xx, yy = np.meshgrid(extent, extent)
image += gaussian([xx, yy], center = [xc, yc], fwhm = 200)
image /= image.max()
image += np.random.random(size = image.shape)
radius, intensity = angular_average(image, (xc, yc))
plt.plot(radius, intensity)
plt.show()

We can also get the standard error in the mean of this average::

extras = dict()
radius, intensity = angular_average(image, (xc, yc), extras = extras)

plt.errorbar(radius, intensity, yerr - extras['error'])

.. plot::

from skued.image_analysis import angular_average
from skued import gaussian
import numpy as np
import matplotlib.pyplot as plt
from skued import gaussian
image = np.zeros( (256, 256) )
xc, yc = image.shape[0]/2, image.shape[1]/2 # center
extent = np.arange(0, image.shape[0])
xx, yy = np.meshgrid(extent, extent)
image += gaussian([xx, yy], center = [xc, yc], fwhm = 200)
image /= image.max()
image += np.random.random(size = image.shape)
extras = dict()
radius, intensity = angular_average(image, (xc, yc), extras = extras)
plt.errorbar(radius, intensity, yerr = extras['error'])
plt.show()

As expected, the points close to the center and very far from it display as higher
amount of noise due to the number of points used in the averaging.

:ref:`Return to Top <image_analysis_tutorial>`
2 changes: 2 additions & 0 deletions docs/source/tutorials/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ We currently have the following tutorials:
.. toctree::
:maxdepth: 1

structure
baseline
image_analysis
File renamed without changes.
26 changes: 26 additions & 0 deletions docs/source/tutorials/plots/powder_dt_baseline_progression.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import matplotlib.pyplot as plt
import numpy as np
from skued import gaussian
from skued.baseline import baseline_dt

s, intensity = np.load('powder.npy')

# Double exponential inelastic background and substrate effects
background = 75 * np.exp(-7 * s) + 55 * np.exp(-2 * s)
substrate1 = 0.8 * gaussian(s, center = s.mean(), fwhm = s.mean()/4)
substrate2 = 0.9 * gaussian(s, center = s.mean()/2.5, fwhm = s.mean()/4)

signal = intensity + background + substrate1 + substrate2

for l in range(5):
baseline = baseline_dt(signal, level = l, max_iter = 100)
plt.plot(s, baseline, color = 'r', label = 'Baseline level {}'.format(l))

plt.plot(s, signal, 'k-', label = 'Diffraction')

plt.title('Diffraction pattern of rutile VO$_2$')
plt.xlabel('Scattering angle (1/$\AA$)')
plt.ylabel('Diffracted intensity (counts)')
plt.xlim([s.min(), s.max()])
plt.ylim([0, 100])
plt.show()
11 changes: 11 additions & 0 deletions docs/source/tutorials/plots/powder_plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import matplotlib.pyplot as plt
import numpy as np

s, intensity = np.load('powder.npy')
plt.plot(s, intensity, 'k-')
plt.title('Background-subtracted diffraction pattern of rutile VO$_2$')
plt.xlabel('Scattering angle (1/$\AA$)')
plt.ylabel('Diffracted intensity (counts)')
plt.xlim([s.min(), s.max()])
plt.ylim([0, 20])
plt.show()
24 changes: 24 additions & 0 deletions docs/source/tutorials/plots/powder_w_background.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import matplotlib.pyplot as plt
import numpy as np
from skued import gaussian

s, intensity = np.load('powder.npy')

# Double exponential inelastic background and substrate effects
background = 75 * np.exp(-7 * s) + 55 * np.exp(-2 * s)
substrate1 = 0.8 * gaussian(s, center = s.mean(), fwhm = s.mean()/4)
substrate2 = 0.9 * gaussian(s, center = s.mean()/2.5, fwhm = s.mean()/4)

plt.plot(s, intensity + background + substrate1 + substrate2, 'k-',
label = 'Diffraction')
plt.plot(s, background + substrate1 + substrate2, 'r-',
label = 'Baseline')

plt.legend()

plt.title('Diffraction pattern of rutile VO$_2$')
plt.xlabel('Scattering angle (1/$\AA$)')
plt.ylabel('Diffracted intensity (counts)')
plt.xlim([s.min(), s.max()])
plt.ylim([0, 100])
plt.show()

0 comments on commit ea27d46

Please sign in to comment.