Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add vispy plotting of crystal structure to pyspinw #161

Merged
merged 35 commits into from
Jan 17, 2024

Conversation

RichardWaiteSTFC
Copy link
Collaborator

@RichardWaiteSTFC RichardWaiteSTFC commented Dec 6, 2023

Class to plot supercells with atoms, bonds and magnetic structures (in rotating frame representation only - i.e. from spinw.magstr) instantiated with a spinw object

To Test

Test the following systems with multiple and non-integer unit cells along different direction.

(1) Plot magnetic structure (and rotation plane of moment) of a triangular AFM over multiple unit cells

import numpy as np
from pyspinw import Matlab
from pyspinw.plotting import *

m = Matlab(matlab_version='R2022b', matlab_path=r'C:\Program Files\MATLAB\R2022b')

# Create a spinw model, in this case a triangular antiferromagnet
s = m.sw_model('triAF', 1)

super_cell = SuperCell(m, s, extent=(2,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type="aniso")
super_cell.plot()

image

(2) Plot single-ion anisotropy ellipsoid (example from tutorial 32)

s=m.spinw();
s.genlattice('sym','P 4','lat_const',[8, 8, 6])
s.addatom('r',[1/4, 1/4, 0],'S',1)
s.gencoupling()
s.addmatrix('label','A','value',1-np.eye(3))
s.addaniso('A')

super_cell = SuperCell(m, s, extent=(2,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type="aniso")

super_cell.plot()

image

(3) Plot multiple DM bonds (example taken from tutorial 32)

s = m.spinw();
s.genlattice('lat_const',[6, 4, 4],'sym','-x,y,z','label','m_x') # 'angled',[90 90 120],
s.addatom('r',[0.3, 0.5, 0.5],'S',1)  # [3/8, 1/2, 1/2]
s.gencoupling('maxDistance', 6)
s.addmatrix('label','DM1','value',[0, 0, 1],'color','blue')
s.addmatrix('label','DM2','value',[0, 1, 0],'color','purple')
s.addcoupling('mat','DM1','bond',1)
s.addcoupling('mat','DM2','bond',1)
super_cell = SuperCell(m, s, extent=(1,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type=None)
super_cell.arrow_head_size += 4
super_cell.plot()

image

(4) Plot unit cell with no bonds, but different sized atoms (and atoms of same type with different labels)

luvo = m.spinw();
luvo.genlattice('lat_const',[5.2821, 5.6144, 7.5283], 'spgr','x+1/2,-y+1/2,-z; -x,-y,z+1/2; -x,-y,-z','label','P n m a')
luvo.addatom('r',[0.003, 0.031, 1/4],'label','Lu1 Lu3+','color',[0, 171, 36])
luvo.addatom('r',[1/2, 0, 0],'label','V1 V3+','S',1,'color',[166, 166, 171])
luvo.addatom('r',[0.082, 0.487, 1/4],'label','O1 O2-','color',[255, 13, 13])
luvo.addatom('r',[0.223, 0.216, 0.534],'label','O2 O2-','color',[255, 13, 13])
super_cell = SuperCell(m, luvo, extent=(1,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type=None)
super_cell.plot()

image

(5) Add polyhedra to luvo example above like so

polyhedra_args = PolyhedraArgs(atom1_idx=2, atom2_idx=[3,4], color="yellow", n_nearest=6)
super_cell = SuperCell(m, luvo, extent=(1,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type=None, polyhedra_args=polyhedra_args)

image

(6) Plot luvo with a complicated-ish magnetic structure (and compare to existing MATLAB)

luvo.genmagstr('mode', 'helical', 'S', np.array([1.0,0,0])[:,None], 'k',[0.5,0,0.5], 'n', [0, 0, 1])

super_cell = SuperCell(m, luvo, extent=(2,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=False, ion_type=None)

image

(7) Plot 2D polygons in 3D

s = m.spinw();
s.genlattice('lat_const',[4, 4, 8],'sym','I 4')
s.addatom('r',[0, 0, 0],'label','atom1','color',[0, 171, 36]);
s.addatom('r', [0.5, 0 , 0],'label','atom2', 'color',[255, 13, 13])
polyhedra_args = PolyhedraArgs(atom1_idx=1, atom2_idx=2, color="yellow", n_nearest=4)
super_cell = SuperCell(m, s, extent=(1,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type=None, polyhedra_args=polyhedra_args)
super_cell.plot()

image

(8) Any other systems you can think of!

Fixes #150

@codecov-commenter
Copy link

codecov-commenter commented Dec 6, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (ea5ea33) 40.48% compared to head (be98824) 40.51%.
Report is 4 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #161      +/-   ##
==========================================
+ Coverage   40.48%   40.51%   +0.02%     
==========================================
  Files         240      240              
  Lines       15979    15981       +2     
==========================================
+ Hits         6469     6474       +5     
+ Misses       9510     9507       -3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

github-actions bot commented Dec 6, 2023

Test Results

    4 files  ±0    106 suites  ±0   14m 18s ⏱️ + 1m 9s
  619 tests ±0    619 ✅ +1  0 💤 ±0  0 ❌  - 1 
1 766 runs  ±0  1 766 ✅ +2  0 💤 ±0  0 ❌  - 2 

Results for commit be98824. ± Comparison against base commit 735d30a.

♻️ This comment has been updated with latest results.

Use PyQt5 backend version used in mantid (although allow patch verisons above) and therefore compatible with IDAaaS
@RichardWaiteSTFC RichardWaiteSTFC force-pushed the 150_add_vispy_xtal_plotting_to_pyspinw branch from a04e7b4 to 13a992f Compare December 6, 2023 15:39
@RichardWaiteSTFC
Copy link
Collaborator Author

Can now plot single-ion ellipsoids - this example is adapted from tutorial 32

s=m.spinw();
s.genlattice('sym','P 4','lat_const',[8, 8, 6])
s.addatom('r',[1/4, 1/4, 0],'S',1)
s.gencoupling()
s.addmatrix('label','A','value',1-np.eye(3))
s.addaniso('A')

super_cell = SuperCellSimple(s, extent=(2,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type="aniso")

super_cell.plot()

image

There is a small difference compared to the current MATLAB plotting
image
which scales the eigenvalues such that hard-axis is squashed to 0 - I can do this if required but it seems misleading?

@RichardWaiteSTFC RichardWaiteSTFC force-pushed the 150_add_vispy_xtal_plotting_to_pyspinw branch from 2c1d0b6 to bf14f4a Compare January 4, 2024 12:08
@RichardWaiteSTFC
Copy link
Collaborator Author

Supports DM bonds now - but think I need to get the arrows to terminate before entering the atom marker.
Example adapted from tutorial 32

s = m.spinw();
s.genlattice('lat_const',[6, 4, 4],'sym','-x,y,z','label','m_x') # 'angled',[90 90 120],
s.addatom('r',[0.3, 0.5, 0.5],'S',1)  # [3/8, 1/2, 1/2]
s.gencoupling('maxDistance', 6)
s.addmatrix('label','DM1','value',[0, 0, 1],'color','blue')
s.addmatrix('label','DM2','value',[0, 1, 0],'color','purple')
s.addcoupling('mat','DM1','bond',1)
s.addcoupling('mat','DM2','bond',1)
super_cell = SuperCellSimple(s, extent=(2,1,1), plot_mag=True, plot_bonds=True, plot_atoms=True, plot_cell=True, plot_axes=True, plot_plane=True, ion_type=None)
super_cell.plot()

image

Compared to existing MATLAB
image

@RichardWaiteSTFC
Copy link
Collaborator Author

Have now put arrow along DM bond at mid-point for now
image

@RichardWaiteSTFC RichardWaiteSTFC force-pushed the 150_add_vispy_xtal_plotting_to_pyspinw branch from b68e350 to 50ed59f Compare January 9, 2024 09:33
Also added tolerance to _remove_points_outside_extent and increased supercell used to get vertices of polyhedra
Copy link
Member

@mducle mducle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just one major bug due to the "mutable default arguments" that needs to be changed... The other comments are suggestions!

python/pyspinw/plotting.py Outdated Show resolved Hide resolved
python/pyspinw/plotting.py Outdated Show resolved Hide resolved
python/pyspinw/plotting.py Outdated Show resolved Hide resolved
python/pyspinw/plotting.py Outdated Show resolved Hide resolved
python/pyspinw/plotting.py Outdated Show resolved Hide resolved
python/pyspinw/plotting.py Outdated Show resolved Hide resolved
python/pyspinw/plotting.py Outdated Show resolved Hide resolved
Copy link
Member

@mducle mducle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works well and seems to run a bit faster for large supercells.

@mducle
Copy link
Member

mducle commented Jan 15, 2024

Thanks. Plotting things as a single mesh seems to have speed up by a factor of 2-3x. Plotting a 5x5x5 supercell of the triAF model used to take ~15s with the original code, ~10s with the code which eliminated the UnitCellSimple copies and now takes ~5s with the single mesh.

@RichardWaiteSTFC RichardWaiteSTFC force-pushed the 150_add_vispy_xtal_plotting_to_pyspinw branch from c8b801c to c7c0f9c Compare January 15, 2024 17:49
@mducle mducle merged commit 950ad3b into master Jan 17, 2024
15 checks passed
@mducle mducle deleted the 150_add_vispy_xtal_plotting_to_pyspinw branch May 30, 2024 02:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

VisPy plotting of unit cells and magnetic structure in 3D
3 participants