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

View File

@@ -0,0 +1,66 @@
###
# 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
import os, sys
from diffcalc.hardware import ScannableHardwareAdapter
import diffcalc.hkl.you.geometry
from diffcalc.ub.persistence import UbCalculationNonPersister, UBCalculationJSONPersister
from diffcalc import settings
import diffcalc.util
try:
__IPYTHON__ # @UndefinedVariable
IPYTHON = True
except NameError:
IPYTHON = False
try:
from gda.device.scannable.scannablegroup import ScannableGroup
from gdascripts.scannable.dummy import SingleInputDummy as Dummy
from diffcmd.diffcmd_utils import alias_commands
GDA = True
except ImportError:
# Not running in gda environment so fall back to minigda emulation
from diffcalc.gdasupport.minigda.scannable import ScannableGroup
from diffcalc.gdasupport.minigda.scannable import SingleFieldDummyScannable as Dummy
GDA = False
HELP_STRING = \
"""Quick: https://github.com/DiamondLightSource/diffcalc/blob/master/README.rst
Manual: http://diffcalc.readthedocs.io/en/latest/youmanual.html
Type: > help ub
> help hkl"""
if GDA:
from gda.configuration.properties import LocalProperties # @UnresolvedImport
var_folder = LocalProperties.get("gda.var")
diffcalc_persistance_path = os.path.join(var_folder, 'diffcalc')
if not os.path.exists(diffcalc_persistance_path):
print "Making diffcalc var folder:'%s'" % diffcalc_persistance_path
os.makedirs(diffcalc_persistance_path)
settings.ubcalc_persister = UBCalculationJSONPersister(diffcalc_persistance_path)
# else: should have been set if outside GDA

View File

@@ -0,0 +1,138 @@
'''
Created on 19 Feb 2017
@author: zrb13439
'''
import diffcmd.ipython
try:
__IPYTHON__ # @UndefinedVariable
IPYTHON = True
except NameError:
IPYTHON = False
GEOMETRIES = ['sixc', 'fivec', 'fourc', 'i16']
def echo(cmd):
print "\n>>> " + str(cmd)
def print_heading(s):
print '\n' + '=' * len(s) + '\n' + s + '\n' + '=' * len(s)
class Demo(object):
def __init__(self, namespace, geometry):
self.namespace = namespace
assert geometry in GEOMETRIES
self.geometry = geometry
def all(self):
self.orient()
self.constrain()
self.scan()
def orient(self):
print_heading('Orientation demo')
self.remove_test_ubcalc()
pos_cmd_001 = {
'sixc': 'pos sixc [0 60 0 30 90 0]', # mu, delta, gam, eta, chi, phi
'i16': 'pos sixc [0 90 30 0 60 0]', # phi, chi, eta, mu, delta, gam
'fivec': 'pos fivec [60 0 30 90 0]',
'fourc': 'pos fourc [60 30 90 0]'
}[self.geometry]
pos_cmd_011 = {
'sixc': 'pos sixc [0 90 0 45 45 90]', # mu, delta, gam, eta, chi, phi
'i16': 'pos sixc [90 45 45 0 90 0]', # phi, chi, eta, mu, delta, gam
'fivec': 'pos fivec [90 0 45 45 90]',
'fourc': 'pos fourc [90 45 45 90]'
}[self.geometry]
self.echorun_magiccmd_list([
'help ub',
'pos wl 1',
"newub 'test'",
"setlat 'cubic' 1 1 1 90 90 90",
'ub',
'c2th [0 0 1]',
pos_cmd_001,
'addref [0 0 1]',
'c2th [0 1 1]',
pos_cmd_011,
'addref [0 1 1]',
'ub',
'checkub'])
def constrain(self):
print_heading('Constraint demo')
con_qaz_cmd = '' if self.geometry == 'fourc' else 'con qaz 90'
con_mu_cmd = 'con mu 0' if self.geometry in ('sixc', 'i16') else ''
self.echorun_magiccmd_list([
'help hkl',
con_qaz_cmd,
'con a_eq_b',
con_mu_cmd,
'con',
'setmin delta 0',
'setmin chi 0'])
def scan(self):
print_heading('Scanning demo')
diff_name = 'sixc' if self.geometry == 'i16' else self.geometry
self.echorun_magiccmd_list([
'pos hkl [1 0 0]',
'scan delta 40 90 10 hkl ct 1',
'pos hkl [0 1 0]',
'scan h 0 1 .2 k l %s ct 1' % diff_name,
'con psi',
'scan psi 0 90 10 hkl [1 0 1] eta chi phi ct .1'])
def echorun_magiccmd_list(self, magic_cmd_list):
for cmd in magic_cmd_list:
self.echorun_magiccmd(cmd)
def remove_test_ubcalc(self):
try:
eval("rmub('test')", self.namespace)
except (OSError, KeyError):
pass
def echorun_magiccmd(self, magic_cmd):
if IPYTHON:
from IPython import get_ipython
echo(magic_cmd)
get_ipython().magic(magic_cmd)
else: # Python
# python's help is interactive. Handle specially
if magic_cmd == 'help ub':
echo("help ub")
exec("print ub.__doc__", self.namespace)
return
if magic_cmd == 'help hkl':
echo("help(hkl)")
exec("print hkl.__doc__", self.namespace)
return
# Echo the Python version of the magic command
tokens = diffcmd.ipython.tokenify(magic_cmd)
if not tokens:
return
python_cmd = tokens.pop(0) + '(' + ', '.join(tokens) + ')'
python_cmd = python_cmd.replace('[, ', '[')
python_cmd = python_cmd.replace(',]', ']')
python_cmd = python_cmd.replace(', ]', ']')
echo(python_cmd)
# Run the Python version of the magic command
elements = diffcmd.ipython.parse(magic_cmd, self.namespace)
func = elements.pop(0)
result = func(*elements)
if result:
print result

