This commit is contained in:
2019-03-20 13:52:00 +01:00
parent 3084fe0510
commit 5db0f78aee
910 changed files with 191152 additions and 322 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,419 @@
###
# Copyright 2008-2011 Diamond Light Source Ltd.
# This file is part of Diffcalc.
#
# Diffcalc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Diffcalc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Diffcalc. If not, see <http://www.gnu.org/licenses/>.
###
from math import pi
from diffcalc import settings
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.util import DiffcalcException, bold
TODEG = 180 / pi
TORAD = pi / 180
NUNAME = 'gam'
def filter_dict(d, keys):
"""Return a copy of d containing only keys that are in keys"""
##return {k: d[k] for k in keys} # requires Python 2.6
return dict((k, d[k]) for k in keys if k in d.keys())
det_constraints = ('delta', NUNAME, 'qaz', 'naz')
ref_constraints = ('a_eq_b', 'alpha', 'beta', 'psi')
samp_constraints = ('mu', 'eta', 'chi', 'phi', 'mu_is_' + NUNAME, 'bisect', 'omega')
valueless_constraints = ('a_eq_b', 'mu_is_' + NUNAME, 'bisect')
all_constraints = det_constraints + ref_constraints + samp_constraints
number_single_sample = (len(det_constraints) * len(ref_constraints) *
len(samp_constraints))
class YouConstraintManager(object):
def __init__(self, hardware, fixed_constraints = {}):
self._hardware = hardware
self._constrained = {}
# self._tracking = []
self.n_phi = matrix([[0], [0], [1]])
self._hide_detector_constraint = False # default
self._fixed_samp_constraints = ()
self._fix_constraints(fixed_constraints)
def __str__(self):
lines = []
# TODO: Put somewhere with access to UB matrix!
# WIDTH = 13
# n_phi = self.n_phi
# fmt = "% 9.5f % 9.5f % 9.5f"
# lines.append(" n_phi:".ljust(WIDTH) +
# fmt % (n_phi[0, 0], n_phi[1, 0], n_phi[2, 0]))
# if self._getUBMatrix():
# n_cryst = self._getUMatrix().I * self.n_phi
# lines.append(" n_cryst:".ljust(WIDTH) +
# fmt % (n_cryst[0, 0], n_cryst[1, 0], n_cryst[2, 0]))
# n_recip = self._getUBMatrix().I * self.n_phi
# lines.append(" n_recip:".ljust(WIDTH) +
# fmt % (n_recip[0, 0], n_recip[1, 0], n_recip[2, 0]))
# else:
# lines.append(
# " n_cryst:".ljust(WIDTH) + ' "<<< No U matrix >>>"')
# lines.append(
# " n_recip:".ljust(WIDTH) + ' "<<< No UB matrix >>>"')
lines.extend(self.build_display_table_lines())
lines.append("")
lines.extend(self.report_constraints_lines())
lines.append("")
if (self.is_fully_constrained() and
not self.is_current_mode_implemented()):
lines.append(
" Sorry, this constraint combination is not implemented")
lines.append(" Type 'help con' for available combinations")
else:
lines.append(" Type 'help con' for instructions") # okay
return '\n'.join(lines)
@property
def available_constraint_names(self):
"""list of all available constraints"""
return all_constraints
@property
def settable_constraint_names(self):
"""list of all available constraints that have settable values"""
all_copy = list(all_constraints)
for valueless in valueless_constraints:
all_copy.remove(valueless)
return all_copy
@property
def all(self): # @ReservedAssignment
"""dictionary of all constrained values"""
return self._constrained.copy()
@property
def detector(self):
"""dictionary of constrained detector circles"""
return filter_dict(self.all, det_constraints[:-1])
@property
def reference(self):
"""dictionary of constrained reference circles"""
return filter_dict(self.all, ref_constraints)
@property
def sample(self):
"""dictionary of constrained sample circles"""
return filter_dict(self.all, samp_constraints)
@property
def naz(self):
"""dictionary with naz and value if constrained"""
return filter_dict(self.all, ('naz',))
@property
def constrained_names(self):
"""ordered tuple of constained circles"""
names = self.all.keys()
names.sort(key=lambda name: list(all_constraints).index(name))
return tuple(names)
@property
def available_names(self):
"""ordered tuple of fixed circles"""
names = [name for name in self.all.keys() if not self.is_constraint_fixed(name)]
names.sort(key=lambda name: list(all_constraints).index(name))
return tuple(names)
def _fix_constraints(self, fixed_constraints):
for name in fixed_constraints:
self.constrain(name)
self.set_constraint(name, fixed_constraints[name])
if self.detector or self.naz:
self._hide_detector_constraint = True
fixed_samp_constraints = list(self.sample.keys())
if 'mu' in self.sample or NUNAME in self.detector:
fixed_samp_constraints.append('mu_is_' + NUNAME)
self._fixed_samp_constraints = tuple(fixed_samp_constraints)
def is_constrained(self, name):
return name in self._constrained
def get_value(self, name):
return self._constrained[name]
def build_display_table_lines(self):
unfixed_samp_constraints = list(samp_constraints)
for name in self._fixed_samp_constraints:
unfixed_samp_constraints.remove(name)
if self._hide_detector_constraint:
constraint_types = (ref_constraints, unfixed_samp_constraints)
else:
constraint_types = (det_constraints, ref_constraints,
unfixed_samp_constraints)
num_rows = max([len(col) for col in constraint_types])
max_name_width = max(
[len(name) for name in sum(constraint_types[:-1], ())])
cells = []
header_cells = []
if not self._hide_detector_constraint:
header_cells.append(bold(' ' + 'DET'.ljust(max_name_width)))
header_cells.append(bold(' ' + 'REF'.ljust(max_name_width)))
header_cells.append(bold(' ' + 'SAMP'))
cells.append(header_cells)
underline_cells = [' ' + '-' * max_name_width] * len(constraint_types)
cells.append(underline_cells)
for n_row in range(num_rows):
row_cells = []
for col in constraint_types:
name = col[n_row] if n_row < len(col) else ''
row_cells.append(self._label_constraint(name))
ext_name = settings.geometry.map_to_external_name(name)
row_cells.append(('%-' + str(max_name_width) + 's') % ext_name)
cells.append(row_cells)
lines = [' '.join(row_cells).rstrip() for row_cells in cells]
return lines
def _report_constraint(self, name):
val = self.get_constraint(name)
ext_name = settings.geometry.map_to_external_name(name)
if name in valueless_constraints:
return " %s" % ext_name
else:
if val is None:
return "! %-5s: ---" % ext_name
else:
ext_name, ext_val = settings.geometry.map_to_external_position(name, val)
return " %-5s: %.4f" % (ext_name, ext_val)
def report_constraints_lines(self):
lines = []
required = 3 - len(self.all)
if required == 0:
pass
elif required == 1:
lines.append('! 1 more constraint required')
else:
lines.append('! %d more constraints required' % required)
lines.extend([self._report_constraint(name) for name in self.available_names])
return lines
def is_fully_constrained(self):
return len(self.all) == 3
def is_current_mode_implemented(self):
if not self.is_fully_constrained():
raise ValueError("Three constraints required")
if len(self.sample) == 3:
if set(self.sample.keys()) == set(['chi', 'phi', 'eta']):
return True
return False
if len(self.sample) == 1:
return ('omega' not in set(self.sample.keys()) or
'bisect' not in set(self.sample.keys()))
if len(self.reference) == 1:
return (set(self.sample.keys()) == set(['chi', 'phi']) or
set(self.sample.keys()) == set(['chi', 'eta']) or
set(self.sample.keys()) == set(['chi', 'mu']) or
set(self.sample.keys()) == set(['mu', 'eta']))
if len(self.detector) == 1:
return (set(self.sample.keys()) == set(['chi', 'phi']) or
set(self.sample.keys()) == set(['mu', 'eta']) or
set(self.sample.keys()) == set(['mu', 'phi']) or
set(self.sample.keys()) == set(['eta', 'phi']) or
set(self.sample.keys()) == set(['mu', 'bisect']) or
set(self.sample.keys()) == set(['eta', 'bisect']) or
set(self.sample.keys()) == set(['omega', 'bisect']))
return False
def _label_constraint(self, name):
if name == '':
label = ' '
# elif self.is_tracking(name): # implies constrained
# label = '~~> '
elif (self.is_constrained(name) and (self.get_value(name) is None) and
name not in valueless_constraints):
label = 'o->'
elif self.is_constrained(name):
label = '-->'
else:
label = ' '
return label
def constrain(self, name):
ext_name = settings.geometry.map_to_external_name(name)
if self.is_constraint_fixed(name):
raise DiffcalcException('%s constraint cannot be changed' % ext_name)
if name in self.all:
return "%s is already constrained." % ext_name.capitalize()
elif name in det_constraints:
return self._constrain_detector(name)
elif name in ref_constraints:
return self._constrain_reference(name)
elif name in samp_constraints:
return self._constrain_sample(name)
else:
raise DiffcalcException("%s is not a valid constraint name. Type 'con' for a table of constraint name" % ext_name)
def is_constraint_fixed(self, name):
return ((name in det_constraints and self._hide_detector_constraint) or
(name in samp_constraints and name in self._fixed_samp_constraints))
def _constrain_detector(self, name):
if self.naz:
del self._constrained['naz']
self._constrained[name] = None
return 'Naz constraint replaced.'
elif self.detector:
constrained_name = self.detector.keys()[0]
del self._constrained[constrained_name]
self._constrained[name] = None
return'%s constraint replaced.' % constrained_name.capitalize()
elif len(self.all) == 3: # and no detector
raise self._could_not_constrain_exception(name)
else:
self._constrained[name] = None
def _could_not_constrain_exception(self, name):
ext_name = settings.geometry.map_to_external_name(name)
names = [settings.geometry.map_to_external_name(nm) for nm in self.available_names]
if len(names) > 1:
names_fmt = 'one of the\nangles ' + ', '.join(names[:-1]) + ' or ' + names[-1]
else:
names_fmt = 'angle ' + names[0]
return DiffcalcException(
"%s could not be constrained. First un-constrain %s "
"(with 'uncon')" %
(ext_name.capitalize(), names_fmt))
def _constrain_reference(self, name):
if self.reference:
constrained_name = self.reference.keys()[0]
elif len(self._constrained) < 3:
constrained_name = None
elif len(self.available_names) == 1:
constrained_name = self.available_names[0]
else:
raise self._could_not_constrain_exception(name)
try:
del self._constrained[constrained_name]
self._constrained[name] = None
ext_constrained_name = settings.geometry.map_to_external_name(constrained_name)
return '%s constraint replaced.' % ext_constrained_name.capitalize()
except KeyError:
self._constrained[name] = None
def _constrain_sample(self, name):
if len(self._constrained) < 3:
constrained_name = None
elif len(self.available_names) == 1:
# Only one settable constraint
constrained_name = self.available_names[0]
elif len(self.sample) == 1:
# (detector and reference constraints set)
# it is clear which sample constraint to remove
constrained_name = self.sample.keys()[0]
if self.is_constraint_fixed(constrained_name):
raise self._could_not_constrain_exception(name)
else:
# else: three constraints are set
raise self._could_not_constrain_exception(name)
try:
del self._constrained[constrained_name]
self._constrained[name] = None
ext_constrained_name = settings.geometry.map_to_external_name(constrained_name)
return '%s constraint replaced.' % ext_constrained_name.capitalize()
except KeyError:
self._constrained[name] = None
def unconstrain(self, name):
ext_name = settings.geometry.map_to_external_name(name)
if self.is_constraint_fixed(name):
raise DiffcalcException('%s constraint cannot be removed' % ext_name)
if name in self._constrained:
del self._constrained[name]
else:
return "%s was not already constrained." % ext_name.capitalize()
def _check_constraint_settable(self, name):
ext_name = settings.geometry.map_to_external_name(name)
if name not in all_constraints:
raise DiffcalcException(
'Could not set %(ext_name)s. This is not an available '
'constraint.' % locals())
elif name not in self.all.keys():
raise DiffcalcException(
'Could not set %(ext_name)s. This is not currently '
'constrained.' % locals())
elif name in valueless_constraints:
raise DiffcalcException(
'Could not set %(ext_name)s. This constraint takes no '
'value.' % locals())
def clear_constraints(self):
self._constrained = {}
def set_constraint(self, name, value): # @ReservedAssignment
ext_name = settings.geometry.map_to_external_name(name)
if self.is_constraint_fixed(name):
raise DiffcalcException('%s constraint cannot be changed' % ext_name)
self._check_constraint_settable(name)
# if name in self._tracking:
# raise DiffcalcException(
# "Could not set %s as this constraint is configured to track "
# "its associated\nphysical angle. First remove this tracking "
# "(use 'untrack %s').""" % (name, name))
old_value = self.get_constraint(name)
try:
old_str = '---' if old_value is None else str(old_value)
except Exception:
old_str = '---'
try:
self._constrained[name] = float(value) * TORAD
except Exception:
raise DiffcalcException('Cannot set %s constraint. Invalid input value.' % ext_name)
try:
new_str = '---' if value is None else str(value)
except Exception:
new_str = '---'
return "%s : %s --> %s" % (name, old_str, new_str)
def get_constraint(self, name):
value = self.all[name]
return None if value is None else value * TODEG

