diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4606f9ff0299c33960901b882dfef9e665c797b4..0f342a184d887f641c8ed766f6861798b13f2615 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,7 +17,7 @@ test_style: image: continuumio/miniconda3:latest script: # -m: only run tests marked with "flake8" - - pyroma . --min=9 # Checks setup.py for cheese! # TODO: Set to maxium cheese (10)! + - pyroma . --min=10 # Checks setup.py for cheese! Maxium cheese 10! - python setup.py test --addopts "--flake8 -m flake8" test_function: @@ -39,7 +39,8 @@ test_docs: # -e: Put documentation for each module on its own page. # -o: Directory to place the output files. If it does not exist, it is created. # last parameter: module path - - sphinx-apidoc -f -e -o docs/api src/empyre + - python setup.py clean # TODO: Simplest way to generate version.py without doing anything else? + #- sphinx-apidoc -f -e -o docs/api src/empyre # Build the documentation from 'docs' and put into 'build/sphinx': - sphinx-build docs build/sphinx artifacts: diff --git a/README.rst b/README.rst index 0dd248142998ad9a209e4835465fd8038410c79c..9ab316742ea6bc3a218cd1d6c15795d2bbe6c165 100644 --- a/README.rst +++ b/README.rst @@ -1 +1,70 @@ -The documentation can be found [here](https://empyre.iffgit.fz-juelich.de/empyre/)! +|pipeline|_ |coverage|_ |pypi|_ + +.. |pipeline| image:: https://iffgit.fz-juelich.de/empyre/empyre/badges/master/pipeline.svg +.. _pipeline: https://iffgit.fz-juelich.de/empyre/empyre/commits/master + +.. |coverage| image:: https://iffgit.fz-juelich.de/empyre/empyre/badges/master/coverage.svg +.. _coverage: https://iffgit.fz-juelich.de/empyre/empyre + +.. |pypi| image:: https://badge.fury.io/py/empyre.svg +.. _pypi: https://pypi.org/project/empyre/ + + +EMPyRe is an open source framework for constructing and solving hyperdimensional inverse problems and visualizing the corresponding input and output data. it has +its roots in the reconstruction of three-dimensional magnetization distributions from magnetic phase images generated by electron holography but is meant to be +extendable for many other problems that are based on forward models that are expressable as a combination of linear subproblems. EMPyRe is purely Python +package, so all platforms should be supported. + + +Installation +------------ + +EMPyRe is available on the `Python Package Index <http://pypi.python.org/pypi>`_ and can be simply be installed via `pip <http://pypi.python.org/pypi/pip>`_: + +.. code-block:: bash + + $ pip install empyre + +Per default, only the strictly required libraries are installed, but there are a few additional dependencies that will unlock additional capabilites of EMPYRE. + +* ``io`` will install the `HyperSpy <https://hyperspy.org/>`_ package that is used for loading and saving additional file formats. + + .. warning:: + Due to this `issue <https://github.com/hyperspy/hyperspy/issues/2315>`_, a pip install of hyperspy is currently not possible. Please use + `conda <https://docs.conda.io/en/latest/>`_ to install HyperSpy, instead. + + +* ``fftw`` will install `PyFFTW <https://github.com/pyFFTW/pyFFTW>`_ to speed up Fourier transforms used in some forward models. + +* ``colors`` will install the `cmocean <https://matplotlib.org/cmocean/>`_, whose ``balance`` color map is used as a default for the ``imshow`` commmand, if available. + +* ``all`` will install all of the dependencies listed above. + + +You can choose these settings by using, *e.g.*: + +.. code-block:: bash + + $ pip install empyre[all] + + +Structure +--------- + +EMPyRe has several dedicated submodules which are fully documented `here <https://empyre.iffgit.fz-juelich.de/empyre/>`_! + +* The ``fields`` submodule provides the ``Field`` container class for multidimensional scalar or vector fields and is the fundamental data structure used in EMPyRe. + +* The ``vis`` submodule enables the plotting of ``Field`` objects, based on and similar in syntax to the commonly known `matplotlib <https://matplotlib.org/>`_ framework. + +* The ``models`` submodule provides tools for constructing forward models that describe processes in Electron Microscopy. + +* The ``reconstruct`` submodule is a collection of tools for solving the inverse problems corresponding to the constructed forward models and diagnostic tools for their assessment. + +* The ``io`` submodule is used to load and save ``Field`` objects and the models generated by the ``models`` subpackage. + + + +License +------- +EMPyRe is licensed under `GPLv3 <https://iffgit.fz-juelich.de/empyre/empyre/-/blob/master/LICENSE>`_. diff --git a/docs/api/empyre.fields.rst b/docs/api/empyre.fields.rst deleted file mode 100644 index 4669873262616d27adb8f6a8b5ee5db1ca66b7c5..0000000000000000000000000000000000000000 --- a/docs/api/empyre.fields.rst +++ /dev/null @@ -1,38 +0,0 @@ -empyre.fields package -===================== - -Submodules ----------- - -empyre.fields.field module --------------------------- - -.. automodule:: empyre.fields.field - :members: - :undoc-members: - :show-inheritance: - -empyre.fields.shapes module ---------------------------- - -.. automodule:: empyre.fields.shapes - :members: - :undoc-members: - :show-inheritance: - -empyre.fields.vectors module ----------------------------- - -.. automodule:: empyre.fields.vectors - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: empyre.fields - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/empyre.io.rst b/docs/api/empyre.io.rst deleted file mode 100644 index b90f22cbbc5afa37ff23d595bae7bc61a7e2d7b4..0000000000000000000000000000000000000000 --- a/docs/api/empyre.io.rst +++ /dev/null @@ -1,10 +0,0 @@ -empyre.io package -================= - -Module contents ---------------- - -.. automodule:: empyre.io - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/empyre.models.rst b/docs/api/empyre.models.rst deleted file mode 100644 index 084117eb743b7f20c1f6fbe1e67c3df377458644..0000000000000000000000000000000000000000 --- a/docs/api/empyre.models.rst +++ /dev/null @@ -1,10 +0,0 @@ -empyre.models package -===================== - -Module contents ---------------- - -.. automodule:: empyre.models - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/empyre.reconstruct.rst b/docs/api/empyre.reconstruct.rst deleted file mode 100644 index 48243874e0991f872a187108183a1ba93cdb5cd8..0000000000000000000000000000000000000000 --- a/docs/api/empyre.reconstruct.rst +++ /dev/null @@ -1,10 +0,0 @@ -empyre.reconstruct package -========================== - -Module contents ---------------- - -.. automodule:: empyre.reconstruct - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/empyre.rst b/docs/api/empyre.rst deleted file mode 100644 index a935d59aabedeba316b557a0c07093ad276cddde..0000000000000000000000000000000000000000 --- a/docs/api/empyre.rst +++ /dev/null @@ -1,33 +0,0 @@ -empyre package -============== - -Subpackages ------------ - -.. toctree:: - - empyre.fields - empyre.io - empyre.models - empyre.reconstruct - empyre.vis - -Submodules ----------- - -empyre.version module ---------------------- - -.. automodule:: empyre.version - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: empyre - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/empyre.vis.rst b/docs/api/empyre.vis.rst deleted file mode 100644 index 0a08bbcc5023beba7ae53dc0ec2f74fde1eb21ff..0000000000000000000000000000000000000000 --- a/docs/api/empyre.vis.rst +++ /dev/null @@ -1,46 +0,0 @@ -empyre.vis package -================== - -Submodules ----------- - -empyre.vis.colors module ------------------------- - -.. automodule:: empyre.vis.colors - :members: - :undoc-members: - :show-inheritance: - -empyre.vis.decorators module ----------------------------- - -.. automodule:: empyre.vis.decorators - :members: - :undoc-members: - :show-inheritance: - -empyre.vis.plot2d module ------------------------- - -.. automodule:: empyre.vis.plot2d - :members: - :undoc-members: - :show-inheritance: - -empyre.vis.tools module ------------------------ - -.. automodule:: empyre.vis.tools - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: empyre.vis - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/api/modules.rst b/docs/api/modules.rst deleted file mode 100644 index aab610281a1a2ebe430e0d26fb8b5e9a0d13c564..0000000000000000000000000000000000000000 --- a/docs/api/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -empyre -====== - -.. toctree:: - :maxdepth: 4 - - empyre diff --git a/docs/conf.py b/docs/conf.py index aedfb1b895ea3bbbfad6e395be746f1dea99d612..f1fffc4961e285f45beaf68d1c9debce9e39ce34 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -35,8 +35,7 @@ author = 'Jan Caron' # ones. extensions = [ 'sphinx.ext.autodoc', - 'sphinx.ext.coverage', - 'sphinx.ext.mathjax', + 'sphinx.ext.viewcode', 'numpydoc' ] diff --git a/docs/fields.rst b/docs/fields.rst index 68bd3b1ca868f9c686f6274bfcdd25f976ca578a..4f07378a570562236ddf1a9e3ec768f7965d5617 100644 --- a/docs/fields.rst +++ b/docs/fields.rst @@ -1,4 +1,28 @@ The Field container class ========================= -Field docu here! +General empyre.fields docu here! + + +The field submodule +------------------- + +.. automodule:: empyre.fields.field + :members: + :show-inheritance: + + +The shapes submodule +-------------------- + +.. automodule:: empyre.fields.shapes + :members: + :show-inheritance: + + +The vectors submodule +--------------------- + +.. automodule:: empyre.fields.vectors + :members: + :show-inheritance: diff --git a/docs/index.rst b/docs/index.rst index 6d83a3dd626f1c839d1686b3ef16e729396a3334..5d131276df81f473248c4516cfb81c56ba54f1bc 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to EMPyRe's documentation! -================================== +EMPyRe - Electron Microscopy Reconstruction +=========================================== .. include:: ../README.rst diff --git a/docs/vis.rst b/docs/vis.rst index 8cb785a62281372c7d12aa6d8290036fdd5dd189..c8822679b31b815d2aedfe7dd170040f2fde54bd 100644 --- a/docs/vis.rst +++ b/docs/vis.rst @@ -1,4 +1,36 @@ The vis visualization submodule =============================== -vis docu here! +General empyre.vis docu here! + + +The plot2d submodule +-------------------- + +.. automodule:: empyre.vis.plot2d + :members: + :show-inheritance: + + +The decorators submodule +------------------------ + +.. automodule:: empyre.vis.decorators + :members: + :show-inheritance: + + +The colors submodule +-------------------- + +.. automodule:: empyre.vis.colors + :members: + :show-inheritance: + + +The tools submodule +------------------- + +.. automodule:: empyre.vis.tools + :members: + :show-inheritance: diff --git a/environment.yml b/environment.yml index 3ce80b669839c9688654b9fe8c5039f2aa0cbfb4..7252c577e8a5ab037cf053efb9541a3121b68098 100644 --- a/environment.yml +++ b/environment.yml @@ -38,7 +38,7 @@ dependencies: #- pytest-mpl=0.10 # Needed for testing hyperspy! # TODO: Use for pyramid/plotting library, too! - coverage=4.5 # Documentation: - - sphinx=2.1 + - sphinx=2.4 - numpydoc=0.9 - sphinx_rtd_theme=0.4 # TODO: not needed? # IPython and notebooks: diff --git a/src/empyre/fields/field.py b/src/empyre/fields/field.py index c590e0b26c84085df6f91a7ea19731a914f2483e..b94f32f6c650b3e15cf899c2d5f9ccefb1d926cc 100644 --- a/src/empyre/fields/field.py +++ b/src/empyre/fields/field.py @@ -438,7 +438,7 @@ class Field(NDArrayOperatorsMixin): The calculation depends on the input: 3 dimensions, 3 components: Calculates the full 3D rotational vector field! 2 dimensions, 2 components: Calculates the out-of-plane component of the curl as a 2D scalar field! - 2 dimensions, scalar: Calculates the planar rotatio as a 2D vector field! + 2 dimensions, scalar: Calculates the planar rotation as a 2D vector field! """ self._log.debug('Calling curl') @@ -447,12 +447,12 @@ class Field(NDArrayOperatorsMixin): if squeezed_field.ncomp == 3: # 3 component vector field (standard case): self._log.debug('input: 3 dimensions, 3 components!') field_x, field_y, field_z = squeezed_field.comp - grad_xx, grad_xy, grad_xz = field_x.gradient().comp - grad_yx, grad_yy, grad_yz = field_y.gradient().comp - grad_zx, grad_zy, grad_zz = field_z.gradient().comp - curl_x = grad_zy - grad_yz - curl_y = grad_xz - grad_zx - curl_z = grad_yx - grad_xy + gradx_x, grady_x, gradz_x = field_x.gradient().comp + gradx_y, grady_y, gradz_y = field_y.gradient().comp + gradx_z, grady_z, gradz_z = field_z.gradient().comp + curl_x = grady_z - gradz_y + curl_y = gradz_x - gradx_z + curl_z = gradx_y - grady_x return Field.from_scalar_fields([curl_x, curl_y, curl_z]) else: raise AssertionError('Can only handle 3 component vector fields in 3D!') @@ -460,14 +460,14 @@ class Field(NDArrayOperatorsMixin): if squeezed_field.ncomp == 2: # 2 component vector field (return perpendicular component as scalar field): self._log.debug('input: 2 dimensions, 2 components!') field_x, field_y = squeezed_field.comp - grad_xx, grad_xy = field_x.gradient().comp - grad_yx, grad_yy = field_y.gradient().comp - return grad_yx - grad_xy + gradx_x, grady_x = field_x.gradient().comp + gradx_y, grady_y = field_y.gradient().comp + return gradx_y - grady_x elif not squeezed_field.vector: # scalar field (return planar components as 2D vector field): self._log.debug('input: 3 dimensions, scalar field!') - grad_x, grad_y = squeezed_field.gradient().comp - curl_x = grad_y - curl_y = -grad_x + gradx, grady = squeezed_field.gradient().comp + curl_x = grady + curl_y = -gradx return Field.from_scalar_fields([curl_x, curl_y]) else: raise AssertionError('Can only handle 3 component vector or scalar fields in 2D!') @@ -475,7 +475,7 @@ class Field(NDArrayOperatorsMixin): raise AssertionError('Can only handle 3D or 2D cases (see documentation for specifics)!') def clip(self, vmin=None, vmax=None, sigma=None, mask=None): - """Clip (limit) the values in an array. For vector fields, this will take the amplitude into account + """Clip (limit) the values in an array. For vector fields, this will take the amplitude into account. Parameters ---------- @@ -517,9 +517,8 @@ class Field(NDArrayOperatorsMixin): if vmax is None: vmax = np.nanmax(amp_masked) if self.vector: # Vector fields need to scale components according to masked amplitude - mask_vec = np.logical_and(mask, amp <= vmax) # Only vmax is important! - data = amp / np.where(mask_vec, 1, amp) # TODO: needs testing! - # TODO: Test np.clip(field) (also ufunc?? think not...) seems to work, but what about others? + mask_vec = (amp <= vmax)[..., None] # Only vmax is important for vectors! mask_vec broadcast to components! + data = np.where(mask_vec, self.data, vmax * self.data/amp[..., None]) # Scale outliers to vmax! else: # For scalar fields, just delegate to the numpy function: data = np.clip(self.data, vmin, vmax) return Field(data, self.scale, self.vector)