View File

@@ -0,0 +1,44 @@
from startup._common_imports import *
diffcalc.util.COLOURISE_TERMINAL_OUTPUT = False
### Create dummy scannables ###
print "Dummy scannables: sixc(mu, delta, gam, eta, chi, phi) and en"
mu = Dummy('mu')
delta = Dummy('delta')
gam = Dummy('gam')
eta = Dummy('eta')
chi = Dummy('chi')
phi = Dummy('phi')
_sixc = ScannableGroup('sixc', (mu, delta, gam, eta, chi, phi))
en = Dummy('en')
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 1
settings.hardware = ScannableHardwareAdapter(_sixc, en, ESMTGKeV)
settings.geometry = diffcalc.hkl.you.geometry.SixCircle() # @UndefinedVariable
settings.energy_scannable = en
settings.axes_scannable_group= _sixc
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
# For manual!
from diffcalc.ub.persistence import UbCalculationNonPersister
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.gdasupport.you import * # @UnusedWildImport
DIFFCALC_ROOT = os.sep.join(
os.path.realpath(diffcalc.__file__).split(os.sep)[:-2])
MANUALS_TO_MAKE = [
os.path.join(
DIFFCALC_ROOT, 'doc', 'source', 'youmanual_template.rst'),
os.path.join(
DIFFCALC_ROOT, 'README_template.rst')]
print 'MANUALS_TO_MAKE: ', MANUALS_TO_MAKE

View File

@@ -0,0 +1,73 @@
from __future__ import absolute_import
from diffcalc import settings
from diffcalc.hkl.you.geometry import SixCircle
from diffcalc.hardware import DummyHardwareAdapter
import diffcalc.util # @UnusedImport
# Disable error handling designed for interactive use
diffcalc.util.DEBUG = True
# Configure and import diffcalc objects
settings.hardware = DummyHardwareAdapter(('mu', 'delta', 'gam', 'eta', 'chi', 'phi'))
settings.geometry = SixCircle() # @UndefinedVariable
# These must be imported AFTER the settings have been configured
from diffcalc.dc import dcyou as dc
from diffcalc.ub import ub
from diffcalc import hardware
from diffcalc.hkl.you import hkl
# Set some limits
hardware.setmin('gam', -179)
hardware.setmax('gam', 179)
# These demos reproduce the outline in the developer guide
def demo_all():
demo_orient()
demo_motion()
def demo_orient():
ub.listub()
# Create a new ub calculation and set lattice parameters
ub.newub('test')
ub.setlat('cubic', 1, 1, 1, 90, 90, 90)
# Add 1st reflection (demonstrating the hardware adapter)
settings.hardware.wavelength = 1
ub.c2th([1, 0, 0]) # energy from hardware
settings.hardware.position = 0, 60, 0, 30, 0, 0
ub.addref([1, 0, 0])# energy and position from hardware
# Add 2nd reflection (this time without the harware adapter)
ub.c2th([0, 1, 0], 12.39842)
ub.addref([0, 1, 0], [0, 60, 0, 30, 0, 90], 12.39842)
# check the state
ub.ub()
ub.checkub()
def demo_motion():
dc.angles_to_hkl((0., 60., 0., 30., 0., 0.))
hkl.con('qaz', 90)
hkl.con('a_eq_b')
hkl.con('mu', 0)
hardware.setmin('delta', 0)
dc.hkl_to_angles(1, 0, 0)
demo_all()

View File