View File

@@ -0,0 +1,235 @@
###
# Copyright 2008-2011 Diamond Light Source Ltd.
# This file is part of Diffcalc.
#
# Diffcalc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Diffcalc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Diffcalc. If not, see <http://www.gnu.org/licenses/>.
###
from math import pi
from diffcalc.util import AbstractPosition, DiffcalcException
TORAD = pi / 180
TODEG = 180 / pi
from diffcalc.util import x_rotation, z_rotation, y_rotation
from diffcalc.hkl.you.constraints import NUNAME
class YouGeometry(object):
def __init__(self, name, fixed_constraints, beamline_axes_transform=None):
self.name = name
self.fixed_constraints = fixed_constraints
# beamline_axes_transform matrix is composed of columns of the
# beamline basis vector coordinates in the diffcalc coordinate system,
# i.e. it transforms the beamline coordinate system into the diffcalc one.
self.beamline_axes_transform = beamline_axes_transform
def map_to_internal_position(self, name, value):
return name, value
def map_to_external_position(self, name, value):
return name, value
def map_to_internal_name(self, name):
return name
def map_to_external_name(self, name):
return name
def physical_angles_to_internal_position(self, physical_angle_tuple):
raise NotImplementedError()
def internal_position_to_physical_angles(self, internal_position):
raise NotImplementedError()
def create_position(self, *args):
return YouPosition(*args, unit='DEG')
#==============================================================================
#==============================================================================
# Geometry plugins for use with 'You' hkl calculation engine
#==============================================================================
#==============================================================================
class SixCircle(YouGeometry):
def __init__(self, beamline_axes_transform=None):
YouGeometry.__init__(self, 'sixc', {}, beamline_axes_transform)
def physical_angles_to_internal_position(self, physical_angle_tuple):
# mu, delta, nu, eta, chi, phi
return YouPosition(*physical_angle_tuple, unit='DEG')
def internal_position_to_physical_angles(self, internal_position):
clone_position = internal_position.clone()
clone_position.changeToDegrees()
return clone_position.totuple()
class FourCircle(YouGeometry):
"""For a diffractometer with angles:
delta, eta, chi, phi
"""
def __init__(self, beamline_axes_transform=None):
YouGeometry.__init__(self, 'fourc', {'mu': 0, NUNAME: 0}, beamline_axes_transform)
def physical_angles_to_internal_position(self, physical_angle_tuple):
# mu, delta, nu, eta, chi, phi
delta, eta, chi, phi = physical_angle_tuple
return YouPosition(0, delta, 0, eta, chi, phi, 'DEG')
def internal_position_to_physical_angles(self, internal_position):
clone_position = internal_position.clone()
clone_position.changeToDegrees()
_, delta, _, eta, chi, phi = clone_position.totuple()
return delta, eta, chi, phi
class FiveCircle(YouGeometry):
"""For a diffractometer with angles:
delta, nu, eta, chi, phi
"""
def __init__(self, beamline_axes_transform=None):
YouGeometry.__init__(self, 'fivec', {'mu': 0}, beamline_axes_transform)
def physical_angles_to_internal_position(self, physical_angle_tuple):
# mu, delta, nu, eta, chi, phi
delta, nu, eta, chi, phi = physical_angle_tuple
return YouPosition(0, delta, nu, eta, chi, phi, 'DEG')
def internal_position_to_physical_angles(self, internal_position):
clone_position = internal_position.clone()
clone_position.changeToDegrees()
_, delta, nu, eta, chi, phi = clone_position.totuple()
return delta, nu, eta, chi, phi
#==============================================================================
def create_you_matrices(mu=None, delta=None, nu=None, eta=None, chi=None,
phi=None):
"""
Create transformation matrices from H. You's paper.
"""
MU = None if mu is None else calcMU(mu)
DELTA = None if delta is None else calcDELTA(delta)
NU = None if nu is None else calcNU(nu)
ETA = None if eta is None else calcETA(eta)
CHI = None if chi is None else calcCHI(chi)
PHI = None if phi is None else calcPHI(phi)
return MU, DELTA, NU, ETA, CHI, PHI
def calcNU(nu):
return x_rotation(nu)
def calcDELTA(delta):
return z_rotation(-delta)
def calcMU(mu_or_alpha):
return x_rotation(mu_or_alpha)
def calcETA(eta):
return z_rotation(-eta)
def calcCHI(chi):
return y_rotation(chi)
def calcPHI(phi):
return z_rotation(-phi)
class YouPosition(AbstractPosition):
def __init__(self, mu, delta, nu, eta, chi, phi, unit):
self.mu = mu
self.delta = delta
self.nu = nu
self.eta = eta
self.chi = chi
self.phi = phi
if unit not in ['DEG', 'RAD']:
raise DiffcalcException("Invalid angle unit value %s." % str(unit))
else:
self.unit = unit
def clone(self):
return YouPosition(self.mu, self.delta, self.nu, self.eta, self.chi,
self.phi, self.unit)
def changeToRadians(self):
if self.unit == 'DEG':
self.mu *= TORAD
self.delta *= TORAD
self.nu *= TORAD
self.eta *= TORAD
self.chi *= TORAD
self.phi *= TORAD
self.unit = 'RAD'
elif self.unit == 'RAD':
return
else:
raise DiffcalcException("Invalid angle unit value %s." % str(self.unit))
def changeToDegrees(self):
if self.unit == 'RAD':
self.mu *= TODEG
self.delta *= TODEG
self.nu *= TODEG
self.eta *= TODEG
self.chi *= TODEG
self.phi *= TODEG
self.unit = 'DEG'
elif self.unit == 'DEG':
return
else:
raise DiffcalcException("Invalid angle unit value %s." % str(self.unit))
@staticmethod
def get_names():
return ('mu', 'delta', NUNAME, 'eta', 'chi', 'phi')
def totuple(self):
return (self.mu, self.delta, self.nu, self.eta, self.chi, self.phi)
def todict(self):
return dict(zip(self.get_names(), self.totuple()))
def __str__(self):
fmt_tuple = sum(zip(self.get_names(), self.totuple()), ()) + (self.unit,)
return ("YouPosition(%s: %r %s: %r %s: %r %s: %r %s: %r %s: %r) in %s"
% fmt_tuple)
def __eq__(self, other):
return self.totuple() == other.totuple()
class WillmottHorizontalPosition(YouPosition):
def __init__(self, delta=None, gamma=None, omegah=None, phi=None):
self.mu = 0
self.delta = delta
self.nu = gamma
self.eta = omegah
self.chi = -90
self.phi = phi
self.unit= 'DEG'

