Source code for diffpy.srfit.structure.cctbxparset

#!/usr/bin/env python
##############################################################################
#
# diffpy.srfit      by DANSE Diffraction group
#                   Simon J. L. Billinge
#                   (c) 2009 The Trustees of Columbia University
#                   in the City of New York.  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.
#
##############################################################################
"""Wrappers for interfacing cctbx crystal with SrFit.

This wraps a cctbx.crystal as a ParameterSet with a similar hierarchy, which
can then be used within a FitRecipe. Note that all manipulations to the
cctbx.crystal should be done before wrapping. Changes made to the cctbx.crystal
object after wrapping may not be reflected within the wrapper, which can have
unpredictable results during a structure refinement.

Classes:

CCTBXCrystalParSet  --  Wrapper for cctbx.crystal
CCTBXUnitCellParSet --  Wrapper for the unit cell of cctbx.crystal
CCTBXScattererParSet --  Wrapper for cctbx.xray.scatterer
"""

from diffpy.srfit.fitbase.parameter import ParameterAdapter
from diffpy.srfit.fitbase.parameterset import ParameterSet
from diffpy.srfit.structure.basestructureparset import BaseStructureParSet

__all__ = ["CCTBXScattererParSet", "CCTBXUnitCellParSet", "CCTBXCrystalParSet"]


[docs] class CCTBXScattererParSet(ParameterSet): """A wrapper for cctbx.xray.scatterer. This class derives from ParameterSet. Attributes ---------- name Name of the scatterer. The name is always of the form "%s%i" % (element, number), where the number is the running index of that element type (starting at 0). x (y, z) -- Atom position in crystal coordinates (ParameterAdapter) occupancy Occupancy of the atom on its crystal location (ParameterAdapter) Uiso Isotropic scattering factor (ParameterAdapter). """ def __init__(self, name, strups, idx): """Initialize. Attributes ---------- name The name of this scatterer. strups The CCTBXCrystalParSet that contains the cctbx structure idx The index of the scatterer in the structure. """ ParameterSet.__init__(self, name) self.strups = strups self.idx = idx # x, y, z, occupancy self.addParameter( ParameterAdapter("x", None, self._xyzgetter(0), self._xyzsetter(0)) ) self.addParameter( ParameterAdapter("y", None, self._xyzgetter(1), self._xyzsetter(1)) ) self.addParameter( ParameterAdapter("z", None, self._xyzgetter(2), self._xyzsetter(2)) ) self.addParameter( ParameterAdapter("occupancy", None, self._getocc, self._setocc) ) self.addParameter( ParameterAdapter("Uiso", None, self._getuiso, self._setuiso) ) return # Getters and setters def _xyzgetter(self, i): def f(dummy): return self.strups.stru.scatterers()[self.idx].site[i] return f def _xyzsetter(self, i): def f(dummy, value): xyz = list(self.strups.stru.scatterers()[self.idx].site) xyz[i] = value self.strups.stru.scatterers()[self.idx].site = tuple(xyz) return return f def _getocc(self, dummy): return self.strups.stru.scatterers()[self.idx].occupancy def _setocc(self, dummy, value): self.strups.stru.scatterers()[self.idx].occupancy = value return def _getuiso(self, dummy): return self.strups.stru.scatterers()[self.idx].u_iso def _setuiso(self, dummy, value): self.strups.stru.scatterers()[self.idx].u_iso = value return def _getElem(self): return self.stru.element_symbol() element = property(_getElem)
# End class CCTBXScattererParSet
[docs] class CCTBXUnitCellParSet(ParameterSet): """A wrapper for cctbx unit_cell object. Attributes ---------- name Always "unitcell". a Unit cell parameters (ParameterAdapter). b Unit cell parameters (ParameterAdapter). c Unit cell parameters (ParameterAdapter). alpha Unit cell parameters (ParameterAdapter). beta Unit cell parameters (ParameterAdapter). gamma Unit cell parameters (ParameterAdapter). """ def __init__(self, strups): """Initialize. Attributes ---------- strups The CCTBXCrystalParSet that contains the cctbx structure and the unit cell we're wrapper. """ ParameterSet.__init__(self, "unitcell") self.strups = strups self._latpars = list(self.strups.stru.unit_cell().parameters()) self.addParameter( ParameterAdapter("a", None, self._latgetter(0), self._latsetter(0)) ) self.addParameter( ParameterAdapter("b", None, self._latgetter(1), self._latsetter(1)) ) self.addParameter( ParameterAdapter("c", None, self._latgetter(2), self._latsetter(2)) ) self.addParameter( ParameterAdapter( "alpha", None, self._latgetter(3), self._latsetter(3) ) ) self.addParameter( ParameterAdapter( "beta", None, self._latgetter(4), self._latsetter(4) ) ) self.addParameter( ParameterAdapter( "gamma", None, self._latgetter(5), self._latsetter(5) ) ) return def _latgetter(self, i): def f(dummy): return self._latpars[i] return f def _latsetter(self, i): def f(dummy, value): self._latpars[i] = value self.strups._update = True return return f
# End class CCTBXUnitCellParSet # FIXME - Special positions should be constant.
[docs] class CCTBXCrystalParSet(BaseStructureParSet): """A wrapper for CCTBX structure. Attributes ---------- stru The adapted cctbx structure object. scatterers The list of ScattererParSets. unitcell The CCTBXUnitCellParSet for the structure. """ def __init__(self, name, stru): """Initialize. Attributes ---------- name A name for this stru A CCTBX structure instance. """ ParameterSet.__init__(self, name) self.stru = stru self.addParameterSet(CCTBXUnitCellParSet(self)) self.scatterers = [] self._update = False cdict = {} for s in stru.scatterers(): el = s.element_symbol() i = cdict.get(el, 0) sname = "%s%i" % (el, i) cdict[el] = i + 1 scatterer = CCTBXScattererParSet(sname, self, i) self.addParameterSet(scatterer) self.scatterers.append(scatterer) # Constrain the lattice from diffpy.srfit.structure.sgconstraints import _constrainSpaceGroup symbol = self.getSpaceGroup() _constrainSpaceGroup(self, symbol) return
[docs] def update(self): """Update the unit_cell to a change in lattice parameters. This remakes the unit cell according to a change in the lattice parameters. Call this function before using the CCTBXCrystalParSet. The unit_cell will only be remade if necessary. """ if not self._update: return self._update = False stru = self.stru sgn = stru.space_group().match_tabulated_settings().number() # Create the symmetry object from cctbx.crystal import symmetry symm = symmetry( unit_cell=self.unitcell._latpars, space_group_symbol=sgn ) # Now the new structure newstru = stru.__class__( crystal_symmetry=symm, scatterers=stru.scatterers() ) self.unitcell._latpars = list(newstru.unit_cell().parameters()) self.stru = newstru return
[docs] @classmethod def canAdapt(self, stru): """Return whether the structure can be adapted by this class.""" try: from cctbx.crystal import special_position_settings except ImportError: return False return isinstance(stru, special_position_settings)
[docs] def getLattice(self): """Get the ParameterSet containing the lattice Parameters.""" return self.unitcell
[docs] def getScatterers(self): """Get a list of ParameterSets that represents the scatterers. The site positions must be accessible from the list entries via the names "x", "y", and "z". The ADPs must be accessible as well, but the name and nature of the ADPs (U-factors, B-factors, isotropic, anisotropic) depends on the adapted structure. """ return self.scatterers
[docs] def getSpaceGroup(self): """Get the HM space group symbol for the structure.""" sg = self.stru.space_group() t = sg.type() return t.lookup_symbol()
# End class CCTBXCrystalParSet