@@ -0,0 +1,341 @@
'''
Created on 19 Feb 2017
@author: zrb13439
'''
from diffcalc.gdasupport.minigda.scannable import ScannableMotionWithScannableFieldsBase,\
ScannableBase
from math import pi
# TP_HELP="""
# Use the Scannables tplab, tplabx, tplaby, tplabz to move the configured tool point in
# the lab frame. For example to move it to the centre of the diffractomter:
#
# >>> pos tplab [0 0 0] # Move the toolpoint
#
# use 'settp' to change the configured toolpoint in the phi frame:
#
# >>> pos tphi [0 0 1] # will not move anything
#
# or use it with no args to make the location in the phi frame currently in
# the centre of the diffracomtter the tool point. i.e. to make the tblab
# report back [0 0 0]
# """
TP_HELP="""
For help with sa, tp_phi and tp_lab see: http://confluence.diamond.ac.uk/x/CBIAB
"""
from diffcalc.hkl.you.geometry import calcETA, calcCHI, calcPHI
try:
from numpy import matrix
except ImportError:
from numjy import matrix
TORAD = pi / 180
TODEG = 180 / pi
DEBUG = False
def calc_tp_lab(tp_phi_tuple, eta, chi, phi, xyz_eta=[0, 0, 0]):
tp_phi = matrix(tp_phi_tuple).T
ETA = calcETA(eta * TORAD)
CHI = calcCHI(chi * TORAD)
PHI = calcPHI(phi * TORAD)
xyz_eta = matrix(xyz_eta).T
tp_lab = ETA * (xyz_eta + (CHI * PHI * tp_phi))
return list(tp_lab.T.tolist()[0])
def calc_tp_eta(tp_phi_tuple, chi, phi):
return calc_tp_lab(tp_phi_tuple, 0, chi, phi, [0, 0, 0])
def move_lab_origin_into_phi(chi, phi, xyz_eta_tuple):
# the inverse of calc_tp_lab with tp_lab=0:
CHI = calcCHI(chi * TORAD)
PHI = calcPHI(phi * TORAD)
xyz_eta = matrix(xyz_eta_tuple).T
try:
#work in IPython with numpy
tp_phi = PHI.I * CHI.I * (-1.0 * xyz_eta)
except:
# work in GDA using jama_matrix_wrapper - definitely not nice
tp_phi = PHI.I * CHI.I * (xyz_eta.__mul__(-1.0))
return list(tp_phi.T.tolist()[0])
def _format_vector(vector, fmt = '%7.4f'):
vals = [fmt % e for e in vector]
return ' '.join(vals)
class I21SampleStage(ScannableMotionWithScannableFieldsBase):
def __init__(self, name, pol_scn, tilt_scn, az_scn, xyz_eta_scn):
self.setName(name)
self._scn_list = [pol_scn, tilt_scn, az_scn]
self.xyz_eta_scn = xyz_eta_scn
self.setInputNames([pol_scn.getName(), tilt_scn.getName(), az_scn.getName()]) # note, names copied below
self.setOutputFormat(['%7.5f'] * 3)
self.completeInstantiation()
# tp_phi is the TARGET tool point to end up at the diffractometer centre
self.tp_phi = [0, 0, 0]
self.tp_phi_scannable = I21SampleStage.TpPhiScannable('tp_phi', self)
self.centre_toolpoint = True
def asynchronousMoveTo(self, pos_triple):
if len(pos_triple) != 3:
raise ValueError(self.getName() + ' device expects three inputs')
# Move pol, tilt & az (None if not to be moved)
pol, tilt, az = pos_triple
if pol is not None:
self._scn_list[0].asynchronousMoveTo(pol)
if tilt is not None:
self._scn_list[1].asynchronousMoveTo(tilt)
if az is not None:
self._scn_list[2].asynchronousMoveTo(az)
if self.centre_toolpoint:
_, tilt, az = self.completePosition(pos_triple)
chi = tilt + 90
phi = az
tp_offset_eta = calc_tp_eta(self.tp_phi, chi, phi)
if DEBUG:
print ('{Correcting xyz_eta for '
'tilt(chi-90)=%.2f & az(phi)=%.2f}' % (tilt, az)).rjust(79)
xyz = [-1 * e for e in tp_offset_eta]
self.xyz_eta_scn.asynchronousMoveTo(xyz)
def rawGetPosition(self):
return [scn.getPosition() for scn in self._scn_list]
def getFieldPosition(self, i):
return self._scn_list[i].getPosition()
def isBusy(self):
return (any([scn.isBusy() for scn in self._scn_list])
or self.xyz_eta_scn.isBusy())
def waitWhileBusy(self):
for scn in self._scn_list:
scn.waitWhileBusy()
self.xyz_eta_scn.waitWhileBusy()
def __repr__(self):
# Sample angle columns
pos = self.getPosition()
formatted_values = self.formatPositionFields(pos)
sa_col = []
sa_col.append('%s:' % self.getName())
sa_col.append('sapolar: %s (eta)' % formatted_values[0])
sa_col.append('satilt: %s (chi-90)' % formatted_values[1])
sa_col.append('saazimuth: %s (phi)' % formatted_values[2])
sa_col_width = len(sa_col[2])
# Toolpoint column
xyz_eta = list(self.xyz_eta_scn.getPosition())
eta, chi, phi = self.getEulerPosition()
tp_lab = calc_tp_lab(self.tp_phi, eta, chi, phi, xyz_eta)
tp_col = []
tp_col.append('')
tp_col.append('tp_phi : %s (set)' % _format_vector(self.tp_phi))
tp_col.append('tp_lab : %s' % _format_vector(tp_lab))
tp_col.append('xyz_eta: %s' % _format_vector(xyz_eta))
# Combine columns
lines = []
while sa_col or tp_col:
sa_row = sa_col.pop(0) if sa_col else ''
tp_row = tp_col.pop(0) if tp_col else ''
lines.append(sa_row.ljust(sa_col_width + 3) + tp_row)
if self.centre_toolpoint:
lines.append("\nToolpoint centring ENABLED (disable with toolpoint_off)")
else:
lines.append("\nToolpoint centring DISABLED (enable with toolpoint_on)")
# Add some help
return '\n'.join(lines) + TP_HELP
def getEulerPosition(self):
pol, tilt, az = self.getPosition()
eta, chi, phi = pol, tilt + 90, az
return eta, chi, phi
class TpPhiScannable(ScannableBase):
def __init__(self, name, i21_sample_stage):
self.name = name
self.i21_sample_stage = i21_sample_stage
self.inputNames = [name + 'x', name +'y', name + 'z']
self.outputFormat = ['% 6.4f'] * 3
self.level = 3
def isBusy(self):
return False
def waitWhileBusy(self):
return
def asynchronousMoveTo(self, new_position):
if len(new_position) != 3:
raise TypeError('Expected 3 element target')
self.i21_sample_stage.tp_phi = list(new_position)
def getPosition(self):
return list(self.i21_sample_stage.tp_phi)
def zerosample(self):
"""Calculate tp_phi from the currently centred sample location."""
_, chi, phi = self.getEulerPosition()
xyz_eta_tuple = list(self.xyz_eta_scn.getPosition())
tp_phi = move_lab_origin_into_phi(chi, phi, xyz_eta_tuple)
self.tp_phi = tp_phi
print "tp_phi set to: %s" % tp_phi
def centresample(self):
"""Centre the sample. Equivilent to moving sa to its current position."""
self.asynchronousMoveTo([None, None, None])
self.waitWhileBusy()
class I21DiffractometerStage(ScannableMotionWithScannableFieldsBase):
def __init__(self, name, delta_scn, sample_stage_scn, chi_offset,
delta_offset=0):
"""Create diffractomter stage from 3circle sample axes and a
delta/tth axis.
Both the chi and delta offsets are added to underlying scannable values
when *reading* the position. iu the same offset is subtracted when
*setting* the position.
"""
self.sample_stage_scn = sample_stage_scn
self.delta_scn = delta_scn
self.chi_offset = chi_offset
self.delta_offset = delta_offset
self.setName(name)
self.setInputNames(['delta', 'eta', 'chi', 'phi']) # note, names copied below
self.setOutputFormat(['%7.4f'] * 4)
self.completeInstantiation()
def asynchronousMoveTo(self, pos_quadruple):
if len(pos_quadruple) != 4:
raise ValueError(self.getName() + ' device expects four inputs')
delta, eta, chi, phi = pos_quadruple
pol = eta
tilt = chi - self.chi_offset if (chi is not None) else None
az = phi
if delta is not None:
self.delta_scn.asynchronousMoveTo(delta - self.delta_offset)
if (pol is not None) or (tilt is not None) or (az is not None):
self.sample_stage_scn.asynchronousMoveTo([pol, tilt, az])
def rawGetPosition(self):
delta = self.delta_scn.getPosition()
pol, tilt, az = self.sample_stage_scn.getPosition()
eta, chi, phi = pol, tilt + self.chi_offset, az
return delta + self.delta_offset, eta, chi, phi
def getFieldPosition(self, i):
return self.getPosition()[i]
def isBusy(self):
return self.delta_scn.isBusy() or self.sample_stage_scn.isBusy()
def waitWhileBusy(self):
self.delta_scn.waitWhileBusy()
self.sample_stage_scn.waitWhileBusy()
def __repr__(self):
vals = self.formatPositionFields(self.getPosition())
lines = []
for name, val, hint in zip(self.getInputNames(), vals, self.get_hints()):
lines.append('%-6s : %s%s' % (name, val, hint))
return '\n'.join(lines)
def get_hints(self):
sample_names = self.sample_stage_scn.getInputNames()
hints = []
if self.delta_offset != 0:
sign = '+' if self.delta_offset > 0 else '-'
hints.append(' (%s %s %s)' %
(self.delta_scn.getName(), sign, abs(self.delta_offset))) # delta
else:
hints.append(' (%s)' % self.delta_scn.getName()) # delta
hints.append(' (%s)' % sample_names[0]) # eta
hints.append(' (%s + %s)' % (sample_names[1], self.chi_offset)) # chi
hints.append(' (%s)' % sample_names[2]) # phi
return hints
class I21TPLab(ScannableMotionWithScannableFieldsBase):
def __init__(self, name, sample_stage_scn):
self.name = name
self.sample_stage_scn = sample_stage_scn
self.setInputNames([name + 'x', name + 'y', name + 'z']) # note, names copied below
self.setOutputFormat(['%7.4f'] * 3)
self.completeInstantiation()
self.setAutoCompletePartialMoveToTargets(True)
def rawAsynchronousMoveTo(self, tp_lab_target):
if len(tp_lab_target) != 3:
raise ValueError(self.getName() + ' device expects three inputs')
if None in tp_lab_target:
raise ValueError('unexpected None in tp_lab_target: ', tp_lab_target)
eta, chi, phi = self.sample_stage_scn.getEulerPosition()
ETA = calcETA(eta * TORAD)
# Move tp target from lab frame inwards to eta frame
tp_lab_target = matrix(tp_lab_target).T
tp_eta_target = ETA.T * tp_lab_target # ETA.I == ETA.T
# Move configured tp from phi frame outwards to eta frame
tp_eta = calc_tp_eta(self.sample_stage_scn.tp_phi, chi, phi)
# Calculate offset required to align the two
xyz_eta = tp_eta_target - matrix(tp_eta).T
xyz_eta = xyz_eta.T.tolist()[0]
self.sample_stage_scn.xyz_eta_scn.asynchronousMoveTo(xyz_eta)
def rawGetPosition(self):
tp_phi = list(self.sample_stage_scn.tp_phi)
eta, chi, phi = self.sample_stage_scn.getEulerPosition()
xyz_eta = list(self.sample_stage_scn.xyz_eta_scn.getPosition())
tp_lab = calc_tp_lab(tp_phi, eta, chi, phi, xyz_eta)
return tp_lab
def getFieldPosition(self, i):
return self.getPosition()[i]
def isBusy(self):
return self.sample_stage_scn.xyz_eta_scn.isBusy()
def waitWhileBusy(self):
self.sample_stage_scn.xyz_eta_scn.waitWhileBusy()

