Symmetrizing data using the Symmetrizer classes#

Import functions#

from nxs_analysis_tools import load_data, plot_slice
from nxs_analysis_tools.pairdistribution import Symmetrizer3D, Symmetrizer2D

Load data#

data = load_data('example_data/pairdistribution_data/test_hkli.nxs')
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)

The Symmetrizer2D class#

A Symmetrizer2D object can be initialized by defining a theta_min and theta_max representing the range of angles (clockwise relative the y-axis) which define the region to use for symmetrization.

s2d = Symmetrizer2D(theta_min=0, theta_max=45)

Because data is not specified, the Symmetrizer2D object can be applied to any NXdata object. Perform the symmetrization using the .symmetrize_2d() method.

symmetrized_data = s2d.symmetrize_2d(data[:,:,0.0])
plot_slice(symmetrized_data)
<matplotlib.collections.QuadMesh at 0x7f1deea3ead0>
../_images/b24cc120c8695a9c6a2131758f968e741fe16a57bc8019016eda814b76cecd60.png

Viewing the symmetrization mask#

The symmetrization mask for the most recent symmetrized dataset is stored in symmetrization_mask

plot_slice(data=s2d.symmetrization_mask)
<matplotlib.collections.QuadMesh at 0x7f1df0bfac50>
../_images/44cce07e256f815b769cd00ee997626730cd07f35ce59af7fbce7ddd7c09e47b.png

Viewing the wedge used for symmetrization#

The .wedge attribute stores the wedge of data used to recreate the entire dataset.

plot_slice(s2d.wedge)
<matplotlib.collections.QuadMesh at 0x7f1df0bfadd0>
../_images/b5edf9dfcb12ce293ade5fd298fbd6485c1993c0005e0aaafb3c43bd89e8f8ba.png

The mirror operation#

The optional Boolean parameter mirror applies a mirror transformation to the wedge before it is rotated around the origin to reconstruct the dataset. The default value is True, in order to preserve the mirror symmetry common to diffraction patterns. If false, the wedge is rotated enough times to recreate all 360 degrees of the plane.

Here, the effect is noticeable because the wedge is only 45 degrees, and 8-fold rotational symmtery is not present in the parent dataset.

s2d = Symmetrizer2D(theta_min=0, theta_max=45, mirror=False)
plot_slice(s2d.symmetrize_2d(data[:,:,0.0]))
<matplotlib.collections.QuadMesh at 0x7f1dee7da0e0>
../_images/093d9ba0abc0506206123e6cd4b1cbe86ae892000edb389055d193f1d5a0b8cf.png

Here, we change the wedge to cover 90 degrees, and since 4-fold rotation is present in the parent dataset the symmetrization produces the expected result.

s2d = Symmetrizer2D(theta_min=45, theta_max=135, mirror=False)
plot_slice(s2d.symmetrize_2d(data[:,:,0.0]))
<matplotlib.collections.QuadMesh at 0x7f1dee6d3d00>
../_images/ecda97475fb5dc57adfe5ec982d36c650f9819fc4ec9302318d143af4a3f9977.png

The test function#

Use the .test() method to visualize an overview of the symmetrization process, including the raw data, symmetrization mask, wedge, and reconstructed dataset.

s2d.test(data[:,:,0.0])
../_images/35fec05bdac818e25928da46cb65baae7f5d0c32a5c023f6024c4f464e27ca8c.png
(<Figure size 1000x800 with 8 Axes>,
 array([[<Axes: title={'center': 'data'}, xlabel='H', ylabel='K'>,
         <Axes: title={'center': 'mask'}, xlabel='H', ylabel='K'>],
        [<Axes: title={'center': 'wedge'}, xlabel='H', ylabel='K'>,
         <Axes: title={'center': 'symmetrized'}, xlabel='H', ylabel='K'>]],
       dtype=object))

The Symmetrizer3D class#

The Symmetrizer3D class wraps three instances of the Symmetrizer2D class, which represent the three primary cross-sections of the dataset, called “Plane 1”, “Plane 2”, and “Plane 3”.

s = Symmetrizer3D(data)
Plane 1: HK
Plane 2: HL
Plane 3: KL

Each Symmetrizer2D object is then accessible via the attributes .plane1symmetrizer, etc.

s.plane1symmetrizer
<nxs_analysis_tools.pairdistribution.Symmetrizer2D at 0x7f1decdcc190>

The parameters for each Symmetrizer2D object can then be set in the usual way.

s.plane1symmetrizer.set_parameters(theta_min=0, theta_max=90, mirror=True)

The .test() method of the Symmetrizer2D class should be used to verify the symmetry operations on each plane.

s.plane1symmetrizer.test(data[:,:,len(data.L)//2])
../_images/b61cdb7a7b2bf43e4d63a63ed910c9940a2c589722eca327d20375d07fd7bb67.png
(<Figure size 1000x800 with 8 Axes>,
 array([[<Axes: title={'center': 'data'}, xlabel='H', ylabel='K'>,
         <Axes: title={'center': 'mask'}, xlabel='H', ylabel='K'>],
        [<Axes: title={'center': 'wedge'}, xlabel='H', ylabel='K'>,
         <Axes: title={'center': 'symmetrized'}, xlabel='H', ylabel='K'>]],
       dtype=object))

Once the Symmetrizer2D objects for each plane have been initialized, the .symmetrize() method of the Symmetrize3D object can be used to perform the full symmetrization.

s.plane2symmetrizer.set_parameters(theta_min=45, theta_max=90, mirror=True)
s.plane2symmetrizer.test(data[:,len(data.K)//2,:])
../_images/24391faf46a578dd7a35599ea138b2c242a2c98ae7edf2dd03ff64dc53a87374.png
(<Figure size 1000x800 with 8 Axes>,
 array([[<Axes: title={'center': 'data'}, xlabel='H', ylabel='L'>,
         <Axes: title={'center': 'mask'}, xlabel='H', ylabel='L'>],
        [<Axes: title={'center': 'wedge'}, xlabel='H', ylabel='L'>,
         <Axes: title={'center': 'symmetrized'}, xlabel='H', ylabel='L'>]],
       dtype=object))
s.plane3symmetrizer.set_parameters(theta_min=0, theta_max=90, mirror=False)
s.plane3symmetrizer.test(data[len(data.H)//2,:,:])
../_images/f6d609bae4bb61b7ba7d454223a26ce421411052cb6ab0f1c3f2e1bbc8b303e3.png
(<Figure size 1000x800 with 8 Axes>,
 array([[<Axes: title={'center': 'data'}, xlabel='K', ylabel='L'>,
         <Axes: title={'center': 'mask'}, xlabel='K', ylabel='L'>],
        [<Axes: title={'center': 'wedge'}, xlabel='K', ylabel='L'>,
         <Axes: title={'center': 'symmetrized'}, xlabel='K', ylabel='L'>]],
       dtype=object))
s.symmetrize()
Symmetrizing HK planes...
Symmetrizing L=1.00...
Symmetrized HK planes.
Symmetrizing HL planes...
Symmetrizing K=1.00...
Symmetrized HL planes.
Symmetrizing KL planes...
Symmetrizing H=1.00...
Symmetrized KL planes.

Symmetriztaion finished in 1.05 minutes.
NXdata('data')