Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • empyre/empyre
  • weber/empyre
  • wessels/empyre
  • bryan/empyre
4 results
Show changes
Showing
with 0 additions and 1179 deletions
# -*- coding: utf-8 -*-
"""Create simple LLG Files which describe magnetization in 2D (z-Dim=1)."""
import numpy as np
from numpy import pi
class Shapes:
'''Class containing functions for generating shapes.'''
@classmethod
def soft_slab(cls, dim, center, width):
'''Get the magnetic shape of a slab.
Arguments:
dim - the dimensions of the grid, shape(z, y, x)
center - the center of the slab in pixel coordinates, shape(z, y, x)
width - the width of the slab in pixel coordinates, shape(z, y, x)
Returns:
the magnetic shape as a 3D-array with ones and zeros
'''
assert np.shape(dim) == (3,), 'Parameter dim has to be a shape of 3 dimensions!'
assert np.shape(center) == (3,), 'Parameter center has to be a shape of 3 dimensions!'
assert np.shape(width) == (3,), 'Parameter width has to be a shape of 3 dimensions!'
z0, y0, x0 = center
Lz, Ly, Lx = width
mag_shape = np.zeros(dim)
for z in range(dim[0]):
for y in range(dim[1]):
for x in range(dim[2]):
mag_shape[z, y, x] = (max(min(x+0.5, x0+Lx/2.)-max(x-0.5, x0-Lx/2.), 0)
* max(min(y+0.5, y0+Ly/2.)-max(y-0.5, y0-Ly/2.), 0)
* max(min(z+0.5, z0+Lz/2.)-max(z-0.5, z0-Lz/2.), 0))
return mag_shape
@classmethod
def slab(cls, dim, center, width):
'''Get the magnetic shape of a slab.
Arguments:
dim - the dimensions of the grid, shape(z, y, x)
center - the center of the slab in pixel coordinates, shape(z, y, x)
width - the width of the slab in pixel coordinates, shape(z, y, x)
Returns:
the magnetic shape as a 3D-array with ones and zeros
'''
assert np.shape(dim) == (3,), 'Parameter dim has to be a shape of 3 dimensions!'
assert np.shape(center) == (3,), 'Parameter center has to be a shape of 3 dimensions!'
assert np.shape(width) == (3,), 'Parameter width has to be a shape of 3 dimensions!'
mag_shape = np.array([[[abs(x - center[2]) <= width[2] / 2
and abs(y - center[1]) <= width[1] / 2
and abs(z - center[0]) <= width[0] / 2
for x in range(dim[2])]
for y in range(dim[1])]
for z in range(dim[0])])
return mag_shape
@classmethod
def disc(cls, dim, center, radius, height, axis='z'):
'''Get the magnetic shape of a zylindrical disc in x-, y-, or z-direction.
Arguments:
dim - the dimensions of the grid, shape(z, y, x)
center - the center of the disc in pixel coordinates, shape(z, y, x)
radius - the radius of the disc in pixel coordinates (scalar value)
height - the height of the disc in pixel coordinates (scalar value)
axis - the orientation of the disc axis, (String: 'x', 'y', 'z'), default = 'z'
Returns:
the magnetic shape as a 3D-array with ones and zeros
'''
assert np.shape(dim) == (3,), 'Parameter dim has to be a shape of 3 dimensions!'
assert np.shape(center) == (3,), 'Parameter center has to be a shape of 3 dimensions!'
assert radius > 0 and np.shape(radius) == (), 'Radius has to be positive scalar value!'
assert height > 0 and np.shape(height) == (), 'Height has to be positive scalar value!'
assert axis == 'z' or axis == 'y' or axis == 'x', 'Axis has to be x, y or z (as String)!'
if axis == 'z':
mag_shape = np.array([[[np.hypot(x - center[2], y - center[1]) <= radius
and abs(z - center[0]) <= height / 2
for x in range(dim[2])]
for y in range(dim[1])]
for z in range(dim[0])])
elif axis == 'y':
mag_shape = np.array([[[np.hypot(x - center[2], z - center[0]) <= radius
and abs(y - center[1]) <= height / 2
for x in range(dim[2])]
for y in range(dim[1])]
for z in range(dim[0])])
elif axis == 'x':
mag_shape = np.array([[[np.hypot(y - center[1], z - center[0]) <= radius
and abs(x - center[2]) <= height / 2
for x in range(dim[2])]
for y in range(dim[1])]
for z in range(dim[0])])
return mag_shape
@classmethod
def sphere(cls, dim, center, radius):
'''Get the magnetic shape of a sphere.
Arguments:
dim - the dimensions of the grid, shape(z, y, x)
center - the center of the disc in pixel coordinates, shape(z, y, x)
radius - the radius of the disc in pixel coordinates (scalar value)
height - the height of the disc in pixel coordinates (scalar value)
axis - the orientation of the disc axis, (String: 'x', 'y', 'z'), default = 'z'
Returns:
the magnetic shape as a 3D-array with ones and zeros
'''
assert np.shape(dim) == (3,), 'Parameter dim has to be a shape of 3 dimensions!'
assert np.shape(center) == (3,), 'Parameter center has to be a shape of 3 dimensions!'
assert radius > 0 and np.shape(radius) == (), 'Radius has to be positive scalar value!'
mag_shape = np.array([[[np.sqrt((x-center[2])**2
+ (y-center[1])**2
+ (z-center[0])**2) <= radius
for x in range(dim[2])]
for y in range(dim[1])]
for z in range(dim[0])])
return mag_shape
@classmethod
def filament(cls, dim, pos, axis='y'):
'''Get the magnetic shape of a single filament in x-, y-, or z-direction.
Arguments:
dim - the dimensions of the grid, shape(z, y, x)
pos - the position of the filament in pixel coordinates, shape(coord1, coord2)
axis - the orientation of the filament axis, (String: 'x', 'y', 'z'), default = 'y'
Returns:
the magnetic shape as a 3D-array with ones and zeros
'''
assert np.shape(dim) == (3,), 'Parameter dim has to be a shape of 3 dimensions!'
assert np.shape(pos) == (2,), 'Parameter pos has to be a shape of 2 dimensions!'
assert axis == 'z' or axis == 'y' or axis == 'x', 'Axis has to be x, y or z (as String)!'
mag_shape = np.zeros(dim)
if axis == 'z':
mag_shape[:, pos[0], pos[1]] = 1
elif axis == 'y':
mag_shape[pos[0], :, pos[1]] = 1
elif axis == 'x':
mag_shape[pos[0], pos[1], :] = 1
return mag_shape
@classmethod
def pixel(cls, dim, pixel):
'''Get the magnetic shape of a single magnetized pixel.
Arguments:
dim - the dimensions of the grid, shape(z, y, x)
pixel - the coordinates of the magnetized pixel, shape(z, y, x)
Returns:
the magnetic shape as a 3D-array with ones and zeros
'''
assert np.shape(dim) == (3,), 'Parameter dim has to be a shape of 3 dimensions!'
assert np.shape(pixel) == (3,), 'Parameter pixel has to be a shape of 3 dimensions!'
mag_shape = np.zeros(dim)
mag_shape[pixel] = 1
return mag_shape
def create_mag_dist(mag_shape, phi, theta=pi/2, magnitude=1):
'''Create a 3-dimensional magnetic distribution of a homogeneous magnetized object.
Arguments:
mag_shape - the magnetic shapes (numpy arrays, see Shapes.* for examples)
phi - the azimuthal angle, describing the direction of the magnetized object
theta - the polar angle, describing the direction of the magnetized object
(optional, is set to pi/2 if not specified -> z-component is zero)
magnitude - the relative magnitudes for the magnetic shape (optional, one if not specified)
Returns:
the 3D magnetic distribution as a MagData object (see pyramid.magdata for reference)
'''
dim = np.shape(mag_shape)
assert len(dim) == 3, 'Magnetic shapes must describe 3-dimensional distributions!'
z_mag = np.ones(dim) * np.cos(theta) * mag_shape * magnitude
y_mag = np.ones(dim) * np.sin(theta) * np.sin(phi) * mag_shape * magnitude
x_mag = np.ones(dim) * np.sin(theta) * np.cos(phi) * mag_shape * magnitude
return z_mag, y_mag, x_mag
def create_mag_dist_comb(mag_shape_list, phi_list, theta_list=None, magnitude_list=None):
'''Create a 3-dimensional magnetic distribution from a list of homogeneous magnetized objects.
Arguments:
mag_shape_list - a list of magnetic shapes (numpy arrays, see Shapes.* for examples)
phi_list - a list of azimuthal angles, describing the direction of the
magnetized object
theta_list - a list of polar angles, describing the direction of the magnetized object
(optional, is set to pi/2 if not specified -> z-component is zero)
magnitude_list - a list of relative magnitudes for the magnetic shapes
(optional, if not specified, every relative magnitude is set to one)
Returns:
the 3D magnetic distribution as a MagData object (see pyramid.magdata for reference)
'''
# If no relative magnitude is specified, 1 is assumed for every homog. object:
if magnitude_list is None:
magnitude_list = np.ones(len(phi_list))
# If no relative magnitude is specified, 1 is assumed for every homog. object:
if theta_list is None:
theta_list = np.ones(len(phi_list)) * pi/2
# For every shape of a homogeneous object a relative magnitude and angle have to be set:
assert np.shape(mag_shape_list)[0] == len(phi_list) == len(theta_list) == len(magnitude_list),\
'Lists have not the same length!'
dim = np.shape(mag_shape_list[0]) # Has to be the shape of ALL mag_shapes!
assert len(dim) == 3, 'Magnetic shapes must describe 3-dimensional distributions!'
assert np.array([mag_shape_list[i].shape == dim for i in range(len(mag_shape_list))]).all(),\
'Magnetic shapes must describe distributions with the same size!'
# Start with a zero distribution:
x_mag = np.zeros(dim)
y_mag = np.zeros(dim)
z_mag = np.zeros(dim)
# Add every specified homogeneous object:
for i in range(np.size(phi_list)):
mag_object = create_mag_dist(mag_shape_list[i], phi_list[i], magnitude_list[i])
z_mag += mag_object[0]
y_mag += mag_object[1]
x_mag += mag_object[2]
return z_mag, y_mag, x_mag
def create_mag_dist_vortex(mag_shape, center=None, magnitude=1):
'''Create a 3-dimensional magnetic distribution of a homogeneous magnetized object.
Arguments:
mag_shape - the magnetic shapes (numpy arrays, see Shapes.* for examples)
phi - the azimuthal angle, describing the direction of the magnetized object
theta - the polar angle, describing the direction of the magnetized object
(optional, is set to pi/2 if not specified -> z-component is zero)
magnitude - the relative magnitudes for the magnetic shape (optional, one if not specified)
Returns:
the 3D magnetic distribution as a MagData object (see pyramid.magdata for reference)
'''
dim = np.shape(mag_shape)
assert len(dim) == 3, 'Magnetic shapes must describe 3-dimensional distributions!'
if center is None:
center = (int(dim[1]/2)-0.5, int(dim[2]/2)-0.5) # center has to be between (!) two pixels
assert len(center) == 2, 'Vortex center has to be defined in 2D!'
x = np.linspace(-center[1], dim[2]-1-center[1], dim[2])
y = np.linspace(-center[0], dim[1]-1-center[0], dim[1])
xx, yy = np.meshgrid(x, y)
phi = np.arctan2(yy, xx) - pi/2
z_mag = np.zeros(dim)
y_mag = -np.ones(dim) * np.sin(phi) * mag_shape * magnitude
x_mag = -np.ones(dim) * np.cos(phi) * mag_shape * magnitude
return z_mag, y_mag, x_mag
\ No newline at end of file
# -*- coding: utf-8 -*-
"""Class for creating objects to store magnetizatin data."""
import numpy as np
import tables.netcdf3 as nc
import matplotlib.pyplot as plt
class MagData:
'''An object storing magnetization data.'''
def __init__(self, res, magnitude): # TODO: electrostatic component!
'''Constructor for a MagData object for storing magnetization data.
Arguments:
res - the resolution of the grid (grid spacing) in nm
magnitude - the z-, y- and x-component of the magnetization vector for every
3D-gridpoint as a tuple
Returns:
MagData object
'''
dim = np.shape(magnitude[0])
assert len(dim) == 3, 'Magnitude has to be defined for a 3-dimensional grid!'
assert np.shape(magnitude[1]) == np.shape(magnitude[2]) == dim, \
'Dimensions of the magnitude components do not match!'
self.res = res
self.dim = dim
self.magnitude = magnitude
def get_vector(self, mask):
# TODO: Implement!
return np.concatenate([self.magnitude[2][mask],
self.magnitude[1][mask],
self.magnitude[0][mask]])
def set_vector(self, mask, vector):
# TODO: Implement!
assert np.size(vector) % 3 == 0, 'Vector has to contain all 3 components for every pixel!'
count = np.size(vector)/3
self.magnitude[2][mask] = vector[:count] # x-component
self.magnitude[1][mask] = vector[count:2*count] # y-component
self.magnitude[0][mask] = vector[2*count:] # z-component
@classmethod
def load_from_llg(cls, filename):
'''Construct DataMag object from LLG-file (classmethod).
Arguments:
filename - the name of the LLG-file from which to load the data
Returns.
MagData object
'''
scale = 1.0E-9 / 1.0E-2 # From cm to nm
data = np.genfromtxt(filename, skip_header=2)
x_dim, y_dim, z_dim = np.genfromtxt(filename, dtype=int, skip_header=1,
skip_footer=len(data[:, 0]))
res = (data[1, 0] - data[0, 0]) / scale
# Reshape in Python and Igor is different, Python fills rows first, Igor columns:
x_mag, y_mag, z_mag = [data[:, i].reshape(z_dim, y_dim, x_dim) for i in range(3, 6)]
return MagData(res, (z_mag, y_mag, x_mag))
def save_to_llg(self, filename='magdata_output.txt'):
'''Save magnetization data in a file with LLG-format.
Arguments:
filename - the name of the LLG-file in which to store the magnetization data
(default: 'magdata_output.txt')
Returns:
None
'''
dim = self.dim
res = self.res * 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[res/2:(dim[0]*res-res/2):dim[0]*1j,
res/2:(dim[1]*res-res/2):dim[1]*1j,
res/2:(dim[2]*res-res/2):dim[2]*1j]
xx = xx.reshape(-1)
yy = yy.reshape(-1)
zz = zz.reshape(-1)
x_mag = np.reshape(self.magnitude[2], (-1))
y_mag = np.reshape(self.magnitude[1], (-1))
z_mag = np.reshape(self.magnitude[0], (-1))
# Save data to file:
data = np.array([xx, yy, zz, x_mag, y_mag, z_mag]).T
with open(filename, 'w') as mag_file:
mag_file.write('LLGFileCreator: %s\n' % filename.replace('.txt', ''))
mag_file.write(' %d %d %d\n' % (dim[2], dim[1], dim[0]))
mag_file.writelines('\n'.join(' '.join('{:7.6e}'.format(cell)
for cell in row) for row in data))
@classmethod
def load_from_netcdf(cls, filename):
'''Construct MagData object from a NetCDF-file (classmethod).
Arguments:
filename - name of the file from which to load the data
Returns:
PhaseMap object
'''
f = nc.NetCDFFile(filename, 'r')
res = getattr(f, 'res')
z_mag = f.variables['z_mag'].getValue()
y_mag = f.variables['y_mag'].getValue()
x_mag = f.variables['x_mag'].getValue()
f.close()
return MagData(res, (z_mag, y_mag, x_mag))
def save_to_netcdf(self, filename='..\output\magdata_output.nc'):
'''Save magnetization data in a file with NetCDF-format.
Arguments:
filename - the name of the file in which to store the phase map data
(default: 'phasemap_output.txt')
Returns:
None
'''
f = nc.NetCDFFile(filename, 'w')
setattr(f, 'res', self.res)
f.createDimension('z_dim', self.dim[0])
f.createDimension('y_dim', self.dim[1])
f.createDimension('x_dim', self.dim[2])
z_mag = f.createVariable('z_mag', 'f', ('z_dim', 'y_dim', 'x_dim'))
y_mag = f.createVariable('y_mag', 'f', ('z_dim', 'y_dim', 'x_dim'))
x_mag = f.createVariable('x_mag', 'f', ('z_dim', 'y_dim', 'x_dim'))
z_mag[:] = self.magnitude[0]
y_mag[:] = self.magnitude[1]
x_mag[:] = self.magnitude[2]
print f
f.close()
def quiver_plot(self, axis='z', ax_slice=0):
'''Plot a slice of the magnetization as a quiver plot.
Arguments:
axis - the axis from which a slice is plotted ('x', 'y' or 'z'), default = 'z'
ax_slice - the slice-index of the specified axis
Returns:
None
'''
assert axis == 'z' or axis == 'y' or axis == 'x', 'Axis has to be x, y or z (as string).'
if axis == 'z': # Slice of the xy-plane with z = ax_slice
mag_slice_u = self.magnitude[2][ax_slice, ...]
mag_slice_v = self.magnitude[1][ax_slice, ...]
elif axis == 'y': # Slice of the xz-plane with y = ax_slice
mag_slice_u = self.magnitude[2][:, ax_slice, :]
mag_slice_v = self.magnitude[0][:, ax_slice, :]
elif axis == 'x': # Slice of the yz-plane with x = ax_slice
mag_slice_u = self.magnitude[1][..., ax_slice]
mag_slice_v = self.magnitude[0][..., ax_slice]
# Plot the magnetization vectors:
fig = plt.figure()
fig.add_subplot(111, aspect='equal')
plt.quiver(mag_slice_u, mag_slice_v, pivot='middle', angles='xy', scale_units='xy',
scale=1, headwidth=6, headlength=7)
def quiver_plot3d(self):
'''3D-Quiver-Plot of the magnetization as vectors.
Arguments:
None
Returns:
None
'''
from mayavi import mlab
res = self.res
dim = self.dim
# Create points and vector components as lists:
zz, yy, xx = np.mgrid[res/2:(dim[0]*res-res/2):dim[0]*1j,
res/2:(dim[1]*res-res/2):dim[1]*1j,
res/2:(dim[2]*res-res/2):dim[2]*1j]
xx = xx.reshape(-1)
yy = yy.reshape(-1)
zz = zz.reshape(-1)
x_mag = np.reshape(self.magnitude[2], (-1))
y_mag = np.reshape(self.magnitude[1], (-1))
z_mag = np.reshape(self.magnitude[0], (-1))
# Plot them as vectors:
plot = mlab.quiver3d(xx, yy, zz, x_mag, y_mag, z_mag, mode='arrow', scale_factor=10.0)
mlab.outline(plot)
mlab.axes(plot)
mlab.colorbar()
from phase_mag_real import *
import math
def great_circle(float lon1, float lat1, float lon2, float lat2):
cdef float radius = 3956.0
cdef float pi = 3.14159265
cdef float x = pi / 180.0
cdef float a, b, theta,c
a = (90.0 - lat1) * (x)
b = (90.0 - lat2) * (x)
theta = (lon2 - lon1) * (x)
c = math.acos((math.cos(a)*math.cos(b)) + (math.sin(a)*math.sin(b)*math.cos(theta)))
return radius*c
cdef extern from "math.h":
float cosf(float theta)
float sinf(float theta)
float acosf(float theta)
def great_circle(float lon1,float lat1,float lon2,float lat2):
cdef float radius = 3956.0
cdef float pi = 3.14159265
cdef float x = pi/180.0
cdef float a,b,theta,c
a = (90.0-lat1)*(x)
b = (90.0-lat2)*(x)
theta = (lon2-lon1)*(x)
c = acosf((cosf(a)*cosf(b)) + (sinf(a)*sinf(b)*cosf(theta)))
return radius*c
\ No newline at end of file
cdef extern from "math.h":
float cosf(float theta)
float sinf(float theta)
float acosf(float theta)
cdef float _great_circle(float lon1,float lat1,float lon2,float lat2):
cdef float radius = 3956.0
cdef float pi = 3.14159265
cdef float x = pi/180.0
cdef float a,b,theta,c
a = (90.0-lat1)*(x)
b = (90.0-lat2)*(x)
theta = (lon2-lon1)*(x)
c = acosf((cosf(a)*cosf(b)) + (sinf(a)*sinf(b)*cosf(theta)))
return radius*c
def great_circle(float lon1,float lat1,float lon2,float lat2,int num):
cdef int i
cdef float x
for i from 0 <= i < num:
x = _great_circle(lon1,lat1,lon2,lat2)
return x
\ No newline at end of file
def say_hello_to(name):
print 'Hello %s!' % name
\ No newline at end of file
# -*- coding: utf-8 -*-
"""Script to initialize Cythons pyximport to ensure compatibility with MinGW compiler and NumPy."""
import os
import numpy
import pyximport
if os.name == 'nt':
if 'CPATH' in os.environ:
os.environ['CPATH'] = os.environ['CPATH'] + numpy.get_include()
else:
os.environ['CPATH'] = numpy.get_include()
# # XXX: assuming that MinGW is installed in C:\MinGW (default)
# # for PythonXY the default is C:\MinGW-xy
# if os.environ.has_key('PATH'):
# os.environ['PATH'] = os.environ['PATH'] + ';C:\MinGW\bin'
# else:
# os.environ['PATH'] = 'C:\MinGW\bin'
mingw_setup_args = {'options': {'build_ext': {'compiler': 'mingw32'}}}
pyximport.install(setup_args=mingw_setup_args, inplace=True)
elif os.name == 'posix':
if 'CFLAGS' in os.environ:
os.environ['CFLAGS'] = os.environ['CFLAGS'] + ' -I' + numpy.get_include()
else:
os.environ['CFLAGS'] = ' -I' + numpy.get_include()
pyximport.install(inplace=True)
import numpy as np
import math
cimport cython
cimport numpy as np
@cython.boundscheck(False)
@cython.wraparound(False)
def phase_mag_real_helper_1(
unsigned int v_dim, unsigned int u_dim,
double[:, :] phi_u,
double[:, :] phi_v,
double[:, :] u_mag,
double[:, :] v_mag,
double[:, :] phase, float threshold):
cdef unsigned int i, j, ii, jj, iii, jjj
cdef double u, v
for j in range(v_dim):
for i in range(u_dim):
u = u_mag[j, i]
v = v_mag[j, i]
iii = u_dim - 1 - i
jjj = v_dim - 1 - j
if abs(u) > threshold:
for jj in range(phase.shape[0]):
for ii in range(phase.shape[1]):
phase[jj, ii] += u * phi_u[jjj + jj, iii + ii]
if abs(v) > threshold:
for jj in range(phase.shape[0]):
for ii in range(phase.shape[1]):
phase[jj, ii] -= v * phi_v[jjj + jj, iii + ii]
# -*- coding: utf-8 -*-
"""Class for creating objects to store phase maps."""
import numpy as np
import matplotlib.pyplot as plt
import tables.netcdf3 as nc
class PhaseMap:
'''An object storing magnetization data.'''
def __init__(self, res, phase):
'''Constructor for a MagData object for storing magnetization data.
Arguments:
res - the resolution of the grid (grid spacing) in nm
magnitude - the z-, y- and x-component of the magnetization vector for every
3D-gridpoint as a tuple
Returns:
MagData object
'''
dim = np.shape(phase)
assert len(dim) == 2, 'Phasemap has to be 2-dimensional!'
self.res = res
self.dim = dim
self.phase = phase
@classmethod
def load_from_txt(cls, filename):
'''Construct PhaseMap object from a human readable txt-file (classmethod).
Arguments:
filename - name of the file from which to load the data
Returns.
PhaseMap object
'''
with open(filename, 'r') as f:
f.readline() # Headerline is not used
res = int(f.readline()[13:-4])
phase = np.loadtxt(filename, delimiter='\t', skiprows=2)
return PhaseMap(res, phase)
def save_to_txt(self, filename='..\output\phasemap_output.txt'):
'''Save PhaseMap data in a file with txt-format.
Arguments:
filename - the name of the file in which to store the phase map data
(default: 'phasemap_output.txt')
Returns:
None
'''
with open(filename, 'w') as f:
f.write('{}\n'.format(filename.replace('.txt', '')))
f.write('resolution = {} nm\n'.format(self.res))
np.savetxt(f, self.phase, fmt='%7.6e', delimiter='\t')
@classmethod
def load_from_netcdf(cls, filename):
'''Construct PhaseMap object from a NetCDF-file (classmethod).
Arguments:
filename - name of the file from which to load the data
Returns:
PhaseMap object
'''
f = nc.NetCDFFile(filename, 'r')
res = getattr(f, 'res')
phase = f.variables['phase'].getValue()
f.close()
return PhaseMap(res, phase)
def save_to_netcdf(self, filename='..\output\phasemap_output.nc'):
'''Save PhaseMap data in a file with NetCDF-format.
Arguments:
filename - the name of the file in which to store the phase map data
(default: 'phasemap_output.txt')
Returns:
None
'''
f = nc.NetCDFFile(filename, 'w')
setattr(f, 'res', self.res)
f.createDimension('v_dim', self.dim[0])
f.createDimension('u_dim', self.dim[1])
phase = f.createVariable('phase', 'f', ('v_dim', 'u_dim'))
phase[:] = self.phase
f.close()
def display(self, title='Phase Map', axis=None, cmap='gray'):
'''Display the phasemap as a colormesh.
Arguments:
title - the title of the plot (default: 'Phase Map')
axis - the axis on which to display the plot (default: None, a new figure is created)
cmap - the colormap which is used for the plot (default: 'gray')
Returns:
None
'''
# If no axis is specified, a new figure is created:
if axis is None:
fig = plt.figure()
axis = fig.add_subplot(1, 1, 1, aspect='equal')
im = plt.pcolormesh(self.phase, cmap=cmap)
# Set the axes ticks and labels:
ticks = axis.get_xticks()*self.res
axis.set_xticklabels(ticks)
ticks = axis.get_yticks()*self.res
axis.set_yticklabels(ticks)
axis.set_title(title)
axis.set_xlabel('x-axis [nm]')
axis.set_ylabel('y-axis [nm]')
# Plot the phase map:
fig = plt.gcf()
fig.subplots_adjust(right=0.85)
cbar_ax = fig.add_axes([0.9, 0.15, 0.02, 0.7])
fig.colorbar(im, cax=cbar_ax)
plt.show()
# -*- coding: utf-8 -*-
"""Create and display a phase map from magnetization data."""
import numpy as np
import numcore
import time
# Physical constants
PHI_0 = -2067.83 # magnetic flux in T*nm²
H_BAR = 6.626E-34 # Planck constant in J*s
M_E = 9.109E-31 # electron mass in kg
Q_E = 1.602E-19 # electron charge in C
C = 2.998E8 # speed of light in m/s
def phase_mag_fourier(res, projection, b_0=1, padding=0):
'''Calculate phasemap from magnetization data (Fourier space approach).
Arguments:
res - the resolution of the grid (grid spacing) in nm
projection - projection of a magnetic distribution (created with pyramid.projector)
b_0 - magnetic induction corresponding to a magnetization Mo in T (default: 1)
padding - factor for zero padding, the default is 0 (no padding), for a factor of n the
number of pixels is increase by (1+n)**2, padded zeros are cropped at the end
Returns:
the phasemap as a 2 dimensional array
'''
v_dim, u_dim = np.shape(projection[0])
v_mag, u_mag = projection
# Create zero padded matrices:
u_pad = u_dim/2 * padding
v_pad = v_dim/2 * padding
u_mag_big = np.zeros(((1 + padding) * v_dim, (1 + padding) * u_dim))
v_mag_big = np.zeros(((1 + padding) * v_dim, (1 + padding) * u_dim))
u_mag_big[v_pad:v_pad+v_dim, u_pad:u_pad+u_dim] = u_mag
v_mag_big[v_pad:v_pad+v_dim, u_pad:u_pad+u_dim] = v_mag
# Fourier transform of the two components:
u_mag_fft = np.fft.fftshift(np.fft.rfft2(u_mag_big), axes=0)
v_mag_fft = np.fft.fftshift(np.fft.rfft2(v_mag_big), axes=0)
# Calculate the Fourier transform of the phase:
nyq = 1 / res # nyquist frequency
f_u = np.linspace(0, nyq/2, u_mag_fft.shape[1])
f_v = np.linspace(-nyq/2, nyq/2, u_mag_fft.shape[0], endpoint=False)
f_uu, f_vv = np.meshgrid(f_u, f_v)
coeff = (1j*b_0) / (2*PHI_0)
phase_fft = coeff * res * (u_mag_fft*f_vv - v_mag_fft*f_uu) / (f_uu**2 + f_vv**2 + 1e-30)
# Transform to real space and revert padding:
phase_big = np.fft.irfft2(np.fft.ifftshift(phase_fft, axes=0))
phase = phase_big[v_pad:v_pad+v_dim, u_pad:u_pad+u_dim]
return phase
def phase_mag_real(res, projection, method, b_0=1, jacobi=None):
'''Calculate phasemap from magnetization data (real space approach).
Arguments:
res - the resolution of the grid (grid spacing) in nm
projection - projection of a magnetic distribution (created with pyramid.projector)
method - String, describing the method to use for the pixel field ('slab' or 'disc')
b_0 - magnetic induction corresponding to a magnetization Mo in T (default: 1)
jacobi - matrix in which to save the jacobi matrix (default: None, faster computation)
Returns:
the phasemap as a 2 dimensional array
'''
# Function for creating the lookup-tables:
def phi_lookup(method, n, m, res, b_0):
if method == 'slab':
def F_h(n, m):
a = np.log(res**2 * (n**2 + m**2))
b = np.arctan(n / m)
return n*a - 2*n + 2*m*b
return coeff * 0.5 * (F_h(n-0.5, m-0.5) - F_h(n+0.5, m-0.5)
- F_h(n-0.5, m+0.5) + F_h(n+0.5, m+0.5))
elif method == 'disc':
in_or_out = np.logical_not(np.logical_and(n == 0, m == 0))
return coeff * m / (n**2 + m**2 + 1E-30) * in_or_out
# Process input parameters:
v_dim, u_dim = np.shape(projection[0])
v_mag, u_mag = projection
coeff = -b_0 * res**2 / (2*PHI_0)
# Create lookup-tables for the phase of one pixel:
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)
uu, vv = np.meshgrid(u, v)
phi_u = phi_lookup(method, uu, vv, res, b_0)
phi_v = phi_lookup(method, vv, uu, res, b_0)
# Calculation of the phase:
phase = np.zeros((v_dim, u_dim))
threshold = 0
if jacobi is not None: # With Jacobian matrix (slower)
jacobi[:] = 0 # Jacobi matrix --> zeros
############################### TODO: NUMERICAL CORE #####################################
for j in range(v_dim):
for i in range(u_dim):
phase_u = phi_u[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i]
jacobi[:, i+u_dim*j] = phase_u.reshape(-1)
if abs(u_mag[j, i]) > threshold:
phase += u_mag[j, i] * phase_u
phase_v = phi_v[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i]
jacobi[:, u_dim*v_dim+i+u_dim*j] = -phase_v.reshape(-1)
if abs(v_mag[j, i]) > threshold:
phase -= v_mag[j, i] * phase_v
############################### TODO: NUMERICAL CORE #####################################
else: # Without Jacobi matrix (faster)
## phasecopy = phase.copy()
## start_time = time.time()
## numcore.phase_mag_real_helper_1(v_dim, u_dim, phi_u, phi_v, u_mag, v_mag, phasecopy, threshold)
## print time.time() - start_time
## start_time = time.time()
for j in range(v_dim):
for i in range(u_dim):
if abs(u_mag[j, i]) > threshold:
phase += u_mag[j, i] * phi_u[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i]
if abs(v_mag[j, i]) > threshold:
phase -= v_mag[j, i] * phi_v[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i]
## print time.time() - start_time
## print ((phase - phasecopy) ** 2).sum()
# Return the phase:
return phase
def phase_mag_real_alt(res, projection, method, b_0=1, jacobi=None): # TODO: Modify
'''Calculate phasemap from magnetization data (real space approach).
Arguments:
res - the resolution of the grid (grid spacing) in nm
projection - projection of a magnetic distribution (created with pyramid.projector)
method - String, describing the method to use for the pixel field ('slab' or 'disc')
b_0 - magnetic induction corresponding to a magnetization Mo in T (default: 1)
jacobi - matrix in which to save the jacobi matrix (default: None, faster computation)
Returns:
the phasemap as a 2 dimensional array
'''
# Function for creating the lookup-tables:
def phi_lookup(method, n, m, res, b_0):
if method == 'slab':
def F_h(n, m):
a = np.log(res**2 * (n**2 + m**2))
b = np.arctan(n / m)
return n*a - 2*n + 2*m*b
return coeff * 0.5 * (F_h(n-0.5, m-0.5) - F_h(n+0.5, m-0.5)
- F_h(n-0.5, m+0.5) + F_h(n+0.5, m+0.5))
elif method == 'disc':
in_or_out = np.logical_not(np.logical_and(n == 0, m == 0))
return coeff * m / (n**2 + m**2 + 1E-30) * in_or_out
# Function for the phase contribution of one pixel:
def phi_mag(i, j):
return (np.cos(beta[j, i]) * phi_u[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i]
- np.sin(beta[j, i]) * phi_v[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i])
# Function for the derivative of the phase contribution of one pixel:
def phi_mag_deriv(i, j):
return -(np.sin(beta[j, i]) * phi_u[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i]
+ np.cos(beta[j, i]) * phi_v[v_dim-1-j:(2*v_dim-1)-j, u_dim-1-i:(2*u_dim-1)-i])
# Process input parameters:
v_dim, u_dim = np.shape(projection[0])
v_mag, u_mag = projection
beta = np.arctan2(v_mag, u_mag)
mag = np.hypot(u_mag, v_mag)
coeff = -b_0 * res**2 / (2*PHI_0)
# Create lookup-tables for the phase of one pixel:
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)
uu, vv = np.meshgrid(u, v)
phi_u = phi_lookup(method, uu, vv, res, b_0)
phi_v = phi_lookup(method, vv, uu, res, b_0)
# Calculation of the phase:
phase = np.zeros((v_dim, u_dim))
threshold = 0
if jacobi is not None: # With Jacobian matrix (slower)
jacobi[:] = 0 # Jacobi matrix --> zeros
############################### TODO: NUMERICAL CORE #####################################
for j in range(v_dim):
for i in range(u_dim):
phase_cache = phi_mag(i, j)
jacobi[:, i+u_dim*j] = phase_cache.reshape(-1)
if mag[j, i] > threshold:
phase += mag[j, i]*phase_cache
jacobi[:, u_dim*v_dim+i+u_dim*j] = (mag[j, i]*phi_mag_deriv(i, j)).reshape(-1)
############################### TODO: NUMERICAL CORE #####################################
else: # Without Jacobi matrix (faster)
for j in range(v_dim):
for i in range(u_dim):
if abs(mag[j, i]) > threshold:
phase += mag[j, i] * phi_mag(i, j)
# Return the phase:
return phase
#def phase_elec(mag_data, v_0=0, v_acc=30000):
# # TODO: Docstring
#
# res = mag_data.res
# z_dim, y_dim, x_dim = mag_data.dim
# z_mag, y_mag, x_mag = mag_data.magnitude
#
# phase = np.logical_or(x_mag, y_mag, z_mag)
#
# lam = H_BAR / np.sqrt(2 * M_E * v_acc * (1 + Q_E*v_acc / (2*M_E*C**2)))
#
# Ce = (2*pi*Q_E/lam * (Q_E*v_acc + M_E*C**2) /
# (Q_E*v_acc * (Q_E*v_acc + 2*M_E*C**2)))
#
# phase *= res * v_0 * Ce
#
# return phase
# -*- coding: utf-8 -*-
"""Planar projection of the magnetization distribution of a MagData object."""
from pyramid.magdata import MagData
def simple_axis_projection(mag_data, axis='z'):
'''Project a magnetization distribution along one of the main axes of the 3D-grid.
Arguments:
mag_data - a MagData object storing the magnetization distribution
axis - the projection direction (String: 'x', 'y', 'z'), default = 'z'
Returns:
the in-plane projection of the magnetization as a tuple: (x_mag, y_mag)
()
'''
assert isinstance(mag_data, MagData), 'Parameter mag_data has to be a MagData object!'
assert axis == 'z' or axis == 'y' or axis == 'x', 'Axis has to be x, y or z (as String)!'
if axis == 'z':
projection = (mag_data.magnitude[1].sum(0), # y_mag -> v_mag
mag_data.magnitude[2].sum(0)) # x_mag -> u_mag
elif axis == 'y':
projection = (mag_data.magnitude[0].sum(1), # z_mag -> v_mag
mag_data.magnitude[2].sum(1)) # x_mag -> u_mag
elif axis == 'x':
projection = (mag_data.magnitude[0].sum(2), # z_mag -> v_mag
mag_data.magnitude[1].sum(2)) # y_mag -> u_mag
return projection
# TODO: proper projection algorithm with two angles and such!
# CAUTION: the res for the projection does not have to be the res of the 3D-magnetization!
# Just for a first approach
# -*- coding: utf-8 -*-
"""Reconstruct magnetic distributions with given phasemaps"""
import numpy as np
import pyramid.projector as pj
import pyramid.phasemapper as pm
from pyramid.magdata import MagData
from scipy.optimize import leastsq
def reconstruct_simple_leastsq(phase_map, mask, b_0):
'''Reconstruct a magnetic distribution where the positions of the magnetized voxels are known
from a single phase_map using the least square method (only works for slice thickness = 1)
Arguments:
phase_map - a PhaseMap object, from which to reconstruct the magnetic distribution
mask - a boolean matrix representing the positions of the magnetized voxels (3D)
b_0 - magnetic induction corresponding to a magnetization Mo in T (default: 1)
Returns:
the reconstructed magnetic distribution (as a MagData object)
'''
# Read in parameters:
y_m = phase_map.phase.reshape(-1) # Measured phase map as a vector
res = phase_map.res # Resolution
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(res, (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(res, pj.simple_axis_projection(mag_data_rec), 'slab', 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
# -*- coding: utf-8 -*-
"""Unittests for pyramid."""
import unittest
from test_compliance import TestCaseCompliance
from test_magcreator import TestCaseMagCreator
from test_magdata import TestCaseMagData
from test_projector import TestCaseProjector
from test_phasemapper import TestCasePhaseMapper
from test_phasemap import TestCasePhaseMap
from test_holoimage import TestCaseHoloImage
from test_analytic import TestCaseAnalytic
from test_reconstructor import TestCaseReconstructor
def run():
suite = unittest.TestSuite()
loader = unittest.TestLoader()
runner = unittest.TextTestRunner(verbosity=2)
suite.addTest(loader.loadTestsFromTestCase(TestCaseCompliance))
suite.addTest(loader.loadTestsFromTestCase(TestCaseMagCreator))
suite.addTest(loader.loadTestsFromTestCase(TestCaseMagData))
suite.addTest(loader.loadTestsFromTestCase(TestCaseProjector))
suite.addTest(loader.loadTestsFromTestCase(TestCasePhaseMapper))
suite.addTest(loader.loadTestsFromTestCase(TestCasePhaseMap))
suite.addTest(loader.loadTestsFromTestCase(TestCaseHoloImage))
suite.addTest(loader.loadTestsFromTestCase(TestCaseAnalytic))
suite.addTest(loader.loadTestsFromTestCase(TestCaseReconstructor))
runner.run(suite)
if __name__ == '__main__':
run()
# -*- coding: utf-8 -*-
"""Testcase for the analytic module."""
import unittest
import pyramid.analytic as an
class TestCaseAnalytic(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_template(self):
pass
def test_phase_mag_slab(self):
pass
def test_phase_mag_disc(self):
pass
def test_phase_mag_sphere(self):
pass
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestCaseAnalytic)
unittest.TextTestRunner(verbosity=2).run(suite)
# -*- coding: utf-8 -*-
"""Testcase for the magcreator module."""
import datetime
import sys
import os
import unittest
import pep8
class TestCaseCompliance(unittest.TestCase):
"""
Class for checking compliance of pyjurassic.
""" # TODO: Docstring
def setUp(self):
pass
def tearDown(self):
pass
def get_files_to_check(self, rootdir):
filepaths = []
for root, dirs, files in os.walk(rootdir):
for filename in files:
if filename.endswith('.py'):
filepaths.append(os.path.join(root, filename))
return filepaths
def test_pep8(self):
# TODO: Docstring
files = self.get_files_to_check('..') # search in pyramid package
ignores = ('E226', 'E128')
pep8.MAX_LINE_LENGTH = 99
pep8style = pep8.StyleGuide(quiet=False)
pep8style.options.ignore = ignores
stdout_buffer = sys.stdout
with open(os.path.join('..', '..', 'output', 'pep8_log.txt'), 'w') as sys.stdout:
print '<<< PEP8 LOGFILE >>>'
print 'RUN:', datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print 'IGNORED RULES:', ', '.join(ignores)
print 'MAX LINE LENGTH:', pep8.MAX_LINE_LENGTH
print '\nERRORS AND WARNINGS:'
result = pep8style.check_files(files)
if result.total_errors == 0:
print 'No Warnings or Errors detected!'
sys.stdout = stdout_buffer
error_message = 'Found %s Errors and Warnings!' % result.total_errors
self.assertEqual(result.total_errors, 0, error_message)
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestCaseCompliance)
unittest.TextTestRunner(verbosity=2).run(suite)
# -*- coding: utf-8 -*-
"""Testcase for the holoimage module."""
import unittest
import pyramid.holoimage as hi
class TestCaseHoloImage(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_holo_image(self):
pass
def test_make_color_wheel(self):
pass
def test_display(self):
pass
def test_display_combined(self):
pass
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestCaseHoloImage)
unittest.TextTestRunner(verbosity=2).run(suite)
# -*- coding: utf-8 -*-
"""Testcase for the magcreator module."""
import unittest
import numpy as np
import pyramid.magcreator as mc
# TODO: Proper messages
class TestCaseMagCreator(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def test_shape_slab(self):
test_slab = mc.Shapes.slab((5, 6, 7), (2, 3, 4), (1, 3, 5))
np.testing.assert_equal(test_slab, np.load('test_magcreator/ref_slab.npy'),
'Testmessage')
def test_shape_disc(self):
test_disc_z = mc.Shapes.disc((5, 6, 7), (2, 3, 4), 2, 3, 'z')
test_disc_y = mc.Shapes.disc((5, 6, 7), (2, 3, 4), 2, 3, 'y')
test_disc_x = mc.Shapes.disc((5, 6, 7), (2, 3, 4), 2, 3, 'x')
np.testing.assert_equal(test_disc_z, np.load('test_magcreator/ref_disc_z.npy'),
'Testmessage')
np.testing.assert_equal(test_disc_y, np.load('test_magcreator/ref_disc_y.npy'),
'Testmessage')
np.testing.assert_equal(test_disc_x, np.load('test_magcreator/ref_disc_x.npy'),
'Testmessage')
def test_shape_sphere(self):
test_sphere = mc.Shapes.sphere((5, 6, 7), (2, 3, 4), 2)
np.testing.assert_equal(test_sphere, np.load('test_magcreator/ref_sphere.npy'),
'Testmessage')
def test_shape_filament(self):
test_filament_z = mc.Shapes.filament((5, 6, 7), (2, 3), 'z')
test_filament_y = mc.Shapes.filament((5, 6, 7), (2, 3), 'y')
test_filament_x = mc.Shapes.filament((5, 6, 7), (2, 3), 'x')
np.testing.assert_equal(test_filament_z, np.load('test_magcreator/ref_filament_z.npy'),
'Testmessage')
np.testing.assert_equal(test_filament_y, np.load('test_magcreator/ref_filament_y.npy'),
'Testmessage')
np.testing.assert_equal(test_filament_x, np.load('test_magcreator/ref_filament_x.npy'),
'Testmessage')
def test_shape_pixel(self):
test_pixel = mc.Shapes.pixel((5, 6, 7), (2, 3, 4))
np.testing.assert_equal(test_pixel, np.load('test_magcreator/ref_pixel.npy'),
'Testmessage')
def test_create_mag_dist(self):
pass
def test_create_mag_dist_comb(self):
pass
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestCaseMagCreator)
unittest.TextTestRunner(verbosity=2).run(suite)
File deleted
File deleted