Skip to content

Commit

Permalink
Merge f31aae4 into fae5ca5
Browse files Browse the repository at this point in the history
  • Loading branch information
CSSFrancis committed Jan 14, 2024
2 parents fae5ca5 + f31aae4 commit 53c81e5
Show file tree
Hide file tree
Showing 28 changed files with 2,376 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Expand Up @@ -45,7 +45,7 @@ jobs:
- os: ubuntu-latest
python-version: 3.7
OLDEST_SUPPORTED_VERSION: true
DEPENDENCIES: diffpy.structure==3.0.0 matplotlib==3.3 numpy==1.17 orix==0.9.0 scipy==1.1 tqdm==4.9
DEPENDENCIES: diffpy.structure==3.0.2 matplotlib==3.3 numpy==1.17 orix==0.11.0 scipy==1.2 tqdm==4.9
LABEL: -oldest
steps:
- uses: actions/checkout@v3
Expand Down
8 changes: 8 additions & 0 deletions .pre-commit-config.yaml
@@ -0,0 +1,8 @@
repos:
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black
- id: black-jupyter
files: \.ipynb
args: [--line-length=77]
13 changes: 13 additions & 0 deletions CHANGELOG.rst
Expand Up @@ -13,13 +13,26 @@ Unreleased
Added
-----
- Explicit support for Python 3.11.
- Added deprecation tools for deprecating functions and arguments.
- Added new class :class:`diffsims.generators.simulation_generator.SimulationGenerator` for
generating kinemetic diffraction from a phase and a set of reflections.
- Added new class :class:`diffsims.generators.simulations.Simulation` for storing results
from a :class:`diffsims.generators.simulation_generator.SimulationGenerator`.
- Added new class :class:`diffsims.simulations.Simulation1D` for storing the results of a
1D simulation.

Changed
-------
- Documentation theme from Furo to the PyData-Sphinx-Theme.

Deprecated
----------
- Deprecated :class:`diffsims.generators.diffraction_generator.DiffractionGenerator` in
favor of :class:`diffsims.generators.simulation_generator.SimulationGenerator`.
- Deprecated :class:`diffsims.generators.library_generator.DiffractionLibraryGenerator` in
favor of :class:`diffsims.generators.simulation_generator.SimulationGenerator`.
- Deprecated :class:`diffsims.diffraction_library.DiffractionLibrary` in favor of
:class:`diffsims.generators.simulations.Simulation`.

Removed
-------
Expand Down
21 changes: 21 additions & 0 deletions CONTRIBUTING.rst
Expand Up @@ -124,6 +124,27 @@ Useful hints on testing:
error-prone. See `pytest documentation for more details
<https://doc.pytest.org/en/latest/how-to/parametrize.html>`_.


Deprecations
------------
'This project attempts to adhere to (pre 1.0.0) semantic versioning and ideally no functionality
should be broken between minor releases. Deprecation warnings are raised to give user a full minor
release cycle to adjust their code before a breaking change is implemented.'

The decorator should be placed right above the object signature to be deprecated::

.. code-block:: python
>>> from diffsims.utils._deprecated import deprecate
>>> @deprecate(since=0.8, removal=0.9, alternative="bar")
>>> def foo(self, n):
>>> return n + 1
>>> @property
>>> @deprecate(since=0.9, removal=0.10, alternative="another", is_function=True)
>>> def this_property(self):
>>> return 2
Build and write documentation
-----------------------------

Expand Down
1 change: 0 additions & 1 deletion diffsims/crystallography/reciprocal_lattice_point.py
Expand Up @@ -29,7 +29,6 @@
get_refraction_corrected_wavelength,
)


_FLOAT_EPS = np.finfo(float).eps # Used to round values below 1e-16 to zero


Expand Down
94 changes: 89 additions & 5 deletions diffsims/crystallography/reciprocal_lattice_vector.py
Expand Up @@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU General Public License
# along with diffsims. If not, see <http://www.gnu.org/licenses/>.

from typing import Tuple
from collections import defaultdict
from copy import deepcopy

Expand Down Expand Up @@ -122,10 +122,11 @@ def __init__(self, phase, xyz=None, hkl=None, hkil=None):

self._theta = np.full(self.shape, np.nan)
self._structure_factor = np.full(self.shape, np.nan, dtype="complex128")
self._intensity = np.full(self.shape, np.nan)

def __getitem__(self, key):
miller_new = self.to_miller().__getitem__(key)
rlv_new = self.from_miller(miller_new)
new_data = self.data[key]
rlv_new = self.__class__(self.phase, xyz=new_data)