View File

@@ -0,0 +1,198 @@
###
# Copyright 2008-2011 Diamond Light Source Ltd.
# This file is part of Diffcalc.
#
# Diffcalc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Diffcalc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Diffcalc. If not, see <http://www.gnu.org/licenses/>.
###
from __future__ import absolute_import
from diffcalc.hkl.common import getNameFromScannableOrString
from diffcalc.util import command
from diffcalc.hkl.you.calc import YouHklCalculator
from diffcalc import settings
import diffcalc.ub.ub
from diffcalc.hkl.you.constraints import YouConstraintManager
__all__ = ['allhkl', 'con', 'uncon', 'hklcalc', 'constraint_manager']
_fixed_constraints = settings.geometry.fixed_constraints # @UndefinedVariable
constraint_manager = YouConstraintManager(settings.hardware, _fixed_constraints)
hklcalc = YouHklCalculator(
diffcalc.ub.ub.ubcalc, settings.geometry, settings.hardware, constraint_manager)
def __str__(self):
return hklcalc.__str__()
@command
def con(*args):
"""
con -- list available constraints and values
con <name> {val} -- constrains and optionally sets one constraint
con <name> {val} <name> {val} <name> {val} -- clears and then fully constrains
Select three constraints using 'con' and 'uncon'. Choose up to one
from each of the sample and detector columns and up to three from
the sample column.
Not all constraint combinations are currently available:
1 x samp: all
2 x samp and 1 x ref: chi & phi
chi & eta
chi & mu
mu & eta
2 x samp and 1 x det: chi & phi
mu & eta
mu & phi
eta & phi
bisect & mu
bisect & eta
bisect & omega
3 x samp: eta, chi & phi
See also 'uncon'
"""
args = list(args)
msg = _handle_con(args)
if (hklcalc.constraints.is_fully_constrained() and
not hklcalc.constraints.is_current_mode_implemented()):
msg += ("\n\nWARNING: The selected constraint combination "
"is not implemented.\n\nType 'help con' to see implemented combinations")
if msg:
print msg
diffcalc.ub.ub.ubcalc.save()
def _handle_con(args):
if not args:
return hklcalc.constraints.__str__()
if len(args) > 6:
raise TypeError("Unexpected args: " + str(args))
cons_value_pairs = []
while args:
scn_or_str = args.pop(0)
ext_name = getNameFromScannableOrString(scn_or_str)
if args and isinstance(args[0], (int, long, float)):
ext_value = args.pop(0)
else:
try:
ext_value = settings.hardware.get_position_by_name(ext_name)
except ValueError:
ext_value = None
cons_name, cons_value = settings.geometry.map_to_internal_position(ext_name, ext_value)
cons_value_pairs.append((cons_name, cons_value))
if len(cons_value_pairs) == 1:
pass
elif len(cons_value_pairs) == 3:
hklcalc.constraints.clear_constraints()
else:
raise TypeError("Either one or three constraints must be specified")
for name, value in cons_value_pairs:
hklcalc.constraints.constrain(name)
if value is not None:
hklcalc.constraints.set_constraint(name, value)
return '\n'.join(hklcalc.constraints.report_constraints_lines())
@command
def uncon(scn_or_string):
"""uncon <name> -- remove constraint
See also 'con'
"""
ext_name = getNameFromScannableOrString(scn_or_string)
cons_name = settings.geometry.map_to_internal_name(ext_name)
hklcalc.constraints.unconstrain(cons_name)
print '\n'.join(hklcalc.constraints.report_constraints_lines())
diffcalc.ub.ub.ubcalc.save()
@command
def allhkl(hkl, wavelength=None):
"""allhkl [h k l] -- print all hkl solutions ignoring limits
"""
hardware = hklcalc._hardware
geometry = hklcalc._geometry
if wavelength is None:
wavelength = hardware.get_wavelength()
h, k, l = hkl
pos_virtual_angles_pairs = hklcalc.hkl_to_all_angles(
h, k, l, wavelength)
cells = []
# virtual_angle_names = list(pos_virtual_angles_pairs[0][1].keys())
# virtual_angle_names.sort()
virtual_angle_names = ['qaz', 'psi', 'naz', 'tau', 'theta', 'alpha', 'beta', 'bin', 'bout']
header_cells = list(hardware.get_axes_names()) + [' '] + virtual_angle_names
cells.append(['%9s' % s for s in header_cells])
cells.append([''] * len(header_cells))
for pos, virtual_angles in pos_virtual_angles_pairs:
row_cells = []
angle_tuple = geometry.internal_position_to_physical_angles(pos)
angle_tuple = hardware.cut_angles(angle_tuple)
for val in angle_tuple:
row_cells.append('%9.4f' % val)
row_cells.append('|')
for name in virtual_angle_names:
row_cells.append('%9.4f' % virtual_angles[name])
cells.append(row_cells)
column_widths = []
for col in range(len(cells[0])):
widths = []
for row in range(len(cells)):
cell = cells[row][col]
width = len(cell.strip())
widths.append(width)
column_widths.append(max(widths))
lines = []
for row_cells in cells:
trimmed_row_cells = []
for cell, width in zip(row_cells, column_widths):
trimmed_cell = cell.strip().rjust(width)
trimmed_row_cells.append(trimmed_cell)
lines.append(' '.join(trimmed_row_cells))
print '\n'.join(lines)
commands_for_help = ['Constraints',
con,
uncon,
'Hkl',
allhkl
]

