#!/usr/bin/env python
##############################################################################
#
# diffpy.structure by DANSE Diffraction group
# Simon J. L. Billinge
# (c) 2008 trustees of the Michigan State University.
# All rights reserved.
#
# File coded by: Chris Farrow
#
# See AUTHORS.txt for a list of people who contributed.
# See LICENSE_DANSE.txt for license information.
#
##############################################################################
"""Make a spheroid nanoparticle from a template structure."""
from math import ceil
from numpy import array
from diffpy.structure import Structure
from diffpy.structure.expansion.shapeutils import find_center
from diffpy.utils._deprecator import build_deprecation_message, deprecated
base = "diffpy.structure"
removal_version = "4.0.0"
makeSphere_deprecation_msg = build_deprecation_message(
base,
"makeSphere",
"make_sphere",
removal_version,
)
makeEllipsoid_deprecation_msg = build_deprecation_message(
base,
"makeEllipsoid",
"make_ellipsoid",
removal_version,
)
@deprecated(makeSphere_deprecation_msg)
def makeSphere(S, radius):
"""This function has been deprecated and will be removed in version
4.0.0.
Please use diffpy.structure.make_sphere instead.
"""
return make_sphere(S, radius)
[docs]
def make_sphere(S, radius):
"""Create a spherical nanoparticle.
Parameters
----------
S : Structure
A `Structure` instance.
radius : float
Primary equatorial radius (along x-axis).
Returns
-------
Structure
A new `Structure` instance.
"""
return make_ellipsoid(S, radius)
@deprecated(makeEllipsoid_deprecation_msg)
def makeEllipsoid(S, a, b=None, c=None):
"""This function has been deprecated and will be removed in version
4.0.0.
Please use diffpy.structure.make_ellipsoid instead.
"""
return make_ellipsoid(S, a, b, c)
[docs]
def make_ellipsoid(S, a, b=None, c=None):
"""Cut a `Structure` out of another one.
Parameters
----------
S : Structure
A `Structure` instance.
a : float
Primary equatorial radius (along x-axis).
b : float, Optional
Secondary equatorial radius (along y-axis). If `b` is ``None``
(default), then it is set equal to `a`.
c : float, Optional
Polar radius (along z-axis). If `c` is ``None`` (default), then it is
set equal to `a`.
Returns
-------
Structure :
A new `Structure` instance.
"""
if b is None:
b = a
if c is None:
c = a
sabc = array([a, b, c])
# Create a supercell large enough for the ellipsoid
frac = S.lattice.fractional(sabc)
# FIXME - this looks fishy for non-orthogonal lattices
mno = max(ceil(2 * xi) for xi in frac) * array([1, 1, 1])
# Make the supercell
from diffpy.structure.expansion import supercell
newS = supercell(S, mno)
lat = newS.lattice
# Find the central atom
ncenter = find_center(newS)
cxyz = lat.cartesian(newS[ncenter].xyz)
delList = []
N = len(newS)
j = N
for i in range(N):
j -= 1
# Calculate (x/a)**2 + (y/b)**2 + (z/c)**2
xyz = lat.cartesian(newS[j].xyz)
darray = ((xyz - cxyz) / sabc) ** 2
d = sum(darray) ** 0.5
# Discard atom if (x/a)**2 + (y/b)**2 + (z/c)**2 > 1
if d > 1:
delList.append(j)
for i in delList:
newS.pop(i)
return newS
# ----------------------------------------------------------------------------
if __name__ == "__main__":
import os.path
datadir = "../../tests/testdata"
S = Structure()
S.read(os.path.join(datadir, "CdSe_bulk.stru"), "pdffit")
newS = make_ellipsoid(S, 12)
newS.write("CdSe_d24.stru", "pdffit")
newS = make_ellipsoid(S, 20, 10, 10)
newS.write("CdSe_a20_b10_c10.stru", "pdffit")
newS = make_ellipsoid(S, 20, 15, 10)
newS.write("CdSe_a20_b15_c10.stru", "pdffit")
S = Structure()
S.read(os.path.join(datadir, "Ni.stru"), "pdffit")
newS = make_ellipsoid(S, 10)
newS.write("Ni_d20.stru", "pdffit")
newS = make_ellipsoid(S, 20, 4)
newS.write("Ni_a20_b4_c20.stru", "pdffit")
newS = make_ellipsoid(S, 20, 15, 10)
newS.write("Ni_a20_b15_c10.stru", "pdffit")