msspec_python3/doc/source/tutorials/AlN/AlN.py

131 lines
4.7 KiB
Python

# coding: utf8
from ase.build import bulk
import numpy as np
from msspec.calculator import MSSPEC, XRaySource
from msspec.utils import hemispherical_cluster, get_atom_index
def create_clusters(nplanes=6):
def get_AlN_tags_planes(side, emitter):
AlN = bulk('AlN', crystalstructure='wurtzite', a=3.11, c=4.975)
[atom.set('tag', i) for i, atom in enumerate(AlN)]
if side == 'Al':
AlN.rotate([0,0,1],[0,0,-1])
Al_planes = range(0, nplanes, 2)
N_planes = range(1, nplanes, 2)
else:
N_planes = range(0, nplanes, 2)
Al_planes = range(1, nplanes, 2)
if emitter == 'Al':
tags = [0, 2]
planes = Al_planes
else:
tags = [1, 3]
planes = N_planes
return AlN, tags, planes
clusters = []
for side in ('Al', 'N'):
for emitter in ('Al', 'N'):
AlN, tags, planes = get_AlN_tags_planes(side, emitter)
for emitter_tag in tags:
for emitter_plane in planes:
cluster = hemispherical_cluster(AlN,
emitter_tag=emitter_tag,
emitter_plane=emitter_plane,
planes=emitter_plane+2)
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
cluster.info.update({
'emitter_plane': emitter_plane,
'emitter_tag' : emitter_tag,
'emitter' : emitter,
'side' : side,
})
clusters.append(cluster)
print("Added cluster {}-side, emitter {}(tag {:d}) in "
"plane #{:d}".format(side, emitter, emitter_tag,
emitter_plane))
return clusters
def compute(clusters, theta=np.arange(-20., 80., 1.), phi=0.):
data = None
for ic, cluster in enumerate(clusters):
# Retrieve info from cluster object
side = cluster.info['side']
emitter = cluster.info['emitter']
plane = cluster.info['emitter_plane']
tag = cluster.info['emitter_tag']
# Set the level and the kinetic energy
if emitter == 'Al':
level = '2p'
ke = 1407.
elif emitter == 'N':
level = '1s'
ke = 1083.
calc = MSSPEC(spectroscopy='PED', algorithm='expansion')
calc.source_parameters.energy = XRaySource.AL_KALPHA
calc.source_parameters.theta = -35
calc.detector_parameters.angular_acceptance = 4.
calc.detector_parameters.average_sampling = 'medium'
calc.calculation_parameters.scattering_order = max(1, min(4, plane))
calc.calculation_parameters.path_filtering = 'forward_scattering'
calc.calculation_parameters.off_cone_events = 1
[a.set('forward_angle', 30.) for a in cluster]
calc.set_atoms(cluster)
data = calc.get_theta_scan(level=level, theta=theta, phi=phi,
kinetic_energy=ke, data=data)
dset = data[-1]
dset.title = "\'{}\' side - {}({}) tag #{:d}, plane #{:d}".format(
side, emitter, level, tag, plane)
return data
def analysis(data):
tmp_data = {}
for dset in data:
info = dset.get_cluster().info
side = info['side']
emitter = info['emitter']
try:
key = '{}_{}'.format(side, emitter)
tmp_data[key] += dset.cross_section
except KeyError:
tmp_data[key] = dset.cross_section.copy()
tmp_data['theta'] = dset.theta.copy()
tmp_data['Al_side'] = tmp_data['Al_Al'] / tmp_data['Al_N']
tmp_data['N_side'] = tmp_data['N_Al'] / tmp_data['N_N']
# now add all columns
substrate_dset = data.add_dset('Total substrate signal')
substrate_dset.add_columns(**tmp_data)
view = substrate_dset.add_view('Ratios',
title=r'Al(2p)/N(1s) ratios on both polar '
r'sides of AlN in the (10$\bar{1}$0) '
r'azimuthal plane',
xlabel=r'$\Theta (\degree$)',
ylabel='Intenisty ratio')
view.select('theta', 'Al_side', legend='Al side',
where="theta >= 0 and theta <=70")
view.select('theta', 'N_side', legend='N side',
where="theta >= 0 and theta <=70")
view.set_plot_options(autoscale=True)
return data
clusters = create_clusters()
data = compute(clusters)
data = analysis(data)
data.view()