View File

@@ -0,0 +1,36 @@
from startup._common_imports import *
import startup._demo
### Create dummy scannables ###
print "Diffcalc creating dummy Scannables as _fivec and en were not found"
delta = Dummy('delta')
gam = Dummy('gam')
eta = Dummy('eta')
chi = Dummy('chi')
phi = Dummy('phi')
_fivec = ScannableGroup('_fivec', (delta, gam, eta, chi, phi))
en = Dummy('en')
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 1
settings.hardware = ScannableHardwareAdapter(_fivec, en, ESMTGKeV)
settings.geometry = diffcalc.hkl.you.geometry.FiveCircle() # @UndefinedVariable
settings.energy_scannable = en
settings.axes_scannable_group = _fivec
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
from diffcalc.gdasupport.you import * # @UnusedWildImport
if GDA:
print "Running in GDA --- aliasing commands"
alias_commands(globals())
lastub() # Load the last ub calculation used
# Set some limits
setmin('gam', -179)
setmax('gam', 179)
demo = startup._demo.Demo(globals(), 'fivec')

View File

@@ -0,0 +1,31 @@
from startup._common_imports import *
import startup._demo
### Create dummy scannables ###
delta = Dummy('delta')
eta = Dummy('eta')
chi = Dummy('chi')
phi = Dummy('phi')
_fourc = ScannableGroup('_fourc', (delta, eta, chi, phi))
en = Dummy('en')
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 1
settings.hardware = ScannableHardwareAdapter(_fourc, en, ESMTGKeV)
settings.geometry = diffcalc.hkl.you.geometry.FourCircle() # @UndefinedVariable
settings.energy_scannable = en
settings.axes_scannable_group= _fourc
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
from diffcalc.gdasupport.you import * # @UnusedWildImport
if GDA:
print "Running in GDA --- aliasing commands"
alias_commands(globals())
# Load the last ub calculation used
lastub()
demo = startup._demo.Demo(globals(), 'fourc')