if np.isnan(self.structure_factor).all():
rlv_new._structure_factor = np.full(
Expand All @@ -139,6 +140,18 @@ def __getitem__(self, key):
else:
rlv_new._theta = self.theta[key]

if np.isnan(self.intensity).all():
rlv_new._intensity = np.full(rlv_new.shape, np.nan)
else:
slic = self.intensity[key]
if not hasattr(slic, "__len__"):
slic = np.array(
[
slic,
]
)
rlv_new._intensity = slic

return rlv_new

def __repr__(self):
Expand Down Expand Up @@ -169,7 +182,6 @@ def hkl(self):
>>> rlv.hkl
array([[1., 1., 1.],
[2., 0., 0.]])
"""

return _transform_space(self.data, "c", "r", self.phase.structure.lattice)
Expand Down Expand Up @@ -502,6 +514,28 @@ def scattering_parameter(self):

return 0.5 * self.gspacing

@property
def intensity(self):
return self._intensity

@intensity.setter
def intensity(self, value):
if not hasattr(value, "__len__"):
value = np.array(
[
value,
]
* self.size
)
if len(value) != self.size:
raise ValueError("Length of intensity array must match number of vectors")
self._intensity = np.array(value)

def rotate_from_matrix(self, rotation_matrix):
return ReciprocalLatticeVector(
phase=self.phase, xyz=np.matmul(rotation_matrix, self.data.T).T
)

@property
def structure_factor(self):
r"""Kinematical structure factors :math:`F`.
Expand Down Expand Up @@ -1070,7 +1104,7 @@ def from_highest_hkl(cls, phase, hkl):
return cls(phase, hkl=idx).unique()

@classmethod
def from_min_dspacing(cls, phase, min_dspacing=0.7):
def from_min_dspacing(cls, phase, min_dspacing=0.7, include_zero_beam=False):
"""Create a set of unique reciprocal lattice vectors with a
a direct space interplanar spacing greater than a lower
threshold.
Expand Down Expand Up @@ -1128,6 +1162,8 @@ def from_min_dspacing(cls, phase, min_dspacing=0.7):
dspacing = 1 / phase.structure.lattice.rnorm(hkl)
idx = dspacing >= min_dspacing
hkl = hkl[idx]
if include_zero_beam:
hkl = np.vstack((hkl, np.zeros(3, dtype=int)))
return cls(phase, hkl=hkl).unique()

@classmethod
Expand Down Expand Up @@ -1180,6 +1216,54 @@ def from_miller(cls, miller):
)
return cls(miller.phase, **{miller.coordinate_format: miller.coordinates})

def to_polar(
self, degrees: bool = False
) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:
"""Convert the vectors to polar coordinates.
Parameters
----------
degrees : bool, optional
Whether to return angles in degrees (default is False).
Returns
-------
r : numpy.ndarray
Length of the vectors.
theta : numpy.ndarray
Polar angle of the vectors.
phi : numpy.ndarray
Azimuthal angle of the vectors.
Examples
--------
See :class:`ReciprocalLatticeVector` for the creation of ``rlv``
>>> rlv
ReciprocalLatticeVector (2,), al (m-3m)
[[1. 1. 1.]
[2. 0. 0.]]
>>> r, theta, phi = rlv.to_polar()
>>> r
array([1.73205081, 2. ])
>>> theta
array([0.95531662, 0. ])
>>> phi
array([0., 0.])
"""

x = self.data[:, 0]
y = self.data[:, 1]
z = self.data[:, 2]

r = np.sqrt(x**2 + y**2)
theta = np.arctan2(y, x)

if degrees:
theta = np.rad2deg(theta)
return r, theta, z

def to_miller(self):
"""Return the vectors as a ``Miller`` instance.
Expand Down
2 changes: 2 additions & 0 deletions diffsims/generators/__init__.py
Expand Up @@ -26,12 +26,14 @@
rotation_list_generators,
sphere_mesh_generators,
zap_map_generator,
simulation_generator,
)

__all__ = [
"diffraction_generator",
"library_generator",
"rotation_list_generators",
"sphere_mesh_generators",
"simulation_generator",
"zap_map_generator",
]
4 changes: 4 additions & 0 deletions diffsims/generators/diffraction_generator.py
Expand Up @@ -41,6 +41,7 @@
lorentzian_precession,
)

from diffsims.utils._deprecated import deprecated

__all__ = [
"AtomicDiffractionGenerator",
Expand Down Expand Up @@ -153,6 +154,9 @@ class DiffractionGenerator(object):
`custom shape_factor_model` is used.
"""

@deprecated(since="0.6.0",
removal="0.7.0",
alternative="diffsims.generators.simulation_generator.SimulationGenerator")
def __init__(
self,
accelerating_voltage,
Expand Down
4 changes: 2 additions & 2 deletions diffsims/generators/library_generator.py
Expand Up @@ -27,7 +27,7 @@

from diffsims.utils.sim_utils import get_points_in_sphere
from diffsims.utils.vector_utils import get_angle_cartesian_vec

from diffsims.utils._deprecated import deprecated

__all__ = [
"DiffractionLibraryGenerator",
Expand All @@ -39,7 +39,7 @@ class DiffractionLibraryGenerator:
"""Computes a library of electron diffraction patterns for specified atomic
structures and orientations.
"""

@deprecated(since="0.6.0", alternative="Diffsims.generators.SimulationGenerator")
def __init__(self, electron_diffraction_calculator):
"""Initialises the generator with a diffraction calculator.
Expand Down

0 comments on commit 53c81e5

Please sign in to comment.