View File

@@ -0,0 +1,52 @@
###
# Copyright 2008-2018 Diamond Light Source Ltd.
# This file is part of Diffcalc.
#
# Diffcalc is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Diffcalc is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Diffcalc. If not, see <http://www.gnu.org/licenses/>.
###
from diffcalc.ub.calcstate import UBCalcStateEncoder, UBCalcState
from diffcalc.util import DiffcalcException, TODEG
class YouStateEncoder(UBCalcStateEncoder):
def default(self, obj):
if isinstance(obj, UBCalcState):
d = UBCalcStateEncoder.default(self, obj)
from diffcalc.hkl.you.hkl import constraint_manager
d['constraints'] = constraint_manager.all
return d
return UBCalcStateEncoder.default(self, obj)
@staticmethod
def decode_ubcalcstate(state, geometry, diffractometer_axes_names, multiplier):
# Backwards compatibility code
try:
cons_dict = state['constraints']
from diffcalc.hkl.you.hkl import constraint_manager
for cons_name, val in cons_dict.iteritems():
try:
constraint_manager.constrain(cons_name)
if val is not None:
constraint_manager.set_constraint(cons_name, val * TODEG)
except DiffcalcException:
print 'WARNING: Ignoring constraint %s' % cons_name
except KeyError:
pass
return UBCalcStateEncoder.decode_ubcalcstate(state, geometry, diffractometer_axes_names, multiplier)