View File

@@ -0,0 +1,54 @@
from startup._common_imports import * # @UnusedWildImport
from diffcalc.gdasupport.minigda.scannable import ScannableMotionWithScannableFieldsBase # @UnusedImport
from diffcalc.gdasupport.minigda.scannable import DummyPD
if not GDA:
import startup._demo
else:
# import __main__ # @UnresolvedImport
from __main__ import dd2th,ddth,denergy # @UnresolvedImport
LOCAL_MANUAL = "http://confluence.diamond.ac.uk/pages/viewpage.action?pageId=31853413"
# Diffcalc i06-1
# ======== ===
# delta dd2th
# eta ddth
# chi dummy
# phi dummy
### Create dummy scannables ###
if GDA:
print "!!! Starting LIVE diffcalc with delta(dd2th), eta(ddth), chi(dummy), phi(dummy) and denergy."
delta = dd2th
eta = ddth
en=denergy
else:
delta = Dummy('delta')
eta = Dummy('eta')
en = Dummy('en')
en(1500)
chi = DummyPD('chi')
phi = DummyPD('phi')
_fourc = ScannableGroup('_fourc', (delta, eta, chi, phi))
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 1
settings.hardware = ScannableHardwareAdapter(_fourc, en, ESMTGKeV)
settings.geometry = diffcalc.hkl.you.geometry.FourCircle() # @UndefinedVariable
settings.energy_scannable = en
settings.axes_scannable_group= _fourc
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
from diffcalc.gdasupport.you import * # @UnusedWildImport
if GDA:
print "Running in GDA --- aliasing commands"
alias_commands(globals())
# Load the last ub calculation used
lastub()
if not GDA:
demo = startup._demo.Demo(globals(), 'fourc')

View File

