Hyperfine parameters
The hyperfine parameters define the energy of the Hamiltonian for the different spin states of the nucleus. For a Moessbauer isotope one has to consider the isomer shift, the quadrupole splitting and the magnetic hyperfine field. The quantization system for the hyperfine parameters is set to the coordinates system of the beam
and all angles of the spherical hyperfine parameters are referenced to this coordinate system.
The following parameters are Var objects and can be fit for :class:`Hyperfine` site:
relative weight of the site
isomer shift
magnetic field
magnetic polar angle
magnetic azimuthal angle
quadrupole slitting
quadrupole ZYZ Euler angle alpha
quadrupole ZYZ Euler angle beta
quadrupole ZYZ Euler angle gamma
quadrupole asymmetry
Added in version 1.2.0.
texture
Lamb-Moessbauer factor
broadening
Added in version 2.0.0.
Gaussian broadening
A Hyperfine object with all attributes defined looks like this
hyperfine = nx.Hyperfine(
id = "example parameter",
weight = 1, # relative weight of the site in the material
isomer = -0.11, # isomer shift in mm/s
magnetic_field = 33, # magnetic field in T
magnetic_theta = 0, # polar angle
magnetic_phi = 45, # azimuthal angle
quadrupole = 0.8, # quadrupole slitting in mm/s
quadrupole_alpha = 90, # ZYZ Euler angle alpha
quadrupole_beta = 45, # ZYZ Euler angle beta
quadrupole_gamma = 0, # ZYZ Euler angle gamma
quadrupole_asymmetry = 0.05, # Asymmetry parameter
texture = 1.0, # texture coefficient
lamb_moessbauer = 1.0, # site specific Lamb-Moessbauer factor
broadening = 1.0, # broadening parameter of the linewidth
gaussian_broadening = 0.0, # Gaussian broadening parameter, since version 2.0.0
isomer_dist = None,
magnetic_field_dist = None,
magnetic_theta_dist = None,
magnetic_phi_dist = None,
quadrupole_dist = None,
quadrupole_alpha_dist = None,
quadrupole_beta_dist = None,
quadrupole_gamma_dist = None,
quadrupole_asymmetry_dist = None,
isotropic = False) # 3D distribution in mag and EFG
print(hyperfine)
Hyperfine .id: example parameter
.weight = 1.0
.isomer_shift = -0.11 dist points: 1
.magnetic_field = 33.0 dist points: 1
.magnetic_theta = 0.0 dist points: 1
.magnetic_phi = 45.0 dist points: 1
.quadrupole = 0.8 dist points: 1
.quadrupole_alpha = 90.0 dist points: 1
.quadrupole_beta = 45.0 dist points: 1
.quadrupole_gamma = 0.0 dist points: 1
.quadrupole_asymmetry = 0.05 dist points: 1
.isotropic = False 3D distribution in mag and efg. Random mag or efg distributions are ignored.
random magnetic distribution: none dist points: 1
random quadrupole distribution: none dist points: 1
total number of distribution points: 1
In the initialization the parameters and their distributions can be set.
Distributions are special objects, which we will cover in the next section.
Here, the basic hyperfine parameters are covered.
Weight
In case you specify more than one site to a material, this parameter gives the relative contribution of the hyperfine site to the material. The values are normalized to the total relative weight of all sites.
Isomer shift
The isomer shift is isotropic and no angles have to be defined.
Magnetic hyperfine field
For the magnetic field its field strength and two angles are given. The polar angle \(\vartheta\) is defined from the \(k\) vector. The azimuthal angle \(\varphi\) is defined in the \(\sigma - \pi\) plane from the \(\sigma\) direction.
For a magnetic field along \(k\) (Faraday geometry) set the Hyperfine parameters to
hyperfine = nx.Hyperfine(
magnetic_field = 33, # magnetic field in T
magnetic_theta = 0, # polar angle
magnetic_phi = 0) # azimuthal angle
For a magnetic field along \(\sigma\) set it to
hyperfine = nx.Hyperfine(
magnetic_field = 33, # magnetic field in T
magnetic_theta = 90, # polar angle
magnetic_phi = 0) # azimuthal angle
and for a magnetic field along \(\pi\) to
hyperfine = nx.Hyperfine(
magnetic_field = 33, # magnetic field in T
magnetic_theta = 90, # polar angle
magnetic_phi = 90) # azimuthal angle
A magnetic field can be given in the Nexus frame can be converted to spherical coordinates and vie versa with the functions MagVectorToSpherical() and MagSphericalToVector().
Added in version 1.0.2.
# Nexus frame (sigma, pi, k)
# spherical (mag, polar, azimuthal)
# convert a magnetic field along pi direction to spherical coordinates
print(nx.MagVectorToSpherical(0, 33, 0))
# convert a magnetic field along k direction to Nexus frame
print(nx.MagSphericalToVector(33, 0, 0))
(33.0, 90.0, 90.0)
(0.0, 0.0, 33.0)
Electric field gradient and quadrupole splitting
Changed in version 2.0.0
This tutorial section has been changed.
It contained two errors in versions 1.X.X.
The angles in the extrinsic rotation of the EFG away from the internal frame were defined as active rotations.
However, after finding the angles with an active rotation, the angles need to be inverted (passive rotation).
In addition, the angles \(\alpha\) and \(\gamma\) were described to be exchanged when used in CONUSS, which is not the case.
The passive and active rotation difference is only important when combined magnetic and EFG fields are present.
This section has been rewritten largely to clarify these points.
Note, that the Euler angles itself were properly included in the C++ routines.
So, the Euler angles provided to Hyperfine objects and obtained from fitting are correct.
For a more detailed description of the angles have a look to the euler module.
The electric field gradient tensor is defined by the largest principal tensor component \(V_{zz}\), the asymmetry parameter \(\eta\), and three Euler angles \(\alpha\), \(\beta\), \(\gamma\). In Nexus, instead of \(V_{zz}\) the quadrupole splitting \(QS\) (mm/s) is given. The quadrupole energy is
where \(Q_i\) is the quadrupole moment of either ground or excited state.
The given value of the quadrupole splitting is the value of the split state for isotopes with either ground or excited state split. For example, for Fe-57 (\(I_g = 1/2\) and \(I_e = 3/2\)) only the excited state is split, while for Ir-193 (\(I_g = 3/2\) and \(I_e = 1/2\)) only the ground state is split. For isotopes with split ground and excited state (e.g. Ru-99 with \(I_g = 5/2\) and \(I_e = 3/2\)), the value gives the quadrupole energy of the excited state (with \(Q_e\)) and the quadrupole energy of the ground state is scaled by the ratio \(Q_g/Q_e\).
See also
https://en.wikipedia.org/wiki/Electric_field_gradient
https://en.wikipedia.org/wiki/Quadrupole_splitting
For the energy conversion see https://en.wikipedia.org/wiki/Doppler_effect
The Euler angles are defined as the rotation angles in ZYZ convention, which rotate the EFG to the quantization frame. Without rotation (\(\alpha=0,\beta=0,\gamma=0\)), the EFG main axis \(V_{zz}\) points along \(\vec{k}\). The two components \(V_{xx}\) and \(V_{yy}\) point along \(\sigma\) and \(\pi\), respectively.
There are several ways to perfrom the rotation to obtain the Euler angles, where we will show two possible ways. The first option via the above given definition: As a rotation of the EFG to the internal frame of Nexus, which is the \((\sigma, \pi, k)\) coordiante system. In this convention the rotatio are as follows:
Rotation by \(\alpha\) around axis \(z\) in the EFG frame.
Rotation by \(\beta\) around new axis \(y'\) in the rotated EFG frame.
Rotation by \(\gamma\) around new axis \(z''\) in the rotated EFG frame.
Such an intrinsic rotation of the EFG to the quantization axis is shown in the figure below, where the EFG main axis \(V_{zz}\) points initially along the \(\pi\) direction, \(V_{yy}\) along the \(\sigma\) and \(V_{xx}\) along the \(k\). The axis of rotation is shown that will give the new alignment of the EFG to the previous picture.
INTRINSIC ROTATION AROUND EFG FRAME TO THE INTERNAL REFERENCE FRAME
The first rotation is zero and keeps the EFG frame unchanged. The second rotation around \(V_{yy}\) (\(y'\)) by 90 degree will rotate \(V_{zz}\) to \(k\) and \(V_{xx}\) to \(-\pi\). The third rotation around the new \(V_{zz}\) (\(z''\)) by 90 degree will rotate \(V_{yy}\) to \(\pi\) and \(V_{xx}\) to \(\sigma\). The EFG frame is now aligned with the fixed frame (\(\sigma\), \(\pi\), \(k\)). The Euler angles are thus \(\alpha = 0°\), \(\beta = 90°\) and \(\gamma = 90°\).
Finding the correct Euler angles by hand can be a tedious task and is prone to error.
Therefore, Nexus provides functions in the euler module to find the Euler angles from the initial alignment.
import nexus as nx
import numpy as np
rad2deg = 180 / np.pi
Vxx = [0,0,1] # k
Vyy = [1,0,0] # sigma
Vzz = [0,1,0] # pi
# note the order of Vzz, Vxx, Vyy here
alpha, beta, gamma = nx.euler.VectorsToAngles(Vzz, Vxx, Vyy)
print(alpha * rad2deg, beta * rad2deg, gamma* rad2deg)
will result in the three angles
0.0 90.0 90.0
In case the asymmetry parameter is zero you can also provide Vzz only
Vxx = [0,0,1]
alpha, beta, gamma = nx.euler.VectorsToAngles(Vzz)
print(alpha * rad2deg, beta * rad2deg, gamma* rad2deg)
0.0 90.0 90.0
To obtain the orientation of the EFG axes from Euler angles (e.g. fitted values) use
import nexus as nx
import numpy as np
deg2rad = np.pi / 180
Vxx, Vyy, Vzz = nx.euler.AnglesToVectors(0, 90 * deg2rad, 90 * deg2rad)
print(Vxx)
print(Vyy)
print(Vzz)
to obtain the vectors
[ 3.74939946e-33 -6.12323400e-17 1.00000000e+00]
[1.000000e+00 6.123234e-17 0.000000e+00]
[-6.123234e-17 1.000000e+00 6.123234e-17]
Using the these functions is the prefered way to find the Euler angles.
In a few cases it might be helpful to start with the EFG aligned with the reference frame and to find the Euler angles by rotating the EFG to the final position. Then, the rotation should happen around the axes of the reference frame (extrinsic rotation). The order of rotations then is
Rotation by \(\alpha\) around axis \(k\) in the fixed internal frame.
Rotation by \(\beta\) around axis \(\pi\) in the fixed internal frame.
Rotation by \(\gamma\) around axis \(k\) in the fixed internal frame.
as shown for the case where the EFG is rotated to \(\pi\) axis as in the previous example.
EXTRINSIC ROTATION AROUND INTERNAL REFERENCE FRAME TO THE FINAL EFG ALIGNMENT
Note that the angles are inverted for this rotation -90° instead of 90°. In order to get the proper Euler angles, the angles for this extrinsic rotation (inverse rotation) need to be inverted. The Euler angles are again \(\alpha = 0°\), \(\beta = 90°\) and \(\gamma = 90°\).
When you have found angles with this extrinsic rotation procedure around the internal frame you can also use the euler module.
import nexus as nx
import numpy as np
deg2rad = np.pi / 180
# tell the function you used extrinsic rotation around internal frame
Vxx, Vyy, Vzz = nx.euler.AnglesToVectors(0, -90 * deg2rad, -90 * deg2rad, rotation="extrinsicINT")
print(Vxx)
print(Vyy)
print(Vzz)
[ 3.74939946e-33 -6.12323400e-17 1.00000000e+00]
[1.000000e+00 6.123234e-17 0.000000e+00]
[-6.123234e-17 1.000000e+00 6.123234e-17]
For more information on Euler angle convention and additional functions have a look to the euler module.
Lamb-Moessbauer factor
Added in version 1.2.0.
A site specific Lamb-Moessbauer factor lamb_moessbauer has been added.
If the Material has a Lamb Moessbauer factor defined, the material`s factor is used.
In case you want to use the site specific Lamb-Moessbauer factor, set the lamb_moessbauer of the Material to None.
In that case each site assigned to the material must have a valid Lamb-Moessbauer factor defined.
Note
Set the Lamb-Moessbauer factor in the material in case you do not expect changes between different sites in the material.
Line broadening
Line broadening can have several reasons and be modeled in different ways. Nexus provides two model free broadening parameters, which can be used when no micoscopic model for the broadening is present. For specific models for the broadening, e.g. due to a distribution of hyperfine parameters, use the distribution functions described in section Hyperfine parameter distributions.
This parameter should only be used when no model for the broadening is present. In case you know that you have a certain distribution of hyperfine parameters use the distribution functions on these parameters.
Warning
Please also note that the broadening parameters are intended for intensity spectra (EnergySpectrum, MoessbauerSpectrum and EmissionSpectrum).
You can use it also for TimeSpectrum or amplitude spectra, but the physical interpretation of the broadening is not straightforward in these cases.
Especially the phases might differ for different hyperfine broadenings or distributions, which can lead to non-trivial effects in the time domain and amplitude spectra.
Note
The broadening parameters have the advantage that only one site is used in the calculations instead of a distribution of sites as with the Distribution class (see next section).
It is thus computationally more efficient than using distributions, but in a model free approach.
Lorentzian broadening
Added in version 1.2.0.
The broadening factor gives an additional Lorentzian line broadening.
The factor multiplies with the natural linewidth and describes any model-free additional Lorentzian broadening of the line.
So, a boradeing of 1 corresponds to the natural linewidth, a broadening of 2 corresponds to a doubling of the natural linewidth, etc.
Gaussian broadening
Added in version 2.0.0.
The factor gaussian_broadening gives an additional Gaussian line broadening.
The combined Lorentzian and Gaussian broadening is calculated via a convolution of the Lorentzian with a Gaussian using the Faddeeva function.
Broadening in both Lorentzian and Gaussian form are supported at the same time.
A Gaussian broadening of 0 corresponds to no additional Gaussian broadening, a factor of 1 corresponds to an addition of a Gaussian with FWHM of one Gamma.
The total FWHM \(F\) of the line can be estimated with the formula by Olivero and Longbothum
where \(F_L\) is the Lorentzian FWHM and \(F_G\) is the Gaussian FWHM. Please note that additional broadening due to thickness effects can take place.
Distributions
It is possible to assign distributions directly during the initialization of a Hyperfine site. Therefore, you need to specify a distribution (see Hyperfine parameter distributions.) and assign it to “x_dist”, where “x” represents any hyperfine parameter, e.g. “isomer_dist” or “quadrupole_gamma_dist”.
Isotropic
The isotropic option sets a 3D angular distribution of the site.
The site parameters (the angels between the magnetic field and the EFG) are fixed.
This corresponds, for example, to randomly oriented powder samples or crystalites in a thin films.
When a preferred direction is expected or an external field is applied this parameter must be False.
Texture
Added in version 1.2.0.
Since version 1.2.0 Nexus offers a texture coefficient texture as in CONUSS.
It is only used when .isotropic = False.
Please be aware that the texture coefficient relates to a very special situation of hyperfine parameters.
A texture of 1 corresponds to site whose directional parameters are such as given.
A texture of 0 corresponds to a site whose isotropic is set to True.
It means that the non-texture part models a site with magnetic field and quadrupole slitting fixed to each other and this site randomly distributed in 3D.
All values between 0 and 1 mix the two cases.
Note
Prior to version 1.2.0 use
Texture as in CONUSS
If you are familiar with CONUSS you might want to set the texture of a sample. Here is how to emulate the texture coefficient from CONUSS. Let’s assume a hyperfine site with a magnetic field directed along the photon k-vector. The texture should be 80% in CONUSS. Then, in Nexus write
# this site corresponds to the 80% textured part with both magnetic field and efg
# being directed along their given directions
site_1 = nx.Hyperfine(weight = 0.8,
magnetic_field = 33,
magnetic_theta = 0,
magnetic_phi = 0,
quadrupole = 0,
isotropic = False)
# this site corresponds to the 20% non-textured part with both magnetic field and efg
# being spherically distributed
site_2 = nx.Hyperfine(weight = 0.2,
magnetic_field = 33,
quadrupole = 0,
isotropic = True)
material.hyperfine_sites = [site_1, site_2]
When you want to fit a texture just let one of the weights be fitted and keep the other one fixed. As the weight give the relative contribution you can easily calculate the percentage.
Notebooks
hyperfine - nb_hyperfine.ipynb.
Please have a look to the API Reference for more information.