diff --git a/.hgignore b/.hgignore index a9ff8eb73973341b9b5be1c54ca39fe7a8f97483..5f7570492ed255fd62287fc2d9bf2abec379c3c8 100644 --- a/.hgignore +++ b/.hgignore @@ -8,7 +8,6 @@ syntax: glob *.so *.os *.c -_* output* build* Pyramid.egg-info* \ No newline at end of file diff --git a/desktop.ini b/desktop.ini index e3da4d705005ef1b5c7e9641c22981f1312e37d6..ed829e62137655210c6d17e08844b0ed9929acac 100644 --- a/desktop.ini +++ b/desktop.ini @@ -1,5 +1,5 @@ [.ShellClassInfo] -IconResource=C:\Users\Jan\Home\PhD Thesis\Pyramid\icon.ico,0 +IconResource=C:\Users\Jan\Home\PhD Thesis\Pyramid\docs\icon.ico,0 [ViewState] Mode= Vid= diff --git a/docs/Pyramid Logo.png b/docs/Pyramid Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..9d68d277a5b322c744a6fd941e1baf1d978759e4 Binary files /dev/null and b/docs/Pyramid Logo.png differ diff --git a/docs/_static/sphinxdoc.css b/docs/_static/sphinxdoc.css new file mode 100644 index 0000000000000000000000000000000000000000..d208cf7974e78e10ef9bf7d6c99c2a9b376ddf3e --- /dev/null +++ b/docs/_static/sphinxdoc.css @@ -0,0 +1,354 @@ +/* + * sphinxdoc.css_t + * ~~~~~~~~~~~~~~~ + * + * Sphinx stylesheet -- sphinxdoc theme. Originally created by + * Armin Ronacher for Werkzeug. + * + * :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + * :license: BSD, see LICENSE for details. + * + */ + +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +body { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; + font-size: 14px; + letter-spacing: -0.01em; + line-height: 150%; + text-align: center; + background-color: #BFD1D4; + color: black; + padding: 0; + border: 1px solid #aaa; + + margin: 0px 80px 0px 80px; + min-width: 740px; +} + +div.document { + background-color: white; + text-align: left; + background-image: url(contents.png); + background-repeat: repeat-x; +} + +div.bodywrapper { + margin: 0 240px 0 0; + border-right: 1px solid #ccc; +} + +div.body { + margin: 0; + padding: 0.5em 20px 20px 20px; +} + +div.related { + font-size: 1em; +} + +div.related ul { + background-image: url(navigation.png); + height: 2em; + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; +} + +div.related ul li { + margin: 0; + padding: 0; + height: 2em; + float: left; +} + +div.related ul li.right { + float: right; + margin-right: 5px; +} + +div.related ul li a { + margin: 0; + padding: 0 5px 0 5px; + line-height: 1.75em; + color: #EE9816; +} + +div.related ul li a:hover { + color: #3CA8E7; +} + +div.sphinxsidebarwrapper { + padding: 0; +} + +div.sphinxsidebar { + margin: 0; + padding: 0.5em 15px 15px 0; + width: 210px; + float: right; + font-size: 1em; + text-align: left; +} + +div.sphinxsidebar h3, div.sphinxsidebar h4 { + margin: 1em 0 0.5em 0; + font-size: 1em; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border: 1px solid #86989B; + background-color: #AFC1C4; +} + +div.sphinxsidebar h3 a { + color: white; +} + +div.sphinxsidebar ul { + padding-left: 1.5em; + margin-top: 7px; + padding: 0; + line-height: 130%; +} + +div.sphinxsidebar ul ul { + margin-left: 20px; +} + +div.footer { + background-color: #E3EFF1; + color: #86989B; + padding: 3px 8px 3px 0; + clear: both; + font-size: 0.8em; + text-align: right; +} + +div.footer a { + color: #86989B; + text-decoration: underline; +} + +/* -- body styles ----------------------------------------------------------- */ + +p { + margin: 0.8em 0 0.5em 0; +} + +a { + color: #CA7900; + text-decoration: none; +} + +a:hover { + color: #2491CF; +} + +div.body a { + text-decoration: underline; +} + +h1 { + margin: 0; + padding: 0.7em 0 0.3em 0; + font-size: 1.5em; + color: #11557C; + background-color: #ccd8ff; +} + +h2 { + margin: 1.3em 0 0.2em 0; + font-size: 1.35em; + padding: 0; + background-color: #ccd8ff; +} + +h3 { + margin: 1em 0 -0.3em 0; + font-size: 1.2em; + background-color: #ccd8ff; +} + +h4 { + background-color: #ccd8ff +} + +h5 { + background-color: #ccd8ff +} + +div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a { + color: black!important; +} + +h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor { + display: none; + margin: 0 0 0 0.3em; + padding: 0 0.2em 0 0.2em; + color: #aaa!important; +} + +h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, +h5:hover a.anchor, h6:hover a.anchor { + display: inline; +} + +h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover, +h5 a.anchor:hover, h6 a.anchor:hover { + color: #777; + background-color: #eee; +} + +a.headerlink { + color: #c60f0f!important; + font-size: 1em; + margin-left: 6px; + padding: 0 4px 0 4px; + text-decoration: none!important; +} + +a.headerlink:hover { + background-color: #ccc; + color: white!important; +} + +cite, code, tt { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 1.17em; + letter-spacing: 0.01em; +} + +tt { + background-color: #f2f2f2; + border-bottom: 1px solid #ddd; + color: #333; +} + +tt.descname, tt.descclassname, tt.xref { + border: 0; +} + +hr { + border: 1px solid #abc; + margin: 2em; +} + +a tt { + border: 0; + color: #CA7900; +} + +a tt:hover { + color: #2491CF; +} + +th { + background-color: #fff3cc; +} + +pre { + font-family: 'Consolas', 'Deja Vu Sans Mono', + 'Bitstream Vera Sans Mono', monospace; + font-size: 0.95em; + letter-spacing: 0.015em; + line-height: 120%; + padding: 0.5em; + border: 1px solid #ccc; + background-color: #f8f8f8; +} + +pre a { + color: inherit; + text-decoration: underline; +} + +td.linenos pre { + padding: 0.5em 0; +} + +div.quotebar { + background-color: #f8f8f8; + max-width: 250px; + float: right; + padding: 2px 7px; + border: 1px solid #ccc; +} + +div.topic { + background-color: #f8f8f8; +} + +table { + border-collapse: collapse; + margin: 0 -0.5em 0 -0.5em; +} + +table td, table th { + padding: 0.2em 0.5em 0.2em 0.5em; +} + +div.admonition, div.warning { + font-size: 0.9em; + margin: 1em 0 1em 0; + border: 1px solid #86989B; + background-color: #f7f7f7; + padding: 0; +} + +div.admonition p, div.warning p { + margin: 0.5em 1em 0.5em 1em; + padding: 0; +} + +div.admonition pre, div.warning pre { + margin: 0.4em 1em 0.4em 1em; +} + +div.admonition p.admonition-title, +div.warning p.admonition-title { + margin: 0; + padding: 0.1em 0 0.1em 0.5em; + color: white; + border-bottom: 1px solid #86989B; + font-weight: bold; + background-color: #AFC1C4; +} + +div.warning { + border: 1px solid #940000; +} + +div.warning p.admonition-title { + background-color: #CF0000; + border-bottom-color: #940000; +} + +div.admonition ul, div.admonition ol, +div.warning ul, div.warning ol { + margin: 0.1em 0.5em 0.5em 3em; + padding: 0; +} + +div.versioninfo { + margin: 1em 0 0 0; + border: 1px solid #ccc; + background-color: #DDEAF0; + padding: 8px; + line-height: 1.3em; + font-size: 0.9em; +} + +.viewcode-back { + font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', + 'Verdana', sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 259c0970cd0e2eb3617b88fb2c71f1e1ccfade8e..cf566933896ec3965fae8427376f9e83e72a170a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,8 +25,10 @@ sys.path.insert(0, os.path.abspath('C:\Users\Jan\Home\PhD Thesis\Pyramid')) # 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.viewcode', 'rst2pdf.pdfbuilder', - 'numpydoc'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.autosummary', + 'rst2pdf.pdfbuilder', 'numpydoc'] + +numpydoc_show_class_members = False # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -92,7 +94,7 @@ pygments_style = 'sphinx' # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'default' +html_theme = 'sphinxdoc' # 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 @@ -111,12 +113,12 @@ html_theme = 'default' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +html_logo = 'Pyramid Logo.png' # 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 +html_favicon = 'icon.ico' # 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, diff --git a/icon.ico b/docs/icon.ico similarity index 100% rename from icon.ico rename to docs/icon.ico diff --git a/docs/pyramid.numcore.rst b/docs/pyramid.numcore.rst index 9d3a9c39bab16bb343a843246c3726977a079b81..4ad4c515f2c46870d53142b9d064a0467a3835e9 100644 --- a/docs/pyramid.numcore.rst +++ b/docs/pyramid.numcore.rst @@ -6,7 +6,6 @@ numcore Package .. automodule:: pyramid.numcore :members: - :undoc-members: :show-inheritance: :special-members: diff --git a/docs/pyramid.rst b/docs/pyramid.rst index 3491e66ec3ab49baf2a06d77b1b654c0f9670ee2..8bd3b4c52bfc4d67c3eb53e14e9df3d08ac51b51 100644 --- a/docs/pyramid.rst +++ b/docs/pyramid.rst @@ -6,25 +6,38 @@ pyramid Package .. automodule:: pyramid.analytic :members: - :undoc-members: :show-inheritance: :special-members: -:mod:`holoimage` Module ------------------------ +:mod:`costfunction` Module +-------------------------- + +.. automodule:: pyramid.costfunction + :members: + :show-inheritance: + :special-members: + +:mod:`datacollection` Module +---------------------------- -.. automodule:: pyramid.holoimage +.. automodule:: pyramid.datacollection + :members: + :show-inheritance: + :special-members: + +:mod:`forwardmodel` Module +-------------------------- + +.. automodule:: pyramid.forwardmodel :members: - :undoc-members: :show-inheritance: :special-members: :mod:`kernel` Module ------------------------ +-------------------- .. automodule:: pyramid.kernel :members: - :undoc-members: :show-inheritance: :special-members: @@ -33,7 +46,6 @@ pyramid Package .. automodule:: pyramid.magcreator :members: - :undoc-members: :show-inheritance: :special-members: @@ -42,7 +54,14 @@ pyramid Package .. automodule:: pyramid.magdata :members: - :undoc-members: + :show-inheritance: + :special-members: + +:mod:`optimizer` Module +----------------------- + +.. automodule:: pyramid.optimizer + :members: :show-inheritance: :special-members: @@ -51,7 +70,6 @@ pyramid Package .. automodule:: pyramid.phasemap :members: - :undoc-members: :show-inheritance: :special-members: @@ -60,7 +78,6 @@ pyramid Package .. automodule:: pyramid.phasemapper :members: - :undoc-members: :show-inheritance: :special-members: @@ -69,16 +86,6 @@ pyramid Package .. automodule:: pyramid.projector :members: - :undoc-members: - :show-inheritance: - :special-members: - -:mod:`reconstructor` Module ---------------------------- - -.. automodule:: pyramid.reconstructor - :members: - :undoc-members: :show-inheritance: :special-members: diff --git a/logfile.log b/logfile.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyramid/__init__.py b/pyramid/__init__.py index 109731534a012c2fa22dbc214f7909a8ebbd23a0..8d25565aa7341e668317b8fd813c6ca9765d8e3d 100644 --- a/pyramid/__init__.py +++ b/pyramid/__init__.py @@ -6,9 +6,9 @@ Modules magcreator Create simple magnetic distributions. magdata - Class for the storage of magnetizatin data. + Class for the storage of magnetization data. projector - Create projections of a given magnetization distribution. + Class for projections of given magnetization distribution. kernel Class for the kernel matrix representing one magnetized pixel. phasemapper @@ -17,8 +17,14 @@ phasemap Class for the storage of phase data. analytic Create phase maps for magnetic distributions with analytic solutions. -holoimage - Create holographic contour maps from a given phase map. +datacollection + Class for collecting pairs of phase maps and corresponding projectors. +forwardmodel + Class which represents a phase mapping strategy. +costfunction + Class for the evaluation of the cost of a function. +optimizer + Provides strategies for optimizing first guess magnetic distributions. reconstructor Reconstruct magnetic distributions from given phasemaps. @@ -33,10 +39,8 @@ numcore import logging, logging.config import os -LOGGING_CONF = os.path.join(os.path.dirname(__file__), 'logging.ini') -logging.config.fileConfig(LOGGING_CONF) +LOGGING_CONF = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'logging.ini') -log = logging.getLogger(__name__) -log.info('imported package, log:'+log.name) \ No newline at end of file +logging.config.fileConfig(LOGGING_CONF) diff --git a/pyramid/analytic.py b/pyramid/analytic.py index 5445990a923ede7dccd77d4d1232bd90aeff8c27..bf2ffccd69db5206304c463fd5da401519acecb2 100644 --- a/pyramid/analytic.py +++ b/pyramid/analytic.py @@ -11,6 +11,8 @@ calculated by the functions from the :mod:`~pyramid.phasemapper` module. import numpy as np from numpy import pi +from pyramid.phasemap import PhaseMap + PHI_0 = -2067.83 # magnetic flux in T*nm² @@ -44,17 +46,17 @@ def phase_mag_slab(dim, a, phi, center, width, b_0=1): # Function for the phase: def phi_mag(x, y): def F_0(x, y): - a = np.log(x**2 + y**2 + 1E-30) - b = np.arctan(x / (y+1E-30)) - return x*a - 2*x + 2*y*b + A = np.log(x**2 + y**2 + 1E-30) + B = np.arctan(x / (y+1E-30)) + return x*A - 2*x + 2*y*B return coeff * Lz * (- np.cos(phi) * (F_0(x-x0-Lx/2, y-y0-Ly/2) - - F_0(x-x0+Lx/2, y-y0-Ly/2) - - F_0(x-x0-Lx/2, y-y0+Ly/2) - + F_0(x-x0+Lx/2, y-y0+Ly/2)) + - F_0(x-x0+Lx/2, y-y0-Ly/2) + - F_0(x-x0-Lx/2, y-y0+Ly/2) + + F_0(x-x0+Lx/2, y-y0+Ly/2)) + np.sin(phi) * (F_0(y-y0-Ly/2, x-x0-Lx/2) - - F_0(y-y0+Ly/2, x-x0-Lx/2) - - F_0(y-y0-Ly/2, x-x0+Lx/2) - + F_0(y-y0+Ly/2, x-x0+Lx/2))) + - F_0(y-y0+Ly/2, x-x0-Lx/2) + - F_0(y-y0-Ly/2, x-x0+Lx/2) + + F_0(y-y0+Ly/2, x-x0+Lx/2))) # Process input parameters: z_dim, y_dim, x_dim = dim y0 = a * (center[1] + 0.5) # y0, x0 define the center of a pixel, @@ -66,7 +68,7 @@ def phase_mag_slab(dim, a, phi, center, width, b_0=1): y = np.linspace(a/2, y_dim*a-a/2, num=y_dim) xx, yy = np.meshgrid(x, y) # Return phase: - return phi_mag(xx, yy) + return PhaseMap(a, phi_mag(xx, yy)) def phase_mag_disc(dim, a, phi, center, radius, height, b_0=1): @@ -115,7 +117,7 @@ def phase_mag_disc(dim, a, phi, center, radius, height, b_0=1): y = np.linspace(a/2, y_dim*a-a/2, num=y_dim) xx, yy = np.meshgrid(x, y) # Return phase: - return phi_mag(xx, yy) + return PhaseMap(a, phi_mag(xx, yy)) def phase_mag_sphere(dim, a, phi, center, radius, b_0=1): @@ -161,7 +163,7 @@ def phase_mag_sphere(dim, a, phi, center, radius, b_0=1): y = np.linspace(a / 2, y_dim * a - a / 2, num=y_dim) xx, yy = np.meshgrid(x, y) # Return phase: - return phi_mag(xx, yy) + return PhaseMap(a, phi_mag(xx, yy)) def phase_mag_vortex(dim, a, center, radius, height, b_0=1): @@ -206,4 +208,4 @@ def phase_mag_vortex(dim, a, center, radius, height, b_0=1): y = np.linspace(a/2, y_dim*a-a/2, num=y_dim) xx, yy = np.meshgrid(x, y) # Return phase: - return phi_mag(xx, yy) + return PhaseMap(a, phi_mag(xx, yy)) diff --git a/pyramid/costfunction.py b/pyramid/costfunction.py index 3a5ac71ccbb5847c156094a2589bba203f45d491..6201f91519b23f5d0514c65383891aa41f7a055b 100644 --- a/pyramid/costfunction.py +++ b/pyramid/costfunction.py @@ -14,12 +14,14 @@ class Costfunction: # TODO: Docstring! def __init__(self, y, F): + '''TEST DOCSTRING FOR INIT''' # TODO: Docstring! self.y = y # TODO: get y from phasemaps! self.F = F # Forward Model self.Se_inv = np.eye(len(y)) def __call__(self, x): + '''TEST DOCSTRING FOR CALL''' # TODO: Docstring! y = self.y F = self.F diff --git a/pyramid/datacollection.py b/pyramid/datacollection.py index 43320b029c8811a94596cc9e88639af7b058fdf0..54d03710c8cd15678e414daa51f0c31742badd59 100644 --- a/pyramid/datacollection.py +++ b/pyramid/datacollection.py @@ -1,7 +1,10 @@ # -*- coding: utf-8 -*- -"""Class for the collection of phase maps and additional data.""" +"""This module provides the :class:`~.DataCollection` class for the collection of phase maps +and additional data like corresponding projectors.""" +import logging + import numpy as np from numbers import Number @@ -11,6 +14,29 @@ from pyramid.projector import Projector class DataCollection(object): + '''Class for collecting phase maps and corresponding projectors. + + Represents a collection of (e.g. experimentally derived) phase maps, stored as + :class:´~.PhaseMap´ objects and corresponding projectors stored as :class:`~.Projector` + objects. At creation, the grid spacing `a` and the dimension `dim` of the projected grid. + Data can be added via the :func:`~.append` method, where a :class:`~.PhaseMap` and a + :class:`~.Projector` have to be given as tuple argument. + + Attributes + ---------- + a: float + The grid spacing in nm. + dim: tuple (N=2) + Dimensions of the projected grid. + phase_maps: + A list of all stored :class:`~.PhaseMap` objects. + projectors: + A list of all stored :class:`~.Projector` objects. + phase_vec: :class:`~numpy.ndarray` (N=1) + The concatenaded, vectorized phase of all ;class:`~.PhaseMap` objects. + + ''' + @property def a(self): return self._a @@ -32,7 +58,8 @@ class DataCollection(object): return [d[1] for d in self.data] def __init__(self, a, dim): - # TODO: Docstring! + self.log = logging.getLogger(__name__) + self.log.info('Creating '+str(self)) assert isinstance(a, Number), 'Grid spacing has to be a number!' assert a >= 0, 'Grid spacing has to be a positive number!' self._a = a @@ -41,8 +68,30 @@ class DataCollection(object): self.dim = dim self.data = [] + def __repr__(self): + self.log.info('Calling __repr__') + return '%s(a=%r, dim=%r)' % (self.__class__, self.a, self.dim) + + def __str__(self): + self.log.info('Calling __str__') + return 'DataCollection(a=%s, dim=%s, data_count=%s)' % \ + (self.__class__, self.a, self.dim, len(self.phase_maps)) + def append(self, (phase_map, projector)): - # TODO: Docstring! + '''Appends a data pair of phase map and projection infos to the data collection.` + + Parameters + ---------- + (phase_map, projector): tuple (N=2) + tuple which contains a :class:`~.PhaseMap` object and a :class:`~.Projector` object, + which should be added to the data collection. + + Returns + ------- + None + + ''' + self.log.info('Calling append') assert isinstance(phase_map, PhaseMap) and isinstance(projector, Projector), \ 'Argument has to be a tuple of a PhaseMap and a Projector object!' assert phase_map.dim == self.dim, 'Added phasemap must have the same dimension!' diff --git a/pyramid/kernel.py b/pyramid/kernel.py index 2f1a0735f2108b2ad37246af68def8d908388a90..b8653e36c52921f926ce28095260640f4c230988 100644 --- a/pyramid/kernel.py +++ b/pyramid/kernel.py @@ -1,30 +1,35 @@ # -*- coding: utf-8 -*- -"""Class for the calculation and storage of kernel. +"""This module provides the :class:`~.Kernel` class, representing the phase contribution of one +single magnetized pixel.""" -This module provides the :class:`~.Kernel` class whose instances can be used to calculate and -store the kernel matrix representing the phase of a single pixel for the convolution used in the -phase calculation. The phasemap of a single pixel for two orthogonal directions (`u` and `v`) are -stored seperately as 2-dimensional matrices. The Jacobi matrix of the phasemapping just depends -on the kernel and can be calculated via the :func:`~.get_jacobi` function. Storing the Jacobi -matrix uses much memory, thus it is also possible to directly get the multiplication of a given -vector with the (transposed) Jacobi matrix without explicit calculation of the latter. -It is possible to load data from and save them to NetCDF4 files. See :class:`~.Kernel` for further -information. - -""" +import logging import numpy as np -import pyramid.numcore as nc +import pyramid.numcore.kernel_core as core PHI_0 = -2067.83 # magnetic flux in T*nm² # TODO: sign? -class Kernel: +class Kernel(object): + '''Class for calculating kernel matrices for the phase calculation. + + + + This module provides the :class:`~.Kernel` class whose instances can be used to calculate and + store the kernel matrix representing the phase of a single pixel for the convolution used in the + phase calculation. The phasemap of a single pixel for two orthogonal directions (`u` and `v`) are + stored seperately as 2-dimensional matrices. The Jacobi matrix of the phasemapping just depends + on the kernel and can be calculated via the :func:`~.get_jacobi` function. Storing the Jacobi + matrix uses much memory, thus it is also possible to directly get the multiplication of a given + vector with the (transposed) Jacobi matrix without explicit calculation of the latter. + It is possible to load data from and save them to NetCDF4 files. See :class:`~.Kernel` for further + information. + Represents the phase of a single magnetized pixel for two orthogonal directions (`u` and `v`), which can be accessed via the corresponding attributes. The default elementary geometry is @@ -32,6 +37,18 @@ class Kernel: magnetized pixel. During the construction, a few attributes are calculated that are used in the convolution during phase calculation. + + An instance `kernel` of the :class:`~.Kernel` class is callable via: + + .. :function:: kernel(vector) + + do stuff + + :param str sender: do other stuff + :return: nix + + with `vector` being a :class:`~numpy.ndarray` (N=1). + Attributes ---------- dim : tuple (N=2) @@ -56,7 +73,7 @@ class Kernel: and increasing to the next multiple of 2 (for faster FFT). slice_fft : tuple (N=2) of :class:`slice` A tuple of :class:`slice` objects to extract the original field of view from the increased - size (size_fft) of the grid for the FFT-convolution. + size (`size_fft`) of the grid for the FFT-convolution. '''# TODO: Can be used for several PhaseMappers via the fft arguments or via calling! @@ -75,6 +92,8 @@ class Kernel: The elementary geometry of the single magnetized pixel. ''' # TODO: Docstring + self.log = logging.getLogger(__name__) + self.log.info('Calling __init__') # TODO: Check if b_0 has an influence or is forgotten # Function for the phase of an elementary geometry: def get_elementary_phase(geometry, n, m, a): @@ -95,7 +114,7 @@ class Kernel: self.geometry = geometry self.b_0 = b_0 # Calculate kernel (single pixel phase): - coeff = -a**2 / (2*PHI_0) + coeff = -a**2 * b_0 / (2*PHI_0) v_dim, u_dim = dim u = np.linspace(-(u_dim-1), u_dim-1, num=2*u_dim-1) v = np.linspace(-(v_dim-1), v_dim-1, num=2*v_dim-1) @@ -108,22 +127,33 @@ class Kernel: self.slice_fft = (slice(dim[0]-1, 2*dim[0]-1), slice(dim[1]-1, 2*dim[1]-1)) self.u_fft = np.fft.rfftn(self.u, self.dim_fft) self.v_fft = np.fft.rfftn(self.v, self.dim_fft) + self.log.info('Created '+str(self)) def __call__(self, x): + '''Test''' + self.log.info('Calling __call__') if self.numcore: return self._multiply_jacobi_core(x) else: return self._multiply_jacobi(x) # TODO: Bei __init__ variable auf die entsprechende Funktion setzen. + def __repr__(self): + self.log.info('Calling __repr__') + return '%s(a=%r, dim=%r, b_0=%r, numcore=%r, geometry=%r)' % \ + (self.__class__, self.a, self.dim, self.b_0, self.numcore, self.geometry) - def jac_dot(self, vector): + def jac_dot(self, vector): + '''TEST'''# TODO: Docstring + self.log.info('Calling jac_dot') if self.numcore: return self._multiply_jacobi_core(vector) else: return self._multiply_jacobi(vector) def jac_T_dot(self, vector): + # TODO: Docstring + self.log.info('Calling jac_dot_T') return self._multiply_jacobi_T(vector) def _multiply_jacobi(self, vector): @@ -141,7 +171,8 @@ class Kernel: result : :class:`~numpy.ndarray` (N=1) Product of the Jacobi matrix (which is not explicitely calculated) with the vector. - ''' + '''# TODO: move! + self.log.info('Calling _multiply_jacobi') v_dim, u_dim = self.dim size = v_dim * u_dim assert len(vector) == 2*size, 'vector size not compatible!' @@ -173,7 +204,8 @@ class Kernel: Product of the transposed Jacobi matrix (which is not explicitely calculated) with the vector. - ''' + '''# TODO: move! + self.log.info('Calling _multiply_jacobi_T') v_dim, u_dim = self.dim size = v_dim * u_dim assert len(vector) == size, 'vector size not compatible!' @@ -190,7 +222,7 @@ class Kernel: return result def _multiply_jacobi_core(self, vector): - # TODO: Docstring! + self.log.info('Calling _multiply_jacobi_core') result = np.zeros(np.prod(self.dim)) - nc.multiply_jacobi_core(self.dim[0], self.dim[1], self.u, self.v, vector, result) + core.multiply_jacobi_core(self.dim[0], self.dim[1], self.u, self.v, vector, result) return result diff --git a/pyramid/logging.ini b/pyramid/logging.ini index 0803943502b3aeaab94b50e11cd8d72e5748b84e..266c37587b5288c8d796dfc92c4025f405264fba 100644 --- a/pyramid/logging.ini +++ b/pyramid/logging.ini @@ -9,7 +9,7 @@ class=logging.Formatter [formatter_file] format=%(asctime)s: %(levelname)-8s @ <%(name)s>: %(message)s -datefmt=%Y-%m-%d H:%M:%S +datefmt=%Y-%m-%d %H:%M:%S class=logging.Formatter [handlers] @@ -25,7 +25,7 @@ args=tuple() class=logging.FileHandler level=INFO formatter=file -args=('../output/logfile.log', 'w') +args=('logfile.log', 'w') [loggers] keys=root diff --git a/pyramid/magdata.py b/pyramid/magdata.py index 30cc4ac2a30fc8e3c2e5ac5ad1516cf89b1283d6..0dc7044b92183182a680aeb5c9d6ce32852c8163 100644 --- a/pyramid/magdata.py +++ b/pyramid/magdata.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 -*- -"""Class for the storage of magnetizatin data.""" +"""This module provides the :class:`~.MagData` class for storing of magnetization data.""" +import logging import numpy as np +from scipy.ndimage.interpolation import zoom import matplotlib.pyplot as plt from matplotlib.ticker import MaxNLocator - from mayavi import mlab from numbers import Number @@ -20,30 +21,28 @@ class MagData(object): Represents 3-dimensional magnetic distributions with 3 components which are stored as a 2-dimensional numpy array in `magnitude`, but which can also be accessed as a vector via - `mag_vec`. :class:`~.MagData` objects support arithmetic operators (``+``, ``-``, ``*``, ``/``) - and their augmented counterparts (``+=``, ``-=``, ``*=``, ``/=``), with numbers and other - :class:`~.MagData` objects, if their dimensions and grid spacings match. It is possible to load - data from NetCDF4 or LLG (.txt) files or to save the data in these formats. Plotting methods - are also provided. + `mag_vec`. :class:`~.MagData` objects support negation, arithmetic operators + (``+``, ``-``, ``*``) and their augmented counterparts (``+=``, ``-=``, ``*=``), with numbers + and other :class:`~.MagData` objects, if their dimensions and grid spacings match. It is + possible to load data from NetCDF4 or LLG (.txt) files or to save the data in these formats. + Plotting methods are also provided. Attributes ---------- - a : float + a: float The grid spacing in nm. - dim : tuple (N=3) + dim: tuple (N=3) Dimensions (z, y, x) of the grid. - magnitude : :class:`~numpy.ndarray` (N=4) + magnitude: :class:`~numpy.ndarray` (N=4) The `x`-, `y`- and `z`-component of the magnetization vector for every 3D-gridpoint as a 4-dimensional numpy array (first dimension has to be 3, because of the 3 components). mag_vec: :class:`~numpy.ndarray` (N=1) Vector containing the magnetic distribution. ''' - - # TODO: Implement: __str__ or __repr__ - - # TODO: Implement: logging - + + log = logging.getLogger() + @property def a(self): return self._a @@ -81,57 +80,94 @@ class MagData(object): self.magnitude = mag_vec.reshape((3,)+self.dim) def __init__(self, a, magnitude): + self.log = logging.getLogger(__name__) + self.log.info('Calling __init__') self.a = a - self.magnitude = magnitude + self.magnitude = magnitude + self.log.info('Created '+str(self)) + + def __getstate__(self): + d = dict(self.__dict__) + del d['log'] + return d + + def __setstate__(self, d): + self.__dict__.update(d) + self.log = logging.getLogger(__name__) + + def __repr__(self): + self.log.info('Calling __repr__') + return '%s(a=%r, magnitude=%r)' % (self.__class__, self.a, self.magnitude) + + def __str__(self): + self.log.info('Calling __str__') + return 'MagData(a=%s, dim=%s)' % (self.a, self.dim) def __neg__(self): # -self + self.log.info('Calling __neg__') return MagData(self.a, -self.magnitude) def __add__(self, other): # self + other + self.log.info('Calling __add__') assert isinstance(other, (MagData, Number)), \ 'Only MagData objects and scalar numbers (as offsets) can be added/subtracted!' if isinstance(other, MagData): + self.log.info('Adding two MagData objects') assert other.a == self.a, 'Added phase has to have the same grid spacing!' assert other.magnitude.shape == (3,)+self.dim, \ 'Added magnitude has to have the same dimensions!' return MagData(self.a, self.magnitude+other.magnitude) else: # other is a Number + self.log.info('Adding an offset') return MagData(self.a, self.magnitude+other) def __sub__(self, other): # self - other + self.log.info('Calling __sub__') return self.__add__(-other) def __mul__(self, other): # self * other + self.log.info('Calling __mul__') assert isinstance(other, Number), 'MagData objects can only be multiplied by numbers!' return MagData(self.a, other*self.magnitude) - def __div__(self, other): # self / other - assert other != 0, 'Division by zero!' - return self.__mul__(1./other) - # TODO: Does not work, but why? - def __radd__(self, other): # other + self + self.log.info('Calling __radd__') return self.__add__(other) def __rsub__(self, other): # other - self + self.log.info('Calling __rsub__') return -self.__sub__(other) def __rmul__(self, other): # other * self + self.log.info('Calling __rmul__') return self.__mul__(other) def __iadd__(self, other): # self += other + self.log.info('Calling __iadd__') return self.__add__(other) def __isub__(self, other): # self -= other + self.log.info('Calling __isub__') return self.__sub__(other) def __imul__(self, other): # self *= other + self.log.info('Calling __imul__') return self.__mul__(other) - - def __idiv__(self, other): # self /= other - return self.__div__(other) def copy(self): + '''Returns a copy of the :class:`~.MagData` object + + Parameters + ---------- + None + + Returns + ------- + mag_data: :class:`~.MagData` + A copy of the :class:`~.MagData`. + + ''' + self.log.info('Calling copy7') return MagData(self.a, self.magnitude.copy()) def scale_down(self, n=1): @@ -152,12 +188,32 @@ class MagData(object): Only possible, if each axis length is a power of 2! ''' + self.log.info('Calling scale_down') assert n > 0 and isinstance(n, (int, long)), 'n must be a positive integer!' assert np.all([d % 2**n == 0 for d in self.dim]), 'Dimensions must a multiples of 2!' + self.a = self.a * 2**n for t in range(n): # Create coarser grid for the magnetization: self.magnitude = self.magnitude.reshape( 3, self.dim[0]/2, 2, self.dim[1]/2, 2, self.dim[2]/2, 2).mean(axis=(6, 4, 2)) + + + def scale_up(self, n=1, order=0): + # TODO: Docstring! + self.log.info('Calling scale_up') + assert n > 0 and isinstance(n, (int, long)), 'n must be a positive integer!' + assert 5 > order >= 0 and isinstance(order, (int, long)), \ + 'order must be a positive integer between 0 and 5!' + self.a = self.a / 2**n + self.magnitude = np.array((zoom(self.magnitude[0], zoom=2**n, order=order), + zoom(self.magnitude[1], zoom=2**n, order=order), + zoom(self.magnitude[2], zoom=2**n, order=order))) + + def pad(self, x_pad, y_pad, z_pad): + # TODO: Docstring! + self.magnitude = np.pad(self.magnitude, + ((0, 0), (z_pad, z_pad), (y_pad, y_pad), (x_pad, x_pad)), + mode='constant', constant_values=0) def save_to_llg(self, filename='..\output\magdata_output.txt'): '''Save magnetization data in a file with LLG-format. @@ -173,6 +229,7 @@ class MagData(object): None ''' + self.log.info('Calling save_to_llg') a = self.a * 1.0E-9 / 1.0E-2 # from nm to cm # Create 3D meshgrid and reshape it and the magnetization into a list where x varies first: zz, yy, xx = np.mgrid[a/2:(self.dim[0]*a-a/2):self.dim[0]*1j, @@ -202,6 +259,7 @@ class MagData(object): A :class:`~.MagData` object containing the loaded data. ''' + cls.log.info('Calling load_from_llg') SCALE = 1.0E-9 / 1.0E-2 # From cm to nm data = np.genfromtxt(filename, skip_header=2) dim = tuple(np.genfromtxt(filename, dtype=int, skip_header=1, skip_footer=len(data[:, 0]))) @@ -223,6 +281,7 @@ class MagData(object): None ''' + self.log.info('Calling save_to_netcdf4') mag_file = netCDF4.Dataset(filename, 'w', format='NETCDF4') mag_file.a = self.a mag_file.createDimension('comp', 3) # Number of components @@ -248,6 +307,7 @@ class MagData(object): A :class:`~.MagData` object containing the loaded data. ''' + cls.log.info('Calling copy') mag_file = netCDF4.Dataset(filename, 'r', format='NETCDF4') a = mag_file.a magnitude = mag_file.variables['magnitude'][...] @@ -279,24 +339,31 @@ class MagData(object): The axis on which the graph is plotted. ''' + self.log.info('Calling quiver_plot') assert proj_axis == 'z' or proj_axis == 'y' or proj_axis == 'x', \ 'Axis has to be x, y or z (as string).' if proj_axis == 'z': # Slice of the xy-plane with z = ax_slice + self.log.info('proj_axis == z') if ax_slice is None: + self.log.info('ax_slice is None') ax_slice = int(self.dim[0]/2) mag_slice_u = self.magnitude[0][ax_slice, ...] # x-component mag_slice_v = self.magnitude[1][ax_slice, ...] # y-component u_label = 'x [px]' v_label = 'y [px]' elif proj_axis == 'y': # Slice of the xz-plane with y = ax_slice + self.log.info('proj_axis == y') if ax_slice is None: + self.log.info('ax_slice is None') ax_slice = int(self.dim[1]/2) mag_slice_u = self.magnitude[0][:, ax_slice, :] # x-component mag_slice_v = self.magnitude[2][:, ax_slice, :] # z-component u_label = 'x [px]' v_label = 'z [px]' elif proj_axis == 'x': # Slice of the yz-plane with x = ax_slice + self.log.info('proj_axis == x') if ax_slice is None: + self.log.info('ax_slice is None') ax_slice = int(self.dim[2]/2) mag_slice_u = self.magnitude[1][..., ax_slice] # y-component mag_slice_v = self.magnitude[2][..., ax_slice] # z-component @@ -304,6 +371,7 @@ class MagData(object): v_label = 'z [px]' # If no axis is specified, a new figure is created: if axis is None: + self.log.info('axis is None') fig = plt.figure(figsize=(8.5, 7)) axis = fig.add_subplot(1, 1, 1, aspect='equal') axis.quiver(mag_slice_u, mag_slice_v, pivot='middle', angles='xy', scale_units='xy', @@ -331,6 +399,7 @@ class MagData(object): None ''' + self.log.info('Calling quiver_plot3D') a = self.a dim = self.dim # Create points and vector components as lists: @@ -345,7 +414,7 @@ class MagData(object): z_mag = np.reshape(self.magnitude[2], (-1)) # Plot them as vectors: mlab.figure() - plot = mlab.quiver3d(xx, yy, zz, x_mag, y_mag, z_mag, mode='arrow')#, scale_factor=5.0) + plot = mlab.quiver3d(xx, yy, zz, x_mag, y_mag, z_mag, mode='arrow') mlab.outline(plot) mlab.axes(plot) mlab.colorbar() diff --git a/pyramid/numcore/__init__.py b/pyramid/numcore/__init__.py index df89b8e95b165b037eba1bbe18824f3a3d219f9e..fd8ed341b1fb38e8aa62c63d1398301b0745be86 100644 --- a/pyramid/numcore/__init__.py +++ b/pyramid/numcore/__init__.py @@ -11,5 +11,3 @@ Notes Packages are written in `pyx`-format for the use with :mod:`~cython`. """ - -from phase_mag_real import * diff --git a/pyramid/optimizer.py b/pyramid/optimizer.py index b2d0aff814ca6d7807dc9822fe6df3cc67c0ae2d..ca226018246a2f56eb2f7459c4e0c63cda1d17ed 100644 --- a/pyramid/optimizer.py +++ b/pyramid/optimizer.py @@ -56,85 +56,85 @@ def optimize_cg(self, data_collection, first_guess): # TODO: Implement the following: -# -*- coding: utf-8 -*- -"""Reconstruct magnetic distributions from given phasemaps. - -This module reconstructs 3-dimensional magnetic distributions (as :class:`~pyramid.magdata.MagData` -objects) from a given set of phase maps (represented by :class:`~pyramid.phasemap.PhaseMap` -objects) by using several model based reconstruction algorithms which use the forward model -provided by :mod:`~pyramid.projector` and :mod:`~pyramid.phasemapper` and a priori knowledge of -the distribution. -So far, only a simple least square algorithm for known pixel locations for 2-dimensional problems -is implemented (:func:`~.reconstruct_simple_leastsq`), but more complex solutions are planned. - -""" - - - -import numpy as np - -from scipy.optimize import leastsq - -import pyramid.projector as pj -import pyramid.phasemapper as pm -from pyramid.magdata import MagData -from pyramid.projector import Projection -from pyramid.kernel import Kernel - - -def reconstruct_simple_leastsq(phase_map, mask, b_0=1): - '''Reconstruct a magnetic distribution for a 2-D problem with known pixel locations. - - Parameters - ---------- - phase_map : :class:`~pyramid.phasemap.PhaseMap` - A :class:`~pyramid.phasemap.PhaseMap` object, representing the phase from which to - reconstruct the magnetic distribution. - mask : :class:`~numpy.ndarray` (N=3) - A boolean matrix (or a matrix consisting of ones and zeros), representing the - positions of the magnetized voxels in 3 dimensions. - b_0 : float, optional - The magnetic induction corresponding to a magnetization `M`\ :sub:`0` in T. - The default is 1. - Returns - ------- - mag_data : :class:`~pyramid.magdata.MagData` - The reconstructed magnetic distribution as a - :class:`~pyramid.magdata.MagData` object. - - Notes - ----- - Only works for a single phase_map, if the positions of the magnetized voxels are known and - for slice thickness of 1 (constraint for the `z`-dimension). - - ''' - # Read in parameters: - y_m = phase_map.phase.reshape(-1) # Measured phase map as a vector - a = phase_map.a # Grid spacing - dim = mask.shape # Dimensions of the mag. distr. - count = mask.sum() # Number of pixels with magnetization - lam = 1e-6 # Regularisation parameter - # Create empty MagData object for the reconstruction: - mag_data_rec = MagData(a, (np.zeros(dim), np.zeros(dim), np.zeros(dim))) - - # Function that returns the phase map for a magnetic configuration x: - def F(x): - mag_data_rec.set_vector(mask, x) - phase = pm.phase_mag_real(a, pj.simple_axis_projection(mag_data_rec), b_0) - return phase.reshape(-1) - - # Cost function which should be minimized: - def J(x_i): - y_i = F(x_i) - term1 = (y_i - y_m) - term2 = lam * x_i - return np.concatenate([term1, term2]) - - # Reconstruct the magnetization components: - x_rec, _ = leastsq(J, np.zeros(3*count)) - mag_data_rec.set_vector(mask, x_rec) - return mag_data_rec - -def reconstruct_test(): - product = (kernel.multiply_jacobi_T(projection.multiply_jacobi_T(x)) - * kernel.multiply_jacobi(projection.multiply_jacobi(x))) \ No newline at end of file +## -*- coding: utf-8 -*- +#"""Reconstruct magnetic distributions from given phasemaps. +# +#This module reconstructs 3-dimensional magnetic distributions (as :class:`~pyramid.magdata.MagData` +#objects) from a given set of phase maps (represented by :class:`~pyramid.phasemap.PhaseMap` +#objects) by using several model based reconstruction algorithms which use the forward model +#provided by :mod:`~pyramid.projector` and :mod:`~pyramid.phasemapper` and a priori knowledge of +#the distribution. +#So far, only a simple least square algorithm for known pixel locations for 2-dimensional problems +#is implemented (:func:`~.reconstruct_simple_leastsq`), but more complex solutions are planned. +# +#""" +# +# +# +#import numpy as np +# +#from scipy.optimize import leastsq +# +#import pyramid.projector as pj +#import pyramid.phasemapper as pm +#from pyramid.magdata import MagData +#from pyramid.projector import Projection +#from pyramid.kernel import Kernel +# +# +#def reconstruct_simple_leastsq(phase_map, mask, b_0=1): +# '''Reconstruct a magnetic distribution for a 2-D problem with known pixel locations. +# +# Parameters +# ---------- +# phase_map : :class:`~pyramid.phasemap.PhaseMap` +# A :class:`~pyramid.phasemap.PhaseMap` object, representing the phase from which to +# reconstruct the magnetic distribution. +# mask : :class:`~numpy.ndarray` (N=3) +# A boolean matrix (or a matrix consisting of ones and zeros), representing the +# positions of the magnetized voxels in 3 dimensions. +# b_0 : float, optional +# The magnetic induction corresponding to a magnetization `M`\ :sub:`0` in T. +# The default is 1. +# Returns +# ------- +# mag_data : :class:`~pyramid.magdata.MagData` +# The reconstructed magnetic distribution as a +# :class:`~pyramid.magdata.MagData` object. +# +# Notes +# ----- +# Only works for a single phase_map, if the positions of the magnetized voxels are known and +# for slice thickness of 1 (constraint for the `z`-dimension). +# +# ''' +# # Read in parameters: +# y_m = phase_map.phase.reshape(-1) # Measured phase map as a vector +# a = phase_map.a # Grid spacing +# dim = mask.shape # Dimensions of the mag. distr. +# count = mask.sum() # Number of pixels with magnetization +# lam = 1e-6 # Regularisation parameter +# # Create empty MagData object for the reconstruction: +# mag_data_rec = MagData(a, (np.zeros(dim), np.zeros(dim), np.zeros(dim))) +# +# # Function that returns the phase map for a magnetic configuration x: +# def F(x): +# mag_data_rec.set_vector(mask, x) +# phase = pm.phase_mag_real(a, pj.simple_axis_projection(mag_data_rec), b_0) +# return phase.reshape(-1) +# +# # Cost function which should be minimized: +# def J(x_i): +# y_i = F(x_i) +# term1 = (y_i - y_m) +# term2 = lam * x_i +# return np.concatenate([term1, term2]) +# +# # Reconstruct the magnetization components: +# x_rec, _ = leastsq(J, np.zeros(3*count)) +# mag_data_rec.set_vector(mask, x_rec) +# return mag_data_rec +# +#def reconstruct_test(): +# product = (kernel.multiply_jacobi_T(projection.multiply_jacobi_T(x)) +# * kernel.multiply_jacobi(projection.multiply_jacobi(x))) \ No newline at end of file diff --git a/pyramid/phasemap.py b/pyramid/phasemap.py index 6964ded5353fd3c567b3838b0ba12f3f4c7339a3..293dd6359cbf3ac19052248bb8a74335964eda77 100644 --- a/pyramid/phasemap.py +++ b/pyramid/phasemap.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- -"""Class for the storage of phase data.""" +"""This module provides the :class:`~.PhaseMap` class for storing phase map data.""" +import logging + import numpy as np from numpy import pi @@ -22,8 +24,8 @@ class PhaseMap(object): Represents 2-dimensional phase maps. The phase information itself is stored as a 2-dimensional matrix in `phase`, but can also be accessed as a vector via `phase_vec`. :class:`~.PhaseMap` - objects support arithmetic operators (``+``, ``-``, ``*``, ``/``) and their augmented - counterparts (``+=``, ``-=``, ``*=``, ``/=``), with numbers and other :class:`~.PhaseMap` + objects support negation, arithmetic operators (``+``, ``-``, ``*``) and their augmented + counterparts (``+=``, ``-=``, ``*=``), with numbers and other :class:`~.PhaseMap` objects, if their dimensions and grid spacings match. It is possible to load data from NetCDF4 or textfiles or to save the data in these formats. Methods for plotting the phase or a corresponding holographic contour map are provided. Holographic contour maps are created by @@ -34,44 +36,65 @@ class PhaseMap(object): Attributes ---------- - a : float + a: float The grid spacing in nm. - dim : tuple (N=2) + dim: tuple (N=2) Dimensions of the grid. - phase : :class:`~numpy.ndarray` (N=2) + phase: :class:`~numpy.ndarray` (N=2) Matrix containing the phase shift. phase_vec: :class:`~numpy.ndarray` (N=2) Vector containing the phase shift. - unit : {'rad', 'mrad', 'µrad'}, optional - Set the unit of the phase map. This is important for the :func:`~.display` function, + unit: {'rad', 'mrad'}, optional + Set the unit of the phase map. This is important for the :func:`display` function, because the phase is scaled accordingly. Does not change the phase itself, which is always in `rad`. ''' - UNITDICT = {'rad': 1E0, - 'mrad': 1E3, - 'µrad': 1E6} - - CDICT = {'red': [(0.00, 1.0, 0.0), - (0.25, 1.0, 1.0), - (0.50, 1.0, 1.0), - (0.75, 0.0, 0.0), - (1.00, 0.0, 1.0)], - - 'green': [(0.00, 0.0, 0.0), - (0.25, 0.0, 0.0), - (0.50, 1.0, 1.0), - (0.75, 1.0, 1.0), - (1.00, 0.0, 1.0)], - - 'blue': [(0.00, 1.0, 1.0), - (0.25, 0.0, 0.0), - (0.50, 0.0, 0.0), - (0.75, 0.0, 0.0), - (1.00, 1.0, 1.0)]} + log = logging.getLogger(__name__) + + UNITDICT = {u'rad': 1E0, + u'mrad': 1E3, + u'µrad': 1E6} + + CDICT = {'red': [(0.00, 1.0, 0.0), + (0.25, 1.0, 1.0), + (0.50, 1.0, 1.0), + (0.75, 0.0, 0.0), + (1.00, 0.0, 1.0)], + + 'green': [(0.00, 0.0, 0.0), + (0.25, 0.0, 0.0), + (0.50, 1.0, 1.0), + (0.75, 1.0, 1.0), + (1.00, 0.0, 1.0)], + + 'blue': [(0.00, 1.0, 1.0), + (0.25, 0.0, 0.0), + (0.50, 0.0, 0.0), + (0.75, 0.0, 0.0), + (1.00, 1.0, 1.0)]} + + CDICT_INV = {'red': [(0.00, 0.0, 1.0), + (0.25, 0.0, 0.0), + (0.50, 0.0, 0.0), + (0.75, 1.0, 1.0), + (1.00, 1.0, 0.0)], + + 'green': [(0.00, 1.0, 1.0), + (0.25, 1.0, 1.0), + (0.50, 0.0, 0.0), + (0.75, 0.0, 0.0), + (1.00, 1.0, 0.0)], + + 'blue': [(0.00, 0.0, 0.0), + (0.25, 1.0, 1.0), + (0.50, 1.0, 1.0), + (0.75, 1.0, 1.0), + (1.00, 0.0, 0.0)]} HOLO_CMAP = mpl.colors.LinearSegmentedColormap('my_colormap', CDICT, 256) + HOLO_CMAP_INV = mpl.colors.LinearSegmentedColormap('my_colormap', CDICT_INV, 256) @property def a(self): @@ -121,52 +144,69 @@ class PhaseMap(object): self.a = a self.phase = phase self.unit = unit + self.log = logging.getLogger(__name__) + self.log.info('Created '+str(self)) + + def __repr__(self): + self.log.info('Calling __repr__') + return '%s(a=%r, phase=%r, unit=&r)' % \ + (self.__class__, self.a, self.phase, self.unit) + + def __str__(self): + self.log.info('Calling __str__') + return 'PhaseMap(a=%s, dim=%s)' % (self.a, self.dim) def __neg__(self): # -self + self.log.info('Calling __neg__') return PhaseMap(self.a, -self.phase, self.unit) def __add__(self, other): # self + other + self.log.info('Calling __add__') assert isinstance(other, (PhaseMap, Number)), \ 'Only PhaseMap objects and scalar numbers (as offsets) can be added/subtracted!' if isinstance(other, PhaseMap): + self.log.info('Adding two PhaseMap objects') assert other.a == self.a, 'Added phase has to have the same grid spacing!' assert other.phase.shape == self.dim, \ 'Added magnitude has to have the same dimensions!' return PhaseMap(self.a, self.phase+other.phase, self.unit) else: # other is a Number + self.log.info('Adding an offset') return PhaseMap(self.a, self.phase+other, self.unit) def __sub__(self, other): # self - other + self.log.info('Calling __sub__') return self.__add__(-other) def __mul__(self, other): # self * other + self.log.info('Calling __mul__') assert isinstance(other, Number), 'PhaseMap objects can only be multiplied by numbers!' return PhaseMap(self.a, other*self.phase, self.unit) - def __div__(self, other): # self / other - return self.__mul__(1.0/other) - def __radd__(self, other): # other + self + self.log.info('Calling __radd__') return self.__add__(other) def __rsub__(self, other): # other - self + self.log.info('Calling __rsub__') return -self.__sub__(other) def __rmul__(self, other): # other * self + self.log.info('Calling __rmul__') return self.__mul__(other) def __iadd__(self, other): # self += other + self.log.info('Calling __iadd__') return self.__add__(other) def __isub__(self, other): # self -= other + self.log.info('Calling __isub__') return self.__sub__(other) def __imul__(self, other): # self *= other + self.log.info('Calling __imul__') return self.__mul__(other) - def __idiv__(self, other): # self /= other - return self.__div__(other) - def save_to_txt(self, filename='..\output\phasemap_output.txt'): '''Save :class:`~.PhaseMap` data in a file with txt-format. @@ -181,6 +221,7 @@ class PhaseMap(object): None ''' + self.log.info('Calling save_to_txt') with open(filename, 'w') as phase_file: phase_file.write('{}\n'.format(filename.replace('.txt', ''))) phase_file.write('grid spacing = {} nm\n'.format(self.a)) @@ -201,6 +242,7 @@ class PhaseMap(object): A :class:`~.PhaseMap` object containing the loaded data. ''' + cls.log.info('Calling load_from_txt') with open(filename, 'r') as phase_file: phase_file.readline() # Headerline is not used a = float(phase_file.readline()[15:-4]) @@ -221,6 +263,7 @@ class PhaseMap(object): None ''' + self.log.info('Calling save_to_netcdf4') phase_file = netCDF4.Dataset(filename, 'w', format='NETCDF4') phase_file.a = self.a phase_file.createDimension('v_dim', self.dim[0]) @@ -244,13 +287,15 @@ class PhaseMap(object): A :class:`~.PhaseMap` object containing the loaded data. ''' + cls.log.info('Calling load_from_netcdf4') phase_file = netCDF4.Dataset(filename, 'r', format='NETCDF4') a = phase_file.a phase = phase_file.variables['phase'][:] phase_file.close() return PhaseMap(a, phase) - def display_phase(self, title='Phase Map', cmap='RdBu', limit=None, norm=None, axis=None): + def display_phase(self, title='Phase Map', cmap='RdBu', + limit=None, norm=None, axis=None, show=True): '''Display the phasemap as a colormesh. Parameters @@ -268,6 +313,8 @@ class PhaseMap(object): If not specified, :class:`~matplotlib.colors.Normalize` is automatically used. axis : :class:`~matplotlib.axes.AxesSubplot`, optional Axis on which the graph is plotted. Creates a new figure if none is specified. + show : bool, optional + A switch which determines if the plot is shown at the end of plotting. Returns ------- @@ -275,6 +322,7 @@ class PhaseMap(object): The axis on which the graph is plotted. ''' + self.log.info('Calling display_phase') # Take units into consideration: phase = self.phase * self.UNITDICT[self.unit] if limit is None: @@ -302,9 +350,10 @@ class PhaseMap(object): cbar_ax = fig.add_axes([0.82, 0.15, 0.02, 0.7]) cbar = fig.colorbar(im, cax=cbar_ax) cbar.ax.tick_params(labelsize=14) - cbar.set_label('phase shift [{}]'.format(self.unit), fontsize=15) + cbar.set_label(u'phase shift [{}]'.format(self.unit), fontsize=15) # Show plot: - plt.show() + if show: + plt.show() # Return plotting axis: return axis @@ -325,6 +374,7 @@ class PhaseMap(object): The axis on which the graph is plotted. ''' + self.log.info('Calling display_phase3d') # Take units into consideration: phase = self.phase * self.UNITDICT[self.unit] # Create figure and axis: @@ -347,7 +397,7 @@ class PhaseMap(object): return axis def display_holo(self, density=1, title='Holographic Contour Map', - axis=None, interpolation='none'): + axis=None, grad_encode='dark', interpolation='none', show=True): '''Display the color coded holography image. Parameters @@ -360,13 +410,16 @@ class PhaseMap(object): Axis on which the graph is plotted. Creates a new figure if none is specified. interpolation : {'none, 'bilinear', 'cubic', 'nearest'}, optional Defines the interpolation method. No interpolation is used in the default case. + show: bool, optional + A switch which determines if the plot is shown at the end of plotting. Returns ------- axis: :class:`~matplotlib.axes.AxesSubplot` The axis on which the graph is plotted. - ''' + '''# TODO: Docstring saturation! + self.log.info('Calling display_holo') # Calculate the holography image intensity: img_holo = (1 + np.cos(density * self.phase)) / 2 # Calculate the phase gradients, expressed by magnitude and angle: @@ -374,11 +427,24 @@ class PhaseMap(object): phase_angle = (1 - np.arctan2(phase_grad_y, phase_grad_x)/pi) / 2 phase_magnitude = np.hypot(phase_grad_x, phase_grad_y) if phase_magnitude.max() != 0: - phase_magnitude = np.sin(phase_magnitude/phase_magnitude.max() * pi / 2) + saturation = np.sin(phase_magnitude/phase_magnitude.max() * pi / 2) + phase_saturation = np.dstack((saturation,)*4) # Color code the angle and create the holography image: - rgba = self.HOLO_CMAP(phase_angle) - rgb = (255.999 * img_holo.T * phase_magnitude.T * rgba[:, :, :3].T).T.astype(np.uint8) - holo_image = Image.fromarray(rgb) + if grad_encode == 'dark': + rgba = self.HOLO_CMAP(phase_angle) + rgb = (255.999 * img_holo.T * saturation.T * rgba[:, :, :3].T).T.astype(np.uint8) + elif grad_encode == 'bright': + rgba = self.HOLO_CMAP(phase_angle)+(1-phase_saturation)*self.HOLO_CMAP_INV(phase_angle) + rgb = (255.999 * img_holo.T * rgba[:, :, :3].T).T.astype(np.uint8) + elif grad_encode == 'color': + rgba = self.HOLO_CMAP(phase_angle) + rgb = (255.999 * img_holo.T * rgba[:, :, :3].T).T.astype(np.uint8) + elif grad_encode == 'none': + rgba = self.HOLO_CMAP(phase_angle)+self.HOLO_CMAP_INV(phase_angle) + rgb = (255.999 * img_holo.T * rgba[:, :, :3].T).T.astype(np.uint8) + else: + raise AssertionError('Gradient encoding not recognized!') + holo_image = Image.fromarray(rgb) # If no axis is specified, a new figure is created: if axis is None: fig = plt.figure() @@ -397,11 +463,13 @@ class PhaseMap(object): axis.xaxis.set_major_locator(MaxNLocator(nbins=9, integer=True)) axis.yaxis.set_major_locator(MaxNLocator(nbins=9, integer=True)) # Show Plot: - plt.show() + if show: + plt.show() # Return plotting axis: return axis - def display_combined(self, density=1, title='Combined Plot', interpolation='none'): + def display_combined(self, density=1, title='Combined Plot', interpolation='none', + grad_encode='dark'): '''Display the phase map and the resulting color coded holography image in one plot. Parameters @@ -419,21 +487,25 @@ class PhaseMap(object): phase_axis, holo_axis: :class:`~matplotlib.axes.AxesSubplot` The axes on which the graphs are plotted. - ''' + '''# TODO: Docstring grad_encode! + self.log.info('Calling display_combined') # Create combined plot and set title: fig = plt.figure(figsize=(16, 7)) fig.suptitle(title, fontsize=20) # Plot holography image: holo_axis = fig.add_subplot(1, 2, 1, aspect='equal') - self.display_holo(density=density, axis=holo_axis, interpolation=interpolation) + self.display_holo(density=density, axis=holo_axis, interpolation=interpolation, + show=False, grad_encode=grad_encode) # Plot phase map: phase_axis = fig.add_subplot(1, 2, 2, aspect='equal') fig.subplots_adjust(right=0.85) - self.display_phase(axis=phase_axis) + self.display_phase(axis=phase_axis, show=False) + plt.show() # Return the plotting axes: return phase_axis, holo_axis - def make_color_wheel(self): + @classmethod + def make_color_wheel(cls): '''Display a color wheel to illustrate the color coding of the gradient direction. Parameters @@ -445,6 +517,7 @@ class PhaseMap(object): None ''' + cls.log.info('Calling make_color_wheel') x = np.linspace(-256, 256, num=512) y = np.linspace(-256, 256, num=512) xx, yy = np.meshgrid(x, y) @@ -454,7 +527,7 @@ class PhaseMap(object): color_wheel_magnitude *= 0 * (r > 256) + 1 * (r <= 256) color_wheel_angle = (1 - np.arctan2(xx, -yy)/pi) / 2 # Color code the angle and create the holography image: - rgba = self.HOLO_CMAP(color_wheel_angle) + rgba = cls.HOLO_CMAP(color_wheel_angle) rgb = (255.999 * color_wheel_magnitude.T * rgba[:, :, :3].T).T.astype(np.uint8) color_wheel = Image.fromarray(rgb) # Plot the color wheel: @@ -463,3 +536,7 @@ class PhaseMap(object): axis.imshow(color_wheel, origin='lower') axis.xaxis.set_major_locator(NullLocator()) axis.yaxis.set_major_locator(NullLocator()) + plt.show() + + +PhaseMap.make_color_wheel() diff --git a/pyramid/phasemapper.py b/pyramid/phasemapper.py index e6421d279f8b0299c46c7db831aee666ee62d56d..772e6faae8f1356f1321f18808ee0fcca58cd52c 100644 --- a/pyramid/phasemapper.py +++ b/pyramid/phasemapper.py @@ -14,7 +14,7 @@ from numpy import pi import abc -import pyramid.numcore as nc +import pyramid.numcore.kernel_core as nc from pyramid.kernel import Kernel from pyramid.projector import Projector from pyramid.magdata import MagData @@ -46,13 +46,13 @@ class PMAdapterFM(PhaseMapper): assert isinstance(projector, Projector), 'Argument has to be a Projector object!' self.a = a self.projector = projector - self.fwd_model = ForwardModel([projector], Kernel(a, projector.dim, b_0, geometry)) + self.fwd_model = ForwardModel([projector], Kernel(a, projector.dim_2d, b_0, geometry)) def __call__(self, mag_data): assert isinstance(mag_data, MagData), 'Only MagData objects can be mapped!' assert mag_data.a == self.a, 'Grid spacing has to match!' # TODO: test if mag_data fits in all aspects - phase_map = PhaseMap(self.a, np.zeros(self.projector.dim)) + phase_map = PhaseMap(self.a, np.zeros(self.projector.dim_2d)) phase_map.phase_vec = self.fwd_model(mag_data.mag_vec) return phase_map @@ -94,11 +94,12 @@ class PMFourier(PhaseMapper): assert isinstance(mag_data, MagData), 'Only MagData objects can be mapped!' assert mag_data.a == self.a, 'Grid spacing has to match!' # TODO: test if mag_data fits in all aspects (especially with projector) - v_dim, u_dim = self.projector.dim - u_mag, v_mag = self.projector(mag_data.mag_vec).reshape((2,)+self.projector.dim) + v_dim, u_dim = self.projector.dim_2d + u_mag, v_mag = self.projector(mag_data.mag_vec).reshape((2,)+self.projector.dim_2d) # Create zero padded matrices: u_pad = u_dim/2 * self.padding v_pad = v_dim/2 * self.padding + # TODO: use mag_data.padding or np.pad(...) u_mag_big = np.zeros(((1 + self.padding) * v_dim, (1 + self.padding) * u_dim)) v_mag_big = np.zeros(((1 + self.padding) * v_dim, (1 + self.padding) * u_dim)) u_mag_big[v_pad:v_pad+v_dim, u_pad:u_pad+u_dim] = u_mag @@ -218,12 +219,12 @@ class PMConvolve(PhaseMapper): self.a = a self.projector = projector self.threshold = threshold - self.kernel = Kernel(a, projector.dim, b_0, geometry) + self.kernel = Kernel(a, projector.dim_2d, b_0, geometry) def __call__(self, mag_data): # Docstring! # Process input parameters: - u_mag, v_mag = self.projector(mag_data.mag_vec).reshape((2,)+self.projector.dim) + u_mag, v_mag = self.projector(mag_data.mag_vec).reshape((2,)+self.projector.dim_2d) # Fourier transform the projected magnetisation: kernel = self.kernel u_mag_fft = np.fft.rfftn(u_mag, kernel.dim_fft) @@ -267,15 +268,14 @@ class PMReal(PhaseMapper): self.a = a self.projector = projector self.threshold = threshold - self.kernel = Kernel(a, projector.dim, b_0, geometry) + self.kernel = Kernel(a, projector.dim_2d, b_0, geometry) self.numcore = numcore def __call__(self, mag_data): # TODO: Docstring # Process input parameters: - dim = self.projector.dim + dim = self.projector.dim_2d threshold = self.threshold - v_dim, u_dim = self.projector.dim u_mag, v_mag = self.projector(mag_data.mag_vec).reshape((2,)+dim) # Create kernel (lookup-tables for the phase of one pixel): u_phi = self.kernel.u diff --git a/pyramid/projector.py b/pyramid/projector.py index 28538574af512f14876a13ca175238b3274a0744..85e86415f3f102859b3bcfc2dce931b301799060 100644 --- a/pyramid/projector.py +++ b/pyramid/projector.py @@ -1,13 +1,9 @@ # -*- coding: utf-8 -*- -"""Create projections of a given magnetization distribution. +"""This module provides the abstract base class :class:`~.Projector` and concrete subclasses for +projections of vector and scalar fields.""" -This module creates 2-dimensional projections from 3-dimensional magnetic distributions, which -are stored in :class:`~pyramid.magdata.MagData` objects. Either simple projections along the -major axes are possible (:func:`~.simple_axis_projection`), or projections with a tilt around -the y-axis. The thickness profile is also calculated and can be used for electric phase maps. - -""" +import logging import numpy as np from numpy import pi @@ -16,59 +12,68 @@ import abc import itertools -import scipy.sparse as sp -from scipy.sparse import coo_matrix, csr_matrix, csr_matrix - -from pyramid.magdata import MagData - - - - - - +from scipy.sparse import coo_matrix, csr_matrix class Projector(object): - ''' + '''Abstract base class representing a projection function. + + The :class:`~.Projector` class represents a projection function for a 3-dimensional + vector- or scalar field onto a 2-dimensional grid. :class:`~.Projector` is an abstract base + class and provides a unified interface which should be subclassed with a custom + :func:`__init__` function, which should call the parent :func:`__init__` method. Concrete + subclasses can be called as a function and take a `vector` as argument which contains the + 3-dimensional field. The output is the projected field, given as a `vector`. Depending on the + length of the input and the given dimensions `dim` at construction time, vector or scalar + projection is choosen intelligently. Attributes ---------- - + dim_2d : tuple (N=2) + Dimensions (v, u) of the projected grid. + size_3d : int + Number of voxels of the 3-dimensional grid. + size_2d : int + Number of pixels of the 2-dimensional projected grid. + weight : :class:`~scipy.sparse.csr_matrix` (N=2) + The weight matrix containing the weighting coefficients describing the influence of all + 3-dimensional voxels on the 2-dimensional pixels of the projection. + coeff : list (N=2) + List containing the six weighting coefficients describing the influence of the 3 components + of a 3-dimensional vector field on the 2 projected components. - - ''' # TODO: Docstring! + ''' __metaclass__ = abc.ABCMeta @abc.abstractmethod def __init__(self, (dim_v, dim_u), weight, coeff): - #TODO: Docstring! - self.dim = (dim_v, dim_u) # TODO: are they even used? + self.log = logging.getLogger(__name__) + self.log.info('Calling __init__') + self.dim_2d = (dim_v, dim_u) self.weight = weight self.coeff = coeff self.size_2d, self.size_3d = weight.shape + self.log.info('Created '+str(self)) def __call__(self, vector): - # TODO: Docstring! - assert any([len(vector) == i*self.size_3d for i in (1, 3)]), \ - 'Vector size has to be suited either for vector- or scalar-field-projection!' + self.log.info('Calling as function') if len(vector) == 3*self.size_3d: # mode == 'vector' + self.log.info('mode == vector') return self._vector_field_projection(vector) elif len(vector) == self.size_3d: # mode == 'scalar' + self.log.info('mode == scalar') return self._scalar_field_projection(vector) - # TODO: Raise Assertion Error + else: + raise AssertionError('Vector size has to be suited either for ' \ + 'vector- or scalar-field-projection!') def _vector_field_projection(self, vector): - # TODO: Docstring! + self.log.info('Calling _vector_field_projection') size_2d, size_3d = self.size_2d, self.size_3d result = np.zeros(2*size_2d) -# for j in range(2): -# for i in range(3): -# if coefficient[j, i] != 0: -# result[j*self.size_2d:(j+1)*self.size_2d] += self.coeff[j, i] * self.weight.dot(vector[j*length:(j+1)*length]) - # x_vec, y_vec, z_vec = vector[:length], vector[length:2*length], vector[2*length] - # TODO: Which solution? + # Go over all possible component projections (z, y, x) to (u, v): if self.coeff[0][0] != 0: # x to u result[:size_2d] += self.coeff[0][0] * self.weight.dot(vector[:size_3d]) if self.coeff[0][1] != 0: # y to u @@ -84,30 +89,87 @@ class Projector(object): return result def _scalar_field_projection(self, vector): - # TODO: Docstring! - # TODO: Implement smarter weight-multiplication! + self.log.info('Calling _scalar_field_projection') return np.array(self.weight.dot(vector)) def jac_dot(self, vector): - return self._vector_field_projection(vector) + '''Multiply a `vector` with the jacobi matrix of this :class:`~.Projector` object. + + Parameters + ---------- + vector : :class:`~numpy.ndarray` (N=1) + Vector containing the field which should be projected. Must have the same or 3 times + the size of `size_3d` of the projector for scalar and vector projection, respectively. + + Returns + ------- + proj_vector : :class:`~numpy.ndarray` (N=1) + Vector containing the projected field of the 2-dimensional grid. The length is + always`size_2d`. + ''' + self.log.info('Calling jac_dot') + return self(vector) class YTiltProjector(Projector): +# '''Class representing a projection where the projection axis is tilted around the y-axis. +# +# The :class:`~.YTiltProjector` class is a concrete subclass of the :class:`~.Projector` class +# and overwrites the :func:`__init__` constructor which accepts `dim` and `tilt` as arguments. +# The dimensions of the 3-dimensional grid are given by `dim`, the tilting angle of the ample +# around the y-axis is given by `tilt`. +# +# Attributes +# ---------- +# dim_2d : tuple (N=2) +# Dimensions (v, u) of the projected grid. +# size_3d : int +# Number of voxels of the 3-dimensional grid. +# size_2d : int +# Number of pixels of the 2-dimensional projected grid. +# weight : :class:`~scipy.sparse.csr_matrix` (N=2) +# The weight matrix containing the weighting coefficients describing the influence of all +# 3-dimensional voxels on the 2-dimensional pixels of the projection. +# coeff : list (N=2) +# List containing the six weighting coefficients describing the influence of the 3 components +# of a 3-dimensional vector field on the 2 projected components. +# ''' +# +# ''' +# weight : :class:`~scipy.sparse.csr_matrix` (N=2) +# The weight matrix containing the weighting coefficients which determine the influence of +# all 3-dimensional voxels to the 2-dimensional pixels of the projection. +# coeff : `list`t (N=2) +# List containing the six weighting coefficients describing the influence of the 3 components +# of a 3-dimensional vector fields on the 2 components of the projected field. Only used for +# vector field projection. +# +# Notes +# ----- +# An instance `projector` of the :class:`~.YSimpleProjector` class is callable via: +# +# :func:`projector(vector)` +# +# with `vector` being a :class:`~numpy.ndarray` (N=1). +# ''' + def __init__(self, dim, tilt): - # TODO: Docstring! - # TODO: Implement! + def get_position(p, m, b, size): + self.log.info('Calling get_position') y, x = np.array(p)[:, 0]+0.5, np.array(p)[:, 1]+0.5 return (y-m*x-b)/np.sqrt(m**2+1) + size/2. def get_impact(pos, r, size): + self.log.info('Calling get_impact') return [x for x in np.arange(np.floor(pos-r), np.floor(pos+r)+1, dtype=int) if 0 <= x < size] def get_weight(delta, rho): # use circles to represent the voxels + self.log.info('Calling get_weight') lo, up = delta-rho, delta+rho # Upper boundary: if up >= 1: @@ -121,21 +183,21 @@ class YTiltProjector(Projector): w_lo = (lo*np.sqrt(1-lo**2) + np.arctan(lo/np.sqrt(1-lo**2))) / pi return w_up - w_lo + self.log = logging.getLogger(__name__) + self.log.info('Calling __init__') + self.tilt = tilt # Set starting variables: # length along projection (proj, z), rotation (rot, y) and perpendicular (perp, x) axis: dim_proj, dim_rot, dim_perp = dim size_2d = dim_rot * dim_perp size_3d = dim_proj * dim_rot * dim_perp - # Creating coordinate list of all voxels: voxels = list(itertools.product(range(dim_proj), range(dim_perp))) - # Calculate positions along the projected pixel coordinate system: center = (dim_proj/2., dim_perp/2.) m = np.where(tilt<=pi, -1/np.tan(tilt+1E-30), 1/np.tan(tilt+1E-30)) b = center[0] - m * center[1] positions = get_position(voxels, m, b, dim_perp) - # Calculate weight-matrix: r = 1/np.sqrt(np.pi) # radius of the voxel circle rho = 0.5 / r @@ -151,57 +213,80 @@ class YTiltProjector(Projector): col.append(voxel[0]*size_2d + voxel[1]) row.append(impact) data.append(get_weight(delta, rho)) - # all other slices: + # All other slices: columns = col rows = row for i in np.arange(1, dim_rot): # TODO: more efficient, please! columns = np.hstack((np.array(columns), np.array(col)+i*dim_perp)) rows = np.hstack((np.array(rows), np.array(row)+i*dim_perp)) - + # Calculate weight matrix and coefficients for jacobi matrix: weight = csr_matrix(coo_matrix((np.tile(data, dim_rot), (rows, columns)), - shape = (size_2d, size_3d))) + shape = (size_2d, size_3d))) dim_v, dim_u = dim_rot, dim_perp coeff = [[np.cos(tilt), 0, np.sin(tilt)], [0, 1, 0]] super(YTiltProjector, self).__init__((dim_v, dim_u), weight, coeff) + self.log.info('Created '+str(self)) class SimpleProjector(Projector): - # TODO: Docstring! +# '''Class representing a projection along one of the major axes (x, y, z). +# +# The :class:`~.SimpleProjector` class is a concrete subclass of the :class:`~.Projector` class +# and overwrites the :func:`__init__` constructor which accepts `dim` and `axis` as arguments. +# The dimensions of the 3-dimensional grid are given by `dim`, the major axis along which to +# project is given by `axis` and can be `'x'`, `'y'` or `'z'` (default). +# +# Attributes +# ---------- +# dim_2d : tuple (N=2) +# Dimensions (v, u) of the projected grid. +# weight : :class:`~scipy.sparse.csr_matrix` (N=2) +# The weight matrix containing the weighting coefficients which determine the influence of +# all 3-dimensional voxels to the 2-dimensional pixels of the projection. +# coeff : list (N=2) +# List containing the six weighting coefficients describing the influence of the 3 components +# of a 3-dimensional vector fields on the 2 components of the projected field. Only used for +# vector field projection. +# size_3d : int +# Number of voxels of the 3-dimensional grid. +# size_2d : int +# Number of pixels of the 2-dimensional projected grid. +# +# Notes +# ----- +# An instance `projector` of the :class:`~.SimpleProjector` class is callable via: +# +# :func:`projector(vector)` +# +# with `vector` being a :class:`~numpy.ndarray` (N=1). +# +# ''' + + AXIS_DICT = {'z': (0, 1, 2), 'y': (1, 0, 2), 'x': (1, 2, 0)} def __init__(self, dim, axis='z'): - # TODO: Docstring! + self.log = logging.getLogger(__name__) + self.log.info('Calling __init__') + proj, v, u = self.AXIS_DICT[axis] + dim_proj, dim_v, dim_u = dim[proj], dim[v], dim[u] + dim_z, dim_y, dim_x = dim + size_2d = dim_u * dim_v + size_3d = np.prod(dim) + data = np.repeat(1, size_3d) + indptr = np.arange(0, size_3d+1, dim_proj) if axis == 'z': - dim_z, dim_y, dim_x = dim # TODO: in functions - dim_proj, dim_v, dim_u = dim - size_2d = dim_u * dim_v - size_3d = dim_x * dim_y * dim_z - data = np.repeat(1, size_3d) - indptr = np.arange(0, size_3d+1, dim_proj) + coeff = [[1, 0, 0], [0, 1, 0]] indices = np.array([np.arange(row, size_3d, size_2d) for row in range(size_2d)]).reshape(-1) - weight = csr_matrix((data, indices, indptr), shape = (size_2d, size_3d)) - coeff = [[1, 0, 0], [0, 1, 0]] elif axis == 'y': - dim_z, dim_y, dim_x = dim - dim_v, dim_proj, dim_u = dim - size_2d = dim_u * dim_v - size_3d = dim_x * dim_y * dim_z - data = np.repeat(1, size_3d) - indptr = np.arange(0, size_3d+1, dim_proj) + coeff = [[1, 0, 0], [0, 0, 1]] indices = np.array([np.arange(row%dim_x, dim_x*dim_y, dim_x)+int(row/dim_x)*dim_x*dim_y for row in range(size_2d)]).reshape(-1) - weight = csr_matrix((data, indices, indptr), shape = (size_2d, size_3d)) - coeff = [[1, 0, 0], [0, 0, 1]] elif axis == 'x': - dim_z, dim_y, dim_x = dim - dim_v, dim_u, dim_proj = dim - size_2d = dim_u * dim_v - size_3d = dim_x * dim_y * dim_z - data = np.repeat(1, size_3d) - indptr = np.arange(0, size_3d+1, dim_proj) + coeff = [[0, 1, 0], [0, 0, 1]] indices = np.array([np.arange(dim_proj) + row*dim_proj for row in range(size_2d)]).reshape(-1) - weight = csr_matrix((data, indices, indptr), shape = (size_2d, size_3d)) - coeff = [[0, 1, 0], [0, 0, 1]] + weight = csr_matrix((data, indices, indptr), shape = (size_2d, size_3d)) super(SimpleProjector, self).__init__((dim_v, dim_u), weight, coeff) + self.log.info('Created '+str(self)) diff --git a/regrid/array.cpp b/regrid/array.cpp new file mode 100644 index 0000000000000000000000000000000000000000..23d46f36ef2d50e8f4d3111684f9943b18716ea9 --- /dev/null +++ b/regrid/array.cpp @@ -0,0 +1,46 @@ +#define NO_IMPORT_ARRAY + +#include "gloripex.hpp" +#include "array.hpp" + +namespace gloripex { + using namespace boost::python; + /// Converts a numpy array to an Array instance if possible. Uses + /// constructor of Array class, but needs to manually generate a boost + /// object from raw pointer.. + template <class T> + struct ArrayConverter { + ArrayConverter() { + converter::registry::push_back(&convertible, &construct, type_id<T>()); + } + + static void* convertible(PyObject* obj_ptr) { + return is_object_convertible_to_array<T>(obj_ptr) ? obj_ptr : 0; + } + + /// See here for an explanation + /// http://mail.python.org/pipermail/cplusplus-sig/2008-October/013895.html + static void construct(PyObject* obj_ptr, + converter::rvalue_from_python_stage1_data* data) + { + object obj(handle<>(borrowed(obj_ptr))); + data->convertible = (reinterpret_cast<converter::rvalue_from_python_storage<T>*> (data))->storage.bytes; + new (data->convertible) T(obj); + } + }; + + // Add converters as necessary + ArrayConverter<Array<cub_t, 1> > array_cub_t_1_converter; + ArrayConverter<Array<cub_t, 2> > array_cub_t_2_converter; + ArrayConverter<Array<cub_t, 3> > array_cub_t_3_converter; + + ArrayConverter<Array<float, 1> > array_float_1_converter; + ArrayConverter<Array<float, 2> > array_float_2_converter; + ArrayConverter<Array<float, 3> > array_float_3_converter; + + ArrayConverter<Array<double, 1> > array_double_1_converter; + ArrayConverter<Array<double, 2> > array_double_2_converter; + ArrayConverter<Array<double, 3> > array_double_3_converter; + + ArrayConverter<Array<size_t, 1> > array_sizet_1_converter; +} diff --git a/regrid/array.hpp b/regrid/array.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6b0b2685a7e8af0e447dc73d2781928bde520dd0 --- /dev/null +++ b/regrid/array.hpp @@ -0,0 +1,162 @@ +// +// Copyright 2013 by Forschungszentrum Juelich GmbH +// + +#ifndef GLORIPEX_ARRAY_HPP +#define GLORIPEX_ARRAY_HPP + +#include "numpy.hpp" + +namespace gloripex { + +#pragma GCC diagnostic ignored "-Wold-style-cast" + /// Determines whether a python object is a numpy array fitting to the Array + /// type supplied by T. + /// + /// Example: + /// if (is_object_convertible_to_array<Array<double, 3> >(obj_ptr)) { ... } + template<typename T> + bool is_object_convertible_to_array(PyObject* obj_ptr) { + return (PyArray_Check(obj_ptr) && + PyArray_TYPE(obj_ptr) == numpy::getTypeID(typename T::value_type()) && + PyArray_NDIM(obj_ptr) == T::ndim()); + } +#pragma GCC diagnostic warning "-Wold-style-cast" + + /// \brief A fast array class suited to our needs. Based on the Blitz++ + /// concept without the fancy stuff. + template<typename T, int ndimm> + struct Array { + // some typedefs for making this STL compatible + typedef Array<T, ndimm> type; + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef size_t size_type; + + /// Function that provides a neat wrapper around numpy arrays. No copying is + /// performed. User needs to supply dimensionality and type, but it is + /// checked during runtime, if it fits! + /// + /// object is const, but this class does not really care about this... + /// Instantiate a const Array if object should really be const. + Array(const python::object& object) : + object_(object), + data_(static_cast<T*>(numpy::getArrayData(this->object_))) + { + this->initialise(); + } + + /// This function creates a numpy array. It may be accessed later on + /// with the object member function, e.g. for returning it to python. + Array(const std::vector<npy_intp>& dims) : + object_(numpy::createFromScratch<T>(dims)), + data_(static_cast<T*>(numpy::getArrayData(this->object_))) + { + this->initialise(); + } + + Array(const Array<T, ndimm>& other) : + object_(other.object_), + data_(static_cast<T*>(numpy::getArrayData(this->object_))) + { + this->initialise(); + } + + /// 1D access + inline const T& operator() (size_type idx0) const { + static_assert(ndimm == 1, "dimensionality does not fit function call"); + return this->data()[idx0 * this->stride(0)]; + } + /// 1D access + inline T& operator() (size_type idx0) { + static_assert(ndimm == 1, "dimensionality does not fit function call"); + return this->data()[idx0 * this->stride(0)]; + } + /// 2D access + inline const T& operator() (size_type idx0, size_type idx1) const { + static_assert(ndimm == 2, "dimensionality does not fit function call"); + return this->data()[idx0 * this->stride(0) + idx1 * this->stride(1)]; + } + /// 2D access + inline T& operator() (size_type idx0, size_type idx1) { + static_assert(ndimm == 2, "dimensionality does not fit function call"); + return this->data()[idx0 * this->stride(0) + idx1 * this->stride(1)]; + } + /// 3D access + inline const T& operator() (size_type idx0, size_type idx1, size_type idx2) const { + static_assert(ndimm == 3, "dimensionality does not fit function call"); + return this->data()[idx0 * this->stride(0) + idx1 * this->stride(1) + + idx2 * this->stride(2)]; + } + /// 3D access + inline T& operator() (size_type idx0, size_type idx1, size_type idx2) { + static_assert(ndimm == 3, "dimensionality does not fit function call"); + return this->data()[idx0 * this->stride(0) + idx1 * this->stride(1) + + idx2 * this->stride(2)]; + } + + inline iterator begin() { return this->data(); } + inline const_iterator begin() const { return this->data(); } + inline iterator end() { return this->data() + this->size(); } + inline const_iterator end() const { return this->data() + this->size(); } + + /// returns the number of dimensions. + static inline int ndim() { return ndimm; } + + /// returns the total size of the array + size_type size() const { + size_type result = shape(0); + for (int i = 1; i < this->ndim(); ++ i) { + result *= this->shape(i); + } + return result; + } + /// This function explores the shape of the array. + inline size_type shape(size_type dim) const { + assert(0 <= dim && dim < ndimm); + return static_cast<size_type>(numpy::getArrayDims(this->object_)[dim]); + } + /// This function explores the strides of the array. + inline size_type stride(size_type dim) const { return this->stride_[dim]; } + /// Returns pointer to underlying data. + inline T* data() const { return this->data_; } + + /// Returns the wrapped object. + inline python::object object() const { return this->object_; } + + template<typename T2, int ndim2> + friend std::ostream& operator<<(std::ostream& os, const Array<T2, ndim2>& a); + + private: + + void initialise() { + assert(is_object_convertible_to_array<type>(this->object_.ptr())); + + for (int i = 0; i < ndimm; ++ i) { + this->stride_[i] = numpy::getArrayStrides(this->object_)[i] / sizeof(T); + } + } + + protected: + /// Reference to python array object + python::object object_; + /// Holds the a pointer to the memory of the array (regardless of who manages it). + T* data_; + /// \brief Stores the stride of the array (e.g., 20(=4*5) and 5 for a + /// 3x4x5 array). + size_type stride_[ndimm]; + }; + + // **************************************************************************** + + template<typename T2, int ndim2> + std::ostream& operator<<(std::ostream& os, const Array<T2, ndim2>& a) { + os << python::extract<std::string>(a.object_.attr("__str__")())(); + return os; + } +} + +#endif diff --git a/regrid/gloripex.hpp b/regrid/gloripex.hpp new file mode 100644 index 0000000000000000000000000000000000000000..511b96f3838555a63f6c983f02fa272af885bfbb --- /dev/null +++ b/regrid/gloripex.hpp @@ -0,0 +1,95 @@ +// +// Copyright 2013 by Forschungszentrum Juelich GmbH +// +#ifndef GLORIPEX_HPP +#define GLORIPEX_HPP + +// this removes strange linkage issues with extensions covering multiple files +#define PY_ARRAY_UNIQUE_SYMBOL GLORIPEX_PY_ARRAY + +#include <iostream> +#include <iomanip> +#include <sstream> +#include <vector> +#include <complex> +#include <boost/python/detail/wrap_python.hpp> +#include <boost/python.hpp> +#include <numpy/arrayobject.h> + +#ifdef _OPENMP +#include <omp.h> +#endif + + +namespace std { + /// Conveniencev vvc ostream operator for std::vector. + template<typename T> + inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) { + os << "["; + for (typename std::vector<T>::size_type i = 0; i < vec.size(); ++ i) { + os << (i == 0 ? "" : ", ") << vec[i]; + } + os << "]"; + return os; + } + + /// Convenience ostream operator for std::vector<std::string>. + template<> + inline std::ostream& operator<<(std::ostream& os, const std::vector<std::string>& vec) { + os << "["; + for (std::vector<std::string>::size_type i = 0; i < vec.size(); ++ i) { + os << (i == 0 ? "'" : ", '") << vec[i] << "'"; + } + os << "]"; + return os; + } +} + + +namespace gloripex { + namespace python = boost::python; + + typedef std::complex<float> complex64; + typedef std::complex<double> complex128; + typedef uint16_t cub_t; + + /// Simple struct for error handling. + /// + /// This should be the base struct of all gloripy Exceptions. It is + /// translated to a python runtime error. + struct Exception : std::exception { + std::string msg_; + Exception(std::string msg) : msg_(msg) {} + virtual ~Exception() throw() {} + virtual char const* what() const throw() { return msg_.c_str(); } + }; + + /// An assert that throws an exception instead of aborting the program. +#ifndef NDEBUG +#define gassert(cond, msg) \ + if (!(cond)) { \ + std::ostringstream message; \ + message << __FILE__ << ":" \ + << std::setw(4) << __LINE__ << ": " \ + << msg << std::endl; \ + throw Exception(message.str()); \ + } +#else +#define gassert(cond, msg) (void) (0) +#endif + + /// This functions takes a datum and returns a string representation. + template<typename T> + inline std::string toString(const T& object) { + std::stringstream result; + result << object; + return result.str(); + } + + /// Allows printing of all boost::python wrapped python objects. + inline std::ostream& operator<<(std::ostream& os, const python::object& object) { + os << python::extract<std::string>(object.attr("__str__")())(); + return os; + } +} +#endif diff --git a/regrid/numpy.hpp b/regrid/numpy.hpp new file mode 100644 index 0000000000000000000000000000000000000000..568b6302d8d2ffcb0482ce1f3aaefcba193c9857 --- /dev/null +++ b/regrid/numpy.hpp @@ -0,0 +1,93 @@ +// +// Copyright 2013 by Forschungszentrum Juelich GmbH +// + +#ifndef GLORIPEX_NUMPY +#define GLORIPEX_NUMPY + + +namespace gloripex { + namespace numpy { + typedef python::numeric::array ndarray; + + inline int getTypeID(float) { return NPY_FLOAT; } + inline int getTypeID(double) { return NPY_DOUBLE; } + inline int getTypeID(long double) { return NPY_LONGDOUBLE; } + inline int getTypeID(signed char) { return NPY_BYTE; } + inline int getTypeID(unsigned char) { return NPY_UBYTE; } + inline int getTypeID(int) { return NPY_INT; } + inline int getTypeID(unsigned int) { return NPY_UINT; } + inline int getTypeID(short) { return NPY_SHORT; } + inline int getTypeID(unsigned short) { return NPY_USHORT; } + inline int getTypeID(unsigned long) { return NPY_ULONG; } + inline int getTypeID(long) { return NPY_LONG; } + + + inline int getArrayType(const python::object &x) { + return reinterpret_cast<PyArrayObject*>(x.ptr())->descr->type_num; + } + + inline npy_intp* getArrayDims(const python::object &x) { + return reinterpret_cast<PyArrayObject*>(x.ptr())->dimensions; + } + + inline npy_intp* getArrayStrides(const python::object &x) { + return reinterpret_cast<PyArrayObject*>(x.ptr())->strides; + } + + inline int getArrayNDims(const python::object &x) { + return reinterpret_cast<PyArrayObject*>(x.ptr())->nd; + } + + inline void* getArrayData(const python::object &x) { + return reinterpret_cast<PyArrayObject*>(x.ptr())->data; + } + + inline PyArray_Descr* getArrayDescription(const python::object &x) { + return reinterpret_cast<PyArrayObject*>(x.ptr())->descr; + } + + inline int getArrayItemsize(const python::object &x) { + return reinterpret_cast<PyArrayObject*>(x.ptr())->descr->elsize; + } + + template<typename T> + inline T* getArrayDataAs(const python::object &x) { + return reinterpret_cast<T*>(getArrayData(x)); + } + +#pragma GCC diagnostic ignored "-Wold-style-cast" + inline bool isArray(const python::object &x) { + return PyArray_Check(x.ptr()); + } + + /// Creates an empty python array. + template<typename T> + inline ndarray createFromScratch(const std::vector<npy_intp>& dims) { + PyObject* ptr = PyArray_SimpleNew( + static_cast<int>(dims.size()), + const_cast<npy_intp*>(&dims[0]), + getTypeID(T())); + python::handle<> hndl(ptr); + return ndarray(hndl); + } + + /// Creates a python array from existing memory. As the lifetime of the + /// python object cannot be controlled, it is rather dangerous to delete + /// the memory. Use with utmost care. + template<typename T> + inline ndarray createFromData( + const std::vector<npy_intp>& dims, T* data) { + PyObject* ptr = PyArray_SimpleNewFromData( + static_cast<int>(dims.size()), + const_cast<npy_intp*>(&dims[0]), + getTypeID(T()), + data); + python::handle<> hndl(ptr); + return ndarray(hndl); + } +#pragma GCC diagnostic warning "-Wold-style-cast" + } +} + +#endif diff --git a/regrid/regrid.cc b/regrid/regrid.cc new file mode 100644 index 0000000000000000000000000000000000000000..45f044938b5675d63c718c8d3763116fc3f84ecb --- /dev/null +++ b/regrid/regrid.cc @@ -0,0 +1,94 @@ + +// this removes strange linkage issues with extensions covering multiple files +#define PY_ARRAY_UNIQUE_SYMBOL GLORIPEX_PY_ARRAY +#include <iostream> +#include <iomanip> +#include <sstream> +#include <vector> +#include <complex> +#include <boost/python/detail/wrap_python.hpp> +#include <boost/python.hpp> +#include <numpy/arrayobject.h> + +namespace python = boost::python; + +#include "numpy.hpp" +#include "array.hpp" + +#include <CGAL/Exact_predicates_inexact_constructions_kernel.h> + +#include <CGAL/Delaunay_triangulation_2.h> +#include <CGAL/Delaunay_triangulation_3.h> + +#include <CGAL/Triangulation_vertex_base_with_info_3.h> +#include <CGAL/Triangulation_vertex_base_with_info_2.h> + +#include <CGAL/natural_neighbor_coordinates_2.h> +#include <CGAL/natural_neighbor_coordinates_3.h> + +struct Interpolate { + + typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + typedef Kernel::FT CoordType; + typedef Kernel::Point_3 Point; + typedef CGAL::Triangulation_vertex_base_with_info_3<unsigned, Kernel> Vb; + typedef CGAL::Triangulation_data_structure_3<Vb> Tds; + typedef CGAL::Delaunay_triangulation_3<Kernel, Tds> DelaunayTriangulation; + typedef DelaunayTriangulation::Vertex_handle VertexHandle; + + DelaunayTriangulation T_; + const gloripex::Array<double, 2> data_; + + Interpolate(const gloripex::Array<double, 2>& data) : + data_(data) + { + const auto size = data_.shape(0); + for (size_t i = 0; i < size; ++ i) { + this->T_.insert(Point(data_(i, 0), data_(i, 1), data_(i, 2)))->info() = i; + } + } + + // ***************************************************************************** + + void interpolate(const gloripex::Array<double, 2>& coord2) const + { + gloripex::Array<double, 2>& coord = const_cast<gloripex::Array<double, 2>&>(coord2); + // coordinate computation + const auto size = coord.shape(0); + + for (size_t i = 0; i < size; ++ i) { + Point p(coord(i, 0), coord(i, 1), coord(i, 2)); + std::vector<std::pair<VertexHandle, CoordType> > vertices; + CoordType norm; + + CGAL::laplace_natural_neighbor_coordinates_3(this->T_, p, std::back_inserter(vertices), norm); + + if (! vertices.empty()) { + for (int j = 3; j < data_.shape(1); ++ j) { + coord(i, j) = 0; + } + for (const auto& vertex : vertices) { + double weight = vertex.second / norm; + for (int j = 3; j < data_.shape(1); ++ j) { + coord(i, j) += weight * data_((vertex.first)->info(), j); + } + + } + } else { + for (int j = 3; j < data_.shape(1); ++ j) { + coord(i, j) = std::numeric_limits<double>::quiet_NaN(); + } + } + } + } +}; + +BOOST_PYTHON_MODULE(regrid) +{ + python::numeric::array::set_module_and_type("numpy", "ndarray"); + import_array(); + + python::class_<Interpolate>("regrid", python::init<const gloripex::Array<double, 2>&>()) + .def("__call__", &Interpolate::interpolate); +} + diff --git a/regrid/regrid.o b/regrid/regrid.o new file mode 100644 index 0000000000000000000000000000000000000000..d7cfe16e98b29c5539685fabfb573cff83ca4536 Binary files /dev/null and b/regrid/regrid.o differ diff --git a/regrid/test.py b/regrid/test.py new file mode 100644 index 0000000000000000000000000000000000000000..108f0ae5ee3365e56630e1a63521b3256a2edb80 --- /dev/null +++ b/regrid/test.py @@ -0,0 +1,39 @@ +from regrid import regrid +from pylab import * + + +# semi irregular grid: +data = zeros((10**3,6)) +o = mgrid[0:10, 0:10, 0:10] +for i in range(3): + data[:, i] = o[i].reshape(-1) +data += rand(1000,6) +data -= 0.5 + + +# dummy data +data[:, 3] = sin(data[:, 0] * pi / 2.) + cos(data[:, 1] * pi / 4.) + data[:, 2] +data[:, 4] = data[:, 0] + data[:, 1] + data[:, 2] +data[:, 5] = 0 + +# initialize regridding +functor = regrid(data) + +# regular grid +n = 50 +p = mgrid[0:n, 0:n, 0:n] / 5. +data2 = zeros((n ** 3, 6)) +for i in range(3): + data2[:, i] = p[i].reshape(-1) + +# perform regridding +functor(data2) + +# visualize some portion +data2 = ma.masked_where(isnan(data2), data2) +print data2.shape, data2[:, 3:].shape +pcolor(data2[:, 3].reshape(n, n, n)[:, :, 5]) +colorbar() +show() + + diff --git a/scripts/compare methods/logfile.log b/scripts/compare methods/logfile.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/create distributions/create_logo.py b/scripts/create distributions/create_logo.py index fe6cde5f940dadc1f24e5ed954c4a6684a23ec64..a1561fe03e0f0490ca500dbd2b9f9be1c7c06406 100644 --- a/scripts/create distributions/create_logo.py +++ b/scripts/create distributions/create_logo.py @@ -11,11 +11,9 @@ import numpy as np from numpy import pi import pyramid.magcreator as mc -import pyramid.projector as pj -import pyramid.phasemapper as pm -import pyramid.holoimage as hi +from pyramid.phasemapper import PMAdapterFM from pyramid.magdata import MagData -from pyramid.phasemap import PhaseMap +from pyramid.projector import SimpleProjector def create_logo(): @@ -43,9 +41,9 @@ def create_logo(): # Create magnetic data, project it, get the phase map and display the holography image: mag_data = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) mag_data.quiver_plot() - projection = pj.simple_axis_projection(mag_data) - phase_map = PhaseMap(a, pm.phase_mag(a, projection)) - hi.display(hi.holo_image(phase_map, density), 'PYRAMID - LOGO', interpolation='bilinear') + projector = SimpleProjector(dim) + phase_map = PMAdapterFM(a, projector)(mag_data) + phase_map.display_holo(density, 'PYRAMID - LOGO', interpolation='bilinear', grad_encode='none') if __name__ == "__main__": diff --git a/scripts/create distributions/logfile.log b/scripts/create distributions/logfile.log new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/scripts/edinburgh_test.py b/scripts/edinburgh_test.py new file mode 100644 index 0000000000000000000000000000000000000000..f1015829c609e5b87ce4e7ef2486afced4d4193b --- /dev/null +++ b/scripts/edinburgh_test.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jan 28 15:15:08 2014 + +@author: Jan +""" + + +import numpy as np +from pyramid.magdata import MagData +from pyramid.projector import SimpleProjector +from pyramid.phasemapper import PMAdapterFM +from matplotlib.ticker import FuncFormatter + +data = np.loadtxt('../output/data from Edinburgh/long_grain_remapped_0p0035.txt', delimiter=',') + +a = 1000 * (data[1, 2] - data[0, 2]) + +dim = len(np.unique(data[:, 2])), len(np.unique(data[:, 1])), len(np.unique(data[:, 0])) + +mag_vec = np.concatenate([data[:, 3], data[:, 4], data[:, 5]]) + +x_mag = np.reshape(data[:, 3], dim, order='F') +y_mag = np.reshape(data[:, 4], dim, order='F') +z_mag = np.reshape(data[:, 5], dim, order='F') + +magnitude = np.array((x_mag, y_mag, z_mag)) + +mag_data = MagData(a, magnitude) + +mag_data.pad(30, 20, 0) + +mag_data.scale_up() + +mag_data.quiver_plot() + +#mag_data.quiver_plot3d() + +projector = SimpleProjector(mag_data.dim) + +phasemapper = PMAdapterFM(mag_data.a, projector) + +phase_map = phasemapper(mag_data) + +phase_axis = phase_map.display_combined(density=20, interpolation='bilinear')[0] + +phase_axis.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: '{:3.0f}'.format(x*mag_data.a))) +phase_axis.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: '{:3.0f}'.format(x*mag_data.a))) + +#phase_map.display_phase3d() diff --git a/scripts/images_poster.py b/scripts/images_poster.py new file mode 100644 index 0000000000000000000000000000000000000000..d008673c3fbac97d0825aee76aef952574a34c7c --- /dev/null +++ b/scripts/images_poster.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +""" +Created on Wed Feb 05 19:19:19 2014 + +@author: Jan +""" + +import os +from numpy import pi + +import pyramid.magcreator as mc +from pyramid.magdata import MagData +from pyramid.phasemapper import PMConvolve +from pyramid.projector import SimpleProjector + +import matplotlib.pyplot as plt + + + +directory = '../output/poster' +if not os.path.exists(directory): + os.makedirs(directory) +# Input parameters: +a = 10.0 # nm +dim = (64, 128, 128) +# Slab:f +center = (32, 32, 32) # in px (z, y, x), index starts with 0! +width = (322, 48, 48) # in px (z, y, x) +mag_shape_slab = mc.Shapes.slab(dim, center, width) +# Disc: +center = (32, 32, 96) # in px (z, y, x), index starts with 0! +radius = 24 # in px +height = 24 # in px +mag_shape_disc = mc.Shapes.disc(dim, center, radius, height) +# Sphere: +center = (32, 96, 64) # in px (z, y, x), index starts with 0! +radius = 24 # in px +mag_shape_sphere = mc.Shapes.sphere(dim, center, radius) +# Create empty MagData object and add magnetized objects: +mag_data = MagData(a, mc.create_mag_dist_homog(mag_shape_slab, pi/6)) +mag_data += MagData(a, mc.create_mag_dist_vortex(mag_shape_disc, (32, 96))) +mag_data += MagData(a, mc.create_mag_dist_homog(mag_shape_sphere, -pi/4)) +# Plot the magnetic distribution, phase map and holographic contour map: +mag_data_coarse = mag_data.copy() +mag_data_coarse.scale_down(2) +mag_data_coarse.quiver_plot() +plt.savefig(os.path.join(directory, 'mag.png')) +mag_data_coarse.quiver_plot3d() +projector = SimpleProjector(dim) +phase_map = PMConvolve(a, projector, b_0=0.1)(mag_data) +phase_map.display_phase() +plt.savefig(os.path.join(directory, 'phase.png')) +phase_map.display_holo(density=4, interpolation='bilinear') +plt.savefig(os.path.join(directory, 'holo.png')) + + +dim = (1, 9, 9) +mag_shape = mc.Shapes.pixel(dim, (int(dim[0]/2), int(dim[1]/2), int(dim[2]/2))) +mag_data_x = MagData(a, mc.create_mag_dist_homog(mag_shape, 0)) +mag_data_y = MagData(a, mc.create_mag_dist_homog(mag_shape, pi/2)) +phasemapper = PMConvolve(a, SimpleProjector(dim)) +phasemapper(mag_data_x).display_phase() +phasemapper(mag_data_y).display_phase() \ No newline at end of file diff --git a/scripts/logfile.log b/scripts/logfile.log new file mode 100644 index 0000000000000000000000000000000000000000..8354e3313761d33ac8792c274fddf51547e46c67 --- /dev/null +++ b/scripts/logfile.log @@ -0,0 +1 @@ +2014-02-08 21:43:12: INFO @ <root>: Calling copy diff --git a/scripts/paper 1/ch5-0-evaluation_and_comparison.py b/scripts/paper 1/ch5-0-evaluation_and_comparison.py index bdae2361b751c18660361391eae14d978f1a4d0d..00463cc8dbc9f2044b1b16ac5f728161739277e4 100644 --- a/scripts/paper 1/ch5-0-evaluation_and_comparison.py +++ b/scripts/paper 1/ch5-0-evaluation_and_comparison.py @@ -6,9 +6,6 @@ Created on Fri Jul 26 14:37:20 2013 """ -import sys -import traceback -import pdb import os import numpy as np @@ -24,99 +21,90 @@ import matplotlib.pyplot as plt from matplotlib.ticker import FixedFormatter, IndexLocator -def run(): - - print '\nACCESS SHELVE' - # Create / Open databank: - directory = '../../output/paper 1' - if not os.path.exists(directory): - os.makedirs(directory) - data_shelve = shelve.open(directory + '/paper_1_shelve') - - ############################################################################################### - print 'CH5-0 KERNELS' - - x = np.linspace(-5, 5, 1000) - - y_r = x/np.abs(x)**3 - y_k = x/np.abs(x)**2 - fig = plt.figure() - axis = fig.add_subplot(1, 1, 1, aspect='equal') - axis.plot(x,y_r, 'r', label=r'$r/|r|^3$') - axis.plot(x,y_k, 'b', label=r'$k/|k|^2$') - axis.set_xlim(-5, 5) - axis.set_ylim(-5, 5) - axis.axvline(0, linewidth=2, color='k') - axis.axhline(0, linewidth=2, color='k') - axis.legend() - - ############################################################################################### - print 'CH5-0 MAGNETIC DISTRIBUTIONS' - - key = 'ch5-0-magnetic_distributions' - if key in data_shelve: - print '--LOAD MAGNETIC DISTRIBUTIONS' - (mag_data_disc, mag_data_vort) = data_shelve[key] - else: - print '--CREATE MAGNETIC DISTRIBUTIONS' - # Input parameters: - a = 1.0 # in nm - phi = pi/2 - dim = (16, 128, 128) # in px (z, y, x) - # Create magnetic shape: - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts at 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - mag_shape = mc.Shapes.disc(dim, center, radius, height) - print '--CREATE MAGN. DISTR. OF HOMOG. MAG. DISC' - mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) - mag_data_disc.scale_down(2) - print '--CREATE MAGN. DISTR. OF VORTEX STATE DISC' - mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape, center)) - mag_data_vort.scale_down(2) - # Mayavi-Plots: - mag_data_disc.quiver_plot3d() - mag_data_vort.quiver_plot3d() - print '--SHELVE MAGNETIC DISTRIBUTIONS' - data_shelve[key] = (mag_data_disc, mag_data_vort) - - print '--PLOT/SAVE MAGNETIC DISTRIBUTIONS' - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Magnetic Distributions', fontsize=20) - # Plot MagData (Disc): - mag_data_disc.quiver_plot('Homog. magn. disc', axis=axes[0]) - axes[0].set_aspect('equal') - axes[0].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - axes[0].yaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - axes[0].xaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) - axes[0].yaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) - axes[0].set_xlabel('x [nm]', fontsize=15) - axes[0].set_ylabel('x [ym]', fontsize=15) - # Plot MagData (Disc): - mag_data_vort.quiver_plot('Vortex state disc', axis=axes[1]) - axes[1].set_aspect('equal') - axes[1].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - axes[1].yaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - axes[1].xaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) - axes[1].yaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) - axes[1].set_xlabel('x [nm]', fontsize=15) - axes[1].set_ylabel('x [ym]', fontsize=15) - # Save Plots: - plt.figtext(0.15, 0.15, 'a)', fontsize=30) - plt.figtext(0.57, 0.15, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-0-magnetic_distributions.png', bbox_inches='tight') - - ############################################################################################### - print 'CLOSING SHELVE\n' - # Close shelve: - data_shelve.close() - - ############################################################################################### - -if __name__ == "__main__": - try: - run() - except: - type, value, tb = sys.exc_info() - traceback.print_exc() - pdb.post_mortem(tb) +force_calculation = False + + +print '\nACCESS SHELVE' +# Create / Open databank: +directory = '../../output/paper 1' +if not os.path.exists(directory): + os.makedirs(directory) +data_shelve = shelve.open(directory + '/paper_1_shelve') + +############################################################################################### +print 'CH5-0 KERNELS' + +x = np.linspace(-5, 5, 1000) + +y_r = x/np.abs(x)**3 +y_k = x/np.abs(x)**2 +fig = plt.figure() +axis = fig.add_subplot(1, 1, 1, aspect='equal') +axis.plot(x,y_r, 'r', label=r'$r/|r|^3$') +axis.plot(x,y_k, 'b', label=r'$k/|k|^2$') +axis.set_xlim(-5, 5) +axis.set_ylim(-5, 5) +axis.axvline(0, linewidth=2, color='k') +axis.axhline(0, linewidth=2, color='k') +axis.legend() + +############################################################################################### +print 'CH5-0 MAGNETIC DISTRIBUTIONS' + +key = 'ch5-0-magnetic_distributions' +if key in data_shelve and not force_calculation: + print '--LOAD MAGNETIC DISTRIBUTIONS' + (mag_data_disc, mag_data_vort) = data_shelve[key] +else: + print '--CREATE MAGNETIC DISTRIBUTIONS' + # Input parameters: + a = 1.0 # in nm + phi = pi/2 + dim = (16, 128, 128) # in px (z, y, x) + # Create magnetic shape: + center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts at 0! + radius = dim[1]/4 # in px + height = dim[0]/2 # in px + mag_shape = mc.Shapes.disc(dim, center, radius, height) + print '--CREATE MAGN. DISTR. OF HOMOG. MAG. DISC' + mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) + mag_data_disc.scale_down(2) + print '--CREATE MAGN. DISTR. OF VORTEX STATE DISC' + mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape, center)) + mag_data_vort.scale_down(2) + # Mayavi-Plots: + mag_data_disc.quiver_plot3d() + mag_data_vort.quiver_plot3d() + print '--SHELVE MAGNETIC DISTRIBUTIONS' + data_shelve[key] = (mag_data_disc, mag_data_vort) + +print '--PLOT/SAVE MAGNETIC DISTRIBUTIONS' +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Magnetic Distributions', fontsize=20) +# Plot MagData (Disc): +mag_data_disc.quiver_plot('Homog. magn. disc', axis=axes[0]) +axes[0].set_aspect('equal') +axes[0].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) +axes[0].yaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) +axes[0].xaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) +axes[0].yaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) +axes[0].set_xlabel('x [nm]', fontsize=15) +axes[0].set_ylabel('x [nm]', fontsize=15) +# Plot MagData (Disc): +mag_data_vort.quiver_plot('Vortex state disc', axis=axes[1]) +axes[1].set_aspect('equal') +axes[1].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) +axes[1].yaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) +axes[1].xaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) +axes[1].yaxis.set_major_formatter(FixedFormatter([16*i for i in range(10)])) +axes[1].set_xlabel('x [nm]', fontsize=15) +axes[1].set_ylabel('x [nm]', fontsize=15) +# Save Plots: +plt.figtext(0.15, 0.15, 'a)', fontsize=30) +plt.figtext(0.57, 0.15, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-0-magnetic_distributions.png', bbox_inches='tight') + +############################################################################################### +print 'CLOSING SHELVE\n' +# Close shelve: +data_shelve.close() diff --git a/scripts/paper 1/ch5-1-evaluation_real_space.py b/scripts/paper 1/ch5-1-evaluation_real_space.py index babbdcbac83173d0d34f09b82c35f37221461444..d3a618a0e06080eca94806c733a8617440cd4548 100644 --- a/scripts/paper 1/ch5-1-evaluation_real_space.py +++ b/scripts/paper 1/ch5-1-evaluation_real_space.py @@ -6,9 +6,6 @@ Created on Fri Jul 26 14:37:30 2013 """ -import pdb -import traceback -import sys import os import numpy as np @@ -17,10 +14,9 @@ from numpy import pi import shelve import pyramid.magcreator as mc -import pyramid.projector as pj -import pyramid.phasemapper as pm -import pyramid.holoimage as hi import pyramid.analytic as an +from pyramid.projector import SimpleProjector +from pyramid.phasemapper import PMConvolve from pyramid.magdata import MagData from pyramid.phasemap import PhaseMap @@ -31,346 +27,332 @@ from matplotlib.cm import RdBu from matplotlib.patches import Rectangle +force_calculation = False PHI_0 = -2067.83 # magnetic flux in T*nm² -def run(): - - print '\nACCESS SHELVE' - # Create / Open databank: - directory = '../../output/paper 1' - if not os.path.exists(directory): - os.makedirs(directory) - data_shelve = shelve.open(directory + '/paper_1_shelve') - - ############################################################################################### - print 'CH5-1 ANALYTIC SOLUTIONS' - - # Input parameters: - a = 0.125 # in nm - phi = pi/2 - dim = (128, 1024, 1024) # in px (z, y, x) - density = 100 - # Create magnetic shape: - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - print '--CALCULATE ANALYTIC SOLUTIONS' - # Get analytic solution: - phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) - phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) - phase_map_ana_disc = PhaseMap(a, phase_ana_disc) - phase_map_ana_vort = PhaseMap(a, phase_ana_vort) - print '--PLOT/SAVE ANALYTIC SOLUTIONS' - hi.display_combined(phase_map_ana_disc, density, - 'Analytic solution: hom. magn. disc', 'bilinear') - axis = plt.gcf().add_subplot(1, 2, 2, aspect='equal') - axis.axhline(y=512, linewidth=3, linestyle='--', color='r') - plt.figtext(0.15, 0.2, 'a)', fontsize=30, color='w') - plt.figtext(0.52, 0.2, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-1-analytic_solution_disc.png', bbox_inches='tight') - hi.display_combined(phase_map_ana_vort, density, - 'Analytic solution: vortex state', 'bilinear') - axis = plt.gcf().add_subplot(1, 2, 2, aspect='equal') - axis.axhline(y=512, linewidth=3, linestyle='--', color='r') - plt.figtext(0.15, 0.2, 'c)', fontsize=30, color='w') - plt.figtext(0.52, 0.2, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-1-analytic_solution_vort.png', bbox_inches='tight') - # Get colorwheel: - hi.make_color_wheel() - plt.figtext(0.15, 0.14, 'e)', fontsize=30, color='w') - plt.savefig(directory + '/ch5-1-colorwheel.png', bbox_inches='tight') - - ############################################################################################### - print 'CH5-1 PHASE SLICES REAL SPACE' - - # Input parameters: - a = 0.25 # in nm - phi = pi/2 - density = 100 - dim = (64, 512, 512) # in px (z, y, x) - # Create magnetic shape: - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - - key = 'ch5-1-phase_slices_real' - if key in data_shelve: - print '--LOAD MAGNETIC DISTRIBUTION' - (x_d, y_d, dy_d, x_v, y_v, dy_v) = data_shelve[key] - else: - print '--CREATE MAGNETIC DISTRIBUTION' - mag_shape = mc.Shapes.disc(dim, center, radius, height) - - print '--CREATE PHASE SLICES HOMOG. MAGN. DISC' - # Arrays for plotting: - x_d = [] - y_d = [] - dy_d = [] - # Analytic solution: - L = dim[1] * a # in px/nm - Lz = 0.5 * dim[0] * a # in px/nm - R = 0.25 * L # in px/nm - x0 = L / 2 # in px/nm - - def F_disc(x): - coeff = - pi * Lz / (2*PHI_0) * 1E3 # in mrad -> *1000 - result = coeff * (- (x - x0) * np.sin(phi)) - result *= np.where(np.abs(x - x0) <= R, 1, (R / (x - x0)) ** 2) - return result - - x_d.append(np.linspace(0, L, 5000)) - y_d.append(F_disc(x_d[0])) - dy_d.append(np.zeros_like(x_d[0])) - # Create MagData (Disc): - mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) - for i in range(5): - mag_data_disc.scale_down() - print '----a =', mag_data_disc.a, 'nm', 'dim =', mag_data_disc.dim - projection = pj.simple_axis_projection(mag_data_disc) - phase_map = PhaseMap(mag_data_disc.a, pm.phase_mag(mag_data_disc.a, projection)) - hi.display_combined(phase_map, density, 'Disc, a = {} nm'.format(mag_data_disc.a)) - x_d.append(np.linspace(mag_data_disc.a * 0.5, - mag_data_disc.a * (mag_data_disc.dim[1]-0.5), - mag_data_disc.dim[1])) - slice_pos = int(mag_data_disc.dim[1]/2) - y_d.append(phase_map.phase[slice_pos, :]*1E3) # *1E3: rad to mrad - dy_d.append(phase_map.phase[slice_pos, :]*1E3 - F_disc(x_d[-1])) # *1E3: rad to mrad - - print '--CREATE PHASE SLICES VORTEX STATE DISC' - x_v = [] - y_v = [] - dy_v = [] - # Analytic solution: - L = dim[1] * a # in px/nm - Lz = 0.5 * dim[0] * a # in px/nm - R = 0.25 * L # in px/nm - x0 = L / 2 # in px/nm - - def F_vort(x): - coeff = pi*Lz/PHI_0 * 1E3 # in mrad -> *1000 - result = coeff * np.where(np.abs(x - x0) <= R, (np.abs(x-x0)-R), 0) - return result - - x_v.append(np.linspace(0, L, 5001)) - y_v.append(F_vort(x_v[0])) - dy_v.append(np.zeros_like(x_v[0])) - # Create MagData (Vortex): - mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape)) - for i in range(5): - mag_data_vort.scale_down() - print '----a =', mag_data_vort.a, 'nm', 'dim =', mag_data_vort.dim - projection = pj.simple_axis_projection(mag_data_vort) - phase_map = PhaseMap(mag_data_vort.a, pm.phase_mag(mag_data_vort.a, projection)) - hi.display_combined(phase_map, density, 'Disc, a = {} nm'.format(mag_data_vort.a)) - x_v.append(np.linspace(mag_data_vort.a * 0.5, - mag_data_vort.a * (mag_data_vort.dim[1]-0.5), - mag_data_vort.dim[1])) - slice_pos = int(mag_data_vort.dim[1]/2) - y_v.append(phase_map.phase[slice_pos, :]*1E3) # *1E3: rad to mrad - dy_v.append(phase_map.phase[slice_pos, :]*1E3 - F_vort(x_v[-1])) # *1E3: rad to mrad - - # Shelve x, y and dy: - print '--SAVE PHASE SLICES' - data_shelve[key] = (x_d, y_d, dy_d, x_v, y_v, dy_v) - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Central phase slices', fontsize=20) - - print '--PLOT/SAVE PHASE SLICES HOMOG. MAGN. DISC' - # Plot phase slices: - axes[0].plot(x_d[0], y_d[0], '-k', linewidth=1.5, label='analytic') - axes[0].plot(x_d[1], y_d[1], '-r', linewidth=1.5, label='0.5 nm') - axes[0].plot(x_d[2], y_d[2], '-m', linewidth=1.5, label='1 nm') - axes[0].plot(x_d[3], y_d[3], '-y', linewidth=1.5, label='2 nm') - axes[0].plot(x_d[4], y_d[4], '-g', linewidth=1.5, label='4 nm') - axes[0].plot(x_d[5], y_d[5], '-c', linewidth=1.5, label='8 nm') - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].set_title('Homog. magn. disc', fontsize=18) - axes[0].set_xlabel('x [nm]', fontsize=15) - axes[0].set_ylabel('phase [mrad]', fontsize=15) - axes[0].set_xlim(0, 128) - axes[0].set_ylim(-220, 220) - # Plot Zoombox and Arrow: - zoom = (23.5, 160, 15, 40) - rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') - axes[0].add_patch(rect) - axes[0].arrow(zoom[0]+zoom[2], zoom[1]+zoom[3]/2, 36, 0, length_includes_head=True, - head_width=10, head_length=4, fc='k', ec='k') - # Plot zoom inset: - ins_axis_d = plt.axes([0.33, 0.57, 0.14, 0.3]) - ins_axis_d.plot(x_d[0], y_d[0], '-k', linewidth=1.5, label='analytic') - ins_axis_d.plot(x_d[1], y_d[1], '-r', linewidth=1.5, label='0.5 nm') - ins_axis_d.plot(x_d[2], y_d[2], '-m', linewidth=1.5, label='1 nm') - ins_axis_d.plot(x_d[3], y_d[3], '-y', linewidth=1.5, label='2 nm') - ins_axis_d.plot(x_d[4], y_d[4], '-g', linewidth=1.5, label='4 nm') - ins_axis_d.plot(x_d[5], y_d[5], '-c', linewidth=1.5, label='8 nm') - ins_axis_d.tick_params(axis='both', which='major', labelsize=14) - ins_axis_d.set_xlim(zoom[0], zoom[0]+zoom[2]) - ins_axis_d.set_ylim(zoom[1], zoom[1]+zoom[3]) - ins_axis_d.xaxis.set_major_locator(MaxNLocator(nbins=4, integer=True)) - ins_axis_d.yaxis.set_major_locator(MaxNLocator(nbins=3)) - - print '--PLOT/SAVE PHASE SLICES VORTEX STATE DISC' - # Plot phase slices: - axes[1].plot(x_v[0], y_v[0], '-k', linewidth=1.5, label='analytic') - axes[1].plot(x_v[1], y_v[1], '-r', linewidth=1.5, label='0.5 nm') - axes[1].plot(x_v[2], y_v[2], '-m', linewidth=1.5, label='1 nm') - axes[1].plot(x_v[3], y_v[3], '-y', linewidth=1.5, label='2 nm') - axes[1].plot(x_v[4], y_v[4], '-g', linewidth=1.5, label='4 nm') - axes[1].plot(x_v[5], y_v[5], '-c', linewidth=1.5, label='8 nm') - axes[1].tick_params(axis='both', which='major', labelsize=14) - axes[1].set_title('Vortex state disc', fontsize=18) - axes[1].set_xlabel('x [nm]', fontsize=15) - axes[1].set_ylabel('phase [mrad]', fontsize=15) - axes[1].set_xlim(0, 128) - axes[1].yaxis.set_major_locator(MaxNLocator(nbins=6)) - axes[1].legend() - # Plot Zoombox and Arrow: - zoom = (59, 340, 10, 55) - rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') - axes[1].add_patch(rect) - axes[1].arrow(zoom[0]+zoom[2]/2, zoom[1], 0, -193, length_includes_head=True, - head_width=2, head_length=20, fc='k', ec='k') - # Plot zoom inset: - ins_axis_v = plt.axes([0.695, 0.15, 0.075, 0.3]) - ins_axis_v.plot(x_v[0], y_v[0], '-k', linewidth=1.5, label='analytic') - ins_axis_v.plot(x_v[1], y_v[1], '-r', linewidth=1.5, label='0.5 nm') - ins_axis_v.plot(x_v[2], y_v[2], '-m', linewidth=1.5, label='1 nm') - ins_axis_v.plot(x_v[3], y_v[3], '-y', linewidth=1.5, label='2 nm') - ins_axis_v.plot(x_v[4], y_v[4], '-g', linewidth=1.5, label='4 nm') - ins_axis_v.plot(x_v[5], y_v[5], '-c', linewidth=1.5, label='8 nm') - ins_axis_v.tick_params(axis='both', which='major', labelsize=14) - ins_axis_v.set_xlim(zoom[0], zoom[0]+zoom[2]) - ins_axis_v.set_ylim(zoom[1], zoom[1]+zoom[3]) - ins_axis_v.xaxis.set_major_locator(MaxNLocator(nbins=4, integer=True)) - ins_axis_v.yaxis.set_major_locator(MaxNLocator(nbins=4)) - - plt.show() - plt.figtext(0.15, 0.13, 'a)', fontsize=30) - plt.figtext(0.57, 0.13, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-1-phase_slice_comparison.png', bbox_inches='tight') - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Central phase slice errors', fontsize=20) - - print '--PLOT/SAVE PHASE SLICE ERRORS HOMOG. MAGN. DISC' - # Plot phase slices: - axes[0].plot(x_d[0], dy_d[0], '-k', linewidth=1.5, label='analytic') - axes[0].plot(x_d[1], dy_d[1], '-r', linewidth=1.5, label='0.5 nm') - axes[0].plot(x_d[2], dy_d[2], '-m', linewidth=1.5, label='1 nm') - axes[0].plot(x_d[3], dy_d[3], '-y', linewidth=1.5, label='2 nm') - axes[0].plot(x_d[4], dy_d[4], '-g', linewidth=1.5, label='4 nm') - axes[0].plot(x_d[5], dy_d[5], '-c', linewidth=1.5, label='8 nm') - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].set_title('Homog. magn. disc', fontsize=18) - axes[0].set_xlabel('x [nm]', fontsize=15) - axes[0].set_ylabel('phase [mrad]', fontsize=15) - axes[0].set_xlim(0, 128) - - print '--PLOT/SAVE PHASE SLICE ERRORS VORTEX STATE DISC' - # Plot phase slices: - axes[1].plot(x_v[0], dy_v[0], '-k', linewidth=1.5, label='analytic') - axes[1].plot(x_v[1], dy_v[1], '-r', linewidth=1.5, label='0.5 nm') - axes[1].plot(x_v[2], dy_v[2], '-m', linewidth=1.5, label='1 nm') - axes[1].plot(x_v[3], dy_v[3], '-y', linewidth=1.5, label='2 nm') - axes[1].plot(x_v[4], dy_v[4], '-g', linewidth=1.5, label='4 nm') - axes[1].plot(x_v[5], dy_v[5], '-c', linewidth=1.5, label='8 nm') - axes[1].tick_params(axis='both', which='major', labelsize=14) - axes[1].set_title('Vortex state disc', fontsize=18) - axes[1].set_xlabel('x [nm]', fontsize=15) - axes[1].set_ylabel('phase [mrad]', fontsize=15) - axes[1].set_xlim(0, 128) - axes[1].legend(loc=4) - - plt.show() - plt.figtext(0.15, 0.13, 'a)', fontsize=30) - plt.figtext(0.57, 0.13, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-1-phase_slice_errors.png', bbox_inches='tight') - - ############################################################################################### - print 'CH5-1 PHASE DIFFERENCES REAL SPACE' - - # Input parameters: - a = 1.0 # in nm - phi = pi/2 - dim = (16, 128, 128) # in px (z, y, x) - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - - key = 'ch5-1-phase_diff_mag_dist' - if key in data_shelve: - print '--LOAD MAGNETIC DISTRIBUTIONS' - (mag_data_disc, mag_data_vort) = data_shelve[key] - else: - print '--CREATE MAGNETIC DISTRIBUTIONS' - # Create magnetic shape (4 times the size): - a_big = a / 2 - dim_big = (dim[0]*2, dim[1]*2, dim[2]*2) - center_big = (dim_big[0]/2-0.5, dim_big[1]/2.-0.5, dim_big[2]/2.-0.5) - radius_big = dim_big[1]/4 # in px - height_big = dim_big[0]/2 # in px - mag_shape = mc.Shapes.disc(dim_big, center_big, radius_big, height_big) - # Create MagData (4 times the size): - mag_data_disc = MagData(a_big, mc.create_mag_dist_homog(mag_shape, phi)) - mag_data_vort = MagData(a_big, mc.create_mag_dist_vortex(mag_shape, center_big)) - # Scale mag_data, grid spacing and dimensions: - mag_data_disc.scale_down() - mag_data_vort.scale_down() - print '--SAVE MAGNETIC DISTRIBUTIONS' - # Shelve magnetic distributions: - data_shelve[key] = (mag_data_disc, mag_data_vort) - - print '--CALCULATE PHASE DIFFERENCES' - # Create projections along z-axis: - projection_disc = pj.simple_axis_projection(mag_data_disc) - projection_vort = pj.simple_axis_projection(mag_data_vort) - # Get analytic solutions: - phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) - phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) - # Create norm for the plots: - bounds = np.array([-3, -0.5, -0.25, -0.1, 0, 0.1, 0.25, 0.5, 3]) - norm = BoundaryNorm(bounds, RdBu.N) - # Calculations (Disc): - phase_num_disc = pm.phase_mag(a, projection_disc) - phase_diff_disc = PhaseMap(a, (phase_num_disc-phase_ana_disc), 'mrad') - RMS_disc = np.sqrt(np.mean(phase_diff_disc.phase**2)) - # Calculations (Vortex): - phase_num_vort = pm.phase_mag(a, projection_vort) - phase_diff_vort = PhaseMap(a, (phase_num_vort-phase_ana_vort), 'mrad') - RMS_vort = np.sqrt(np.mean(phase_diff_vort.phase**2)) - - print '--PLOT/SAVE PHASE DIFFERENCES' - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Difference of the real space approach from the analytical solution', fontsize=20) - # Plot MagData (Disc): - phase_diff_disc.display('Homog. magn. disc, RMS = {:3.2f} mrad'.format(RMS_disc), - limit=np.max(bounds), norm=norm, axis=axes[0]) - axes[0].set_aspect('equal') - # Plot MagData (Disc): - phase_diff_vort.display('Vortex state disc, RMS = {:3.2f} mrad'.format(RMS_vort), - limit=np.max(bounds), norm=norm, axis=axes[1]) - axes[1].set_aspect('equal') - # Save Plots: - plt.figtext(0.15, 0.2, 'a)', fontsize=30) - plt.figtext(0.52, 0.2, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-1-phase_differences.png', bbox_inches='tight') - - ############################################################################################### - print 'CLOSING SHELVE\n' - # Close shelve: - data_shelve.close() - - ############################################################################################### - - -if __name__ == "__main__": - try: - run() - except: - type, value, tb = sys.exc_info() - traceback.print_exc() - pdb.post_mortem(tb) +print '\nACCESS SHELVE' +# Create / Open databank: +directory = '../../output/paper 1' +if not os.path.exists(directory): + os.makedirs(directory) +data_shelve = shelve.open(directory + '/paper_1_shelve') + +############################################################################################### +print 'CH5-1 ANALYTIC SOLUTIONS' + +# Input parameters: +a = 0.125 # in nm +phi = pi/2 +dim = (128, 1024, 1024) # in px (z, y, x) +density = 100 +# Create magnetic shape: +center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! +radius = dim[1]/4 # in px +height = dim[0]/2 # in px +print '--CALCULATE ANALYTIC SOLUTIONS' +# Get analytic solution: +phase_map_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) +phase_map_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) +print '--PLOT/SAVE ANALYTIC SOLUTIONS' +phase_map_ana_disc.display_combined(density, 'Analytic solution: hom. magn. disc', 'bilinear') +axis = plt.gcf().add_subplot(1, 2, 2, aspect='equal') +axis.axhline(y=512, linewidth=3, linestyle='--', color='r') +plt.figtext(0.15, 0.2, 'a)', fontsize=30, color='w') +#plt.figtext(0.52, 0.2, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-1-analytic_solution_disc.png', bbox_inches='tight') +phase_map_ana_vort.display_combined(density, 'Analytic solution: vortex state', 'bilinear') +axis = plt.gcf().add_subplot(1, 2, 2, aspect='equal') +axis.axhline(y=512, linewidth=3, linestyle='--', color='r') +plt.figtext(0.15, 0.2, 'c)', fontsize=30, color='w') +plt.figtext(0.52, 0.2, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-1-analytic_solution_vort.png', bbox_inches='tight') +# Get colorwheel: +PhaseMap.make_color_wheel() +plt.figtext(0.15, 0.14, 'e)', fontsize=30, color='w') +plt.savefig(directory + '/ch5-1-colorwheel.png', bbox_inches='tight') + +############################################################################################### +print 'CH5-1 PHASE SLICES REAL SPACE' + +# Input parameters: +a = 0.5 # in nm +phi = pi/2 +density = 100 +dim = (32, 256, 256) # in px (z, y, x) +# Create magnetic shape: +center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! +radius = dim[1]/4 # in px +height = dim[0]/2 # in px + +key = 'ch5-1-phase_slices_real' +if key in data_shelve and not force_calculation: + print '--LOAD MAGNETIC DISTRIBUTION' + (x_d, y_d, dy_d, x_v, y_v, dy_v) = data_shelve[key] +else: + print '--CREATE MAGNETIC DISTRIBUTION' + mag_shape = mc.Shapes.disc(dim, center, radius, height) + + print '--CREATE PHASE SLICES HOMOG. MAGN. DISC' + # Arrays for plotting: + x_d = [] + y_d = [] + dy_d = [] + # Analytic solution: + L = dim[1] * a # in px/nm + Lz = 0.5 * dim[0] * a # in px/nm + R = 0.25 * L # in px/nm + x0 = L / 2 # in px/nm + + def F_disc(x): + coeff = - pi * Lz / (2*PHI_0) * 1E3 # in mrad -> *1000 + result = coeff * (- (x - x0) * np.sin(phi)) + result *= np.where(np.abs(x - x0) <= R, 1, (R / (x - x0)) ** 2) + return result + + x_d.append(np.linspace(0, L, 5000)) + y_d.append(F_disc(x_d[0])) + dy_d.append(np.zeros_like(x_d[0])) + # Create MagData (Disc): + mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) + for i in range(5): + print '----a =', mag_data_disc.a, 'nm', 'dim =', mag_data_disc.dim + projector = SimpleProjector(mag_data_disc.dim) + phase_map = PMConvolve(mag_data_disc.a, projector)(mag_data_disc) + phase_map.display_combined(density, 'Disc, a = {} nm'.format(mag_data_disc.a)) + x_d.append(np.linspace(mag_data_disc.a * 0.5, + mag_data_disc.a * (mag_data_disc.dim[1]-0.5), + mag_data_disc.dim[1])) + slice_pos = int(mag_data_disc.dim[1]/2) + y_d.append(phase_map.phase[slice_pos, :]*1E3) # *1E3: rad to mrad + dy_d.append(phase_map.phase[slice_pos, :]*1E3 - F_disc(x_d[-1])) # *1E3: rad to mrad + if i < 4: mag_data_disc.scale_down() + + print '--CREATE PHASE SLICES VORTEX STATE DISC' + x_v = [] + y_v = [] + dy_v = [] + # Analytic solution: + L = dim[1] * a # in px/nm + Lz = 0.5 * dim[0] * a # in px/nm + R = 0.25 * L # in px/nm + x0 = L / 2 # in px/nm + + def F_vort(x): + coeff = pi*Lz/PHI_0 * 1E3 # in mrad -> *1000 + result = coeff * np.where(np.abs(x - x0) <= R, (np.abs(x-x0)-R), 0) + return result + + x_v.append(np.linspace(0, L, 5001)) + y_v.append(F_vort(x_v[0])) + dy_v.append(np.zeros_like(x_v[0])) + # Create MagData (Vortex): + mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape)) + for i in range(5): + print '----a =', mag_data_vort.a, 'nm', 'dim =', mag_data_vort.dim + projector = SimpleProjector(mag_data_vort.dim) + phase_map = PMConvolve(mag_data_vort.a, projector)(mag_data_vort) + phase_map.display_combined(density, 'Disc, a = {} nm'.format(mag_data_vort.a)) + x_v.append(np.linspace(mag_data_vort.a * 0.5, + mag_data_vort.a * (mag_data_vort.dim[1]-0.5), + mag_data_vort.dim[1])) + slice_pos = int(mag_data_vort.dim[1]/2) + y_v.append(phase_map.phase[slice_pos, :]*1E3) # *1E3: rad to mrad + dy_v.append(phase_map.phase[slice_pos, :]*1E3 - F_vort(x_v[-1])) # *1E3: rad to mrad + if i < 4: mag_data_vort.scale_down() + + # Shelve x, y and dy: + print '--SAVE PHASE SLICES' + data_shelve[key] = (x_d, y_d, dy_d, x_v, y_v, dy_v) + +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Central phase slices', fontsize=20) + +print '--PLOT/SAVE PHASE SLICES HOMOG. MAGN. DISC' +# Plot phase slices: +axes[0].plot(x_d[0], y_d[0], '-k', linewidth=1.5, label='analytic') +axes[0].plot(x_d[1], y_d[1], '-r', linewidth=1.5, label='0.5 nm') +axes[0].plot(x_d[2], y_d[2], '-m', linewidth=1.5, label='1 nm') +axes[0].plot(x_d[3], y_d[3], '-y', linewidth=1.5, label='2 nm') +axes[0].plot(x_d[4], y_d[4], '-g', linewidth=1.5, label='4 nm') +axes[0].plot(x_d[5], y_d[5], '-c', linewidth=1.5, label='8 nm') +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].set_title('Homog. magn. disc', fontsize=18) +axes[0].set_xlabel('x [nm]', fontsize=15) +axes[0].set_ylabel('phase [mrad]', fontsize=15) +axes[0].set_xlim(0, 128) +axes[0].set_ylim(-220, 220) +# Plot Zoombox and Arrow: +zoom = (23.5, 160, 15, 40) +rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') +axes[0].add_patch(rect) +axes[0].arrow(zoom[0]+zoom[2], zoom[1]+zoom[3]/2, 36, 0, length_includes_head=True, + head_width=10, head_length=4, fc='k', ec='k') +# Plot zoom inset: +ins_axis_d = plt.axes([0.33, 0.57, 0.14, 0.3]) +ins_axis_d.plot(x_d[0], y_d[0], '-k', linewidth=1.5, label='analytic') +ins_axis_d.plot(x_d[1], y_d[1], '-r', linewidth=1.5, label='0.5 nm') +ins_axis_d.plot(x_d[2], y_d[2], '-m', linewidth=1.5, label='1 nm') +ins_axis_d.plot(x_d[3], y_d[3], '-y', linewidth=1.5, label='2 nm') +ins_axis_d.plot(x_d[4], y_d[4], '-g', linewidth=1.5, label='4 nm') +ins_axis_d.plot(x_d[5], y_d[5], '-c', linewidth=1.5, label='8 nm') +ins_axis_d.tick_params(axis='both', which='major', labelsize=14) +ins_axis_d.set_xlim(zoom[0], zoom[0]+zoom[2]) +ins_axis_d.set_ylim(zoom[1], zoom[1]+zoom[3]) +ins_axis_d.xaxis.set_major_locator(MaxNLocator(nbins=4, integer=True)) +ins_axis_d.yaxis.set_major_locator(MaxNLocator(nbins=3)) + +print '--PLOT/SAVE PHASE SLICES VORTEX STATE DISC' +# Plot phase slices: +axes[1].plot(x_v[0], y_v[0], '-k', linewidth=1.5, label='analytic') +axes[1].plot(x_v[1], y_v[1], '-r', linewidth=1.5, label='0.5 nm') +axes[1].plot(x_v[2], y_v[2], '-m', linewidth=1.5, label='1 nm') +axes[1].plot(x_v[3], y_v[3], '-y', linewidth=1.5, label='2 nm') +axes[1].plot(x_v[4], y_v[4], '-g', linewidth=1.5, label='4 nm') +axes[1].plot(x_v[5], y_v[5], '-c', linewidth=1.5, label='8 nm') +axes[1].tick_params(axis='both', which='major', labelsize=14) +axes[1].set_title('Vortex state disc', fontsize=18) +axes[1].set_xlabel('x [nm]', fontsize=15) +axes[1].set_ylabel('phase [mrad]', fontsize=15) +axes[1].set_xlim(0, 128) +axes[1].yaxis.set_major_locator(MaxNLocator(nbins=6)) +axes[1].legend() +# Plot Zoombox and Arrow: +zoom = (59, 340, 10, 55) +rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') +axes[1].add_patch(rect) +axes[1].arrow(zoom[0]+zoom[2]/2, zoom[1], 0, -193, length_includes_head=True, + head_width=2, head_length=20, fc='k', ec='k') +# Plot zoom inset: +ins_axis_v = plt.axes([0.695, 0.15, 0.075, 0.3]) +ins_axis_v.plot(x_v[0], y_v[0], '-k', linewidth=1.5, label='analytic') +ins_axis_v.plot(x_v[1], y_v[1], '-r', linewidth=1.5, label='0.5 nm') +ins_axis_v.plot(x_v[2], y_v[2], '-m', linewidth=1.5, label='1 nm') +ins_axis_v.plot(x_v[3], y_v[3], '-y', linewidth=1.5, label='2 nm') +ins_axis_v.plot(x_v[4], y_v[4], '-g', linewidth=1.5, label='4 nm') +ins_axis_v.plot(x_v[5], y_v[5], '-c', linewidth=1.5, label='8 nm') +ins_axis_v.tick_params(axis='both', which='major', labelsize=14) +ins_axis_v.set_xlim(zoom[0], zoom[0]+zoom[2]) +ins_axis_v.set_ylim(zoom[1], zoom[1]+zoom[3]) +ins_axis_v.xaxis.set_major_locator(MaxNLocator(nbins=4, integer=True)) +ins_axis_v.yaxis.set_major_locator(MaxNLocator(nbins=4)) + +plt.show() +#plt.figtext(0.15, 0.13, 'a)', fontsize=30) +#plt.figtext(0.57, 0.13, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-1-phase_slice_comparison.png', bbox_inches='tight') + +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Central phase slice errors', fontsize=20) + +print '--PLOT/SAVE PHASE SLICE ERRORS HOMOG. MAGN. DISC' +# Plot phase slices: +axes[0].plot(x_d[0], dy_d[0], '-k', linewidth=1.5, label='analytic') +axes[0].plot(x_d[1], dy_d[1], '-r', linewidth=1.5, label='0.5 nm') +axes[0].plot(x_d[2], dy_d[2], '-m', linewidth=1.5, label='1 nm') +axes[0].plot(x_d[3], dy_d[3], '-y', linewidth=1.5, label='2 nm') +axes[0].plot(x_d[4], dy_d[4], '-g', linewidth=1.5, label='4 nm') +axes[0].plot(x_d[5], dy_d[5], '-c', linewidth=1.5, label='8 nm') +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].set_title('Homog. magn. disc', fontsize=18) +axes[0].set_xlabel('x [nm]', fontsize=15) +axes[0].set_ylabel('phase [mrad]', fontsize=15) +axes[0].set_xlim(0, 128) + +print '--PLOT/SAVE PHASE SLICE ERRORS VORTEX STATE DISC' +# Plot phase slices: +axes[1].plot(x_v[0], dy_v[0], '-k', linewidth=1.5, label='analytic') +axes[1].plot(x_v[1], dy_v[1], '-r', linewidth=1.5, label='0.5 nm') +axes[1].plot(x_v[2], dy_v[2], '-m', linewidth=1.5, label='1 nm') +axes[1].plot(x_v[3], dy_v[3], '-y', linewidth=1.5, label='2 nm') +axes[1].plot(x_v[4], dy_v[4], '-g', linewidth=1.5, label='4 nm') +axes[1].plot(x_v[5], dy_v[5], '-c', linewidth=1.5, label='8 nm') +axes[1].tick_params(axis='both', which='major', labelsize=14) +axes[1].set_title('Vortex state disc', fontsize=18) +axes[1].set_xlabel('x [nm]', fontsize=15) +axes[1].set_ylabel('phase [mrad]', fontsize=15) +axes[1].set_xlim(0, 128) +axes[1].legend(loc=4) + +plt.show() +#plt.figtext(0.15, 0.13, 'a)', fontsize=30) +#plt.figtext(0.57, 0.13, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-1-phase_slice_errors.png', bbox_inches='tight') + +############################################################################################### +print 'CH5-1 PHASE DIFFERENCES REAL SPACE' + +# Input parameters: +a = 1.0 # in nm +phi = pi/2 +dim = (16, 128, 128) # in px (z, y, x) +center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! +radius = dim[1]/4 # in px +height = dim[0]/2 # in px + +key = 'ch5-1-phase_diff_mag_dist' +if key in data_shelve and not force_calculation: + print '--LOAD MAGNETIC DISTRIBUTIONS' + (mag_data_disc, mag_data_vort) = data_shelve[key] +else: + print '--CREATE MAGNETIC DISTRIBUTIONS' + # Create magnetic shape (4 times the size): + a_big = a / 2 + dim_big = (dim[0]*2, dim[1]*2, dim[2]*2) + center_big = (dim_big[0]/2-0.5, dim_big[1]/2.-0.5, dim_big[2]/2.-0.5) + radius_big = dim_big[1]/4 # in px + height_big = dim_big[0]/2 # in px + mag_shape = mc.Shapes.disc(dim_big, center_big, radius_big, height_big) + # Create MagData (4 times the size): + mag_data_disc = MagData(a_big, mc.create_mag_dist_homog(mag_shape, phi)) + mag_data_vort = MagData(a_big, mc.create_mag_dist_vortex(mag_shape, center_big)) + # Scale mag_data, grid spacing and dimensions: + mag_data_disc.scale_down() + mag_data_vort.scale_down() + print '--SAVE MAGNETIC DISTRIBUTIONS' + # Shelve magnetic distributions: + data_shelve[key] = (mag_data_disc, mag_data_vort) + +print '--CALCULATE PHASE DIFFERENCES' +# Create projector along z-axis and phasemapper: +projector = SimpleProjector(dim) +phasemapper = PMConvolve(a, projector) +# Get analytic solutions: +phase_map_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) +phase_map_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) +# Create norm for the plots: +bounds = np.array([-3, -0.5, -0.25, -0.1, 0, 0.1, 0.25, 0.5, 3]) +norm = BoundaryNorm(bounds, RdBu.N) +# Calculations (Disc): +phase_map_num_disc = phasemapper(mag_data_disc) +phase_map_num_disc.unit = 'mrad' +phase_diff_disc = phase_map_num_disc - phase_map_ana_disc +RMS_disc = np.sqrt(np.mean(phase_diff_disc.phase**2)) +# Calculations (Vortex): +phase_map_num_vort = phasemapper(mag_data_vort) +phase_map_num_vort.unit = 'mrad' +phase_diff_vort = phase_map_num_vort - phase_map_ana_vort +RMS_vort = np.sqrt(np.mean(phase_diff_vort.phase**2)) + +print '--PLOT/SAVE PHASE DIFFERENCES' +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Difference of the real space approach from the analytical solution', fontsize=20) +# Plot MagData (Disc): +phase_diff_disc.display_phase(u'Homog. magn. disc, RMS = {:3.2f} µrad'.format(RMS_disc*1000), + limit=np.max(bounds), norm=norm, axis=axes[0]) +axes[0].set_aspect('equal') +# Plot MagData (Disc): +phase_diff_vort.display_phase(u'Vortex state disc, RMS = {:3.2f} µrad'.format(RMS_vort*1000), + limit=np.max(bounds), norm=norm, axis=axes[1]) +axes[1].set_aspect('equal') +# Save Plots: +plt.figtext(0.15, 0.2, 'a)', fontsize=30) +plt.figtext(0.52, 0.2, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-1-phase_differences.png', bbox_inches='tight') + +############################################################################################### +print 'CLOSING SHELVE\n' +# Close shelve: +data_shelve.close() diff --git a/scripts/paper 1/ch5-2-evaluation_fourier_space.py b/scripts/paper 1/ch5-2-evaluation_fourier_space.py index 4a1ef4596f874aaf1cb39fb8d9be64a597f09651..53838f275a742c47ece125d2907c7e3266a95022 100644 --- a/scripts/paper 1/ch5-2-evaluation_fourier_space.py +++ b/scripts/paper 1/ch5-2-evaluation_fourier_space.py @@ -7,9 +7,6 @@ Created on Fri Jul 26 14:37:30 2013 import time -import pdb -import traceback -import sys import os import numpy as np @@ -18,12 +15,10 @@ from numpy import pi import shelve import pyramid.magcreator as mc -import pyramid.projector as pj -import pyramid.phasemapper as pm import pyramid.analytic as an -import pyramid.holoimage as hi from pyramid.magdata import MagData -from pyramid.phasemap import PhaseMap +from pyramid.projector import SimpleProjector +from pyramid.phasemapper import PMFourier import matplotlib.pyplot as plt from matplotlib.colors import BoundaryNorm @@ -31,157 +26,151 @@ from matplotlib.ticker import MaxNLocator from matplotlib.cm import RdBu +force_calculation = False PHI_0 = -2067.83 # magnetic flux in T*nm² -def run(): - - print '\nACCESS SHELVE' - # Create / Open databank: - directory = '../../output/paper 1' - if not os.path.exists(directory): - os.makedirs(directory) - data_shelve = shelve.open(directory + '/paper_1_shelve') - - ############################################################################################### - print 'CH5-1 PHASE SLICES FOURIER SPACE' - - # Input parameters: - a = 0.25 # in nm - phi = pi/2 - density = 100 - dim = (64, 512, 512) # in px (z, y, x) - # Create magnetic shape: - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - - key = 'ch5-2-phase_slices_fourier' - if key in data_shelve: - print '--LOAD MAGNETIC DISTRIBUTION' - (x_d, y_d0, y_d10, dy_d0, dy_d10, x_v, y_v0, y_v10, dy_v0, dy_v10) = data_shelve[key] - else: - print '--CREATE MAGNETIC DISTRIBUTION' - mag_shape = mc.Shapes.disc(dim, center, radius, height) - - print '--CREATE PHASE SLICES HOMOG. MAGN. DISC' - # Arrays for plotting: - x_d = [] - y_d0 = [] - y_d10 = [] - dy_d0 = [] - dy_d10 = [] - # Analytic solution: - L = dim[1] * a # in px/nm - Lz = 0.5 * dim[0] * a # in px/nm - R = 0.25 * L # in px/nm - x0 = L / 2 # in px/nm - - def F_disc(x): - coeff = - pi * Lz / (2*PHI_0) * 1E3 # in mrad -> *1000 - result = coeff * (- (x - x0) * np.sin(phi)) - result *= np.where(np.abs(x - x0) <= R, 1, (R / (x - x0)) ** 2) - return result - - x_d.append(np.linspace(0, L, 5000)) - y_d0.append(F_disc(x_d[0])) - y_d10.append(F_disc(x_d[0])) - dy_d0.append(np.zeros_like(x_d[0])) - dy_d10.append(np.zeros_like(x_d[0])) - # Create MagData (Disc): - mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) - for i in range(5): - mag_data_disc.scale_down() - print '----a =', mag_data_disc.a, 'nm', 'dim =', mag_data_disc.dim - projection = pj.simple_axis_projection(mag_data_disc) - phase_map0 = PhaseMap(mag_data_disc.a, - pm.phase_mag_fourier(mag_data_disc.a, projection, - padding=0), 'mrad') - phase_map10 = PhaseMap(mag_data_disc.a, - pm.phase_mag_fourier(mag_data_disc.a, projection, - padding=10), 'mrad') - hi.display_combined(phase_map0, density, - 'Disc, a = {} nm'.format(mag_data_disc.a)) - hi.display_combined(phase_map10, density, - 'Disc, a = {} nm'.format(mag_data_disc.a)) - x_d.append(np.linspace(mag_data_disc.a * 0.5, - mag_data_disc.a * (mag_data_disc.dim[1]-0.5), - mag_data_disc.dim[1])) - slice_pos = int(mag_data_disc.dim[1]/2) - y_d0.append(phase_map0.phase[slice_pos, :]*1E3) # *1E3: rad to mrad - y_d10.append(phase_map10.phase[slice_pos, :]*1E3) # *1E3: rad to mrad - dy_d0.append(phase_map0.phase[slice_pos, :]*1E3 - F_disc(x_d[-1])) # *1E3: in mrad - dy_d10.append(phase_map10.phase[slice_pos, :]*1E3 - F_disc(x_d[-1])) # *1E3: in mrad - - print '--CREATE PHASE SLICES VORTEX STATE DISC' - x_v = [] - y_v0 = [] - y_v10 = [] - dy_v0 = [] - dy_v10 = [] - # Analytic solution: - L = dim[1] * a # in px/nm - Lz = 0.5 * dim[0] * a # in px/nm - R = 0.25 * L # in px/nm - x0 = L / 2 # in px/nm - - def F_vort(x): - coeff = pi*Lz/PHI_0 * 1E3 # in mrad -> *1000 - result = coeff * np.where(np.abs(x - x0) <= R, (np.abs(x-x0)-R), 0) - return result - - x_v.append(np.linspace(0, L, 5000)) - y_v0.append(F_vort(x_v[0])) - y_v10.append(F_vort(x_v[0])) - dy_v0.append(np.zeros_like(x_v[0])) - dy_v10.append(np.zeros_like(x_v[0])) - # Create MagData (Vortex): - mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape)) - for i in range(5): - mag_data_vort.scale_down() - print '----a =', mag_data_vort.a, 'nm', 'dim =', mag_data_vort.dim - projection = pj.simple_axis_projection(mag_data_vort) - phase_map0 = PhaseMap(mag_data_vort.a, - pm.phase_mag_fourier(mag_data_vort.a, projection, - padding=0), 'mrad') - phase_map10 = PhaseMap(mag_data_vort.a, - pm.phase_mag_fourier(mag_data_vort.a, projection, - padding=10), 'mrad') - hi.display_combined(phase_map0, density, - 'Disc, a = {} nm'.format(mag_data_vort.a)) - hi.display_combined(phase_map10, density, - 'Disc, a = {} nm'.format(mag_data_vort.a)) - x_v.append(np.linspace(mag_data_vort.a * 0.5, - mag_data_vort.a * (mag_data_vort.dim[1]-0.5), - mag_data_vort.dim[1])) - slice_pos = int(mag_data_vort.dim[1]/2) - y_v0.append(phase_map0.phase[slice_pos, :]*1E3) # *1E3: rad to mrad - y_v10.append(phase_map10.phase[slice_pos, :]*1E3) # *1E3: rad to mrad - dy_v0.append(phase_map0.phase[slice_pos, :]*1E3 - F_vort(x_v[-1])) # *1E3: in mrad - dy_v10.append(phase_map10.phase[slice_pos, :]*1E3 - F_vort(x_v[-1])) # *1E3: in mrad - - # Shelve x, y and dy: - print '--SAVE PHASE SLICES' - data_shelve[key] = (x_d, y_d0, y_d10, dy_d0, dy_d10, x_v, y_v0, y_v10, dy_v0, dy_v10) - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Central phase slices (padding = 0)', fontsize=20) - - print '--PLOT/SAVE PHASE SLICES HOMOG. MAGN. DISC PADDING = 0' - # Plot phase slices: - axes[0].plot(x_d[0], y_d0[0], '-k', linewidth=1.5, label='analytic') - axes[0].plot(x_d[1], y_d0[1], '-r', linewidth=1.5, label='0.5 nm') - axes[0].plot(x_d[2], y_d0[2], '-m', linewidth=1.5, label='1 nm') - axes[0].plot(x_d[3], y_d0[3], '-y', linewidth=1.5, label='2 nm') - axes[0].plot(x_d[4], y_d0[4], '-g', linewidth=1.5, label='4 nm') - axes[0].plot(x_d[5], y_d0[5], '-c', linewidth=1.5, label='8 nm') - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].set_title('Homog. magn. disc', fontsize=18) - axes[0].set_xlabel('x [nm]', fontsize=15) - axes[0].set_ylabel('phase [mrad]', fontsize=15) - axes[0].set_xlim(0, 128) - axes[0].set_ylim(-220, 220) +print '\nACCESS SHELVE' +# Create / Open databank: +directory = '../../output/paper 1' +if not os.path.exists(directory): + os.makedirs(directory) +data_shelve = shelve.open(directory + '/paper_1_shelve') + +############################################################################################### +print 'CH5-1 PHASE SLICES FOURIER SPACE' + +# Input parameters: +a = 0.5 # in nm +phi = pi/2 +density = 100 +dim = (32, 256, 256) # in px (z, y, x) +# Create magnetic shape: +center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! +radius = dim[1]/4 # in px +height = dim[0]/2 # in px + +key = 'ch5-2-phase_slices_fourier' +if key in data_shelve and not force_calculation: + print '--LOAD MAGNETIC DISTRIBUTION' + (x_d, y_d0, y_d10, dy_d0, dy_d10, x_v, y_v0, y_v10, dy_v0, dy_v10) = data_shelve[key] +else: + print '--CREATE MAGNETIC DISTRIBUTION' + mag_shape = mc.Shapes.disc(dim, center, radius, height) + + print '--CREATE PHASE SLICES HOMOG. MAGN. DISC' + # Arrays for plotting: + x_d = [] + y_d0 = [] + y_d10 = [] + dy_d0 = [] + dy_d10 = [] + # Analytic solution: + L = dim[1] * a # in px/nm + Lz = 0.5 * dim[0] * a # in px/nm + R = 0.25 * L # in px/nm + x0 = L / 2 # in px/nm + + def F_disc(x): + coeff = - pi * Lz / (2*PHI_0) * 1E3 # in mrad -> *1000 + result = coeff * (- (x - x0) * np.sin(phi)) + result *= np.where(np.abs(x - x0) <= R, 1, (R / (x - x0)) ** 2) + return result + + x_d.append(np.linspace(0, L, 5000)) + y_d0.append(F_disc(x_d[0])) + y_d10.append(F_disc(x_d[0])) + dy_d0.append(np.zeros_like(x_d[0])) + dy_d10.append(np.zeros_like(x_d[0])) + # Create MagData (Disc): + mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) + for i in range(5): + print '----a =', mag_data_disc.a, 'nm', 'dim =', mag_data_disc.dim + projector = SimpleProjector(mag_data_disc.dim) + phase_map0 = PMFourier(mag_data_disc.a, projector, padding=0)(mag_data_disc) + phase_map10 = PMFourier(mag_data_disc.a, projector, padding=10)(mag_data_disc) + phase_map0.unit = 'mrad' + phase_map10.unit = 'mrad' + phase_map0.display_combined(density, 'Disc, a = {} nm'.format(mag_data_disc.a)) + phase_map10.display_combined(density, 'Disc, a = {} nm'.format(mag_data_disc.a)) + x_d.append(np.linspace(mag_data_disc.a * 0.5, + mag_data_disc.a * (mag_data_disc.dim[1]-0.5), + mag_data_disc.dim[1])) + slice_pos = int(mag_data_disc.dim[1]/2) + y_d0.append(phase_map0.phase[slice_pos, :]*1E3) # *1E3: rad to mrad + y_d10.append(phase_map10.phase[slice_pos, :]*1E3) # *1E3: rad to mrad + dy_d0.append(phase_map0.phase[slice_pos, :]*1E3 - F_disc(x_d[-1])) # *1E3: in mrad + dy_d10.append(phase_map10.phase[slice_pos, :]*1E3 - F_disc(x_d[-1])) # *1E3: in mrad + if i < 4: mag_data_disc.scale_down() + + print '--CREATE PHASE SLICES VORTEX STATE DISC' + x_v = [] + y_v0 = [] + y_v10 = [] + dy_v0 = [] + dy_v10 = [] + # Analytic solution: + L = dim[1] * a # in px/nm + Lz = 0.5 * dim[0] * a # in px/nm + R = 0.25 * L # in px/nm + x0 = L / 2 # in px/nm + + def F_vort(x): + coeff = pi*Lz/PHI_0 * 1E3 # in mrad -> *1000 + result = coeff * np.where(np.abs(x - x0) <= R, (np.abs(x-x0)-R), 0) + return result + + x_v.append(np.linspace(0, L, 5000)) + y_v0.append(F_vort(x_v[0])) + y_v10.append(F_vort(x_v[0])) + dy_v0.append(np.zeros_like(x_v[0])) + dy_v10.append(np.zeros_like(x_v[0])) + # Create MagData (Vortex): + mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape)) + for i in range(5): + print '----a =', mag_data_vort.a, 'nm', 'dim =', mag_data_vort.dim + projector = SimpleProjector(mag_data_vort.dim) + phase_map0 = PMFourier(mag_data_vort.a, projector, padding=0)(mag_data_vort) + phase_map10 = PMFourier(mag_data_vort.a, projector, padding=10)(mag_data_vort) + phase_map0.unit = 'mrad' + phase_map10.unit = 'mrad' + print np.mean(phase_map0.phase) + phase_map0 -= phase_map0.phase[0, 0] + phase_map10 -= phase_map10.phase[0, 0] + phase_map0.display_combined(density, 'Vortex, a = {} nm'.format(mag_data_vort.a)) + phase_map10.display_combined(density, 'Vortex, a = {} nm'.format(mag_data_vort.a)) + x_v.append(np.linspace(mag_data_vort.a * 0.5, + mag_data_vort.a * (mag_data_vort.dim[1]-0.5), + mag_data_vort.dim[1])) + slice_pos = int(mag_data_vort.dim[1]/2) + y_v0.append(phase_map0.phase[slice_pos, :]*1E3) # *1E3: rad to mrad + y_v10.append(phase_map10.phase[slice_pos, :]*1E3) # *1E3: rad to mrad + dy_v0.append(phase_map0.phase[slice_pos, :]*1E3 - F_vort(x_v[-1])) # *1E3: in mrad + dy_v10.append(phase_map10.phase[slice_pos, :]*1E3 - F_vort(x_v[-1])) # *1E3: in mrad + if i < 4: mag_data_vort.scale_down() + + # Shelve x, y and dy: + print '--SAVE PHASE SLICES' + data_shelve[key] = (x_d, y_d0, y_d10, dy_d0, dy_d10, x_v, y_v0, y_v10, dy_v0, dy_v10) + +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Central phase slices (padding = 0)', fontsize=20) + +print '--PLOT/SAVE PHASE SLICES HOMOG. MAGN. DISC PADDING = 0' +# Plot phase slices: +axes[0].plot(x_d[0], y_d0[0], '-k', linewidth=1.5, label='analytic') +axes[0].plot(x_d[1], y_d0[1], '-r', linewidth=1.5, label='0.5 nm') +axes[0].plot(x_d[2], y_d0[2], '-m', linewidth=1.5, label='1 nm') +axes[0].plot(x_d[3], y_d0[3], '-y', linewidth=1.5, label='2 nm') +axes[0].plot(x_d[4], y_d0[4], '-g', linewidth=1.5, label='4 nm') +axes[0].plot(x_d[5], y_d0[5], '-c', linewidth=1.5, label='8 nm') +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].set_title('Homog. magn. disc', fontsize=18) +axes[0].set_xlabel('x [nm]', fontsize=15) +axes[0].set_ylabel('phase [mrad]', fontsize=15) +axes[0].set_xlim(0, 128) +axes[0].set_ylim(-220, 220) # # Plot Zoombox and Arrow: # zoom = (23.5, 160, 15, 40) # rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') @@ -202,21 +191,21 @@ def run(): # ins_axis_d.xaxis.set_major_locator(MaxNLocator(nbins=4, integer= True)) # ins_axis_d.yaxis.set_major_locator(MaxNLocator(nbins=3)) - print '--PLOT/SAVE PHASE SLICES VORTEX STATE DISC PADDING = 0' - # Plot phase slices: - axes[1].plot(x_v[0], y_v0[0], '-k', linewidth=1.5, label='analytic') - axes[1].plot(x_v[1], y_v0[1], '-r', linewidth=1.5, label='0.5 nm') - axes[1].plot(x_v[2], y_v0[2], '-m', linewidth=1.5, label='1 nm') - axes[1].plot(x_v[3], y_v0[3], '-y', linewidth=1.5, label='2 nm') - axes[1].plot(x_v[4], y_v0[4], '-g', linewidth=1.5, label='4 nm') - axes[1].plot(x_v[5], y_v0[5], '-c', linewidth=1.5, label='8 nm') - axes[1].tick_params(axis='both', which='major', labelsize=14) - axes[1].set_title('Vortex state disc', fontsize=18) - axes[1].set_xlabel('x [nm]', fontsize=15) - axes[1].set_ylabel('phase [mrad]', fontsize=15) - axes[1].set_xlim(0, 128) - axes[1].yaxis.set_major_locator(MaxNLocator(nbins=6)) - axes[1].legend() +print '--PLOT/SAVE PHASE SLICES VORTEX STATE DISC PADDING = 0' +# Plot phase slices: +axes[1].plot(x_v[0], y_v0[0], '-k', linewidth=1.5, label='analytic') +axes[1].plot(x_v[1], y_v0[1], '-r', linewidth=1.5, label='0.5 nm') +axes[1].plot(x_v[2], y_v0[2], '-m', linewidth=1.5, label='1 nm') +axes[1].plot(x_v[3], y_v0[3], '-y', linewidth=1.5, label='2 nm') +axes[1].plot(x_v[4], y_v0[4], '-g', linewidth=1.5, label='4 nm') +axes[1].plot(x_v[5], y_v0[5], '-c', linewidth=1.5, label='8 nm') +axes[1].tick_params(axis='both', which='major', labelsize=14) +axes[1].set_title('Vortex state disc', fontsize=18) +axes[1].set_xlabel('x [nm]', fontsize=15) +axes[1].set_ylabel('phase [mrad]', fontsize=15) +axes[1].set_xlim(0, 128) +axes[1].yaxis.set_major_locator(MaxNLocator(nbins=6)) +axes[1].legend() # # Plot Zoombox and Arrow: # zoom = (59, 340, 10, 55) # rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') @@ -237,29 +226,29 @@ def run(): # ins_axis_v.xaxis.set_major_locator(MaxNLocator(nbins=4, integer= True)) # ins_axis_v.yaxis.set_major_locator(MaxNLocator(nbins=4)) - plt.show() - plt.figtext(0.15, 0.13, 'a)', fontsize=30) - plt.figtext(0.57, 0.13, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-1-phase_slice_padding_0.png', bbox_inches='tight') - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Central phase slices (padding = 10)', fontsize=20) - - print '--PLOT/SAVE PHASE SLICES HOMOG. MAGN. DISC PADDING = 10' - # Plot phase slices: - axes[0].plot(x_d[0], y_d10[0], '-k', linewidth=1.5, label='analytic') - axes[0].plot(x_d[1], y_d10[1], '-r', linewidth=1.5, label='0.5 nm') - axes[0].plot(x_d[2], y_d10[2], '-m', linewidth=1.5, label='1 nm') - axes[0].plot(x_d[3], y_d10[3], '-y', linewidth=1.5, label='2 nm') - axes[0].plot(x_d[4], y_d10[4], '-g', linewidth=1.5, label='4 nm') - axes[0].plot(x_d[5], y_d10[5], '-c', linewidth=1.5, label='8 nm') - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].set_title('Homog. magn. disc', fontsize=18) - axes[0].set_xlabel('x [nm]', fontsize=15) - axes[0].set_ylabel('phase [mrad]', fontsize=15) - axes[0].set_xlim(0, 128) - axes[0].set_ylim(-220, 220) +plt.show() +plt.figtext(0.15, 0.13, 'a)', fontsize=30) +plt.figtext(0.57, 0.13, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-1-phase_slice_padding_0.png', bbox_inches='tight') + +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Central phase slices (padding = 10)', fontsize=20) + +print '--PLOT/SAVE PHASE SLICES HOMOG. MAGN. DISC PADDING = 10' +# Plot phase slices: +axes[0].plot(x_d[0], y_d10[0], '-k', linewidth=1.5, label='analytic') +axes[0].plot(x_d[1], y_d10[1], '-r', linewidth=1.5, label='0.5 nm') +axes[0].plot(x_d[2], y_d10[2], '-m', linewidth=1.5, label='1 nm') +axes[0].plot(x_d[3], y_d10[3], '-y', linewidth=1.5, label='2 nm') +axes[0].plot(x_d[4], y_d10[4], '-g', linewidth=1.5, label='4 nm') +axes[0].plot(x_d[5], y_d10[5], '-c', linewidth=1.5, label='8 nm') +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].set_title('Homog. magn. disc', fontsize=18) +axes[0].set_xlabel('x [nm]', fontsize=15) +axes[0].set_ylabel('phase [mrad]', fontsize=15) +axes[0].set_xlim(0, 128) +axes[0].set_ylim(-220, 220) # # Plot Zoombox and Arrow: # zoom = (23.5, 160, 15, 40) # rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') @@ -280,21 +269,21 @@ def run(): # ins_axis_d.xaxis.set_major_locator(MaxNLocator(nbins=4, integer= True)) # ins_axis_d.yaxis.set_major_locator(MaxNLocator(nbins=3)) - print '--PLOT/SAVE PHASE SLICES VORTEX STATE DISC PADDING = 10' - # Plot phase slices: - axes[1].plot(x_v[0], y_v10[0], '-k', linewidth=1.5, label='analytic') - axes[1].plot(x_v[1], y_v10[1], '-r', linewidth=1.5, label='0.5 nm') - axes[1].plot(x_v[2], y_v10[2], '-m', linewidth=1.5, label='1 nm') - axes[1].plot(x_v[3], y_v10[3], '-y', linewidth=1.5, label='2 nm') - axes[1].plot(x_v[4], y_v10[4], '-g', linewidth=1.5, label='4 nm') - axes[1].plot(x_v[5], y_v10[5], '-c', linewidth=1.5, label='8 nm') - axes[1].tick_params(axis='both', which='major', labelsize=14) - axes[1].set_title('Vortex state disc', fontsize=18) - axes[1].set_xlabel('x [nm]', fontsize=15) - axes[1].set_ylabel('phase [mrad]', fontsize=15) - axes[1].set_xlim(0, 128) - axes[1].yaxis.set_major_locator(MaxNLocator(nbins=6)) - axes[1].legend() +print '--PLOT/SAVE PHASE SLICES VORTEX STATE DISC PADDING = 10' +# Plot phase slices: +axes[1].plot(x_v[0], y_v10[0], '-k', linewidth=1.5, label='analytic') +axes[1].plot(x_v[1], y_v10[1], '-r', linewidth=1.5, label='0.5 nm') +axes[1].plot(x_v[2], y_v10[2], '-m', linewidth=1.5, label='1 nm') +axes[1].plot(x_v[3], y_v10[3], '-y', linewidth=1.5, label='2 nm') +axes[1].plot(x_v[4], y_v10[4], '-g', linewidth=1.5, label='4 nm') +axes[1].plot(x_v[5], y_v10[5], '-c', linewidth=1.5, label='8 nm') +axes[1].tick_params(axis='both', which='major', labelsize=14) +axes[1].set_title('Vortex state disc', fontsize=18) +axes[1].set_xlabel('x [nm]', fontsize=15) +axes[1].set_ylabel('phase [mrad]', fontsize=15) +axes[1].set_xlim(0, 128) +axes[1].yaxis.set_major_locator(MaxNLocator(nbins=6)) +axes[1].legend() # # Plot Zoombox and Arrow: # zoom = (59, 340, 10, 55) # rect = Rectangle((zoom[0], zoom[1]), zoom[2], zoom[3], fc='w', ec='k') @@ -315,349 +304,357 @@ def run(): # ins_axis_v.xaxis.set_major_locator(MaxNLocator(nbins=4, integer= True)) # ins_axis_v.yaxis.set_major_locator(MaxNLocator(nbins=4)) - plt.show() - plt.figtext(0.15, 0.13, 'c)', fontsize=30) - plt.figtext(0.57, 0.13, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-1-phase_slice_padding_10.png', bbox_inches='tight') - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Central phase slice errors (padding = 0)', fontsize=20) - - print '--PLOT/SAVE PHASE SLICE ERRORS HOMOG. MAGN. DISC PADDING = 0' - # Plot phase slices: - axes[0].plot(x_d[0], dy_d0[0], '-k', linewidth=1.5, label='analytic') - axes[0].plot(x_d[1], dy_d0[1], '-r', linewidth=1.5, label='0.5 nm') - axes[0].plot(x_d[2], dy_d0[2], '-m', linewidth=1.5, label='1 nm') - axes[0].plot(x_d[3], dy_d0[3], '-y', linewidth=1.5, label='2 nm') - axes[0].plot(x_d[4], dy_d0[4], '-g', linewidth=1.5, label='4 nm') - axes[0].plot(x_d[5], dy_d0[5], '-c', linewidth=1.5, label='8 nm') - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].set_title('Homog. magn. disc', fontsize=18) - axes[0].set_xlabel('x [nm]', fontsize=15) - axes[0].set_ylabel('phase [mrad]', fontsize=15) - axes[0].set_xlim(0, 128) - - print '--PLOT/SAVE PHASE SLICE ERRORS VORTEX STATE DISC PADDING = 0' - # Plot phase slices: - axes[1].plot(x_v[0], dy_v0[0], '-k', linewidth=1.5, label='analytic') - axes[1].plot(x_v[1], dy_v0[1], '-r', linewidth=1.5, label='0.5 nm') - axes[1].plot(x_v[2], dy_v0[2], '-m', linewidth=1.5, label='1 nm') - axes[1].plot(x_v[3], dy_v0[3], '-y', linewidth=1.5, label='2 nm') - axes[1].plot(x_v[4], dy_v0[4], '-g', linewidth=1.5, label='4 nm') - axes[1].plot(x_v[5], dy_v0[5], '-c', linewidth=1.5, label='8 nm') - axes[1].tick_params(axis='both', which='major', labelsize=14) - axes[1].set_title('Vortex state disc', fontsize=18) - axes[1].set_xlabel('x [nm]', fontsize=15) - axes[1].set_ylabel('phase [mrad]', fontsize=15) - axes[1].set_xlim(0, 128) - axes[1].legend(loc=4) - - plt.show() - plt.figtext(0.15, 0.13, 'c)', fontsize=30) - plt.figtext(0.57, 0.13, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-1-phase_slice_errors_padding_0.png', bbox_inches='tight') - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Central phase slice errors (padding = 10)', fontsize=20) - - print '--PLOT/SAVE PHASE SLICE ERRORS HOMOG. MAGN. DISC PADDING = 10' - # Plot phase slices: - axes[0].plot(x_d[0], dy_d10[0], '-k', linewidth=1.5, label='analytic') - axes[0].plot(x_d[1], dy_d10[1], '-r', linewidth=1.5, label='0.5 nm') - axes[0].plot(x_d[2], dy_d10[2], '-m', linewidth=1.5, label='1 nm') - axes[0].plot(x_d[3], dy_d10[3], '-y', linewidth=1.5, label='2 nm') - axes[0].plot(x_d[4], dy_d10[4], '-g', linewidth=1.5, label='4 nm') - axes[0].plot(x_d[5], dy_d10[5], '-c', linewidth=1.5, label='8 nm') - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].set_title('Homog. magn. disc', fontsize=18) - axes[0].set_xlabel('x [nm]', fontsize=15) - axes[0].set_ylabel('phase [mrad]', fontsize=15) - axes[0].set_xlim(0, 128) - - print '--PLOT/SAVE PHASE SLICE ERRORS VORTEX STATE DISC PADDING = 10' - # Plot phase slices: - axes[1].plot(x_v[0], dy_v10[0], '-k', linewidth=1.5, label='analytic') - axes[1].plot(x_v[1], dy_v10[1], '-r', linewidth=1.5, label='0.5 nm') - axes[1].plot(x_v[2], dy_v10[2], '-m', linewidth=1.5, label='1 nm') - axes[1].plot(x_v[3], dy_v10[3], '-y', linewidth=1.5, label='2 nm') - axes[1].plot(x_v[4], dy_v10[4], '-g', linewidth=1.5, label='4 nm') - axes[1].plot(x_v[5], dy_v10[5], '-c', linewidth=1.5, label='8 nm') - axes[1].tick_params(axis='both', which='major', labelsize=14) - axes[1].set_title('Vortex state disc', fontsize=18) - axes[1].set_xlabel('x [nm]', fontsize=15) - axes[1].set_ylabel('phase [mrad]', fontsize=15) - axes[1].set_xlim(0, 128) - axes[1].legend(loc=4) - - plt.show() - plt.figtext(0.15, 0.13, 'c)', fontsize=30) - plt.figtext(0.57, 0.13, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-1-phase_slice_errors_padding_10.png', bbox_inches='tight') - - ############################################################################################### - print 'CH5-2 PHASE DIFFERENCES FOURIER SPACE' - - # Input parameters: - a = 1.0 # in nm - phi = pi/2 - dim = (16, 128, 128) # in px (z, y, x) - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - - key = 'ch5-1-phase_diff_mag_dist' - if key in data_shelve: - print '--LOAD MAGNETIC DISTRIBUTIONS' - (mag_data_disc, mag_data_vort) = data_shelve[key] +plt.show() +plt.figtext(0.15, 0.13, 'c)', fontsize=30) +plt.figtext(0.57, 0.13, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-1-phase_slice_padding_10.png', bbox_inches='tight') + +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Central phase slice errors (padding = 0)', fontsize=20) + +print '--PLOT/SAVE PHASE SLICE ERRORS HOMOG. MAGN. DISC PADDING = 0' +# Plot phase slices: +axes[0].plot(x_d[0], dy_d0[0], '-k', linewidth=1.5, label='analytic') +axes[0].plot(x_d[1], dy_d0[1], '-r', linewidth=1.5, label='0.5 nm') +axes[0].plot(x_d[2], dy_d0[2], '-m', linewidth=1.5, label='1 nm') +axes[0].plot(x_d[3], dy_d0[3], '-y', linewidth=1.5, label='2 nm') +axes[0].plot(x_d[4], dy_d0[4], '-g', linewidth=1.5, label='4 nm') +axes[0].plot(x_d[5], dy_d0[5], '-c', linewidth=1.5, label='8 nm') +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].set_title('Homog. magn. disc', fontsize=18) +axes[0].set_xlabel('x [nm]', fontsize=15) +axes[0].set_ylabel('phase [mrad]', fontsize=15) +axes[0].set_xlim(0, 128) + +print '--PLOT/SAVE PHASE SLICE ERRORS VORTEX STATE DISC PADDING = 0' +# Plot phase slices: +axes[1].plot(x_v[0], dy_v0[0], '-k', linewidth=1.5, label='analytic') +axes[1].plot(x_v[1], dy_v0[1], '-r', linewidth=1.5, label='0.5 nm') +axes[1].plot(x_v[2], dy_v0[2], '-m', linewidth=1.5, label='1 nm') +axes[1].plot(x_v[3], dy_v0[3], '-y', linewidth=1.5, label='2 nm') +axes[1].plot(x_v[4], dy_v0[4], '-g', linewidth=1.5, label='4 nm') +axes[1].plot(x_v[5], dy_v0[5], '-c', linewidth=1.5, label='8 nm') +axes[1].tick_params(axis='both', which='major', labelsize=14) +axes[1].set_title('Vortex state disc', fontsize=18) +axes[1].set_xlabel('x [nm]', fontsize=15) +axes[1].set_ylabel('phase [mrad]', fontsize=15) +axes[1].set_xlim(0, 128) +axes[1].legend(loc=4) + +plt.show() +plt.figtext(0.15, 0.13, 'c)', fontsize=30) +plt.figtext(0.57, 0.13, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-1-phase_slice_errors_padding_0.png', bbox_inches='tight') + +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Central phase slice errors (padding = 10)', fontsize=20) + +print '--PLOT/SAVE PHASE SLICE ERRORS HOMOG. MAGN. DISC PADDING = 10' +# Plot phase slices: +axes[0].plot(x_d[0], dy_d10[0], '-k', linewidth=1.5, label='analytic') +axes[0].plot(x_d[1], dy_d10[1], '-r', linewidth=1.5, label='0.5 nm') +axes[0].plot(x_d[2], dy_d10[2], '-m', linewidth=1.5, label='1 nm') +axes[0].plot(x_d[3], dy_d10[3], '-y', linewidth=1.5, label='2 nm') +axes[0].plot(x_d[4], dy_d10[4], '-g', linewidth=1.5, label='4 nm') +axes[0].plot(x_d[5], dy_d10[5], '-c', linewidth=1.5, label='8 nm') +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].set_title('Homog. magn. disc', fontsize=18) +axes[0].set_xlabel('x [nm]', fontsize=15) +axes[0].set_ylabel('phase [mrad]', fontsize=15) +axes[0].set_xlim(0, 128) + +print '--PLOT/SAVE PHASE SLICE ERRORS VORTEX STATE DISC PADDING = 10' +# Plot phase slices: +axes[1].plot(x_v[0], dy_v10[0], '-k', linewidth=1.5, label='analytic') +axes[1].plot(x_v[1], dy_v10[1], '-r', linewidth=1.5, label='0.5 nm') +axes[1].plot(x_v[2], dy_v10[2], '-m', linewidth=1.5, label='1 nm') +axes[1].plot(x_v[3], dy_v10[3], '-y', linewidth=1.5, label='2 nm') +axes[1].plot(x_v[4], dy_v10[4], '-g', linewidth=1.5, label='4 nm') +axes[1].plot(x_v[5], dy_v10[5], '-c', linewidth=1.5, label='8 nm') +axes[1].tick_params(axis='both', which='major', labelsize=14) +axes[1].set_title('Vortex state disc', fontsize=18) +axes[1].set_xlabel('x [nm]', fontsize=15) +axes[1].set_ylabel('phase [mrad]', fontsize=15) +axes[1].set_xlim(0, 128) +axes[1].legend(loc=4) + +plt.show() +plt.figtext(0.15, 0.13, 'c)', fontsize=30) +plt.figtext(0.57, 0.13, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-1-phase_slice_errors_padding_10.png', bbox_inches='tight') + +############################################################################################### +print 'CH5-2 PHASE DIFFERENCES FOURIER SPACE' + +# Input parameters: +a = 1.0 # in nm +phi = pi/2 +dim = (16, 128, 128) # in px (z, y, x) +center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! +radius = dim[1]/4 # in px +height = dim[0]/2 # in px + +key = 'ch5-1-phase_diff_mag_dist' +if key in data_shelve and not force_calculation: + print '--LOAD MAGNETIC DISTRIBUTIONS' + (mag_data_disc, mag_data_vort) = data_shelve[key] +else: + print '--CREATE MAGNETIC DISTRIBUTIONS' + # Create magnetic shape (4 times the size): + a_big = a / 2 + dim_big = (dim[0]*2, dim[1]*2, dim[2]*2) + center_big = (dim_big[0]/2-0.5, dim_big[1]/2.-0.5, dim_big[2]/2.-0.5) + radius_big = dim_big[1]/4 # in px + height_big = dim_big[0]/2 # in px + mag_shape = mc.Shapes.disc(dim_big, center_big, radius_big, height_big) + # Create MagData (4 times the size): + mag_data_disc = MagData(a_big, mc.create_mag_dist_homog(mag_shape, phi)) + mag_data_vort = MagData(a_big, mc.create_mag_dist_vortex(mag_shape, center_big)) + # Scale mag_data, grid spacing and dimensions: + mag_data_disc.scale_down() + mag_data_vort.scale_down() + print '--SAVE MAGNETIC DISTRIBUTIONS' + # Shelve magnetic distributions: + data_shelve[key] = (mag_data_disc, mag_data_vort) + +print '--PLOT/SAVE PHASE DIFFERENCES' +# Create projections along z-axis: +projector = SimpleProjector(dim) +# Get analytic solutions: +phase_map_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) +phase_map_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) + +# Create phasemapper: +phasemapper = PMFourier(a, projector, padding=0) +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Difference of the Fourier space approach from the analytical solution', fontsize=20) +# Create norm for the plots: +bounds = np.array([-100, -50, -25, -5, 0, 5, 25, 50, 100]) +norm = BoundaryNorm(bounds, RdBu.N) +# Disc: +phase_map_num_disc = phasemapper(mag_data_disc) +phase_map_num_disc.unit = 'mrad' +phase_diff_disc = phase_map_num_disc - phase_map_ana_disc +RMS_disc = np.sqrt(np.mean(phase_diff_disc.phase**2)) +phase_diff_disc.display_phase('Homog. magn. disc, RMS = {:3.2f} mrad'.format(RMS_disc), + axis=axes[0], limit=np.max(bounds), norm=norm) +axes[0].set_aspect('equal') + +# Create norm for the plots: +bounds = np.array([-3, -0.5, -0.25, -0.1, 0, 0.1, 0.25, 0.5, 3]) +norm = BoundaryNorm(bounds, RdBu.N) +# Vortex: +phase_map_num_vort = phasemapper(mag_data_vort) +phase_map_num_vort.unit = 'mrad' +phase_diff_vort = phase_map_num_vort - phase_map_ana_vort +phase_diff_vort -= np.mean(phase_diff_vort.phase) +RMS_vort = np.sqrt(np.mean(phase_diff_vort.phase**2)) +phase_diff_vort.display_phase(u'Vortex state disc, RMS = {:3.2f} µrad'.format(RMS_vort*1000), + axis=axes[1], limit=np.max(bounds), norm=norm) +axes[1].set_aspect('equal') + +plt.show() +plt.figtext(0.15, 0.2, 'a)', fontsize=30) +plt.figtext(0.52, 0.2, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-2-fourier_phase_differe_no_padding.png', bbox_inches='tight') + +# Create phasemapper: +phasemapper = PMFourier(a, projector, padding=10) +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Difference of the Fourier space approach from the analytical solution', fontsize=20) +# Create norm for the plots: +bounds = np.array([-3, -0.5, -0.25, -0.1, 0, 0.1, 0.25, 0.5, 3]) +norm = BoundaryNorm(bounds, RdBu.N) +# Disc: +phase_map_num_disc = phasemapper(mag_data_disc) +phase_map_num_disc.unit = 'mrad' +phase_diff_disc = phase_map_num_disc - phase_map_ana_disc +RMS_disc = np.sqrt(np.mean(phase_diff_disc.phase**2)) +phase_diff_disc.display_phase(u'Homog. magn. disc, RMS = {:3.2f} µrad'.format(RMS_disc*1000), + axis=axes[0], limit=np.max(bounds), norm=norm) +axes[0].set_aspect('equal') + +# Create norm for the plots: +bounds = np.array([-3, -0.5, -0.25, -0.1, 0, 0.1, 0.25, 0.5, 3]) +norm = BoundaryNorm(bounds, RdBu.N) +# Vortex: +phase_map_num_vort = phasemapper(mag_data_vort) +phase_map_num_vort.unit = 'mrad' +phase_diff_vort = phase_map_num_vort - phase_map_ana_vort +phase_diff_vort -= np.mean(phase_diff_vort.phase) +RMS_vort = np.sqrt(np.mean(phase_diff_vort.phase**2)) +phase_diff_vort.display_phase(u'Vortex state disc, RMS = {:3.2f} µrad'.format(RMS_vort*1000), + axis=axes[1], limit=np.max(bounds), norm=norm) +axes[1].set_aspect('equal') + +plt.show() +plt.figtext(0.15, 0.2, 'c)', fontsize=30) +plt.figtext(0.52, 0.2, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-2-fourier_phase_differe_padding_10.png', bbox_inches='tight') + +############################################################################################### +print 'CH5-2 FOURIER PADDING VARIATION' + +# Input parameters: +a = 1.0 # in nm +phi = pi/2 +dim = (16, 128, 128) # in px (z, y, x) +center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! +radius = dim[1]/4 # in px +height = dim[0]/2 # in px + +key = 'ch5-2-fourier_padding_mag_dist' +if key in data_shelve and not force_calculation: + print '--LOAD MAGNETIC DISTRIBUTIONS' + (mag_data_disc, mag_data_vort) = data_shelve[key] +else: + print '--CREATE MAGNETIC DISTRIBUTIONS' + # Create magnetic shape (4 times the size): + a_big = a / 2 + dim_big = (dim[0]*2, dim[1]*2, dim[2]*2) + center_big = (dim_big[0]/2-0.5, dim_big[1]/2.-0.5, dim_big[2]/2.-0.5) + radius_big = dim_big[1]/4 # in px + height_big = dim_big[0]/2 # in px + mag_shape = mc.Shapes.disc(dim_big, center_big, radius_big, height_big) + # Create MagData (4 times the size): + mag_data_disc = MagData(a_big, mc.create_mag_dist_homog(mag_shape, phi)) + mag_data_vort = MagData(a_big, mc.create_mag_dist_vortex(mag_shape, center_big)) + # Scale mag_data, grid spacing and dimensions: + mag_data_disc.scale_down() + mag_data_vort.scale_down() + print '--SAVE MAGNETIC DISTRIBUTIONS' + # Shelve magnetic distributions: + data_shelve[key] = (mag_data_disc, mag_data_vort) + +# Create projections along z-axis: +projector = SimpleProjector(dim) +# Get analytic solutions: +phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) +phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) + +# List of applied paddings: +padding_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] + +print '--LOAD/CREATE PADDING SERIES OF HOMOG. MAGN. DISC' +data_disc = np.zeros((3, len(padding_list))) +data_disc[0, :] = padding_list +for (i, padding) in enumerate(padding_list): + key = ', '.join(['Padding->RMS|duration', 'Fourier', 'padding={}'.format(padding_list[i]), + 'a={}'.format(a), 'dim={}'.format(dim), 'phi={}'.format(phi), 'disc']) + if key in data_shelve and not force_calculation: + data_disc[:, i] = data_shelve[key] else: - print '--CREATE MAGNETIC DISTRIBUTIONS' - # Create magnetic shape (4 times the size): - a_big = a / 2 - dim_big = (dim[0]*2, dim[1]*2, dim[2]*2) - center_big = (dim_big[0]/2-0.5, dim_big[1]/2.-0.5, dim_big[2]/2.-0.5) - radius_big = dim_big[1]/4 # in px - height_big = dim_big[0]/2 # in px - mag_shape = mc.Shapes.disc(dim_big, center_big, radius_big, height_big) - # Create MagData (4 times the size): - mag_data_disc = MagData(a_big, mc.create_mag_dist_homog(mag_shape, phi)) - mag_data_vort = MagData(a_big, mc.create_mag_dist_vortex(mag_shape, center_big)) - # Scale mag_data, grid spacing and dimensions: - mag_data_disc.scale_down() - mag_data_vort.scale_down() - print '--SAVE MAGNETIC DISTRIBUTIONS' - # Shelve magnetic distributions: - data_shelve[key] = (mag_data_disc, mag_data_vort) - - print '--PLOT/SAVE PHASE DIFFERENCES' - # Create projections along z-axis: - projection_disc = pj.simple_axis_projection(mag_data_disc) - projection_vort = pj.simple_axis_projection(mag_data_vort) - # Get analytic solutions: - phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) - phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Difference of the real space approach from the analytical solution', fontsize=20) - # Create norm for the plots: - bounds = np.array([-100, -50, -25, -5, 0, 5, 25, 50, 100]) - norm = BoundaryNorm(bounds, RdBu.N) - # Disc: - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=0) - phase_diff_disc = PhaseMap(a, (phase_num_disc-phase_ana_disc), 'mrad') - RMS_disc = np.sqrt(np.mean(phase_diff_disc.phase**2)) - phase_diff_disc.display('Homog. magn. disc, RMS = {:3.2f} mrad'.format(RMS_disc), - axis=axes[0], limit=np.max(bounds), norm=norm) - axes[0].set_aspect('equal') - # Vortex: - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=0) - phase_diff_vort = PhaseMap(a, (phase_num_vort-phase_ana_vort), 'mrad') - RMS_vort = np.sqrt(np.mean(phase_diff_vort.phase**2)) - phase_diff_vort.display('Vortex state disc, RMS = {:3.2f} mrad'.format(RMS_vort), - axis=axes[1], limit=np.max(bounds), norm=norm) - axes[1].set_aspect('equal') - - plt.show() - plt.figtext(0.15, 0.2, 'a)', fontsize=30) - plt.figtext(0.52, 0.2, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-2-fourier_phase_differe_no_padding.png', bbox_inches='tight') - - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Difference of the real space approach from the analytical solution', fontsize=20) - # Create norm for the plots: - bounds = np.array([-3, -0.5, -0.25, -0.1, 0, 0.1, 0.25, 0.5, 3]) - norm = BoundaryNorm(bounds, RdBu.N) - # Disc: - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=10) - phase_diff_disc = PhaseMap(a, (phase_num_disc-phase_ana_disc), 'mrad') - RMS_disc = np.sqrt(np.mean(phase_diff_disc.phase**2)) - phase_diff_disc.display('Homog. magn. disc, RMS = {:3.2f} mrad'.format(RMS_disc), - axis=axes[0], limit=np.max(bounds), norm=norm) - axes[0].set_aspect('equal') - # Vortex: - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=10) - phase_diff_vort = PhaseMap(a, (phase_num_vort-phase_ana_vort), 'mrad') - RMS_vort = np.sqrt(np.mean(phase_diff_vort.phase**2)) - phase_diff_vort.display('Vortex state disc, RMS = {:3.2f} mrad'.format(RMS_vort), - axis=axes[1], limit=np.max(bounds), norm=norm) - axes[1].set_aspect('equal') - - plt.show() - plt.figtext(0.15, 0.2, 'c)', fontsize=30) - plt.figtext(0.52, 0.2, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-2-fourier_phase_differe_padding_10.png', bbox_inches='tight') - - ############################################################################################### - print 'CH5-2 FOURIER PADDING VARIATION' - - # Input parameters: - a = 1.0 # in nm - phi = pi/2 - dim = (16, 128, 128) # in px (z, y, x) - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts with 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - - key = 'ch5-2-fourier_padding_mag_dist' - if key in data_shelve: - print '--LOAD MAGNETIC DISTRIBUTIONS' - (mag_data_disc, mag_data_vort) = data_shelve[key] + print '----calculate and save padding =', padding_list[i] + phasemapper = PMFourier(a, projector, padding=padding_list[i]) + start_time = time.time() + phase_num_disc = phasemapper(mag_data_disc) + data_disc[2, i] = time.time() - start_time + phase_map_diff = phase_num_disc - phase_ana_disc + phase_map_diff.unit = 'mrad' + phase_map_diff.display_phase() + data_disc[1, i] = np.sqrt(np.mean(phase_map_diff.phase**2))*1E3 # *1E3: rad to mraddd + data_shelve[key] = data_disc[:, i] + +print '--PLOT/SAVE PADDING SERIES OF HOMOG. MAGN. DISC' +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Variation of the padding (homog. magn. disc)', fontsize=20) +# Plot RMS against padding: +axes[0].axhline(y=0.18, linestyle='--', color='g', label='RMS [mrad] (real space)') +axes[0].plot(data_disc[0], data_disc[1], 'go-', label='RMS [mrad] (Fourier space)') +axes[0].set_xlabel('padding', fontsize=15) +axes[0].set_ylabel('RMS [mrad]', fontsize=15) +axes[0].set_xlim(-0.5, 16.5) +axes[0].set_ylim(-5, 45) +axes[0].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].legend() +# Plot zoom inset: +ins_axis_d = plt.axes([0.2, 0.35, 0.25, 0.4]) +ins_axis_d.axhline(y=0.18, linestyle='--', color='g') +ins_axis_d.plot(data_disc[0], data_disc[1], 'go-') +ins_axis_d.set_yscale('log') +ins_axis_d.set_xlim(5.5, 16.5) +ins_axis_d.set_ylim(0.1, 1.1) +ins_axis_d.tick_params(axis='both', which='major', labelsize=14) +# Plot duration against padding: +axes[1].plot(data_disc[0], data_disc[2], 'bo-') +axes[1].set_xlabel('padding', fontsize=15) +axes[1].set_ylabel('duration [s]', fontsize=15) +axes[1].set_xlim(-0.5, 16.5) +axes[1].set_ylim(-0.05, 1.5) +axes[1].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) +axes[1].yaxis.set_major_locator(MaxNLocator(nbins=10)) +axes[1].tick_params(axis='both', which='major', labelsize=14) + +plt.show() +plt.figtext(0.15, 0.13, 'a)', fontsize=30) +plt.figtext(0.57, 0.17, 'b)', fontsize=30) +plt.savefig(directory + '/ch5-2-disc_padding_variation.png', bbox_inches='tight') + +print '--LOAD/CREATE PADDING SERIES OF VORTEX STATE DISC' +data_vort = np.zeros((3, len(padding_list))) +data_vort[0, :] = padding_list +for (i, padding) in enumerate(padding_list): + key = ', '.join(['Padding->RMS|duration', 'Fourier', 'padding={}'.format(padding_list[i]), + 'a={}'.format(a), 'dim={}'.format(dim), 'phi={}'.format(phi), 'vort']) + if key in data_shelve and not force_calculation: + data_vort[:, i] = data_shelve[key] else: - print '--CREATE MAGNETIC DISTRIBUTIONS' - # Create magnetic shape (4 times the size): - a_big = a / 2 - dim_big = (dim[0]*2, dim[1]*2, dim[2]*2) - center_big = (dim_big[0]/2-0.5, dim_big[1]/2.-0.5, dim_big[2]/2.-0.5) - radius_big = dim_big[1]/4 # in px - height_big = dim_big[0]/2 # in px - mag_shape = mc.Shapes.disc(dim_big, center_big, radius_big, height_big) - # Create MagData (4 times the size): - mag_data_disc = MagData(a_big, mc.create_mag_dist_homog(mag_shape, phi)) - mag_data_vort = MagData(a_big, mc.create_mag_dist_vortex(mag_shape, center_big)) - # Scale mag_data, grid spacing and dimensions: - mag_data_disc.scale_down() - mag_data_vort.scale_down() - print '--SAVE MAGNETIC DISTRIBUTIONS' - # Shelve magnetic distributions: - data_shelve[key] = (mag_data_disc, mag_data_vort) - - # Create projections along z-axis: - projection_disc = pj.simple_axis_projection(mag_data_disc) - projection_vort = pj.simple_axis_projection(mag_data_vort) - # Get analytic solutions: - phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) - phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) - - # List of applied paddings: - padding_list = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16] - - print '--LOAD/CREATE PADDING SERIES OF HOMOG. MAGN. DISC' - data_disc = np.zeros((3, len(padding_list))) - data_disc[0, :] = padding_list - for (i, padding) in enumerate(padding_list): - key = ', '.join(['Padding->RMS|duration', 'Fourier', 'padding={}'.format(padding_list[i]), - 'a={}'.format(a), 'dim={}'.format(dim), 'phi={}'.format(phi), 'disc']) - if key in data_shelve: - data_disc[:, i] = data_shelve[key] - else: - print '----calculate and save padding =', padding_list[i] - start_time = time.time() - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding_list[i]) - data_disc[2, i] = time.time() - start_time - phase_diff = (phase_num_disc-phase_ana_disc) - phase_map_diff = PhaseMap(a, phase_diff, 'mrad') - phase_map_diff.display() - data_disc[1, i] = np.sqrt(np.mean(phase_map_diff.phase**2))*1E3 # *1E3: rad to mraddd - data_shelve[key] = data_disc[:, i] - - print '--PLOT/SAVE PADDING SERIES OF HOMOG. MAGN. DISC' - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Variation of the padding (homog. magn. disc)', fontsize=20) - # Plot RMS against padding: - axes[0].axhline(y=0.18, linestyle='--', color='g', label='RMS [mrad] (real space)') - axes[0].plot(data_disc[0], data_disc[1], 'go-', label='RMS [mrad] (Fourier space)') - axes[0].set_xlabel('padding', fontsize=15) - axes[0].set_ylabel('RMS [mrad]', fontsize=15) - axes[0].set_xlim(-0.5, 16.5) - axes[0].set_ylim(-5, 45) - axes[0].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].legend() - # Plot zoom inset: - ins_axis_d = plt.axes([0.2, 0.35, 0.25, 0.4]) - ins_axis_d.axhline(y=0.18, linestyle='--', color='g') - ins_axis_d.plot(data_disc[0], data_disc[1], 'go-') - ins_axis_d.set_yscale('log') - ins_axis_d.set_xlim(5.5, 16.5) - ins_axis_d.set_ylim(0.1, 1.1) - ins_axis_d.tick_params(axis='both', which='major', labelsize=14) - # Plot duration against padding: - axes[1].plot(data_disc[0], data_disc[2], 'bo-') - axes[1].set_xlabel('padding', fontsize=15) - axes[1].set_ylabel('duration [s]', fontsize=15) - axes[1].set_xlim(-0.5, 16.5) - axes[1].set_ylim(-0.05, 3) - axes[1].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) - axes[1].yaxis.set_major_locator(MaxNLocator(nbins=10)) - axes[1].tick_params(axis='both', which='major', labelsize=14) - - plt.show() - plt.figtext(0.15, 0.13, 'a)', fontsize=30) - plt.figtext(0.57, 0.17, 'b)', fontsize=30) - plt.savefig(directory + '/ch5-2-disc_padding_variation.png', bbox_inches='tight') - - print '--LOAD/CREATE PADDING SERIES OF VORTEX STATE DISC' - data_vort = np.zeros((3, len(padding_list))) - data_vort[0, :] = padding_list - for (i, padding) in enumerate(padding_list): - key = ', '.join(['Padding->RMS|duration', 'Fourier', 'padding={}'.format(padding_list[i]), - 'a={}'.format(a), 'dim={}'.format(dim), 'phi={}'.format(phi), 'vort']) - if key in data_shelve: - data_vort[:, i] = data_shelve[key] - else: - print '----calculate and save padding =', padding_list[i] - start_time = time.time() - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding_list[i]) - data_vort[2, i] = time.time() - start_time - phase_diff = (phase_num_vort-phase_ana_vort) - phase_map_diff = PhaseMap(a, phase_diff, 'mrad') - phase_map_diff.display() - data_vort[1, i] = np.sqrt(np.mean(phase_map_diff.phase**2))*1E3 # *1E3: rad to mrad - data_shelve[key] = data_vort[:, i] - - print '--PLOT/SAVE PADDING SERIES OF VORTEX STATE DISC' - # Create figure: - fig, axes = plt.subplots(1, 2, figsize=(16, 7)) - fig.suptitle('Variation of the padding (Vortex state disc)', fontsize=20) - # Plot RMS against padding: - axes[0].axhline(y=0.22, linestyle='--', color='g', label='RMS [mrad] (real space)') - axes[0].plot(data_vort[0], data_vort[1], 'go-', label='RMS [mrad] (Fourier space)') - axes[0].set_xlabel('padding', fontsize=15) - axes[0].set_ylabel('RMS [mrad]', fontsize=15) - axes[0].set_xlim(-0.5, 16.5) - axes[0].set_ylim(-5, 45) - axes[0].tick_params(axis='both', which='major', labelsize=14) - axes[0].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) - axes[0].legend() - # Plot zoom inset: - ins_axis_v = plt.axes([0.2, 0.35, 0.25, 0.4]) - ins_axis_v.axhline(y=0.22, linestyle='--', color='g') - ins_axis_v.plot(data_vort[0], data_vort[1], 'go-') - ins_axis_v.set_yscale('log') - ins_axis_v.set_xlim(5.5, 16.5) - ins_axis_v.set_ylim(0.1, 1.1) - ins_axis_v.tick_params(axis='both', which='major', labelsize=14) - # Plot duration against padding: - axes[1].plot(data_vort[0], data_vort[2], 'bo-') - axes[1].set_xlabel('padding', fontsize=15) - axes[1].set_ylabel('duration [s]', fontsize=15) - axes[1].set_xlim(-0.5, 16.5) - axes[1].set_ylim(-0.05, 3) - axes[1].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) - axes[1].yaxis.set_major_locator(MaxNLocator(nbins=10)) - axes[1].tick_params(axis='both', which='major', labelsize=14) - - plt.show() - plt.figtext(0.15, 0.13, 'c)', fontsize=30) - plt.figtext(0.57, 0.17, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-2-vortex_padding_variation.png', bbox_inches='tight') - - ############################################################################################### - print 'CLOSING SHELVE\n' - # Close shelve: - data_shelve.close() - - ############################################################################################### - - -if __name__ == "__main__": - try: - run() - except: - type, value, tb = sys.exc_info() - traceback.print_exc() - pdb.post_mortem(tb) + print '----calculate and save padding =', padding_list[i] + phasemapper = PMFourier(a, projector, padding=padding_list[i]) + start_time = time.time() + phase_num_vort = phasemapper(mag_data_vort) + data_vort[2, i] = time.time() - start_time + phase_map_diff = phase_num_vort - phase_ana_vort + phase_map_diff -= np.mean(phase_map_diff.phase) + phase_map_diff.unit = 'mrad' + phase_map_diff.display_phase() + data_vort[1, i] = np.sqrt(np.mean(phase_map_diff.phase**2))*1E3 # *1E3: rad to mrad + data_shelve[key] = data_vort[:, i] + +print '--PLOT/SAVE PADDING SERIES OF VORTEX STATE DISC' +# Create figure: +fig, axes = plt.subplots(1, 2, figsize=(16, 7)) +fig.suptitle('Variation of the padding (Vortex state disc)', fontsize=20) +# Plot RMS against padding: +axes[0].axhline(y=0.22, linestyle='--', color='g', label='RMS [mrad] (real space)') +axes[0].plot(data_vort[0], data_vort[1], 'go-', label='RMS [mrad] (Fourier space)') +axes[0].set_xlabel('padding', fontsize=15) +axes[0].set_ylabel('RMS [mrad]', fontsize=15) +axes[0].set_xlim(-0.5, 16.5) +axes[0].set_ylim(-5, 45) +axes[0].tick_params(axis='both', which='major', labelsize=14) +axes[0].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) +axes[0].legend() +# Plot zoom inset: +ins_axis_v = plt.axes([0.2, 0.35, 0.25, 0.4]) +ins_axis_v.axhline(y=0.22, linestyle='--', color='g') +ins_axis_v.plot(data_vort[0], data_vort[1], 'go-') +ins_axis_v.set_yscale('log') +ins_axis_v.set_xlim(5.5, 16.5) +ins_axis_v.set_ylim(0.1, 1.1) +ins_axis_v.tick_params(axis='both', which='major', labelsize=14) +# Plot duration against padding: +axes[1].plot(data_vort[0], data_vort[2], 'bo-') +axes[1].set_xlabel('padding', fontsize=15) +axes[1].set_ylabel('duration [s]', fontsize=15) +axes[1].set_xlim(-0.5, 16.5) +axes[1].set_ylim(-0.05, 1.5) +axes[1].xaxis.set_major_locator(MaxNLocator(nbins=10, integer=True)) +axes[1].yaxis.set_major_locator(MaxNLocator(nbins=10)) +axes[1].tick_params(axis='both', which='major', labelsize=14) + +plt.show() +plt.figtext(0.15, 0.13, 'c)', fontsize=30) +plt.figtext(0.57, 0.17, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-2-vortex_padding_variation.png', bbox_inches='tight') + +############################################################################################### +print 'CLOSING SHELVE\n' +# Close shelve: +data_shelve.close() diff --git a/scripts/paper 1/ch5-3-comparison_of_methods.py b/scripts/paper 1/ch5-3-comparison_of_methods.py index 6d230f049699fe388d30d5c117f6512aa225f03e..c0c64b4c74136f4439ae31a2ae3a8bad2a51ec20 100644 --- a/scripts/paper 1/ch5-3-comparison_of_methods.py +++ b/scripts/paper 1/ch5-3-comparison_of_methods.py @@ -8,9 +8,6 @@ Created on Fri Jul 26 14:37:30 2013 import time -import pdb -import traceback -import sys import os import numpy as np @@ -27,248 +24,235 @@ from pyramid.magdata import MagData import shelve -def run(): +print '\nACCESS SHELVE' +# Create / Open databank: +directory = '../../output/paper 1' +if not os.path.exists(directory): + os.makedirs(directory) +data_shelve = shelve.open(directory + '/paper_1_shelve') - print '\nACCESS SHELVE' - # Create / Open databank: - directory = '../../output/paper 1' - if not os.path.exists(directory): - os.makedirs(directory) - data_shelve = shelve.open(directory + '/paper_1_shelve') +############################################################################################### +print 'CH5-3 METHOD COMPARISON' - ############################################################################################### - print 'CH5-3 METHOD COMPARISON' +key = 'ch5-3-method_comparison' +if key in data_shelve: + print '--LOAD METHOD DATA' + (data_disc_fourier0, data_vort_fourier0, + data_disc_fourier1, data_vort_fourier1, + data_disc_fourier10, data_vort_fourier10, + data_disc_real_s, data_vort_real_s, + data_disc_real_d, data_vort_real_d) = data_shelve[key] +else: + # Input parameters: + steps = 6 + a = 0.25 # in nm + phi = pi/2 + dim = (64, 512, 512) # in px (z, y, x) + center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts at 0! + radius = dim[1]/4 # in px + height = dim[0]/2 # in px - key = 'ch5-3-method_comparison' - if key in data_shelve: - print '--LOAD METHOD DATA' - (data_disc_fourier0, data_vort_fourier0, - data_disc_fourier1, data_vort_fourier1, - data_disc_fourier10, data_vort_fourier10, - data_disc_real_s, data_vort_real_s, - data_disc_real_d, data_vort_real_d) = data_shelve[key] - else: - # Input parameters: - steps = 6 - a = 0.25 # in nm - phi = pi/2 - dim = (64, 512, 512) # in px (z, y, x) - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts at 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px - - print '--CREATE MAGNETIC SHAPE' - mag_shape = mc.Shapes.disc(dim, center, radius, height) - # Create MagData (4 times the size): - print '--CREATE MAG. DIST. HOMOG. MAGN. DISC' - mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) - print '--CREATE MAG. DIST. VORTEX STATE DISC' - mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape, center)) - - # Create Data Arrays: - a_list = [a*2**i for i in np.linspace(1, steps, steps)] - data_disc_fourier0 = np.vstack((a_list, np.zeros((2, steps)))) - data_vort_fourier0 = np.vstack((a_list, np.zeros((2, steps)))) - data_disc_fourier1 = np.vstack((a_list, np.zeros((2, steps)))) - data_vort_fourier1 = np.vstack((a_list, np.zeros((2, steps)))) - data_disc_fourier10 = np.vstack((a_list, np.zeros((2, steps)))) - data_vort_fourier10 = np.vstack((a_list, np.zeros((2, steps)))) - data_disc_real_s = np.vstack((a_list, np.zeros((2, steps)))) - data_vort_real_s = np.vstack((a_list, np.zeros((2, steps)))) - data_disc_real_d = np.vstack((a_list, np.zeros((2, steps)))) - data_vort_real_d = np.vstack((a_list, np.zeros((2, steps)))) + print '--CREATE MAGNETIC SHAPE' + mag_shape = mc.Shapes.disc(dim, center, radius, height) + # Create MagData (4 times the size): + print '--CREATE MAG. DIST. HOMOG. MAGN. DISC' + mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) + print '--CREATE MAG. DIST. VORTEX STATE DISC' + mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape, center)) - for i in range(steps): - # Scale mag_data, grid spacing and dimensions: - mag_data_disc.scale_down() - mag_data_vort.scale_down() - dim = mag_data_disc.dim - a = mag_data_disc.a - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px, index starts at 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px + # Create Data Arrays: + a_list = [a*2**i for i in np.linspace(1, steps, steps)] + data_disc_fourier0 = np.vstack((a_list, np.zeros((2, steps)))) + data_vort_fourier0 = np.vstack((a_list, np.zeros((2, steps)))) + data_disc_fourier1 = np.vstack((a_list, np.zeros((2, steps)))) + data_vort_fourier1 = np.vstack((a_list, np.zeros((2, steps)))) + data_disc_fourier10 = np.vstack((a_list, np.zeros((2, steps)))) + data_vort_fourier10 = np.vstack((a_list, np.zeros((2, steps)))) + data_disc_real_s = np.vstack((a_list, np.zeros((2, steps)))) + data_vort_real_s = np.vstack((a_list, np.zeros((2, steps)))) + data_disc_real_d = np.vstack((a_list, np.zeros((2, steps)))) + data_vort_real_d = np.vstack((a_list, np.zeros((2, steps)))) - print '--a =', a, 'nm', 'dim =', dim - - print '----CALCULATE RMS/DURATION HOMOG. MAGN. DISC' - # Create projections along z-axis: - projection_disc = pj.simple_axis_projection(mag_data_disc) - # Analytic solution: - phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) - # Fourier unpadded: - padding = 0 - start_time = time.clock() - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) - data_disc_fourier0[2, i] = time.clock() - start_time - print '------time (disc, fourier0) =', data_disc_fourier0[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_fourier0[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Fourier padding 1: - padding = 1 - start_time = time.clock() - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) - data_disc_fourier1[2, i] = time.clock() - start_time - print '------time (disc, fourier1) =', data_disc_fourier1[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_fourier1[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Fourier padding 10: - padding = 10 - start_time = time.clock() - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) - data_disc_fourier10[2, i] = time.clock() - start_time - print '------time (disc, fourier10) =', data_disc_fourier10[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_fourier10[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Real space slab: - start_time = time.clock() - phase_num_disc = pm.phase_mag_real(a, projection_disc, geometry='slab') - data_disc_real_s[2, i] = time.clock() - start_time - print '------time (disc, real slab) =', data_disc_real_s[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_real_s[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Real space disc: - start_time = time.clock() - phase_num_disc = pm.phase_mag_real(a, projection_disc, geometry='disc') - data_disc_real_d[2, i] = time.clock() - start_time - print '------time (disc, real disc) =', data_disc_real_d[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_real_d[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - - print '----CALCULATE RMS/DURATION VORTEX STATE DISC' - # Create projections along z-axis: - projection_vort = pj.simple_axis_projection(mag_data_vort) - # Analytic solution: - phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) - # Fourier unpadded: - padding = 0 - start_time = time.clock() - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) - data_vort_fourier0[2, i] = time.clock() - start_time - print '------time (vortex, fourier0) =', data_vort_fourier0[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_fourier0[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Fourier padding 1: - padding = 1 - start_time = time.clock() - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) - data_vort_fourier1[2, i] = time.clock() - start_time - print '------time (vortex, fourier1) =', data_vort_fourier1[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_fourier1[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Fourier padding 10: - padding = 10 - start_time = time.clock() - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) - data_vort_fourier10[2, i] = time.clock() - start_time - print '------time (vortex, fourier10) =', data_vort_fourier10[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_fourier10[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Real space slab: - start_time = time.clock() - phase_num_vort = pm.phase_mag_real(a, projection_vort, geometry='slab') - data_vort_real_s[2, i] = time.clock() - start_time - print '------time (vortex, real slab) =', data_vort_real_s[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_real_s[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Real space disc: - start_time = time.clock() - phase_num_vort = pm.phase_mag_real(a, projection_vort, geometry='disc') - data_vort_real_d[2, i] = time.clock() - start_time - print '------time (vortex, real disc) =', data_vort_real_d[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_real_d[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) + for i in range(steps): + # Scale mag_data, grid spacing and dimensions: + mag_data_disc.scale_down() + mag_data_vort.scale_down() + dim = mag_data_disc.dim + a = mag_data_disc.a + center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px, index starts at 0! + radius = dim[1]/4 # in px + height = dim[0]/2 # in px - print '--SHELVE METHOD DATA' - data_shelve[key] = (data_disc_fourier0, data_vort_fourier0, - data_disc_fourier1, data_vort_fourier1, - data_disc_fourier10, data_vort_fourier10, - data_disc_real_s, data_vort_real_s, - data_disc_real_d, data_vort_real_d) + print '--a =', a, 'nm', 'dim =', dim - print '--PLOT/SAVE METHOD DATA' + print '----CALCULATE RMS/DURATION HOMOG. MAGN. DISC' + # Create projections along z-axis: + projection_disc = pj.simple_axis_projection(mag_data_disc) + # Analytic solution: + phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) + # Fourier unpadded: + padding = 0 + start_time = time.clock() + phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) + data_disc_fourier0[2, i] = time.clock() - start_time + print '------time (disc, fourier0) =', data_disc_fourier0[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_fourier0[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) + # Fourier padding 1: + padding = 1 + start_time = time.clock() + phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) + data_disc_fourier1[2, i] = time.clock() - start_time + print '------time (disc, fourier1) =', data_disc_fourier1[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_fourier1[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) + # Fourier padding 10: + padding = 10 + start_time = time.clock() + phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) + data_disc_fourier10[2, i] = time.clock() - start_time + print '------time (disc, fourier10) =', data_disc_fourier10[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_fourier10[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) + # Real space slab: + start_time = time.clock() + phase_num_disc = pm.phase_mag_real(a, projection_disc, geometry='slab') + data_disc_real_s[2, i] = time.clock() - start_time + print '------time (disc, real slab) =', data_disc_real_s[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_real_s[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) + # Real space disc: + start_time = time.clock() + phase_num_disc = pm.phase_mag_real(a, projection_disc, geometry='disc') + data_disc_real_d[2, i] = time.clock() - start_time + print '------time (disc, real disc) =', data_disc_real_d[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_real_d[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Plot using shared rows and colums: - fig, axes = plt.subplots(2, 2, sharex='col', sharey='row', figsize=(12, 8)) - fig.tight_layout(rect=(0.05, 0.05, 0.95, 0.95)) - fig.suptitle('Method Comparison', fontsize=20) + print '----CALCULATE RMS/DURATION VORTEX STATE DISC' + # Create projections along z-axis: + projection_vort = pj.simple_axis_projection(mag_data_vort) + # Analytic solution: + phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) + # Fourier unpadded: + padding = 0 + start_time = time.clock() + phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) + data_vort_fourier0[2, i] = time.clock() - start_time + print '------time (vortex, fourier0) =', data_vort_fourier0[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_fourier0[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) + # Fourier padding 1: + padding = 1 + start_time = time.clock() + phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) + data_vort_fourier1[2, i] = time.clock() - start_time + print '------time (vortex, fourier1) =', data_vort_fourier1[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_fourier1[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) + # Fourier padding 10: + padding = 10 + start_time = time.clock() + phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) + data_vort_fourier10[2, i] = time.clock() - start_time + print '------time (vortex, fourier10) =', data_vort_fourier10[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_fourier10[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) + # Real space slab: + start_time = time.clock() + phase_num_vort = pm.phase_mag_real(a, projection_vort, geometry='slab') + data_vort_real_s[2, i] = time.clock() - start_time + print '------time (vortex, real slab) =', data_vort_real_s[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_real_s[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) + # Real space disc: + start_time = time.clock() + phase_num_vort = pm.phase_mag_real(a, projection_vort, geometry='disc') + data_vort_real_d[2, i] = time.clock() - start_time + print '------time (vortex, real disc) =', data_vort_real_d[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_real_d[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Plot duration against a (disc) [top/left]: - axes[1, 0].set_yscale('log') - axes[1, 0].plot(data_disc_fourier0[0], data_disc_fourier0[1], ':bs') - axes[1, 0].plot(data_disc_fourier1[0], data_disc_fourier1[1], ':bo') - axes[1, 0].plot(data_disc_fourier10[0], data_disc_fourier10[1], ':b^') - axes[1, 0].plot(data_disc_real_s[0], data_disc_real_s[1], '--rs') - axes[1, 0].plot(data_disc_real_d[0], data_disc_real_d[1], '--ro') - axes[1, 0].set_xlabel('a [nm]', fontsize=15) - axes[1, 0].set_ylabel('RMS [mrad]', fontsize=15) - axes[1, 0].set_xlim(-0.5, 16.5) - axes[1, 0].tick_params(axis='both', which='major', labelsize=14) - axes[1, 0].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) + print '--SHELVE METHOD DATA' + data_shelve[key] = (data_disc_fourier0, data_vort_fourier0, + data_disc_fourier1, data_vort_fourier1, + data_disc_fourier10, data_vort_fourier10, + data_disc_real_s, data_vort_real_s, + data_disc_real_d, data_vort_real_d) - # Plot RMS against a (disc) [bottom/left]: - plt.tick_params(axis='both', which='major', labelsize=14) - axes[0, 0].set_yscale('log') - axes[0, 0].plot(data_disc_fourier0[0], data_disc_fourier0[2], ':bs') - axes[0, 0].plot(data_disc_fourier1[0], data_disc_fourier1[2], ':bo') - axes[0, 0].plot(data_disc_fourier10[0], data_disc_fourier10[2], ':b^') - axes[0, 0].plot(data_disc_real_s[0], data_disc_real_s[2], '--rs') - axes[0, 0].plot(data_disc_real_d[0], data_disc_real_d[2], '--ro') - axes[0, 0].set_title('Homog. magn. disc', fontsize=18) - axes[0, 0].set_ylabel('duration [s]', fontsize=15) - axes[0, 0].set_xlim(-0.5, 16.5) - axes[0, 0].tick_params(axis='both', which='major', labelsize=14) - axes[0, 0].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) +print '--PLOT/SAVE METHOD DATA' - # Plot duration against a (vortex) [top/right]: - axes[1, 1].set_yscale('log') - axes[1, 1].plot(data_vort_fourier0[0], data_vort_fourier0[1], ':bs') - axes[1, 1].plot(data_vort_fourier1[0], data_vort_fourier1[1], ':bo') - axes[1, 1].plot(data_vort_fourier10[0], data_vort_fourier10[1], ':b^') - axes[1, 1].plot(data_vort_real_s[0], data_vort_real_s[1], '--rs') - axes[1, 1].plot(data_vort_real_d[0], data_vort_real_d[1], '--ro') - axes[1, 1].set_xlabel('a [nm]', fontsize=15) - axes[1, 1].set_xlim(-0.5, 16.5) - axes[1, 1].tick_params(axis='both', which='major', labelsize=14) - axes[1, 1].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) +# Plot using shared rows and colums: +fig, axes = plt.subplots(2, 2, sharex='col', sharey='row', figsize=(12, 8)) +fig.tight_layout(rect=(0.05, 0.05, 0.95, 0.95)) +fig.suptitle('Method Comparison', fontsize=20) - # Plot RMS against a (vortex) [bottom/right]: - axes[0, 1].set_yscale('log') - axes[0, 1].plot(data_vort_fourier0[0], data_vort_fourier0[2], ':bs', - label='Fourier padding=0') - axes[0, 1].plot(data_vort_fourier1[0], data_vort_fourier1[2], ':bo', - label='Fourier padding=1') - axes[0, 1].plot(data_vort_fourier10[0], data_vort_fourier10[2], ':b^', - label='Fourier padding=10') - axes[0, 1].plot(data_vort_real_s[0], data_vort_real_s[2], '--rs', - label='Real space (slab)') - axes[0, 1].plot(data_vort_real_d[0], data_vort_real_d[2], '--ro', - label='Real space (disc)') - axes[0, 1].set_title('Vortex state disc', fontsize=18) - axes[0, 1].set_xlim(-0.5, 16.5) - axes[0, 1].tick_params(axis='both', which='major', labelsize=14) - axes[0, 1].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - axes[0, 1].legend(loc=1) +# Plot duration against a (disc) [top/left]: +axes[1, 0].set_yscale('log') +axes[1, 0].plot(data_disc_fourier0[0], data_disc_fourier0[1], ':bs') +axes[1, 0].plot(data_disc_fourier1[0], data_disc_fourier1[1], ':bo') +axes[1, 0].plot(data_disc_fourier10[0], data_disc_fourier10[1], ':b^') +axes[1, 0].plot(data_disc_real_s[0], data_disc_real_s[1], '--rs') +axes[1, 0].plot(data_disc_real_d[0], data_disc_real_d[1], '--ro') +axes[1, 0].set_xlabel('a [nm]', fontsize=15) +axes[1, 0].set_ylabel('RMS [mrad]', fontsize=15) +axes[1, 0].set_xlim(-0.5, 16.5) +axes[1, 0].tick_params(axis='both', which='major', labelsize=14) +axes[1, 0].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - # Save figure as .png: - plt.show() - plt.figtext(0.45, 0.85, 'a)', fontsize=30) - plt.figtext(0.57, 0.85, 'b)', fontsize=30) - plt.figtext(0.45, 0.15, 'c)', fontsize=30) - plt.figtext(0.57, 0.15, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-3-method comparison.png', bbox_inches='tight') +# Plot RMS against a (disc) [bottom/left]: +plt.tick_params(axis='both', which='major', labelsize=14) +axes[0, 0].set_yscale('log') +axes[0, 0].plot(data_disc_fourier0[0], data_disc_fourier0[2], ':bs') +axes[0, 0].plot(data_disc_fourier1[0], data_disc_fourier1[2], ':bo') +axes[0, 0].plot(data_disc_fourier10[0], data_disc_fourier10[2], ':b^') +axes[0, 0].plot(data_disc_real_s[0], data_disc_real_s[2], '--rs') +axes[0, 0].plot(data_disc_real_d[0], data_disc_real_d[2], '--ro') +axes[0, 0].set_title('Homog. magn. disc', fontsize=18) +axes[0, 0].set_ylabel('duration [s]', fontsize=15) +axes[0, 0].set_xlim(-0.5, 16.5) +axes[0, 0].tick_params(axis='both', which='major', labelsize=14) +axes[0, 0].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - ############################################################################################### - print 'CLOSING SHELVE\n' - # Close shelve: - data_shelve.close() +# Plot duration against a (vortex) [top/right]: +axes[1, 1].set_yscale('log') +axes[1, 1].plot(data_vort_fourier0[0], data_vort_fourier0[1], ':bs') +axes[1, 1].plot(data_vort_fourier1[0], data_vort_fourier1[1], ':bo') +axes[1, 1].plot(data_vort_fourier10[0], data_vort_fourier10[1], ':b^') +axes[1, 1].plot(data_vort_real_s[0], data_vort_real_s[1], '--rs') +axes[1, 1].plot(data_vort_real_d[0], data_vort_real_d[1], '--ro') +axes[1, 1].set_xlabel('a [nm]', fontsize=15) +axes[1, 1].set_xlim(-0.5, 16.5) +axes[1, 1].tick_params(axis='both', which='major', labelsize=14) +axes[1, 1].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) - ############################################################################################### +# Plot RMS against a (vortex) [bottom/right]: +axes[0, 1].set_yscale('log') +axes[0, 1].plot(data_vort_fourier0[0], data_vort_fourier0[2], ':bs', + label='Fourier padding=0') +axes[0, 1].plot(data_vort_fourier1[0], data_vort_fourier1[2], ':bo', + label='Fourier padding=1') +axes[0, 1].plot(data_vort_fourier10[0], data_vort_fourier10[2], ':b^', + label='Fourier padding=10') +axes[0, 1].plot(data_vort_real_s[0], data_vort_real_s[2], '--rs', + label='Real space (slab)') +axes[0, 1].plot(data_vort_real_d[0], data_vort_real_d[2], '--ro', + label='Real space (disc)') +axes[0, 1].set_title('Vortex state disc', fontsize=18) +axes[0, 1].set_xlim(-0.5, 16.5) +axes[0, 1].tick_params(axis='both', which='major', labelsize=14) +axes[0, 1].xaxis.set_major_locator(IndexLocator(base=4, offset=-0.5)) +axes[0, 1].legend(loc=1) +# Save figure as .png: +plt.show() +plt.figtext(0.45, 0.85, 'a)', fontsize=30) +plt.figtext(0.57, 0.85, 'b)', fontsize=30) +plt.figtext(0.45, 0.15, 'c)', fontsize=30) +plt.figtext(0.57, 0.15, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-3-method comparison.png', bbox_inches='tight') -if __name__ == "__main__": - try: - run() - except: - type, value, tb = sys.exc_info() - traceback.print_exc() - pdb.post_mortem(tb) +############################################################################################### +print 'CLOSING SHELVE\n' +# Close shelve: +data_shelve.close() diff --git a/scripts/paper 1/ch5-4-comparison_of_methods_new.py b/scripts/paper 1/ch5-4-comparison_of_methods_new.py index 6be62fcf7f172aaf5c53b626f1bdc66ec6a69775..735db864308c704bf4fc85b4470e68c493ce2a74 100644 --- a/scripts/paper 1/ch5-4-comparison_of_methods_new.py +++ b/scripts/paper 1/ch5-4-comparison_of_methods_new.py @@ -8,9 +8,6 @@ Created on Fri Jul 26 14:37:30 2013 import time -import pdb -import traceback -import sys import os import numpy as np @@ -20,284 +17,272 @@ import matplotlib.pyplot as plt from matplotlib.ticker import NullLocator, LogLocator, LogFormatter import pyramid.magcreator as mc -import pyramid.projector as pj -import pyramid.phasemapper as pm import pyramid.analytic as an from pyramid.magdata import MagData -from pyramid.kernel import Kernel +from pyramid.projector import SimpleProjector +from pyramid.phasemapper import PMConvolve, PMFourier + import shelve -def run(): +force_calculation = False - print '\nACCESS SHELVE' - # Create / Open databank: - directory = '../../output/paper 1' - if not os.path.exists(directory): - os.makedirs(directory) - data_shelve = shelve.open(directory + '/paper_1_shelve') - ############################################################################################### - print 'CH5-4 METHOD COMPARISON' +print '\nACCESS SHELVE' +# Create / Open databank: +directory = '../../output/paper 1' +if not os.path.exists(directory): + os.makedirs(directory) +data_shelve = shelve.open(directory + '/paper_1_shelve') - key = 'ch5-4-method_comparison_new' - if key in data_shelve: - print '--LOAD METHOD DATA' - (data_disc_fourier0, data_vort_fourier0, - data_disc_fourier3, data_vort_fourier3, - data_disc_fourier10, data_vort_fourier10, - data_disc_real_s, data_vort_real_s, - data_disc_real_d, data_vort_real_d) = data_shelve[key] - else: - # Input parameters: - steps = 5 - a = 0.25 # in nm - phi = pi/2 - dim = (64, 512, 512) # in px (z, y, x) - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts at 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px +############################################################################################### +print 'CH5-4 METHOD COMPARISON' - print '--CREATE MAGNETIC SHAPE' - mag_shape = mc.Shapes.disc(dim, center, radius, height) - # Create MagData (4 times the size): - print '--CREATE MAG. DIST. HOMOG. MAGN. DISC' - mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) - print '--CREATE MAG. DIST. VORTEX STATE DISC' - mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape, center)) +key = 'ch5-4-method_comparison_new' +if key in data_shelve and not force_calculation: + print '--LOAD METHOD DATA' + (data_disc_fourier0, data_vort_fourier0, + data_disc_fourier3, data_vort_fourier3, + data_disc_fourier10, data_vort_fourier10, + data_disc_real_s, data_vort_real_s, + data_disc_real_d, data_vort_real_d) = data_shelve[key] +else: + # Input parameters: + steps = 4 + a = 0.5 # in nm + phi = pi/2 + dim = (32, 256, 256) # in px (z, y, x) + center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px (z, y, x) index starts at 0! + radius = dim[1]/4 # in px + height = dim[0]/2 # in px - # Create Data Arrays: - dim_list = [dim[2]/2**i for i in np.linspace(1, steps, steps)] - data_disc_fourier0 = np.vstack((dim_list, np.zeros((2, steps)))) - data_vort_fourier0 = np.vstack((dim_list, np.zeros((2, steps)))) - data_disc_fourier3 = np.vstack((dim_list, np.zeros((2, steps)))) - data_vort_fourier3 = np.vstack((dim_list, np.zeros((2, steps)))) - data_disc_fourier10 = np.vstack((dim_list, np.zeros((2, steps)))) - data_vort_fourier10 = np.vstack((dim_list, np.zeros((2, steps)))) - data_disc_real_s = np.vstack((dim_list, np.zeros((2, steps)))) - data_vort_real_s = np.vstack((dim_list, np.zeros((2, steps)))) - data_disc_real_d = np.vstack((dim_list, np.zeros((2, steps)))) - data_vort_real_d = np.vstack((dim_list, np.zeros((2, steps)))) + print '--CREATE MAGNETIC SHAPE' + mag_shape = mc.Shapes.disc(dim, center, radius, height) + # Create MagData (4 times the size): + print '--CREATE MAG. DIST. HOMOG. MAGN. DISC' + mag_data_disc = MagData(a, mc.create_mag_dist_homog(mag_shape, phi)) + print '--CREATE MAG. DIST. VORTEX STATE DISC' + mag_data_vort = MagData(a, mc.create_mag_dist_vortex(mag_shape, center)) - for i in range(steps): - # Scale mag_data, grid spacing and dimensions: - mag_data_disc.scale_down() - mag_data_vort.scale_down() - dim = mag_data_disc.dim - a = mag_data_disc.a - center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px, index starts at 0! - radius = dim[1]/4 # in px - height = dim[0]/2 # in px + # Create Data Arrays: + dim_list = [dim[2]/2**i for i in range(steps)] + data_disc_fourier0 = np.vstack((dim_list, np.zeros((2, steps)))) + data_vort_fourier0 = np.vstack((dim_list, np.zeros((2, steps)))) + data_disc_fourier3 = np.vstack((dim_list, np.zeros((2, steps)))) + data_vort_fourier3 = np.vstack((dim_list, np.zeros((2, steps)))) + data_disc_fourier10 = np.vstack((dim_list, np.zeros((2, steps)))) + data_vort_fourier10 = np.vstack((dim_list, np.zeros((2, steps)))) + data_disc_real_s = np.vstack((dim_list, np.zeros((2, steps)))) + data_vort_real_s = np.vstack((dim_list, np.zeros((2, steps)))) + data_disc_real_d = np.vstack((dim_list, np.zeros((2, steps)))) + data_vort_real_d = np.vstack((dim_list, np.zeros((2, steps)))) - print '--a =', a, 'nm', 'dim =', dim + for i in range(steps): + # Scale mag_data, grid spacing and dimensions: + dim = mag_data_disc.dim + a = mag_data_disc.a + center = (dim[0]/2-0.5, dim[1]/2.-0.5, dim[2]/2.-0.5) # in px, index starts at 0! + radius = dim[1]/4 # in px + height = dim[0]/2 # in px - print '----CALCULATE RMS/DURATION HOMOG. MAGN. DISC' - # Create projections along z-axis: - projection_disc = pj.simple_axis_projection(mag_data_disc) - # Analytic solution: - phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) - # Fourier unpadded: - padding = 0 - start_time = time.clock() - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) - data_disc_fourier0[2, i] = time.clock() - start_time - print '------time (disc, fourier0) =', data_disc_fourier0[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_fourier0[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Fourier padding 3: - padding = 3 - start_time = time.clock() - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) - data_disc_fourier3[2, i] = time.clock() - start_time - print '------time (disc, fourier3) =', data_disc_fourier3[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_fourier3[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Fourier padding 10: - padding = 10 - start_time = time.clock() - phase_num_disc = pm.phase_mag_fourier(a, projection_disc, padding=padding) - data_disc_fourier10[2, i] = time.clock() - start_time - print '------time (disc, fourier10) =', data_disc_fourier10[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_fourier10[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Real space slab: - kernel = Kernel((dim[1], dim[2]), a, geometry='slab') - start_time = time.clock() - phase_num_disc = pm.phase_mag(a, projection_disc, kernel=kernel) - data_disc_real_s[2, i] = time.clock() - start_time - print '------time (disc, real slab) =', data_disc_real_s[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_real_s[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) - # Real space disc: - kernel = Kernel((dim[1], dim[2]), a, geometry='slab') - start_time = time.clock() - phase_num_disc = pm.phase_mag(a, projection_disc, kernel=kernel) - data_disc_real_d[2, i] = time.clock() - start_time - print '------time (disc, real disc) =', data_disc_real_d[2, i] - phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 - data_disc_real_d[1, i] = np.sqrt(np.mean(phase_diff_disc**2)) + print '--a =', a, 'nm', 'dim =', dim + + # Create projector along z-axis and phasemapper: + projector = SimpleProjector(dim) + pm_fourier0 = PMFourier(a, projector, padding=0) + pm_fourier3 = PMFourier(a, projector, padding=3) + pm_fourier10 = PMFourier(a, projector, padding=10) + pm_slab = PMConvolve(a, projector, geometry='slab') + pm_disc = PMConvolve(a, projector, geometry='disc') - print '----CALCULATE RMS/DURATION HOMOG. MAGN. DISC' - # Create projections along z-axis: - projection_vort = pj.simple_axis_projection(mag_data_vort) - # Analytic solution: - phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) - # Fourier unpadded: - padding = 0 - start_time = time.clock() - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) - data_vort_fourier0[2, i] = time.clock() - start_time - print '------time (vortex, fourier0) =', data_vort_fourier0[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_fourier0[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Fourier padding 3: - padding = 3 - start_time = time.clock() - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) - data_vort_fourier3[2, i] = time.clock() - start_time - print '------time (vortex, fourier3) =', data_vort_fourier3[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_fourier3[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Fourier padding 10: - padding = 10 - start_time = time.clock() - phase_num_vort = pm.phase_mag_fourier(a, projection_vort, padding=padding) - data_vort_fourier10[2, i] = time.clock() - start_time - print '------time (vortex, fourier10) =', data_vort_fourier10[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_fourier10[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Real space slab: - kernel = Kernel((dim[1], dim[2]), a, geometry='slab') - start_time = time.clock() - phase_num_vort = pm.phase_mag(a, projection_vort, kernel=kernel) - data_vort_real_s[2, i] = time.clock() - start_time - print '------time (vortex, real slab) =', data_vort_real_s[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_real_s[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) - # Real space disc: - kernel = Kernel((dim[1], dim[2]), a, geometry='disc') - start_time = time.clock() - phase_num_vort = pm.phase_mag(a, projection_vort, kernel=kernel) - data_vort_real_d[2, i] = time.clock() - start_time - print '------time (vortex, real disc) =', data_vort_real_d[2, i] - phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 - data_vort_real_d[1, i] = np.sqrt(np.mean(phase_diff_vort**2)) + print '----CALCULATE RMS/DURATION HOMOG. MAGN. DISC' + # Analytic solution: + phase_ana_disc = an.phase_mag_disc(dim, a, phi, center, radius, height) + # Fourier unpadded: + start_time = time.clock() + phase_num_disc = pm_fourier0(mag_data_disc) + data_disc_fourier0[2, i] = time.clock() - start_time + print '------time (disc, fourier0) =', data_disc_fourier0[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_fourier0[1, i] = np.sqrt(np.mean(phase_diff_disc.phase**2)) + # Fourier padding 3: + start_time = time.clock() + phase_num_disc = pm_fourier3(mag_data_disc) + data_disc_fourier3[2, i] = time.clock() - start_time + print '------time (disc, fourier3) =', data_disc_fourier3[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_fourier3[1, i] = np.sqrt(np.mean(phase_diff_disc.phase**2)) + # Fourier padding 10: + start_time = time.clock() + phase_num_disc = pm_fourier10(mag_data_disc) + data_disc_fourier10[2, i] = time.clock() - start_time + print '------time (disc, fourier10) =', data_disc_fourier10[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_fourier10[1, i] = np.sqrt(np.mean(phase_diff_disc.phase**2)) + # Real space slab: + start_time = time.clock() + phase_num_disc = pm_slab(mag_data_disc) + data_disc_real_s[2, i] = time.clock() - start_time + print '------time (disc, real slab) =', data_disc_real_s[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_real_s[1, i] = np.sqrt(np.mean(phase_diff_disc.phase**2)) + # Real space disc: + start_time = time.clock() + phase_num_disc = pm_disc(mag_data_disc) + data_disc_real_d[2, i] = time.clock() - start_time + print '------time (disc, real disc) =', data_disc_real_d[2, i] + phase_diff_disc = (phase_ana_disc-phase_num_disc) * 1E3 # in mrad -> *1000 + data_disc_real_d[1, i] = np.sqrt(np.mean(phase_diff_disc.phase**2)) - print '--SHELVE METHOD DATA' - data_shelve[key] = (data_disc_fourier0, data_vort_fourier0, - data_disc_fourier3, data_vort_fourier3, - data_disc_fourier10, data_vort_fourier10, - data_disc_real_s, data_vort_real_s, - data_disc_real_d, data_vort_real_d) + print '----CALCULATE RMS/DURATION HOMOG. MAGN. DISC' + # Analytic solution: + phase_ana_vort = an.phase_mag_vortex(dim, a, center, radius, height) + # Fourier unpadded: + start_time = time.clock() + phase_num_vort = pm_fourier0(mag_data_vort) + data_vort_fourier0[2, i] = time.clock() - start_time + print '------time (vortex, fourier0) =', data_vort_fourier0[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_fourier0[1, i] = np.sqrt(np.mean(phase_diff_vort.phase**2)) + # Fourier padding 3: + start_time = time.clock() + phase_num_vort = pm_fourier3(mag_data_vort) + data_vort_fourier3[2, i] = time.clock() - start_time + print '------time (vortex, fourier3) =', data_vort_fourier3[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_fourier3[1, i] = np.sqrt(np.mean(phase_diff_vort.phase**2)) + # Fourier padding 10: + start_time = time.clock() + phase_num_vort = pm_fourier10(mag_data_vort) + data_vort_fourier10[2, i] = time.clock() - start_time + print '------time (vortex, fourier10) =', data_vort_fourier10[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_fourier10[1, i] = np.sqrt(np.mean(phase_diff_vort.phase**2)) + # Real space slab: + start_time = time.clock() + phase_num_vort = pm_slab(mag_data_vort) + data_vort_real_s[2, i] = time.clock() - start_time + print '------time (vortex, real slab) =', data_vort_real_s[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_real_s[1, i] = np.sqrt(np.mean(phase_diff_vort.phase**2)) + # Real space disc: + start_time = time.clock() + phase_num_vort = pm_disc(mag_data_vort) + data_vort_real_d[2, i] = time.clock() - start_time + print '------time (vortex, real disc) =', data_vort_real_d[2, i] + phase_diff_vort = (phase_ana_vort-phase_num_vort) * 1E3 # in mrad -> *1000 + data_vort_real_d[1, i] = np.sqrt(np.mean(phase_diff_vort.phase**2)) - print '--PLOT/SAVE METHOD DATA' + # Scale down for next iteration: + mag_data_disc.scale_down() + mag_data_vort.scale_down() - # Plot using shared rows and colums: - fig, axes = plt.subplots(2, 2, sharex='col', sharey='row', figsize=(12, 8)) - fig.tight_layout(rect=(0.05, 0.05, 0.95, 0.95)) - fig.suptitle('Method Comparison', fontsize=20) + print '--SHELVE METHOD DATA' + data_shelve[key] = (data_disc_fourier0, data_vort_fourier0, + data_disc_fourier3, data_vort_fourier3, + data_disc_fourier10, data_vort_fourier10, + data_disc_real_s, data_vort_real_s, + data_disc_real_d, data_vort_real_d) - # Plot duration against a (disc) [top/left]: - axes[1, 0].set_xscale('log') - axes[1, 0].set_yscale('log') - axes[1, 0].plot(data_disc_fourier0[0], data_disc_fourier0[1], ':bs') - axes[1, 0].plot(data_disc_fourier3[0], data_disc_fourier3[1], ':bo') - axes[1, 0].plot(data_disc_fourier10[0], data_disc_fourier10[1], ':b^') - axes[1, 0].plot(data_disc_real_s[0], data_disc_real_s[1], '--rs') - axes[1, 0].plot(data_disc_real_d[0], data_disc_real_d[1], '--ro') - axes[1, 0].set_xlabel('grid size [px]', fontsize=15) - axes[1, 0].set_ylabel('RMS [mrad]', fontsize=15) - axes[1, 0].set_xlim(12, 350) - axes[1, 0].tick_params(axis='both', which='major', labelsize=14) - axes[1, 0].xaxis.set_major_locator(LogLocator(base=2)) - axes[1, 0].xaxis.set_major_formatter(LogFormatter(base=2)) - axes[1, 0].xaxis.set_minor_locator(NullLocator()) - axes[1, 0].grid() +print '--PLOT/SAVE METHOD DATA' - # Plot RMS against a (disc) [bottom/left]: - plt.tick_params(axis='both', which='major', labelsize=14) - axes[0, 0].set_xscale('log') - axes[0, 0].set_yscale('log') - axes[0, 0].plot(data_disc_fourier0[0], data_disc_fourier0[2], ':bs') - axes[0, 0].plot(data_disc_fourier3[0], data_disc_fourier3[2], ':bo') - axes[0, 0].plot(data_disc_fourier10[0], data_disc_fourier10[2], ':b^') - axes[0, 0].plot(data_disc_real_s[0], data_disc_real_s[2], '--rs') - axes[0, 0].plot(data_disc_real_d[0], data_disc_real_d[2], '--ro') - axes[0, 0].set_title('Homog. magn. disc', fontsize=18) - axes[0, 0].set_ylabel('duration [s]', fontsize=15) - axes[0, 0].set_xlim(12, 350) - axes[0, 0].tick_params(axis='both', which='major', labelsize=14) - axes[0, 0].xaxis.set_major_locator(LogLocator(base=2)) - axes[0, 0].xaxis.set_major_formatter(LogFormatter(base=2)) - axes[0, 0].xaxis.set_minor_locator(NullLocator()) - axes[0, 0].grid() +# Plot using shared rows and colums: +fig, axes = plt.subplots(2, 2, sharex='col', sharey='row', figsize=(12, 8)) +fig.tight_layout(rect=(0.05, 0.05, 0.95, 0.95)) +fig.suptitle('Method Comparison', fontsize=20) - # Plot duration against a (vortex) [top/right]: - axes[1, 1].set_xscale('log') - axes[1, 1].set_yscale('log') - axes[1, 1].plot(data_vort_fourier0[0], data_vort_fourier0[1], ':bs', - label='Fourier padding=0') - axes[1, 1].plot(data_vort_fourier3[0], data_vort_fourier3[1], ':bo', - label='Fourier padding=3') - axes[1, 1].plot(data_vort_fourier10[0], data_vort_fourier10[1], ':b^', - label='Fourier padding=10') - axes[1, 1].plot(data_vort_real_s[0], data_vort_real_s[1], '--rs', - label='Real space (slab)') - axes[1, 1].plot(data_vort_real_d[0], data_vort_real_d[1], '--ro', - label='Real space (disc)') - axes[1, 1].set_xlabel('grid size [px]', fontsize=15) - axes[1, 1].set_xlim(12, 350) - axes[1, 1].tick_params(axis='both', which='major', labelsize=14) - axes[1, 1].xaxis.set_major_locator(LogLocator(base=2)) - axes[1, 1].xaxis.set_major_formatter(LogFormatter(base=2)) - axes[1, 1].xaxis.set_minor_locator(NullLocator()) - axes[1, 1].grid() +# Plot duration against a (disc) [top/left]: +axes[1, 0].set_xscale('log') +axes[1, 0].set_yscale('log') +axes[1, 0].plot(data_disc_fourier0[0], data_disc_fourier0[1], ':bs') +axes[1, 0].plot(data_disc_fourier3[0], data_disc_fourier3[1], ':bo') +axes[1, 0].plot(data_disc_fourier10[0], data_disc_fourier10[1], ':b^') +axes[1, 0].plot(data_disc_real_s[0], data_disc_real_s[1], '--rs') +axes[1, 0].plot(data_disc_real_d[0], data_disc_real_d[1], '--ro') +axes[1, 0].set_xlabel('grid size [px]', fontsize=15) +axes[1, 0].set_ylabel('RMS [mrad]', fontsize=15) +axes[1, 0].set_xlim(25, 350) +axes[1, 0].tick_params(axis='both', which='major', labelsize=14) +axes[1, 0].xaxis.set_major_locator(LogLocator(base=2)) +axes[1, 0].xaxis.set_major_formatter(LogFormatter(base=2)) +axes[1, 0].xaxis.set_minor_locator(NullLocator()) +axes[1, 0].grid() - # Plot RMS against a (vortex) [bottom/right]: - axes[0, 1].set_xscale('log') - axes[0, 1].set_yscale('log') - axes[0, 1].plot(data_vort_fourier0[0], data_vort_fourier0[2], ':bs', - label='Fourier padding=0') - axes[0, 1].plot(data_vort_fourier3[0], data_vort_fourier3[2], ':bo', - label='Fourier padding=3') - axes[0, 1].plot(data_vort_fourier10[0], data_vort_fourier10[2], ':b^', - label='Fourier padding=10') - axes[0, 1].plot(data_vort_real_s[0], data_vort_real_s[2], '--rs', - label='Real space (slab)') - axes[0, 1].plot(data_vort_real_d[0], data_vort_real_d[2], '--ro', - label='Real space (disc)') - axes[0, 1].set_title('Vortex state disc', fontsize=18) - axes[0, 1].set_xlim(12, 350) - axes[0, 1].tick_params(axis='both', which='major', labelsize=14) - axes[0, 1].xaxis.set_major_locator(LogLocator(base=2)) - axes[0, 1].xaxis.set_major_formatter(LogFormatter(base=2)) - axes[0, 1].xaxis.set_minor_locator(NullLocator()) - axes[0, 1].grid() +# Plot RMS against a (disc) [bottom/left]: +plt.tick_params(axis='both', which='major', labelsize=14) +axes[0, 0].set_xscale('log') +axes[0, 0].set_yscale('log') +axes[0, 0].plot(data_disc_fourier0[0], data_disc_fourier0[2], ':bs') +axes[0, 0].plot(data_disc_fourier3[0], data_disc_fourier3[2], ':bo') +axes[0, 0].plot(data_disc_fourier10[0], data_disc_fourier10[2], ':b^') +axes[0, 0].plot(data_disc_real_s[0], data_disc_real_s[2], '--rs') +axes[0, 0].plot(data_disc_real_d[0], data_disc_real_d[2], '--ro') +axes[0, 0].set_title('Homog. magn. disc', fontsize=18) +axes[0, 0].set_ylabel('duration [s]', fontsize=15) +axes[0, 0].set_xlim(25, 350) +axes[0, 0].tick_params(axis='both', which='major', labelsize=14) +axes[0, 0].xaxis.set_major_locator(LogLocator(base=2)) +axes[0, 0].xaxis.set_major_formatter(LogFormatter(base=2)) +axes[0, 0].xaxis.set_minor_locator(NullLocator()) +axes[0, 0].grid() - # Add legend: - axes[1, 1].legend(bbox_to_anchor=(0, 0, 0.955, 0.615), bbox_transform=fig.transFigure, - prop={'size':12}) +# Plot duration against a (vortex) [top/right]: +axes[1, 1].set_xscale('log') +axes[1, 1].set_yscale('log') +axes[1, 1].plot(data_vort_fourier0[0], data_vort_fourier0[1], ':bs', + label='Fourier padding=0') +axes[1, 1].plot(data_vort_fourier3[0], data_vort_fourier3[1], ':bo', + label='Fourier padding=3') +axes[1, 1].plot(data_vort_fourier10[0], data_vort_fourier10[1], ':b^', + label='Fourier padding=10') +axes[1, 1].plot(data_vort_real_s[0], data_vort_real_s[1], '--rs', + label='Real space (slab)') +axes[1, 1].plot(data_vort_real_d[0], data_vort_real_d[1], '--ro', + label='Real space (disc)') +axes[1, 1].set_xlabel('grid size [px]', fontsize=15) +axes[1, 1].set_xlim(25, 350) +axes[1, 1].tick_params(axis='both', which='major', labelsize=14) +axes[1, 1].xaxis.set_major_locator(LogLocator(base=2)) +axes[1, 1].xaxis.set_major_formatter(LogFormatter(base=2)) +axes[1, 1].xaxis.set_minor_locator(NullLocator()) +axes[1, 1].grid() - # Save figure as .png: - plt.show() - plt.figtext(0.12, 0.85, 'a)', fontsize=30) - plt.figtext(0.57, 0.85, 'b)', fontsize=30) - plt.figtext(0.12, 0.15, 'c)', fontsize=30) - plt.figtext(0.57, 0.15, 'd)', fontsize=30) - plt.savefig(directory + '/ch5-3-method comparison.png', bbox_inches='tight') +# Plot RMS against a (vortex) [bottom/right]: +axes[0, 1].set_xscale('log') +axes[0, 1].set_yscale('log') +axes[0, 1].plot(data_vort_fourier0[0], data_vort_fourier0[2], ':bs', + label='Fourier padding=0') +axes[0, 1].plot(data_vort_fourier3[0], data_vort_fourier3[2], ':bo', + label='Fourier padding=3') +axes[0, 1].plot(data_vort_fourier10[0], data_vort_fourier10[2], ':b^', + label='Fourier padding=10') +axes[0, 1].plot(data_vort_real_s[0], data_vort_real_s[2], '--rs', + label='Real space (slab)') +axes[0, 1].plot(data_vort_real_d[0], data_vort_real_d[2], '--ro', + label='Real space (disc)') +axes[0, 1].set_title('Vortex state disc', fontsize=18) +axes[0, 1].set_xlim(25, 350) +axes[0, 1].tick_params(axis='both', which='major', labelsize=14) +axes[0, 1].xaxis.set_major_locator(LogLocator(base=2)) +axes[0, 1].xaxis.set_major_formatter(LogFormatter(base=2)) +axes[0, 1].xaxis.set_minor_locator(NullLocator()) +axes[0, 1].grid() - ############################################################################################### - print 'CLOSING SHELVE\n' - # Close shelve: - data_shelve.close() +# Add legend: +axes[1, 1].legend(bbox_to_anchor=(0, 0, 0.955, 0.615), bbox_transform=fig.transFigure, + prop={'size':12}) - ############################################################################################### +# Save figure as .png: +plt.show() +plt.figtext(0.12, 0.85, 'a)', fontsize=30) +plt.figtext(0.57, 0.85, 'b)', fontsize=30) +plt.figtext(0.12, 0.15, 'c)', fontsize=30) +plt.figtext(0.57, 0.15, 'd)', fontsize=30) +plt.savefig(directory + '/ch5-3-method comparison.png', bbox_inches='tight') +############################################################################################### +print 'CLOSING SHELVE\n' +# Close shelve: +data_shelve.close() -if __name__ == "__main__": - try: - run() - except: - type, value, tb = sys.exc_info() - traceback.print_exc() - pdb.post_mortem(tb) +############################################################################################### diff --git a/scripts/paper 1/logfile.log b/scripts/paper 1/logfile.log new file mode 100644 index 0000000000000000000000000000000000000000..e8f8d219b3f7e2003db1b0eb3aacc4de9518df38 --- /dev/null +++ b/scripts/paper 1/logfile.log @@ -0,0 +1,85 @@ +2014-02-08 20:46:32: INFO @ <pyramid.phasemap>: Calling make_color_wheel +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Calling __init__ +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Calling __init__ +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Created <pyramid.projector.SimpleProjector object at 0x0A8519F0> +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Created <pyramid.projector.SimpleProjector object at 0x0A8519F0> +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Calling as function +2014-02-08 20:46:43: INFO @ <pyramid.projector>: mode == vector +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Calling _vector_field_projection +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __sub__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __neg__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __add__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Adding two PhaseMap objects +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling display_phase +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Calling as function +2014-02-08 20:46:43: INFO @ <pyramid.projector>: mode == vector +2014-02-08 20:46:43: INFO @ <pyramid.projector>: Calling _vector_field_projection +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __sub__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __neg__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __add__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Adding two PhaseMap objects +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __isub__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __sub__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __add__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Adding an offset +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:43: INFO @ <pyramid.phasemap>: Calling display_phase +2014-02-08 20:46:44: INFO @ <pyramid.projector>: Calling as function +2014-02-08 20:46:44: INFO @ <pyramid.projector>: mode == vector +2014-02-08 20:46:44: INFO @ <pyramid.projector>: Calling _vector_field_projection +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Calling __sub__ +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Calling __neg__ +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Calling __add__ +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Adding two PhaseMap objects +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:44: INFO @ <pyramid.phasemap>: Calling display_phase +2014-02-08 20:46:45: INFO @ <pyramid.projector>: Calling as function +2014-02-08 20:46:45: INFO @ <pyramid.projector>: mode == vector +2014-02-08 20:46:45: INFO @ <pyramid.projector>: Calling _vector_field_projection +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __sub__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __neg__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __add__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Adding two PhaseMap objects +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __isub__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __sub__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __add__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Adding an offset +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:45: INFO @ <pyramid.phasemap>: Calling display_phase +2014-02-08 20:46:47: INFO @ <pyramid.projector>: Calling __init__ +2014-02-08 20:46:47: INFO @ <pyramid.projector>: Calling __init__ +2014-02-08 20:46:47: INFO @ <pyramid.projector>: Created <pyramid.projector.SimpleProjector object at 0x0B117190> +2014-02-08 20:46:47: INFO @ <pyramid.projector>: Created <pyramid.projector.SimpleProjector object at 0x0B117190> +2014-02-08 20:46:47: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:47: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) +2014-02-08 20:46:47: INFO @ <pyramid.phasemap>: Calling __str__ +2014-02-08 20:46:47: INFO @ <pyramid.phasemap>: Created PhaseMap(a=1.0, dim=(128, 128)) diff --git a/scripts/simple_phasemapping.py b/scripts/simple_phasemapping.py new file mode 100644 index 0000000000000000000000000000000000000000..80c67372b54518a2ed487f9da4689f3238b79254 --- /dev/null +++ b/scripts/simple_phasemapping.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 17 14:06:01 2014 + +@author: Jan +""" + + +from pyramid.magdata import MagData +from pyramid.projector import SimpleProjector +from pyramid.phasemapper import PMAdapterFM, PMConvolve, PMFourier, PMReal + +from time import clock + +#import cProfile + + +mag_data = MagData.load_from_netcdf4('../output/vtk data/rect_500x125x3.nc') + +projector = SimpleProjector(mag_data.dim) + +start = clock() +pm_adapter = PMAdapterFM(mag_data.a, projector) +pm_convolve = PMConvolve(mag_data.a, projector) +pm_fourier = PMFourier(mag_data.a, projector, padding=3) +pm_real = PMReal(mag_data.a, projector) +print 'Overhead :', clock()-start + +#cProfile.run('phasemapper(mag_data)')#, filename='../output/profile.profile') + +start = clock() +pm_adapter(mag_data) +print 'Adapter FM:', clock()-start +start = clock() +pm_convolve(mag_data) +print 'Convolve :', clock()-start +start = clock() +pm_fourier(mag_data) +print 'Fourier :', clock()-start +start = clock() +pm_real(mag_data) +print 'Real :', clock()-start + +phase_map = pm_convolve(mag_data) + +(-phase_map).display_combined(density=16) + + + + + +##from xml.etree import ElementTree +#from cProfile import Profile +##xml_content = '<a>\n' + '\t<b/><c><d>text</d></c>\n' * 100 + '</a>' +#profiler = Profile() +##profiler.runctx("ElementTree.fromstring(xml_content)", locals(), globals()) +#profiler.run('phasemapper(mag_data)') +# +#import pyprof2calltree +#from pyprof2calltree import convert, visualize +# +#pyprof2calltree.visualize(profiler.getstats()) # run kcachegrind +#pyprof2calltree.convert(profiler.getstats(), 'profiling_results.kgrind') # save for later \ No newline at end of file diff --git a/scripts/vtk-interpolation.py b/scripts/vtk-interpolation.py deleted file mode 100644 index 24bbaa6a9878175724132426f324a89c655a896b..0000000000000000000000000000000000000000 --- a/scripts/vtk-interpolation.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Tue Jan 14 10:06:42 2014 - -@author: Jan -""" - -import vtk - -reader = vtk.vtkDataSetReader() - -reader.SetFileName('test.vtk') - -reader.ReadAllScalarsOn() - -reader.Update() - -output = reader.GetOutput() -scalar_range = output.GetScalarRange() - -# Create the mapper that corresponds the objects of the vtk file into graphics elements -mapper = vtk.vtkDataSetMapper() -mapper.SetInput(output) -mapper.SetScalarRange(scalar_range) - -# Create the Actor -actor = vtk.vtkActor() -actor.SetMapper(mapper) - -# Create the Renderer -renderer = vtk.vtkRenderer() -renderer.AddActor(actor) -renderer.SetBackground(1, 1, 1) # Set background to white - -# Create the RendererWindow -renderer_window = vtk.vtkRenderWindow() -renderer_window.AddRenderer(renderer) - -# Create the RendererWindowInteractor and display the vtk_file -interactor = vtk.vtkRenderWindowInteractor() -interactor.SetRenderWindow(renderer_window) -interactor.Initialize() -interactor.Start() - - - - - -print reader.GetHeader() - -print 'Points:', output.GetNumberOfPoints() -print 'Cells: ', output.GetNumberOfCells() -#print 'Polys: ', output.GetNumberOfPolys() -#print 'Lines: ', output.GetNumberOfLines() -#print 'Strips:', output.GetNumberOfStrips() -#print 'Piece: ', output.GetNumberOfPiece() -#print 'Verts: ', output.GetNumberOfVerts() - -points = output.GetPoints() - -print output.GetPoint(0) diff --git a/scripts/vtk_conversion.py b/scripts/vtk_conversion.py new file mode 100644 index 0000000000000000000000000000000000000000..bbbb5067be95355684bddf1a69647b5e84b257a2 --- /dev/null +++ b/scripts/vtk_conversion.py @@ -0,0 +1,159 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 24 11:17:11 2014 + +@author: Jan +""" + + +import numpy as np +import vtk +import logging +import os +import sys +import pickle +from tqdm import tqdm +from pyramid.magdata import MagData +import matplotlib.pyplot as plt +from pylab import griddata +from pyramid.projector import SimpleProjector +from pyramid.phasemapper import PMAdapterFM + +################################################################################################### +PATH = '../output/vtk data/tube_90x30x50_sat_edge_equil.gmr' +b_0 = 1.54 +gain = 12 +force_calculation = False +################################################################################################### + +logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s', stream=sys.stdout) +log = logging.getLogger(__name__) + +if force_calculation or not os.path.exists(PATH+'.pickle'): + log.info('Reading data from vtk-file') + # Setting up reader: + reader = vtk.vtkDataSetReader() + reader.SetFileName(PATH+'.vtk') + reader.ReadAllScalarsOn() + reader.ReadAllVectorsOn() + reader.Update() + # Getting output: + output = reader.GetOutput() + # Reading points and vectors: + size = output.GetNumberOfPoints() + vtk_points = output.GetPoints().GetData() + vtk_vectors = output.GetPointData().GetVectors() + # Converting points to numpy array: + point_array = np.zeros(vtk_points.GetSize()) + vtk_points.ExportToVoidPointer(point_array) + point_array = np.reshape(point_array, (-1, 3)) + # Converting vectors to numpy array: + vector_array = np.zeros(vtk_points.GetSize()) + vtk_vectors.ExportToVoidPointer(vector_array) + vector_array = np.reshape(vector_array, (-1, 3)) + # Combining data: + data = np.hstack((point_array, vector_array)) + log.info('Data reading complete!') + log.info('Pickling data!') + with open(PATH+'.pickle', 'w') as pf: + pickle.dump(data, pf) + log.info('Pickling complete!') +else: + log.info('Loading pickled data!') + with open(PATH+'.pickle') as pf: + data = pickle.load(pf) + log.info('Loading complete!') +# Scatter plot of all x-y-coordinates +axis = plt.figure().add_subplot(1, 1, 1) +axis.scatter(data[:, 0], data[:, 1]) +plt.show() + +if force_calculation or not os.path.exists(PATH+'.nc'): + log.info('Arranging data in z-slices!') + # Find unique z-slices: + zs = np.unique(data[:, 2]) + # Determine the grid spacing: + a = zs[1] - zs[0] + # Determine the size of object: + x_min, x_max = data[:, 0].min(), data[:, 0].max() + y_min, y_max = data[:, 1].min(), data[:, 1].max() + z_min, z_max = data[:, 2].min(), data[:, 2].max() + x_diff, y_diff, z_diff = np.ptp(data[:, 0]), np.ptp(data[:, 1]), np.ptp(data[:, 2]) + x_cent, y_cent, z_cent = x_min+x_diff/2., y_min+y_diff/2., z_min+z_diff/2. + # Create regular grid + xs = np.arange(x_cent-x_diff, x_cent+x_diff, a) #linspace(-8.5*2, 8.5*2, 256) + ys = np.arange(y_cent-y_diff, y_cent+y_diff, a) #linspace(-9.5*2, 9.5*2, 256) + o, p = np.meshgrid(xs, ys) + # Create empty magnitude: + magnitude = np.zeros((3, len(zs), len(ys), len(xs))) + + # WITH MASKING OF THE CENTER (SYMMETRIC): + iz_x = np.concatenate([np.linspace(-4.95, -4.95, 50), + np.linspace(-4.95, 0, 50), + np.linspace(0, 4.95, 50), + np.linspace(4.95, 4.95, 50), + np.linspace(-4.95, 0, 50), + np.linspace(0, 4.95, 50),]) + iz_y = np.concatenate([np.linspace(-2.88, 2.88, 50), + np.linspace(2.88, 5.7, 50), + np.linspace(5.7, 2.88, 50), + np.linspace(2.88, -2.88, 50), + np.linspace(-2.88, -5.7, 50), + np.linspace(-5.7, -2.88, 50), ]) + for i, z in tqdm(enumerate(zs), total=len(zs)): + subdata = data[data[:, 2] == z, :] + for j in range(3): # For all 3 components! + gridded_subdata = griddata(np.concatenate([subdata[:, 0], iz_x]), + np.concatenate([subdata[:, 1], iz_y]), + np.concatenate([subdata[:, 3 + j], np.zeros(len(iz_x))]), + o, p) + magnitude[j, i, :, :] = gridded_subdata.filled(fill_value=0) + +# # WITH MASKING OF THE CENTER (ASYMMETRIC): +# iz_x = np.concatenate([np.linspace(-5.88, -5.88, 50), +# np.linspace(-5.88, 0, 50), +# np.linspace(0, 5.88, 50), +# np.linspace(5.88, 5.88, 50), +# np.linspace(5.88, 0, 50), +# np.linspace(0, -5.88, 50),]) +# iz_y = np.concatenate([np.linspace(-2.10, 4.50, 50), +# np.linspace(4.50, 7.90, 50), +# np.linspace(7.90, 4.50, 50), +# np.linspace(4.50, -2.10, 50), +# np.linspace(-2.10, -5.50, 50), +# np.linspace(-5.50, -2.10, 50), ]) +# for i, z in tqdm(enumerate(zs), total=len(zs)): +# subdata = data[data[:, 2] == z, :] +# for j in range(3): # For all 3 components! +# gridded_subdata = griddata(np.concatenate([subdata[:, 0], iz_x]), +# np.concatenate([subdata[:, 1], iz_y]), +# np.concatenate([subdata[:, 3 + j], np.zeros(len(iz_x))]), +# o, p) +# magnitude[j, i, :, :] = gridded_subdata.filled(fill_value=0) + +# # WITHOUT MASKING OF THE CENTER: +# for i, z in tqdm(enumerate(zs), total=len(zs)): +# subdata = data[data[:, 2] == z, :] +# for j in range(3): # For all 3 components! +# gridded_subdata = griddata(subdata[:, 0], subdata[:, 1], subdata[:, 3 + j], o, p) +# magnitude[j, i, :, :] = gridded_subdata.filled(fill_value=0) + + # Creating MagData object: + mag_data = MagData(0.2*10, magnitude) + mag_data.save_to_netcdf4(PATH+'.nc') + log.info('MagData created!') +else: + log.info('Loading MagData!') + mag_data = MagData.load_from_netcdf4(PATH+'.nc') + log.info('Loading complete!') +mag_data.quiver_plot() + +projector = SimpleProjector(mag_data.dim) +phasemapper = PMAdapterFM(mag_data.a, projector) +phase_map = phasemapper(mag_data) +(-phase_map).display_combined(title=r'Combined Plot (B$_0$={} T, Cos x {})'.format(b_0, gain), + density=gain) +plt.savefig(PATH+'_{}T_cosx{}.png'.format(b_0, gain)) +(-phase_map).display_combined(title=r'Combined Plot (B$_0$={} T, Cos x {})'.format(b_0, gain), + density=gain, interpolation='bilinear') +plt.savefig(PATH+'_{}T_cosx{}_smooth.png'.format(b_0, gain)) diff --git a/scripts/vtk_interpolation.py b/scripts/vtk_interpolation.py new file mode 100644 index 0000000000000000000000000000000000000000..3fea0932818f62bbbece6b4fb96151dfe1b6e860 --- /dev/null +++ b/scripts/vtk_interpolation.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +""" +Created on Fri Jan 17 13:09:08 2014 + +@author: Jan +""" + +from pylab import * +import pickle +from tqdm import tqdm +from pyramid.magdata import MagData + +with open("vtk_to_numpy.pickle") as pf: + data = pickle.load(pf) +zs = unique(data[:,2]) + +axis = plt.figure().add_subplot(1, 1, 1) +axis.scatter(data[:, 0], data[:, 1]) +plt.show() + +# # regular grid +xs = linspace(-8.5*2, 8.5*2, 256) +ys = linspace(-9.5*2, 9.5*2, 256) + +o, p = meshgrid(xs, ys) + +newdata = zeros((len(xs), len(ys), len(zs), data.shape[1] - 3)) + + +## WITH MASKING OF THE CENTER: +# +#iz_x = concatenate([linspace(-4.95, -4.95, 50), +# linspace(-4.95, 0, 50), +# linspace(0, 4.95, 50), +# linspace(4.95, 4.95, 50), +# linspace(-4.95, 0, 50), +# linspace(0, 4.95, 50),]) +#iz_y = concatenate([linspace(-2.88, 2.88, 50), +# linspace(2.88, 5.7, 50), +# linspace(5.7, 2.88, 50), +# linspace(2.88, -2.88, 50), +# linspace(-2.88, -5.7, 50), +# linspace(-5.7, -2.88, 50), ]) +# +# +#for i, z in tqdm(enumerate(zs), total=len(zs)): +# subdata = data[data[:, 2] == z, :] +# +# for j in range(newdata.shape[-1]): +# gridded_subdata = griddata(concatenate([subdata[:, 0], iz_x]), +# concatenate([subdata[:, 1], iz_y]), concatenate([subdata[:, 3 + j], +# zeros(len(iz_x))]), o, p) +# newdata[:, :, i, j] = gridded_subdata.filled(fill_value=0) + + +# WITHOUT MASKING OF THE CENTER: + + +for i, z in tqdm(enumerate(zs), total=len(zs)): + subdata = data[data[:, 2] == z, :] + + for j in range(3): # For all 3 components! + gridded_subdata = griddata(subdata[:, 0], subdata[:, 1], subdata[:, 3 + j], o, p) + newdata[:, :, i, j] = gridded_subdata.filled(fill_value=0) + + +magnitude = newdata.swapaxes(0,3).swapaxes(1,2).swapaxes(2,3) + +mag_data = MagData(1., magnitude) + +mag_data.quiver_plot() + +mag_data.save_to_netcdf4('vtk_mag_data.nc') diff --git a/scripts/vtk_to_numpy.py b/scripts/vtk_to_numpy.py new file mode 100644 index 0000000000000000000000000000000000000000..0e88286be7740c90bcfff944ce843058647fd6b0 --- /dev/null +++ b/scripts/vtk_to_numpy.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +""" +Created on Tue Jan 14 10:06:42 2014 + +@author: Jan +""" + + +import numpy as np +import vtk +#import netCDF4 +import logging +import sys + +import pickle + +logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(message)s', stream=sys.stdout) +log = logging.getLogger(__name__) + +reader = vtk.vtkDataSetReader() +reader.SetFileName('irect_500x125x3.vtk') +reader.ReadAllScalarsOn() +reader.ReadAllVectorsOn() +reader.Update() + +output = reader.GetOutput() +size = output.GetNumberOfPoints() + +vtk_points = output.GetPoints().GetData() +vtk_vectors = output.GetPointData().GetVectors() + +point_array = np.zeros(vtk_points.GetSize()) +vtk_points.ExportToVoidPointer(point_array) +point_array = np.reshape(point_array, (-1, 3)) + +vector_array = np.zeros(vtk_points.GetSize()) +vtk_vectors.ExportToVoidPointer(vector_array) +vector_array = np.reshape(vector_array, (-1, 3)) + +data = np.hstack((point_array, vector_array)) + +log.info('Data reading complete!') + +#magfile = netCDF4.Dataset('tube_90x30x30.nc', 'w', format='NETCDF3_64BIT') +#magfile.createDimension('comp', 6) # Number of components +#magfile.createDimension('size', size) +# +#x = magfile.createVariable('x', 'f8', ('size')) +#y = magfile.createVariable('y', 'f8', ('size')) +#z = magfile.createVariable('z', 'f8', ('size')) +#x_mag = magfile.createVariable('x_mag', 'f8', ('size')) +#y_mag = magfile.createVariable('y_mag', 'f8', ('size')) +#z_mag = magfile.createVariable('z_mag', 'f8', ('size')) +# +#log.info('Start saving data separately!') +#x = data[:, 0] +#y = data[:, 1] +#z = data[:, 2] +#x_mag = data[:, 3] +#y_mag = data[:, 4] +#z_mag = data[:, 5] +#log.info('Separate saving complete!') +# +#log.info('Try saving the whole array!') +#filedata = magfile.createVariable('data', 'f8', ('size', 'comp')) +#filedata[:, :] = data +#log.info('Saving complete!') +# +#magfile.close() + +log.info('Pickling data!') +with open('vtk_to_numpy.pickle', 'w') as pf: + pickle.dump(data, pf) +log.info('Pickling complete!') diff --git a/setup.py b/setup.py index 9d9a4eacea61b3ba19b275ce7926d0805790c8a5..42a2f1533583357e894421329f96539c3cc402c6 100644 --- a/setup.py +++ b/setup.py @@ -67,7 +67,7 @@ setup( ext_package = 'pyramid/numcore', ext_modules = [ - Extension('phase_mag_real', ['pyramid/numcore/phase_mag_real.pyx'], + Extension('kernel_core', ['pyramid/numcore/kernel_core.pyx'], include_dirs = [numpy.get_include(), numpy.get_numarray_include()], extra_compile_args=['-march=native', '-mtune=native'] ) diff --git a/tests/test_costfunction.py b/tests/test_costfunction.py new file mode 100644 index 0000000000000000000000000000000000000000..0d06db5a44c2d20495f245c33734ea03ed755e20 --- /dev/null +++ b/tests/test_costfunction.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 20 20:01:25 2014 + +@author: Jan +""" + diff --git a/tests/test_datacollection.py b/tests/test_datacollection.py new file mode 100644 index 0000000000000000000000000000000000000000..ebe232287a5eb502750dbd04f7b8931cea061c49 --- /dev/null +++ b/tests/test_datacollection.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 20 19:58:01 2014 + +@author: Jan +""" + diff --git a/tests/test_forwardmodel.py b/tests/test_forwardmodel.py new file mode 100644 index 0000000000000000000000000000000000000000..5bd1ef1c2e5abd3ffa129b8c99a8d2ed1ad25a3b --- /dev/null +++ b/tests/test_forwardmodel.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 20 20:01:13 2014 + +@author: Jan +""" + diff --git a/tests/test_holoimage.py b/tests/test_holoimage.py deleted file mode 100644 index 2680ef1ca999fa733876863edd6ec654904127b2..0000000000000000000000000000000000000000 --- a/tests/test_holoimage.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -"""Testcase for the holoimage module.""" - - -import os -import unittest -import numpy as np -from numpy import pi - -from pyramid.phasemap import PhaseMap -import pyramid.holoimage as hi - - -class TestCaseHoloImage(unittest.TestCase): - - def setUp(self): - self.path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'test_holoimage') - phase = np.zeros((4, 4)) - phase[1:-1, 1:-1] = pi/4 - self.phase_map = PhaseMap(10.0, phase) - - def tearDown(self): - self.path = None - self.phase_map = None - - def test_holo_image(self): - img = hi.holo_image(self.phase_map) - arr = np.array(img.getdata(), np.uint8).reshape(img.size[1], img.size[0], 3) - holo_img_r, holo_img_g, holo_img_b = arr[..., 0], arr[..., 1], arr[..., 2] - ref_holo_img_r = np.loadtxt(os.path.join(self.path, 'ref_holo_img_r.txt')) - ref_holo_img_g = np.loadtxt(os.path.join(self.path, 'ref_holo_img_g.txt')) - ref_holo_img_b = np.loadtxt(os.path.join(self.path, 'ref_holo_img_b.txt')) - hi.display(img) - np.testing.assert_equal(holo_img_r, ref_holo_img_r, - 'Unexpected behavior in holo_image() (r-component)!') - np.testing.assert_equal(holo_img_g, ref_holo_img_g, - 'Unexpected behavior in holo_image() (g-component)!') - np.testing.assert_equal(holo_img_b, ref_holo_img_b, - 'Unexpected behavior in holo_image() (b-component)!') - - -if __name__ == '__main__': - suite = unittest.TestLoader().loadTestsFromTestCase(TestCaseHoloImage) - unittest.TextTestRunner(verbosity=2).run(suite) diff --git a/tests/test_holoimage/ref_holo_img_b.txt b/tests/test_holoimage/ref_holo_img_b.txt deleted file mode 100644 index fe1fcf2e95f700820ecec28f6f0a4995868f096b..0000000000000000000000000000000000000000 --- a/tests/test_holoimage/ref_holo_img_b.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 -0.000000000000000000e+00 0.000000000000000000e+00 9.700000000000000000e+01 2.550000000000000000e+02 -0.000000000000000000e+00 0.000000000000000000e+00 1.000000000000000000e+02 2.550000000000000000e+02 -0.000000000000000000e+00 3.000000000000000000e+00 3.000000000000000000e+00 0.000000000000000000e+00 diff --git a/tests/test_holoimage/ref_holo_img_g.txt b/tests/test_holoimage/ref_holo_img_g.txt deleted file mode 100644 index a4a674dfa22150e448ee4b39702d3fc8ee85cdcc..0000000000000000000000000000000000000000 --- a/tests/test_holoimage/ref_holo_img_g.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.000000000000000000e+00 1.000000000000000000e+00 1.000000000000000000e+00 0.000000000000000000e+00 -2.550000000000000000e+02 9.900000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 -2.550000000000000000e+02 1.950000000000000000e+02 9.500000000000000000e+01 0.000000000000000000e+00 -0.000000000000000000e+00 2.520000000000000000e+02 2.520000000000000000e+02 0.000000000000000000e+00 diff --git a/tests/test_holoimage/ref_holo_img_r.txt b/tests/test_holoimage/ref_holo_img_r.txt deleted file mode 100644 index 7373e5e22f2ec6849bdad2beb44f6847cf8988d2..0000000000000000000000000000000000000000 --- a/tests/test_holoimage/ref_holo_img_r.txt +++ /dev/null @@ -1,4 +0,0 @@ -0.000000000000000000e+00 2.550000000000000000e+02 2.550000000000000000e+02 0.000000000000000000e+00 -2.530000000000000000e+02 1.950000000000000000e+02 9.800000000000000000e+01 0.000000000000000000e+00 -2.530000000000000000e+02 9.500000000000000000e+01 0.000000000000000000e+00 0.000000000000000000e+00 -0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 diff --git a/tests/test_kernel.py b/tests/test_kernel.py new file mode 100644 index 0000000000000000000000000000000000000000..b4fa9e47e440c1c220f9ea0fa8aff9f473ecb26c --- /dev/null +++ b/tests/test_kernel.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Jan 20 20:00:50 2014 + +@author: Jan +""" + diff --git a/tests/test_reconstructor.py b/tests/test_optimize.py similarity index 100% rename from tests/test_reconstructor.py rename to tests/test_optimize.py