@@ -0,0 +1,185 @@
from diffcalc.util import x_rotation, y_rotation, z_rotation, TORAD, TODEG
import startup._demo
from startup._common_imports import *
if '_fivec' in globals() and 'en' in globals():
# Assume we are running in a live GDA deployment with a _fivec ScannableGroup
# with axes named: delta, gam, eta, chi, phi.
# Ensure that these five Scannables exist.
# There must also be Scannable en for moving and reading the energy
print "Diffcalc using predefined _fivec and en Scannables"
else:
### Create dummy scannables ###
print "Diffcalc creating dummy Scannables as _fivec and en were not found"
delta = Dummy('delta')
gam = Dummy('gam')
eta = Dummy('eta')
chi = Dummy('chi')
phi = Dummy('phi')
_fivec = ScannableGroup('_fivec', (delta, gam, eta, chi, phi))
en = Dummy('en')
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 1
settings.hardware = ScannableHardwareAdapter(_fivec, en, ESMTGKeV)
settings.geometry = diffcalc.hkl.you.geometry.FiveCircle()
settings.energy_scannable = en
settings.axes_scannable_group = _fivec
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
from diffcalc.gdasupport.you import * # @UnusedWildImport
if GDA:
print "Running in GDA --- aliasing commands"
alias_commands(globals())
# Load the last ub calculation used
lastub()
#
# setmax(delta, 28)
# setmin(delta, -1)
# setmin(gam, 0)
# setmax(gam, 16)
# setmin(eta, -10)
# setmax(eta, 10)
# setmin(chi, 90 - 12)
# setmax(chi, 90 + 12)
# setmin(phi, -88)
# setmax(phi, 88)
# setcut(phi, -90)
# hardware()
setmax(delta, 90)
setmin(delta, -1)
setmin(gam, 0)
setmax(gam, 90)
setmin(eta, -90)
setmax(eta, 90)
setmin(chi, -10)
setmax(chi, 100)
setmin(phi, -88)
setmax(phi, 88)
setcut(phi, -90)
hardware()
def X(th_deg):
return x_rotation(th_deg * TORAD)
def Y(th_deg):
return y_rotation(th_deg * TORAD)
def Z(th_deg):
return z_rotation(th_deg * TORAD)
WEDGE = X(15)
if not GDA:
demo = startup._demo.Demo(globals(), 'fivec')
"""
Fivec, no real limits, working out U matrix
===========================================
U = xyz_rotation([-0.70711, 0.70711, 0.00000], 54.73561 * TORAD)
setu U
pos en 20
con qaz 90
con a_eq_b
UBCALC
name: 2017-03-07-i13
n_phi: -0.00000 -0.00000 1.00000
n_hkl: 0.57735 0.57735 0.57735 <- set
miscut:
angle: 0.00003
axis: 0.70711 -0.70711 0.00000
CRYSTAL
name: Si111
a, b, c: 5.43000 5.43000 5.43000
90.00000 90.00000 90.00000
B matrix: 1.15712 0.00000 0.00000
0.00000 1.15712 0.00000
0.00000 0.00000 1.15712
UB MATRIX
U matrix: 0.78868 -0.21133 -0.57735
-0.21132 0.78867 -0.57735
0.57735 0.57735 0.57735
angle: 54.73564
axis: 0.70711 -0.70711 0.00000
UB matrix: 0.91260 -0.24453 -0.66807
-0.24453 0.91259 -0.66807
0.66807 0.66807 0.66807
REFLECTIONS
ENERGY H K L DELTA GAM ETA CHI PHI TAG
1 20.000 1.00 1.00 1.00 11.3483 0.0000 5.6741 90.0000 45.0000
2 20.000 4.00 0.00 0.00 26.3978 0.0000 13.1989 35.2644 -15.0000
In [80]: listub
UB calculations in: /Users/zrb13439/.diffcalc/i13
0) 2017-03-07-i13 14 Mar 2017 (14:35)
1) test 07 Mar 2017 (11:38)
In [81]: hardware
-1.0 <= delta <= 90.0 (cut: -180.0)
0.0 <= gam <= 90.0 (cut: -180.0)
-90.0 <= eta <= 90.0 (cut: -180.0)
-10.0 <= chi <= 100.0 (cut: -180.0)
-180.0 <= phi <= 180.0 (cut: -90.0)
Note: When auto sector/transforms are used,
cuts are applied before checking limits.
Add in delta and gamma constraintss:
In [85]: atan(28/16)*TODEG
Out[85]: 45.0
In [86]: atan(28/16.)*TODEG
Out[86]: 60.25511870305777
In [87]: con qaz 60
qaz : 60.0000
a_eq_b
mu : 0.0000
In [88]: sim hkl [4 0 0]
_fivec would move to:
delta : 22.6459
gam : 13.9379
eta : 59.2132
chi : 8.8270
phi : -63.0717
alpha : 7.5752
beta : 7.5752
naz : 4.5446
psi : 90.0000
qaz : 60.0000
tau : 54.7356
theta : 13.1989
""""

View File

@@ -0,0 +1,68 @@
from startup._common_imports import *
from diffcalc.hkl.you.geometry import YouPosition
import diffcalc.hkl.you.geometry
import startup._demo
LOCAL_MANUAL = 'http://confluence.diamond.ac.uk/display/I16/Diffcalc%20(i16)'
class SixCircleI16(diffcalc.hkl.you.geometry.YouGeometry):
def __init__(self):
diffcalc.hkl.you.geometry.YouGeometry.__init__(self, 'sixc', {})
def physical_angles_to_internal_position(self, physical_angle_tuple):
# i16: phi, chi, eta, mu, delta, gam
# H. You: mu, delta, nu, eta, chi, phi
phi, chi, eta, mu, delta, gam = physical_angle_tuple
return YouPosition(mu, delta, gam, eta, chi, phi)
def internal_position_to_physical_angles(self, internal_position):
mu, delta, nu, eta, chi, phi = internal_position.totuple()
return phi, chi, eta, mu, delta, nu
if GDA:
from scannable.extraNameHider import ExtraNameHider
dummy_energy = Dummy('dummy_energy')
simple_energy = ExtraNameHider('energy', dummy_energy) # @UndefinedVariable
if 'euler' not in locals():
raise Exception('Expecting a device called euler')
else: # Assume running in dummy mode outside GDA
mu = Dummy('mu')
delta = Dummy('delta')
gam = Dummy('gam')
eta = Dummy('eta')
chi = Dummy('chi')
phi = Dummy('phi')
euler = ScannableGroup('euler', (phi, chi, eta, mu, delta, gam))
en = simple_energy = Dummy('energy')
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 1
settings.hardware = ScannableHardwareAdapter(euler, simple_energy, ESMTGKeV)
settings.geometry = SixCircleI16()
settings.energy_scannable = simple_energy
settings.axes_scannable_group= euler
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
from diffcalc.gdasupport.you import * # @UnusedWildImport
hkl.setLevel(6)
if GDA:
print "Running in GDA --- aliasing commands"
alias_commands(globals())
lastub() # Load the last ub calculation used
# iPython removes the actual command from namespace
diffcalc.hardware.setrange(chi, -2, 100)
diffcalc.hardware.setrange(eta, -2, 92)
diffcalc.hardware.setrange(delta, -2, 145)
diffcalc.hardware.setrange(gam, -2, 145)
setcut(phi, -180)
if not GDA:
demo = startup._demo.Demo(globals(), 'i16')

View File

