Skip to content

Commit

Permalink
Merge pull request #8 from jennyfothergill/feat/diffraction-utils
Browse files Browse the repository at this point in the history
Add utilities so that `freud.diffraction.Diffractometer` can be used like bitbucket diffractometer code
  • Loading branch information
jennyfothergill authored Jun 16, 2021
2 parents 8c830b1 + 982f1f5 commit a806ed7
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 5 deletions.
4 changes: 2 additions & 2 deletions cmeutils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from . import gsd_utils
from . import gsd_utils, structure
from .__version__ import __version__

__all__ = ["__version__", "gsd_utils"]
__all__ = ["__version__", "gsd_utils", "structure"]
47 changes: 46 additions & 1 deletion cmeutils/structure.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,53 @@
from cmeutils import gsd_utils
import freud
import gsd
import gsd.hoomd
import numpy as np
from rowan import vector_vector_rotation

from cmeutils import gsd_utils


def get_quaternions(n_views = 20):
"""Get the quaternions for the specified number of views.
The first (n_view - 3) views will be the views even distributed on a sphere,
while the last three views will be the face-on, edge-on, and corner-on
views, respectively.
These quaternions are useful as input to `view_orientation` kwarg in
`freud.diffraction.Diffractometer.compute`.
Parameters
----------
n_views : int, default 20
The number of views to compute.
Returns
-------
list of numpy.ndarray
Quaternions as (4,) arrays.
"""
if n_views <=3 or not isinstance(n_views, int):
raise ValueError("Please set n_views to an integer greater than 3.")
# Calculate points for even distribution on a sphere
ga = np.pi * (3 - 5**0.5)
theta = ga * np.arange(n_views-3)
z = np.linspace(1 - 1/(n_views-3), 1/(n_views-3), n_views-3)
radius = np.sqrt(1 - z * z)
points = np.zeros((n_views, 3))
points[:-3,0] = radius * np.cos(theta)
points[:-3,1] = radius * np.sin(theta)
points[:-3,2] = z

# face on
points[-3] = np.array([0, 0, 1])
# edge on
points[-2] = np.array([0, 1, 1])
# corner on
points[-1] = np.array([1, 1, 1])

unit_z = np.array([0, 0, 1])
return [vector_vector_rotation(i, unit_z) for i in points]


def gsd_rdf(
Expand Down
19 changes: 17 additions & 2 deletions cmeutils/tests/test_structure.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import pytest

import numpy as np

from cmeutils.tests.base_test import BaseTest


Expand All @@ -10,12 +12,25 @@ def test_gsd_rdf(self, gsdfile_bond):
rdf_ex, norm = gsd_rdf(gsdfile_bond, "A", "B")
rdf_noex, norm2 = gsd_rdf(gsdfile_bond, "A", "B", exclude_bonded=False)
assert norm2 == 1
assert rdf_noex != rdf_ex
assert not np.array_equal(rdf_noex, rdf_ex)

def test_gsd_rdf_samename(self, gsdfile_bond):
from cmeutils.structure import gsd_rdf

rdf_ex, norm = gsd_rdf(gsdfile_bond, "A", "A")
rdf_noex, norm2 = gsd_rdf(gsdfile_bond, "A", "A", exclude_bonded=False)
assert norm2 == 1
assert rdf_noex != rdf_ex
assert not np.array_equal(rdf_noex, rdf_ex)

def test_get_quaternions(self):
from cmeutils.structure import get_quaternions

with pytest.raises(ValueError):
get_quaternions(0)

with pytest.raises(ValueError):
get_quaternions(5.3)

qs = get_quaternions()
assert len(qs) == 20
assert len(qs[0]) == 4
2 changes: 2 additions & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@ dependencies:
- numpy
- pip
- python=3.7
- matplotlib
- pytest
- pytest-cov
- rowan

0 comments on commit a806ed7

Please sign in to comment.