233 lines
8.1 KiB
Python
233 lines
8.1 KiB
Python
from diffcalc.hkl.vlieg.geometry import VliegPosition
|
|
from diffcalc.ub.crystal import CrystalUnderTest
|
|
from diffcalc.ub.reflections import ReflectionList, _Reflection
|
|
from math import pi
|
|
import datetime # @UnusedImport For crazy time eval code!
|
|
from diffcalc.ub.reference import YouReference
|
|
from diffcalc.ub.orientations import _Orientation, OrientationList
|
|
from diffcalc.log import logging
|
|
try:
|
|
from collection import OrderedDict
|
|
except ImportError:
|
|
from simplejson import OrderedDict
|
|
|
|
try:
|
|
import json
|
|
except ImportError:
|
|
import simplejson as json
|
|
|
|
try:
|
|
from numpy import matrix
|
|
except ImportError:
|
|
from numjy import matrix
|
|
|
|
logger = logging.getLogger("diffcalc.ub.calcstate")
|
|
|
|
TODEG = 180 / pi
|
|
|
|
|
|
class UBCalcState():
|
|
|
|
def __init__(self, name=None, crystal=None, reflist=None, orientlist=None, tau=0, sigma=0,
|
|
manual_U=None, manual_UB=None, or0=None, or1=None, reference=None):
|
|
|
|
assert reflist is not None
|
|
self.name = name
|
|
self.crystal = crystal
|
|
self.reflist = reflist
|
|
self.orientlist = orientlist
|
|
self.tau = tau # degrees
|
|
self.sigma = sigma # degrees
|
|
self.manual_U = manual_U
|
|
self.manual_UB = manual_UB
|
|
self.or0 = or0
|
|
self.or1 = or1
|
|
self.reference = reference
|
|
|
|
@property
|
|
def is_okay_to_autocalculate_ub(self):
|
|
nothing_set = ((self.manual_U is None) and
|
|
(self.manual_UB is None) and
|
|
(self.or0 is None) and
|
|
(self.or1 is None))
|
|
or0_and_or1_used = (self.or0 is not None) and (self.or1 is not None)
|
|
return nothing_set or or0_and_or1_used
|
|
|
|
|
|
def configure_calc_type(self,
|
|
manual_U=None,
|
|
manual_UB=None,
|
|
or0=None,
|
|
or1=None):
|
|
self.manual_U = manual_U
|
|
self.manual_UB = manual_UB
|
|
self.or0 = or0
|
|
self.or1 = or1
|
|
|
|
|
|
class UBCalcStateEncoder(json.JSONEncoder):
|
|
|
|
def default(self, obj):
|
|
|
|
if isinstance(obj, UBCalcState):
|
|
d = OrderedDict()
|
|
d['name'] = obj.name
|
|
d['crystal'] = obj.crystal
|
|
d['reflist'] = obj.reflist
|
|
d['orientlist'] = obj.orientlist
|
|
d['tau'] = obj.tau
|
|
d['sigma'] = obj.sigma
|
|
d['reference'] = obj.reference
|
|
d['u'] = obj.manual_U
|
|
d['ub'] = obj.manual_UB
|
|
d['or0'] = obj.or0
|
|
d['or1'] = obj.or1
|
|
|
|
return d
|
|
|
|
if isinstance(obj, CrystalUnderTest):
|
|
return repr([obj._name, obj._a1, obj._a2, obj._a3, obj._alpha1 * TODEG,
|
|
obj._alpha2 * TODEG, obj._alpha3 * TODEG])
|
|
|
|
if isinstance(obj, matrix):
|
|
l = [', '.join((repr(e) for e in row)) for row in obj.tolist()]
|
|
return l
|
|
|
|
if isinstance(obj, ReflectionList):
|
|
d = OrderedDict()
|
|
for n, ref in enumerate(obj._reflist):
|
|
d[str(n+1)] = ref
|
|
return d
|
|
|
|
if isinstance(obj, _Reflection):
|
|
d = OrderedDict()
|
|
d['tag'] = obj.tag
|
|
d['hkl'] = repr([obj.h, obj.k, obj.l])
|
|
d['pos'] = repr(list(obj.pos.totuple()))
|
|
d['energy'] = obj.energy
|
|
dt = eval(obj.time) # e.g. --> datetime.datetime(2013, 8, 5, 15, 47, 7, 962432)
|
|
d['time'] = None if dt is None else dt.isoformat()
|
|
return d
|
|
|
|
if isinstance(obj, OrientationList):
|
|
d = OrderedDict()
|
|
for n, orient in enumerate(obj._orientlist):
|
|
d[str(n+1)] = orient
|
|
return d
|
|
|
|
if isinstance(obj, _Orientation):
|
|
d = OrderedDict()
|
|
d['tag'] = obj.tag
|
|
d['hkl'] = repr([obj.h, obj.k, obj.l])
|
|
d['xyz'] = repr([obj.x, obj.y, obj.z])
|
|
dt = eval(obj.time) # e.g. --> datetime.datetime(2013, 8, 5, 15, 47, 7, 962432)
|
|
d['time'] = None if dt is None else dt.isoformat()
|
|
return d
|
|
|
|
if isinstance(obj, YouReference):
|
|
d = OrderedDict()
|
|
if obj.n_hkl_configured is not None:
|
|
d['n_hkl_configured'] = repr(obj.n_hkl_configured.T.tolist()[0])
|
|
else:
|
|
d['n_hkl_configured'] = None
|
|
if obj.n_phi_configured is not None:
|
|
d['n_phi_configured'] = repr(obj.n_phi_configured.T.tolist()[0])
|
|
else:
|
|
d['n_phi_configured'] = None
|
|
return d
|
|
|
|
|
|
return json.JSONEncoder.default(self, obj)
|
|
|
|
@staticmethod
|
|
def decode_ubcalcstate(state, geometry, diffractometer_axes_names, multiplier):
|
|
|
|
# Backwards compatibility code
|
|
orientlist_=OrientationList([])
|
|
try:
|
|
orientlist_=decode_orientlist(state['orientlist'])
|
|
except KeyError:
|
|
pass
|
|
return UBCalcState(
|
|
name=state['name'],
|
|
crystal=state['crystal'] and CrystalUnderTest(*eval(state['crystal'])),
|
|
reflist=decode_reflist(state['reflist'], geometry, diffractometer_axes_names, multiplier),
|
|
orientlist=orientlist_,
|
|
tau=state['tau'],
|
|
sigma=state['sigma'],
|
|
manual_U=state['u'] and decode_matrix(state['u']),
|
|
manual_UB=state['ub'] and decode_matrix(state['ub']),
|
|
or0=state['or0'],
|
|
or1=state['or1'],
|
|
reference=decode_reference(state.get('reference', None))
|
|
)
|
|
|
|
|
|
def decode_matrix(rows):
|
|
return matrix([[eval(e) for e in row.split(', ')] for row in rows])
|
|
|
|
|
|
def decode_reflist(reflist_dict, geometry, diffractometer_axes_names, multiplier):
|
|
reflections = []
|
|
try:
|
|
sorted_ref_keys = sorted(reflist_dict.keys(), key=int)
|
|
except ValueError:
|
|
logger.warning("Warning: Invalid index found in the stored list of reflections. "
|
|
"Please check the reflection list order.")
|
|
sorted_ref_keys = sorted(reflist_dict.keys())
|
|
for key in sorted_ref_keys:
|
|
reflections.append(decode_reflection(reflist_dict[key], geometry))
|
|
|
|
return ReflectionList(geometry, diffractometer_axes_names, reflections, multiplier)
|
|
|
|
|
|
def decode_orientlist(orientlist_dict):
|
|
orientations = []
|
|
try:
|
|
sorted_orient_keys = sorted(orientlist_dict.keys(), key=int)
|
|
except ValueError:
|
|
logger.exception("Warning: Invalid index found in the stored list of orientations. "
|
|
"Please check the orientation list order.")
|
|
sorted_orient_keys = sorted(orientlist_dict.keys())
|
|
for key in sorted_orient_keys:
|
|
orientations.append(decode_orientation(orientlist_dict[key]))
|
|
|
|
return OrientationList(orientations)
|
|
|
|
|
|
def decode_reflection(ref_dict, geometry):
|
|
h, k, l = eval(ref_dict['hkl'])
|
|
time = ref_dict['time'] and gt(ref_dict['time'])
|
|
pos_tuple = eval(ref_dict['pos'])
|
|
try:
|
|
position = geometry.create_position(*pos_tuple)
|
|
except AttributeError:
|
|
position = VliegPosition(*pos_tuple)
|
|
return _Reflection(h, k, l, position, ref_dict['energy'], str(ref_dict['tag']), repr(time))
|
|
|
|
|
|
def decode_reference(ref_dict):
|
|
reference = YouReference(None) # TODO: We can't set get_ub method yet (tangles!)
|
|
if ref_dict:
|
|
nhkl = ref_dict.get('n_hkl_configured', None)
|
|
nphi = ref_dict.get('n_phi_configured', None)
|
|
if nhkl:
|
|
reference.n_hkl_configured = matrix([eval(nhkl)]).T
|
|
if nphi:
|
|
reference.n_phi_configured = matrix([eval(nphi)]).T
|
|
return reference
|
|
|
|
|
|
def decode_orientation(orient_dict):
|
|
h, k, l = eval(orient_dict['hkl'])
|
|
x, y, z = eval(orient_dict['xyz'])
|
|
time = orient_dict['time'] and gt(orient_dict['time'])
|
|
return _Orientation(h, k, l, x, y, z, str(orient_dict['tag']), repr(time))
|
|
|
|
|
|
# From: http://stackoverflow.com/questions/127803/how-to-parse-iso-formatted-date-in-python
|
|
def gt(dt_str):
|
|
dt, _, us= dt_str.partition(".")
|
|
dt= datetime.datetime.strptime(dt, "%Y-%m-%dT%H:%M:%S")
|
|
us= int(us.rstrip("Z"), 10)
|
|
return dt + datetime.timedelta(microseconds=us) |