@@ -0,0 +1,262 @@
from startup._common_imports import * # @UnusedWildImport
from diffcalc.gdasupport.minigda.scannable import ScannableMotionWithScannableFieldsBase # @UnusedImport
from startup.beamlinespecific.i21 import I21SampleStage, I21DiffractometerStage, I21TPLab
if not GDA:
import startup._demo
else:
# import __main__ # @UnresolvedImport
from __main__ import diodetth,m5tth,sapolar,satilt,saazimuth,sax,say,saz, energy # @UnresolvedImport
LOCAL_MANUAL = "http://confluence.diamond.ac.uk/x/UoIQAw"
# Diffcalc i21
# ======== ===
# delta diodetth or m5tth
# eta sapolar
# chi satilt + 90deg
# phi saazimuth
### Create dummy scannables ###
if GDA:
# assert 'diodetth' in __main__.__dict__ #GDA name is diodetth
# assert 'm5tth' in __main__.__dict__ #GDA name is m5tth - m5 has 2 mirrors with fixed tth offset
# assert 'sapolar' in __main__.__dict__ #GDA name is sapolar
# assert 'satilt' in __main__.__dict__ #GDA name is satilt - fix 90 deg offset
# assert 'saazimuth' in __main__.__dict__ #GDA name is saazimuth
# assert 'sax'in __main__.__dict__
# assert 'say'in __main__.__dict__
# assert 'saz'in __main__.__dict__
print "WARNING: saz may need to be reversed to agree with diffcalc"
xyz_eta = ScannableGroup('xyz_eta', [sax, say, saz]) # @UndefinedVariable
else:
diodetth = Dummy('diodetth')
m5tth = Dummy('m5tth')
sapolar = Dummy('sapolar')
satilt = Dummy('satilt')
saazimuth = Dummy('saazimuth')
sax = Dummy('sax')
say = Dummy('say')
saz = Dummy('saz')
xyz_eta = ScannableGroup('xyz_eta', [sax, say, saz])
sa = I21SampleStage('sa', sapolar, satilt, saazimuth, xyz_eta)
sapolar = sa.sapolar
satilt = sa.satilt
saazimuth = sa.saazimuth
tp_phi = sa.tp_phi_scannable
def centresample():
sa.centresample()
def zerosample():
sa.zerosample()
def toolpoint_on():
sa.centre_toolpoint = True
def toolpoint_off():
sa.centre_toolpoint = False
tp_lab = I21TPLab('tp_lab', sa)
tp_labx = tp_lab.tp_labx
tp_laby = tp_lab.tp_laby
tp_labz = tp_lab.tp_labz
_fourc = I21DiffractometerStage('_fourc', diodetth, sa, chi_offset = 90)
delta = _fourc.delta
eta = _fourc.eta
chi = _fourc.chi
phi = _fourc.phi
from diffcalc.hardware import setmax, setmin, hardware,setcut
### Wrap i21 names to get diffcalc names
if GDA:
def usediode():
_fourc.delta_scn = diodetth
setmin(delta, 0)
setmax(delta, 180)
def usevessel():
_fourc.delta_scn = m5tth # note, if changed also update in _fourc_vessel constructor!
setmin(delta, 0)
setmax(delta, 150)
# raise Exception('need gda class for wrapping scannables. There is one somewhere')
# import what_is_its_name as XYZ # @UnresolvedImport
# delta = XYZ(diode_tth, 'delta') # or vessel_tth
# eta = XYZ(sapolar, 'eta')
# chi = XYZ(satilt, 'chi', 90) # chi = satilt + 90deg
# phi = XYZ(saazimuth, 'phi')
#
# def usediode():
# raise Exception('needs implementing')
#
# def usevessel():
# raise Exception('needs implementing')
from gda.jython.commands.GeneralCommands import alias # @UnresolvedImport
alias("usediode")
alias("usevessel")
alias("centresample")
alias("zerosample")
alias("toolpoint_on")
alias("toolpoint_off")
else:
from diffcalc.gdasupport.minigda.scannable import ScannableAdapter
from IPython.core.magic import register_line_magic # @UnresolvedImport
from diffcmd.ipython import parse_line
# delta = ScannableAdapter(diodetth, 'delta') # or vessel_tth
# eta = ScannableAdapter(sapolar, 'eta')
# chi = ScannableAdapter(satilt, 'chi', 90) # chi = satilt + 90deg
# phi = ScannableAdapter(saazimuth, 'phi')
def usediode():
_fourc.delta_scn = diodetth
setmin(delta, 0)
setmax(delta, 180)
def usevessel():
_fourc.delta_scn = m5tth
setmin(delta, 0)
setmax(delta, 150)
if IPYTHON:
from IPython import get_ipython # @UnresolvedImport @UnusedImport
register_line_magic(parse_line(usediode, globals()))
del usediode
register_line_magic(parse_line(usevessel, globals()))
del usevessel
register_line_magic(parse_line(centresample, globals()))
del centresample
register_line_magic(parse_line(zerosample, globals()))
del zerosample
register_line_magic(parse_line(toolpoint_on, globals()))
del toolpoint_on
register_line_magic(parse_line(toolpoint_off, globals()))
del toolpoint_off
print "Created i21 bespoke commands: usediode & usevessel"
if GDA:
en=energy
if float(en.getPosition()) == 0: # no energy value - dummy?
en(800)
else:
en = Dummy('en')
en(800)
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 0.001
settings.hardware = ScannableHardwareAdapter(_fourc, en, ESMTGKeV)
settings.geometry = diffcalc.hkl.you.geometry.FourCircle() # @UndefinedVariable
settings.energy_scannable = en
settings.axes_scannable_group= _fourc
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
from diffcalc.gdasupport.you import * # @UnusedWildImport
# fourc is created in diffcalc.gdasupport.you. Add some I21 hints into it
fourc.hint_generator = _fourc.get_hints # (the callablemethod) # @UndefinedVariable
if GDA:
print "Running in GDA --- aliasing commands"
alias_commands(globals())
### Load the last ub calculation used
from diffcalc.ub.ub import lastub
lastub()
### Set i21 specifi limits
print "INFO: diffcalc limits set in $diffcalc/startup/i21.py taken from http://confluence.diamond.ac.uk/pages/viewpage.action?pageId=51413586"
setmin(delta, 0)
setmax(delta, 150) #defult to m5tth limits
setmin(chi, 60)
setmax(chi, 135)
setmin(eta, 0)
setmax(eta, 360)
setmin(phi, -179)
setmax(phi, 179)
#http://jira.diamond.ac.uk/browse/I21-361
setcut(eta, 0.0)
setcut(phi, -180)
print "Current hardware limits set to:"
hardware()
### Create i21 bespoke secondary hkl devices
# Warning: this breaks the encapsulation provided by the diffcalc.dc.you public
# interface, and may be prone to breakage in future.
print 'Creating i21 bespoke scannables:'
from diffcalc.dc import dcyou as _dc
from diffcalc.gdasupport.scannable.diffractometer import DiffractometerScannableGroup
from diffcalc.gdasupport.scannable.hkl import Hkl
print '- fourc_vessel & hkl_vessel'
_fourc_vessel = I21DiffractometerStage('_fourc_vessel', m5tth, sa, chi_offset = 90)
fourc_vessel = DiffractometerScannableGroup('fourc_vessel', _dc, _fourc_vessel)
fourc_vessel.hint_generator = _fourc_vessel.get_hints
hkl_vessel = Hkl('hkl_vessel', _fourc_vessel, _dc)
h_vessel, k_vessel, l_vessel = hkl_vessel.h, hkl_vessel.k, hkl_vessel.l
print '- fourc_lowq & hkl_lowq'
LOWQ_OFFSET_ADDED_TO_DELTA_WHEN_READING = -8
_fourc_lowq = I21DiffractometerStage(
'_fourc_lowq', m5tth, sa, chi_offset=90,
delta_offset=LOWQ_OFFSET_ADDED_TO_DELTA_WHEN_READING)
fourc_lowq = DiffractometerScannableGroup('fourc_lowq', _dc, _fourc_lowq)
fourc_lowq.hint_generator = _fourc_lowq.get_hints
hkl_lowq = Hkl('hkl_lowq', _fourc_lowq, _dc)
h_lowq, k_lowq, l_lowq = hkl_lowq.h, hkl_lowq.k, hkl_lowq.l
print '- fourc_highq & hkl_highq'
highq_OFFSET_ADDED_TO_DELTA_WHEN_READING = 0
_fourc_highq = I21DiffractometerStage(
'_fourc_highq', m5tth, sa, chi_offset=90,
delta_offset=highq_OFFSET_ADDED_TO_DELTA_WHEN_READING)
fourc_highq = DiffractometerScannableGroup('fourc_highq', _dc, _fourc_highq)
fourc_highq.hint_generator = _fourc_highq.get_hints
hkl_highq = Hkl('hkl_highq', _fourc_highq, _dc)
h_highq, k_highq, l_highq = hkl_highq.h, hkl_highq.k, hkl_highq.l
# vessel
print '- fourc_diode & hkl_diode'
_fourc_diode = I21DiffractometerStage('_fourc_diode', diodetth, sa, chi_offset = 90)
fourc_diode = DiffractometerScannableGroup('fourc_diode', _dc, _fourc_diode)
fourc_diode.hint_generator = _fourc_diode.get_hints
hkl_diode = Hkl('hkl_diode', _fourc_diode, _dc)
h_diode, k_diode, l_diode = hkl_diode.h, hkl_diode.k, hkl_diode.l
### Demo ###
if not GDA:
class I21Demo(startup._demo.Demo):
def __init__(self, namespace):
startup._demo.Demo.__init__(self, namespace, 'fourc')
def i21(self):
startup._demo.print_heading('i21 scannables demo')
self.echorun_magiccmd_list([
'sa',
'pos sapolar 1',
'pos satilt 2',
'pos saazimuth 3',
'pos m5tth 4',
'usevessel',
'fourc'])
if not GDA:
demo = I21Demo(globals())

View File

@@ -0,0 +1,37 @@
from startup._common_imports import *
import startup._demo
### Create dummy scannables ###
mu = Dummy('mu')
delta = Dummy('delta')
gam = Dummy('gam')
eta = Dummy('eta')
chi = Dummy('chi')
phi = Dummy('phi')
_sixc = ScannableGroup('_sixc', (mu, delta, gam, eta, chi, phi))
en = Dummy('en')
en.level = 3
### Configure and import diffcalc objects ###
ESMTGKeV = 1
settings.hardware = ScannableHardwareAdapter(_sixc, en, ESMTGKeV)
settings.geometry = diffcalc.hkl.you.geometry.SixCircle() # @UndefinedVariable
settings.energy_scannable = en
settings.axes_scannable_group= _sixc
settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
from diffcalc.gdasupport.you import * # @UnusedWildImport
if GDA:
print "Running in GDA --- aliasing commands"
alias_commands(globals())
# Load the last ub calculation used
lastub()
# Set some limits
setmin('gam', -179)
setmax('gam', 179)
demo = startup._demo.Demo(globals(), 'sixc')