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,707 @@
###
# 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/>.
###
import unittest
from diffcalc import settings
import pytest
try:
from numpy import matrix
except ImportError:
from numjy import matrix
try:
from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
except ImportError:
from diffcalc.gdasupport.minigda.scannable import DummyPD
from diffcalc.gdasupport.scannable.base import ScannableGroup
from diffcalc.gdasupport.scannable.diffractometer import \
DiffractometerScannableGroup
from diffcalc.gdasupport.scannable.hkl import Hkl
from diffcalc.gdasupport.scannable.parameter import \
DiffractionCalculatorParameter
from diffcalc.gdasupport.scannable.slave_driver import \
NuDriverForSixCirclePlugin
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry, \
SixCircleGeometry, Fivec, Fourc
from diffcalc.hardware import DummyHardwareAdapter
from diffcalc.hardware import ScannableHardwareAdapter
from test.tools import aneq_, mneq_
from diffcalc.ub.persistence import UbCalculationNonPersister
from diffcalc.util import DiffcalcException, MockRawInput
from test.diffcalc import scenarios
import diffcalc.util # @UnusedImport to overide raw_input
from diffcalc.gdasupport.minigda.command import sim
diffcalc.util.DEBUG = True
def prepareRawInput(listOfStrings):
diffcalc.util.raw_input = MockRawInput(listOfStrings)
prepareRawInput([])
def createDummyAxes(names):
result = []
for name in names:
result.append(DummyPD(name))
return result
class BaseTestDiffractionCalculatorWithData(object):
def setSessionAndCalculation(self):
raise Exception("Abstract")
def setup_method(self):
self.geometry = SixCircleGammaOnArmGeometry()
self.hardware = DummyHardwareAdapter(
('alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'))
settings.hardware = self.hardware
settings.geometry = self.geometry
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.dc import dcvlieg as dc
reload(dc)
self.dc = dc
self.setSessionAndCalculation()
prepareRawInput([])
def setDataAndReturnObject(self, sessionScenario, calculationScenario):
self.sess = sessionScenario
self.calc = calculationScenario
return self
def test_angles_to_hkl(self):
with pytest.raises(DiffcalcException):
self.dc.angles_to_hkl((1, 2, 3, 4, 5, 6)) # no energy set
settings.hardware.energy = 10
with pytest.raises(DiffcalcException):
self.dc.angles_to_hkl((1, 2, 3, 4, 5, 6)) # no ub calculated
s = self.sess
c = self.calc
# setup session info
self.dc.newub(s.name)
self.dc.setlat(s.name, *s.lattice)
r = s.ref1
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
r = s.ref2
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
self.dc.calcub()
# check the ubcalculation is okay before continuing
# (useful to check for typos!)
mneq_(self.dc.ubcalc.UB,
matrix(s.umatrix) * matrix(s.bmatrix), 4,
note="wrong UB matrix after calculating U")
# Test each hkl/position pair
for idx in range(len(c.hklList)):
hkl = c.hklList[idx]
pos = c.posList[idx]
# 1) specifying energy explicitely
((h, k, l), params) = self.dc.angles_to_hkl(pos.totuple(), c.energy)
msg = ("wrong hkl calc for TestScenario=%s, AngleTestScenario"
"=%s, pos=%s):\n expected hkl=%f %f %f\n returned hkl="
"%f %f %f "
% (s.name, c.tag, str(pos), hkl[0], hkl[1], hkl[2], h, k, l)
)
assert [h, k, l] == pytest.approx(hkl, abs=.001)
# self.assert_((abs(h - hkl[0]) < .001) & (abs(k - hkl[1]) < .001)
# & (abs(l - hkl[2]) < .001), msg)
# 2) specifying energy via hardware
settings.hardware.energy = c.energy
msg = ("wrong hkl calcualted for TestScenario=%s, "
"AngleTestScenario=%s, pos=%s):\n expected hkl=%f %f %f\n"
" returned hkl=%f %f %f " %
(s.name, c.tag, str(pos), hkl[0], hkl[1], hkl[2], h, k, l))
((h, k, l), params) = self.dc.angles_to_hkl(pos.totuple())
assert [h, k, l] == pytest.approx(hkl, abs=.001)
del params
def test_hkl_to_angles(self):
s = self.sess
c = self.calc
## setup session info
self.dc.newub(s.name)
self.dc.setlat(s.name, *s.lattice)
r = s.ref1
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
r = s.ref2
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
self.dc.calcub()
# check the ubcalculation is okay before continuing
# (useful to check for typos !)
mneq_(self.dc.ubcalc.UB,
matrix(s.umatrix) * matrix(s.bmatrix), 4,
note="wrong UB matrix after calculating U")
## setup calculation info
self.dc.hklmode(c.modeNumber)
# Set fixed parameters
if c.alpha != None:
self.dc.setpar('alpha', c.alpha)
if c.gamma != None:
self.dc.setpar('gamma', c.alpha)
# Test each hkl/position pair
for idx in range(len(c.hklList)):
(h, k, l) = c.hklList[idx]
expectedangles = \
self.geometry.internal_position_to_physical_angles(c.posList[idx])
(angles, params) = self.dc.hkl_to_angles(h, k, l, c.energy)
expectedAnglesStr = ("%f " * len(expectedangles)) % expectedangles
anglesString = ("%f " * len(angles)) % angles
namesString = (("%s " * len(self.hardware.get_axes_names()))
% self.hardware.get_axes_names())
note = ("wrong position calcualted for TestScenario=%s, "
"AngleTestScenario=%s, hkl=%f %f %f:\n"
" { %s }\n"
" expected pos=%s\n returned pos=%s "
% (s.name, c.tag, h, k, l, namesString, expectedAnglesStr,
anglesString))
mneq_(matrix([list(expectedangles)]), matrix([list(angles)]), 2,
note=note)
del params
def testSimWithHklAndSixc(self):
dummyAxes = createDummyAxes(
['alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'])
dummySixcScannableGroup = ScannableGroup('sixcgrp', dummyAxes)
sixcdevice = DiffractometerScannableGroup(
'SixCircleGammaOnArmGeometry', self.dc, dummySixcScannableGroup)
hkldevice = Hkl('hkl', sixcdevice, self.dc)
with pytest.raises(TypeError):
sim()
with pytest.raises(TypeError):
sim(hkldevice)
with pytest.raises(TypeError):
sim(hkldevice, 1, 2, 3)
with pytest.raises(TypeError):
sim('not a proper scannable', 1)
with pytest.raises(TypeError):
sim(hkldevice, (1, 2, 'not a number'))
with pytest.raises(TypeError):
sim(hkldevice, 1)
with pytest.raises(ValueError):
sim(hkldevice, (1, 2, 3, 4))
s = self.sess
c = self.calc
# setup session info
self.dc.newub(s.name)
self.dc.setlat(s.name, *s.lattice)
r = s.ref1
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
r = s.ref2
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
self.dc.calcub()
# check the ubcalculation is okay before continuing
# (useful to check for typos!)
mneq_(self.dc.ubcalc.UB,
(matrix(s.umatrix) * (matrix(s.bmatrix))),
4, note="wrong UB matrix after calculating U")
self.hardware.energy = c.energy
# Test each hkl/position pair
for idx in range(len(c.hklList)):
hkl = c.hklList[idx]
pos = c.posList[idx].totuple()
sim(sixcdevice, pos)
sim(hkldevice, hkl)
def testCheckub(self):
## setup session info
s = self.sess
self.dc.newub(s.name)
self.dc.setlat(s.name, *s.lattice)
r = s.ref1
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
r = s.ref2
self.dc.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
self.dc.calcub()
print "*** checkub ***"
print self.dc.checkub()
print "***************"
class TestDiffractionCalculatorHklWithDataSess2Calc0(
BaseTestDiffractionCalculatorWithData):
def setSessionAndCalculation(self):
self.sess = scenarios.session2
self.calc = scenarios.session2.calculations[0]
class TestDiffractionCalculatorHklWithDataSess3Calc0(
BaseTestDiffractionCalculatorWithData):
def setSessionAndCalculation(self):
self.sess = scenarios.session3
self.calc = scenarios.session3.calculations[0]
class TestSixcBase(object):
def createDiffcalcAndScannables(self, geometryClass):
self.en = DummyPD('en')
dummy = createDummyAxes(
['alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'])
group = ScannableGroup('sixcgrp', dummy)
self.sixc = DiffractometerScannableGroup('sixc', None, group)
self.hardware = DummyHardwareAdapter(
('alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'))
settings.hardware = ScannableHardwareAdapter(self.sixc, self.en)
settings.geometry = geometryClass()
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.dc import dcvlieg as dc
reload(dc)
self.dc = dc
self.sixc.diffcalc = self.dc
self.hkl = Hkl('hkl', self.sixc, self.dc)
class TestFourcBase(object):
def createDiffcalcAndScannables(self):
self.en = DummyPD('en')
dummy = createDummyAxes(['delta', 'omega', 'chi', 'phi'])
scannableGroup = ScannableGroup('fourcgrp', dummy)
self.fourc = DiffractometerScannableGroup(
'fourc', None, scannableGroup)
settings.hardware = ScannableHardwareAdapter(self.fourc, self.en)
settings.geometry = Fourc()
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.dc import dcvlieg as dc
reload(dc)
self.dc = dc
self.fourc.diffcalc = self.dc
self.hkl = Hkl('hkl', self.fourc, self.dc)
class SixCircleGammaOnArmTest(TestSixcBase):
def setup_method(self):
TestSixcBase.createDiffcalcAndScannables(self,
SixCircleGammaOnArmGeometry)
self.hklverbose = Hkl('hkl', self.sixc, self.dc,
('theta', '2theta', 'Bin', 'Bout', 'azimuth'))
settings.hardware.set_cut('phi', -180) # cut phi at -180 to match dif
self.orient()
def orient(self):
self.dc.newub('b16_270608')
self.dc.setlat('xtal', 3.8401, 3.8401, 5.43072)
self.en(12.39842 / 1.24)
self.sixc([5.000, 22.790, 0.000, 1.552, 22.400, 14.255])
self.dc.addref([1, 0, 1.0628])
self.sixc([5.000, 22.790, 0.000, 4.575, 24.275, 101.320])
self.dc.addref([0, 1, 1.0628])
self.dc.checkub()
def testDiffractionCalculatorScannableIntegration(self):
betain = DiffractionCalculatorParameter('betain', 'betain',
self.dc.parameter_manager)
betain.asynchronousMoveTo(12.34)
self.assertEqual(betain.getPosition(), 12.34)
def mode(self, mode, alpha=0, gamma=0, betain=0, betaout=0, phi=0, sig=0,
tau=0):
self.dc.hklmode(mode)
self.dc.setpar('alpha', alpha)
self.dc.setpar('gamma', gamma)
self.dc.setpar('betain', betain)
self.dc.setpar('betaout', betaout)
self.dc.setpar('phi', phi)
self.dc.sigtau(sig, tau)
def test1(self):
self.mode(1)
self.hkl([.7, .9, 1.3])
aneq_((0., 27.3557, 0., 13.6779, 37.7746, 53.9654), self.sixc(), 4)
print self.hkl
print self.hklverbose
def test2(self):
self.mode(1, alpha=5, gamma=0)
self.hkl([.7, .9, 1.3])
aneq_((5., 26.9296, 0., 8.4916, 27.2563, 59.5855), self.sixc(), 4)
def test3(self):
self.mode(1, alpha=5, gamma=10)
self.hkl([.7, .9, 1.3])
aneq_((5., 22.9649, 10., 42.2204, 4.9721, 23.0655), self.sixc(), 4)
def test4(self):
self.mode(2, alpha=5, gamma=10, betain=4)
self.hkl([.7, .9, 1.3])
aneq_((5, 22.9649, 10., -11.8850, 4.7799, 80.4416),
self.sixc(), 4, note="[alpha, delta, gamma, omega, chi, phi")
def test5(self):
self.mode(1, alpha=5, gamma=10, sig=-1.3500, tau=-106)
self.hkl([.7, .9, 1.3])
aneq_((5., 22.9649, 10., 30.6586, 4.5295, 35.4036), self.sixc(), 4)
def test6(self):
self.mode(2, alpha=5, gamma=10, sig=-1.3500, tau=-106, betain=6)
self.hkl([.7, .9, 1.3])
aneq_((5., 22.9649, 10., 2.2388, 4.3898, 65.4395), self.sixc(), 4)
def test7(self):
self.mode(3, alpha=5, gamma=10, sig=-1.3500, tau=-106, betaout=7)
self.hkl([.7, .9, 1.3])
aneq_((5., 22.9649, 10., 43.4628, 5.0387, 21.7292), self.sixc(), 4)
def test7a(self):
self.mode(5, phi=10) # Fix phi
self.hkl([.7, .9, 1.3])
def test8(self):
#8
self.mode(10, gamma=10, sig=-1.35, tau=-106) # 5cgBeq
self.hkl([.7, .9, 1.3])
aneq_((6.1937, 22.1343, 10., 46.9523, 1.5102, 18.8112), self.sixc(), 3)
def test9(self):
self.mode(13, alpha=5, gamma=10, sig=-1.35, tau=-106) # 5cgBeq
self.hkl([.7, .9, 1.3])
aneq_((5., 22.2183, 11.1054, 65.8276, 2.5180, -0.0749), self.sixc(), 4)
def test10(self):
self.mode(20, sig=-1.35, tau=-106) # 6czBeq
self.hkl([.7, .9, 1.3])
aneq_((8.1693, 22.0156, 8.1693, -40.2188, 1.35, 106.), self.sixc(), 4)
def test11(self):
self.mode(21, betain=8, sig=-1.35, tau=-106) # 6czBin
self.hkl([.7, .9, 1.3])
aneq_((8., 22.0156, 8.3386, -40.0939, 1.3500, 106.), self.sixc(), 4)
def test12(self):
self.mode(22, betaout=1, sig=-1.35, tau=-106) # 6czBin
self.hkl([.7, .9, 1.3])
aneq_((15.4706, 22.0994, 1., -45.5521, 1.3500, 106.), self.sixc(), 4)
class ZAxisGammaOnBaseTest(TestSixcBase):
def setup_method(self):
TestSixcBase.createDiffcalcAndScannables(self, SixCircleGeometry)
self.hklverbose = Hkl('hkl', self.sixc, self.dc, ('Bout'))
self.orient()
def orient(self):
self.dc.newub('From DDIF')
self.dc.setlat('cubic', 1, 1, 1)
self.en(12.39842 / 1)
self.dc.setu([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
self.dc.hklmode(20) # zaxis, bisecting
self.dc.sigtau(0, 0)
def checkHKL(self, hkl, adgocp=None, betaout=None, nu=None):
self.hklverbose.asynchronousMoveTo(hkl)
aneq_(self.sixc(), list(adgocp), 3)
aneq_(self.hklverbose(), (hkl[0], hkl[1], hkl[2], betaout), 3)
def testHKL_001(self):
self.checkHKL([0, 0.0000001, 1], [30, 0, 60, 90, 0, 0], betaout=30, nu=0)
def testHKL_010(self):
self.checkHKL([0, 1, 0], [0, 60, 0, 120, 0, 0], betaout=0, nu=0)
def testHKL_011(self):
self.checkHKL([0, 1, 1], [30, 54.7356, 90, 125.2644, 0, 0],
betaout=30, nu=-54.7356)
def testHKL_100(self):
self.checkHKL([1, 0, 0], [0, 60, 0, 30, 0, 0], betaout=0, nu=0)
def testHKL_101(self):
self.checkHKL([1, 0, 1], [30, 54.7356, 90, 35.2644, 0, 0],
betaout=30, nu=-54.7356)
def testHKL_110(self):
#TODO: Modify test to ask that in this case gamma is left unmoved
self.checkHKL([1, 1, 0], [0, 90, 0, 90, 0, 0], betaout=0, nu=0)
def testHKL_1_1_0001(self):
self.checkHKL([1, 1, .0001], [0.0029, 89.9971, 90.0058, 90., 0, 0],
betaout=0.0029, nu=89.9971)
def testHKL_111(self):
self.checkHKL([1, 1, 1], [30, 54.7356, 150, 99.7356, 0, 0],
betaout=30, nu=54.7356)
def testHKL_11_0_0(self):
self.checkHKL([1.1, 0, 0], [0, 66.7340, 0., 33.3670, 0, 0],
betaout=0, nu=0)
def testHKL_09_0_0(self):
self.checkHKL([.9, 0, 0], [0, 53.4874, 0, 26.7437, 0, 0],
betaout=0, nu=0)
def testHKL_07_08_08(self):
self.checkHKL([.7, .8, .8], [23.5782, 59.9980, 76.7037, 84.2591, 0, 0],
betaout=23.5782, nu=-49.1014)
def testHKL_07_08_09(self):
self.checkHKL([.7, .8, .9], [26.7437, 58.6754, 86.6919, 85.3391, 0, 0],
betaout=26.7437, nu=-55.8910)
def testHKL_07_08_1(self):
self.checkHKL([.7, .8, 1], [30, 57.0626, 96.8659, 86.6739, 0, 0],
betaout=30, nu=-63.0210)
class ZAxisGammaOnBaseIncludingNuRotationTest(ZAxisGammaOnBaseTest):
def setup_method(self):
ZAxisGammaOnBaseTest.setup_method(self)
self.nu = DummyPD('nu')
self.sixc.slaveScannableDriver = NuDriverForSixCirclePlugin(self.nu)
class SixcGammaOnBaseTest(TestSixcBase):
def setup_method(self):
TestSixcBase.createDiffcalcAndScannables(self, SixCircleGeometry)
self.hklverbose = Hkl('hkl', self.sixc, self.dc, ('Bout'))
self.orient()
def orient(self):
self.dc.newub('From DDIF')
self.dc.setlat('cubic', 1, 1, 1)
self.en(12.39842 / 1)
self.dc.setu([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
self.dc.sigtau(0, 0)
def testToFigureOut101and011(self):
self.hkl([1, 0, 1])
print "101: ", self.sixc()
self.hkl([0, 1, 1])
print "011: ", self.sixc()
print "**"
def testOrientation(self):
self.dc.newub('cubic')
self.dc.setlat('cubic', 1, 1, 1)
self.en(39842 / 1)
self.dc.sigtau(0, 0)
self.sixc([0, 90, 0, 45, 45, 0])
self.dc.addref([1, 0, 1])
self.sixc([0, 90, 0, 45, 45, 90])
self.dc.addref([0, 1, 1])
self.dc.checkub()
res = self.dc.ubcalc.U
des = matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
mneq_(res, des, 4)
# print "***"
# self.dc.dc()
print "***"
self.dc.showref()
print "***"
self.dc.hklmode()
print "***"
class FiveCircleTest(object):
def setup_method(self):
self.en = DummyPD('en')
dummy = createDummyAxes(['alpha', 'delta', 'omega', 'chi', 'phi'])
group = ScannableGroup('fivecgrp', dummy)
self.fivec = DiffractometerScannableGroup('fivec', None, group)
settings.hardware = ScannableHardwareAdapter(self.fivec, self.en)
settings.geometry = Fivec()
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.dc import dcvlieg as dc
reload(dc)
self.dc = dc
self.fivec.diffcalc = self.dc
self.hkl = Hkl('hkl', self.fivec, self.dc)
self.hklverbose = Hkl('hkl', self.fivec, self.dc,
('theta', '2theta', 'Bin', 'Bout', 'azimuth'))
self.orient()
def orient(self):
self.dc.newub('b16_270608')
self.dc.setlat('xtal', 3.8401, 3.8401, 5.43072)
self.en(12.39842 / 1.24)
self.fivec([5.000, 22.790, 1.552, 22.400, 14.255])
self.dc.addref([1, 0, 1.0628])
self.fivec([5.000, 22.790, 4.575, 24.275, 101.320])
self.dc.addref([0, 1, 1.0628])
self.dc.checkub()
def testSetGammaFails(self):
self.assertRaises(
DiffcalcException, self.dc.setpar, 'gamma', 9999)
def test1(self):
self.dc.hklmode(1)
self.dc.setpar('alpha', 0)
self.hkl([.7, .9, 1.3])
aneq_((0., 27.3557, 13.6779, 37.7746, 53.9654), self.fivec(), 4)
def test2(self):
self.dc.hklmode(1)
self.dc.setpar('alpha', 5)
self.hkl([.7, .9, 1.3])
aneq_((5., 26.9296, 8.4916, 27.2563, 59.5855), self.fivec(), 4)
class FourCircleTest(TestFourcBase):
def setup_method(self):
TestFourcBase.createDiffcalcAndScannables(self)
self.hklverbose = Hkl('hkl', self.fourc, self.dc,
('theta', '2theta', 'Bin', 'Bout', 'azimuth'))
self.orient()
def orient(self):
self.dc.newub('fromDiffcalcItself')
# This dataset generated by diffcalc code itself
# (not a proper test of code guts)
self.dc.setlat('xtal', 3.8401, 3.8401, 5.43072)
self.en(12.39842 / 1.24)
self.fourc([22.790, 1.552, 22.400, 14.255])
self.dc.addref([1, 0, 1.0628])
self.fourc([22.790, 4.575, 24.275, 101.320])
self.dc.addref([0, 1, 1.0628])
self.dc.checkub()
def testSetGammaFails(self):
self.assertRaises(
DiffcalcException, self.dc.setpar, 'gamma', 9999)
def test1(self):
self.dc.hklmode(1)
self.hkl([.7, .9, 1.3])
aneq_((27.3557325339904, 13.67786626699521, 23.481729970652825,
47.81491152277463), self.fourc(), 4)
class FourCircleWithcubic(TestFourcBase):
def setup_method(self):
TestFourcBase.createDiffcalcAndScannables(self)
self.hklverbose = Hkl('hkl', self.fourc, self.dc,
('theta', '2theta', 'Bin', 'Bout', 'azimuth'))
self.orient()
def setUp3(self):
TestFourcBase.createDiffcalcAndScannables(self)
self.hklverbose = Hkl('hkl', self.fourc, self.dc,
('theta', '2theta', 'Bin', 'Bout', 'azimuth'))
self.orient()
def orient(self):
self.dc.newub('cubic')
# This dataset generated by diffcalc code itself
# (not a proper test of code guts)
self.dc.setlat('cube', 1, 1, 1, 90, 90, 90)
self.en(12.39842)
self.fourc([60, 30, 0, 0])
self.dc.addref([1, 0, 0])
self.fourc([60, 30, 90, 0])
self.dc.addref([0, 0, 1])
self.dc.checkub()
def testHkl100(self):
self.dc.hklmode(1)
self.dc.sigtau(0, 0)
self.hkl([1, 0, 0])
aneq_(self.fourc(), (60, -60, 0, 90), 4)
#dif gives
#h k l alpha delta gamma omega chi phi
#1.000 0.000 0.000 0. 60. 0.0000 -60.0000 0.0000 90.0000
#beta_in beta_out rho eta twotheta
#-0.0000 0.0000 0.0000 0.0000 60.0000
def testHkl001(self):
self.dc.hklmode(1)
self.dc.sigtau(0, 0)
self.hkl([0, 0, 1])
aneq_(self.fourc()[0:3], (60, 30, 90), 4) # (phi is undetermined here)
#h k l alpha delta gamma omega ch phi
#0.000 0.000 1.000 0.0000 60. 0. 30.0000 90.0000 45.0000
# beta_in beta_out rho eta twotheta
# 30.0000 30.0000 60.0000 0.5236 60.0000
def testHkl110(self):
self.dc.hklmode(1)
self.dc.sigtau(0, 0)
self.hkl([1, 1, 0])
# TODO: No check here!
# h k l alpha delta gamma omega chi phi
#1.000 1.000 0.000 0. 90. 0.0000 135.0000 0.0000 -45.0000
# beta_in beta_out rho eta twotheta
# 0.0000 -0.0000 -0.0000 0.0000 90.0000
class FourCircleForI06Experiment(TestFourcBase):
def setup_method(self):
TestFourcBase.createDiffcalcAndScannables(self)
self.hklverbose = Hkl('hkl', self.fourc, self.dc,
('theta', '2theta', 'Bin', 'Bout', 'azimuth'))
self.orient()
def orient(self):
self.en(1.650)
self.dc.newub('cubic')
self.dc.setlat('xtal', 5.34, 5.34, 13.2, 90, 90, 90)
self.dc.setu([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
self.dc.hklmode(5)
self.dc.setpar('phi', -90)
self.dc.setcut('phi', -180) # @UndefinedVariable
def testHkl001(self):
self.hkl([0, 0, 1])
aneq_(self.fourc(), [33.07329403295449, 16.536647016477247, 90., -90.],
note="[delta, omega, chi, phi]")
# def testHkl100(self):
# self.pos_hkl(1, 0, 0)
# aneq_(self.pos_fourc(),
# [89.42926563609406, 134.71463281804702, 90.0, -90.0],
# note="[delta, omega, chi, phi]")
def testHkl101(self):
self.hkl([1, 0, 1])
aneq_(self.fourc(), [98.74666191021282, 117.347760720783, 90., -90.],
note="[delta, omega, chi, phi]")

View File

@@ -0,0 +1,72 @@
from math import pi
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from test.tools import mneq_, aneq_, assert_dict_almost_equal
import diffcalc.util # @UnusedImport
from diffcalc.hardware import DummyHardwareAdapter
from diffcalc.hkl.you.geometry import FourCircle
from diffcalc.ub.persistence import UbCalculationNonPersister
from diffcalc import settings
diffcalc.util.DEBUG = True
wl = 1
en = 12.39842 / wl
angles = [60, 30, 0, 0]
param = {'tau': 90, 'psi': 90, 'beta': 0, 'alpha': 0, 'naz': 0, 'qaz': 90, 'theta': 30}
dc = None
def setup_module():
global dc
axes = 'delta', 'eta', 'chi', 'phi'
settings.hardware = DummyHardwareAdapter(axes)
settings.geometry = FourCircle()
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.dc import dcyou as dc
reload(dc)
dc.newub('test')
dc.setlat('cubic', 1, 1, 1, 90, 90, 90)
dc.addref([1, 0, 0], [60, 30, 0, 0], en, 'ref1')
dc.addref([0, 1, 0], [60, 30, 0, 90], en, 'ref2')
def test_orientation_phase():
# assumes reflections added were ideal (with no mis-mount)
dc.ub()
dc.checkub()
dc.showref()
U = matrix('1 0 0; 0 1 0; 0 0 1')
UB = U * 2 * pi
mneq_(dc._ub.ubcalc.U, U)
mneq_(dc._ub.ubcalc.UB, UB)
def test_angles_to_hkl_bypassing_hardware_plugin():
hkl_calc, param_calc = dc.angles_to_hkl(angles, en)
aneq_(hkl_calc, [1, 0, 0])
assert_dict_almost_equal(param_calc, param)
def test_hkl_to_angles_bypassing_hardware_plugin():
dc.con('a_eq_b')
h, k, l = [1, 0, 0]
angles_calc, param_calc = dc.hkl_to_angles(h, k, l, en)
aneq_(angles_calc, angles)
assert_dict_almost_equal(param_calc, param)
def test_angles_to_hkl():
hkl_calc, param_calc = dc.angles_to_hkl(angles, en)
aneq_(hkl_calc, [1, 0, 0])
assert_dict_almost_equal(param_calc, param)
def test_hkl_to_angles():
dc.con('a_eq_b')
h, k, l = [1, 0, 0]
angles_calc, param_calc = dc.hkl_to_angles(h, k, l, en)
aneq_(angles_calc, angles)
assert_dict_almost_equal(param_calc, param)

View File

@@ -0,0 +1,95 @@
from math import pi
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from test.tools import mneq_, aneq_, dneq_
import diffcalc.util # @UnusedImport
from diffcalc.hardware import DummyHardwareAdapter
from diffcalc.hkl.you.geometry import SixCircle
from diffcalc.ub.persistence import UbCalculationNonPersister
from diffcalc.hkl.you.constraints import NUNAME
from diffcalc import settings
diffcalc.util.DEBUG = True
wl = 1
en = 12.39842 / wl
angles = [0, 60, 0, 30, 0, 0]
param = {'tau': 90, 'psi': 90, 'beta': 0, 'alpha': 0, 'naz': 0, 'qaz': 90, 'theta': 30}
dc=None
def setup_module():
global dc
axes = 'mu', 'delta', NUNAME, 'eta', 'chi', 'phi'
settings.hardware = DummyHardwareAdapter(axes)
settings.geometry = SixCircle()
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.dc import dcyou as dc
reload(dc)
dc.newub('test')
dc.setlat('cubic', 1, 1, 1, 90, 90, 90)
dc.addref([1, 0, 0], [0, 60, 0, 30, 0, 0], en, 'ref1')
dc.addref([0, 1, 0], [0, 60, 0, 30, 0, 90], en, 'ref2')
def test_orientation_phase():
# assumes reflections added were ideal (with no mis-mount)
dc.ub()
dc.checkub()
dc.showref()
U = matrix('1 0 0; 0 1 0; 0 0 1')
UB = U * 2 * pi
mneq_(dc._ub.ubcalc.U, U)
mneq_(dc._ub.ubcalc.UB, UB)
def test_angles_to_hkl_bypassing_hardware_plugin():
hkl_calc, param_calc = dc.angles_to_hkl(angles, en)
aneq_(hkl_calc, [1, 0, 0])
dneq_(param_calc, param)
def test_hkl_to_angles_bypassing_hardware_plugin():
dc.con('a_eq_b')
dc.con('mu', 0)
dc.con(NUNAME, 0)
h, k, l = [1, 0, 0]
angles_calc, param_calc = dc.hkl_to_angles(h, k, l, en)
aneq_(angles_calc, angles)
dneq_(param_calc, param)
def test_angles_to_hkl():
hkl_calc, param_calc = dc.angles_to_hkl(angles)
aneq_(hkl_calc, [1, 0, 0])
dneq_(param_calc, param)
def test_hkl_to_angles():
dc.con('a_eq_b')
dc.con('mu', 0)
dc.con(NUNAME, 0)
h, k, l = [1, 0, 0]
angles_calc, param_calc = dc.hkl_to_angles(h, k, l)
aneq_(angles_calc, angles)
dneq_(param_calc, param)
def test_allhkl():
diffcalc.util.DEBUG = True
dc.con('eta', 0, 'chi', 0, 'phi', 0)
dc.allhkl([.1, 0, .01], 1)
# def test_ub_help_visually(self):
# print "-" * 80 + "\nub:"
# print format_command_help(self.dc.ub.commands)
#
# def test_hkl_help_visually(self):
# print "-" * 80 + "\nhkl:"
# print format_command_help(self.dc.hkl.commands)

View File

@@ -0,0 +1,138 @@
###
# 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/>.
###
import unittest
import diffcalc.gdasupport.minigda.command
from diffcalc.gdasupport.minigda.command import Pos, Scan, ScanDataPrinter
from diffcalc.gdasupport.minigda.scannable import \
MultiInputExtraFieldsDummyScannable, SingleFieldDummyScannable
class BadSingleFieldDummyScannable(SingleFieldDummyScannable):
def getPosition(self):
raise Exception("Problem")
class NoneReturningSingleFieldDummyScannable(SingleFieldDummyScannable):
def getPosition(self):
return None
class TestPos(object):
def setup_method(self):
self.dummyMainNamespace = namespace = {}
namespace['notAScannable'] = 3.124
namespace['scnA'] = SingleFieldDummyScannable('scnA')
namespace['scnB'] = SingleFieldDummyScannable('scnB')
namespace['scnC'] = SingleFieldDummyScannable('scnC')
namespace['scnD'] = SingleFieldDummyScannable('scnD')
namespace['scnNone'] = \
NoneReturningSingleFieldDummyScannable('scnNone')
namespace['scnBad'] = BadSingleFieldDummyScannable('scnBad')
diffcalc.gdasupport.minigda.command.ROOT_NAMESPACE_DICT = \
self.dummyMainNamespace
self.pos = Pos()
def testPosReturningReportWithRead(self):
scnA = self.dummyMainNamespace['scnA']
assert self.pos.posReturningReport(scnA) == 'scnA: 0.0000'
def testPosReturningReportWithMove(self):
scnA = self.dummyMainNamespace['scnA']
assert self.pos.posReturningReport(scnA, 1.123) == 'scnA: 1.1230'
def test__call__(self):
scnA = self.dummyMainNamespace['scnA']
self.pos.__call__(scnA)
self.pos.__call__(scnA, 4.321)
print "*"
self.pos.__call__()
print "*"
def testPosReturningReportWithMultiFieldScannables(self):
scn = MultiInputExtraFieldsDummyScannable('mie', ['i1', 'i2'], ['e1'])
assert (self.pos.posReturningReport(scn)
== 'mie: i1: 0.0000 i2: 0.0000 e1: 100.0000 ')
def testPosReturningReportWithBadScannable(self):
scnBad = self.dummyMainNamespace['scnBad']
assert self.pos.posReturningReport(scnBad) == "scnBad: Error: Problem"
assert (self.pos.posReturningReport(scnBad, 4.321)
== "scnBad: Error: Problem")
def testPosReturningReportWithNoneReturningScannable(self):
scnNone = self.dummyMainNamespace['scnNone']
assert self.pos.posReturningReport(scnNone) == "scnNone: ---"
assert self.pos.posReturningReport(scnNone, 4.321) == "scnNone: ---"
class TestScan(object):
def setup_method(self):
self.scan = Scan([ScanDataPrinter()])
def test__parseScanArgsIntoScannableArgGroups(self):
scnA = SingleFieldDummyScannable('scnA')
scnB = SingleFieldDummyScannable('scnB')
scnC = SingleFieldDummyScannable('scnC')
scnD = SingleFieldDummyScannable('scnD')
scanargs = (scnA, 1, 2, 3, scnB, [4, 5, 6], scnC, scnD, 1.123456)
r = self.scan._parseScanArgsIntoScannableArgGroups(scanargs)
result = [r[0].scannable, r[0].args, r[1].scannable, r[1].args,
r[2].scannable, r[2].args, r[3].scannable, r[3].args]
desired = [scnA, [1, 2, 3], scnB, [[4, 5, 6], ], scnC, list(), scnD,
[1.123456]]
assert result == desired
def test__reorderGroupsAccordingToLevel(self):
scn4 = SingleFieldDummyScannable('scn4')
scn4.setLevel(4)
scn5a = SingleFieldDummyScannable('scn5a')
scn5a.setLevel(5)
scn5b = SingleFieldDummyScannable('scn5b')
scn5b.setLevel(5)
scn6 = SingleFieldDummyScannable('scn6')
scn6.setLevel(6)
def t(scanargs):
groups = self.scan._parseScanArgsIntoScannableArgGroups(scanargs)
r = self.scan._reorderInnerGroupsAccordingToLevel(groups)
return [r[0].scannable, r[1].scannable, r[2].scannable,
r[3].scannable]
assert (t((scn5a, 1, 2, 3, scn6, 1, scn5b, scn4))
== [scn5a, scn4, scn5b, scn6])
assert (t((scn5a, 1, 3, scn6, 1, scn5b, scn4))
== [scn4, scn5a, scn5b, scn6])
def test__Frange(self):
assert self.scan._frange(1, 1.3, .1) == [1.0, 1.1, 1.2, 1.3]
def test__Call__(self):
scn4 = SingleFieldDummyScannable('scn4')
scn4.setLevel(4)
scn5a = SingleFieldDummyScannable('scn5a')
scn5a.setLevel(5)
scn5b = SingleFieldDummyScannable('scn5b')
scn5b.setLevel(5)
scn6 = SingleFieldDummyScannable('scn6')
scn6.setLevel(6)
self.scan.__call__(scn5a, 1, 3, 1, scn6, 1, scn5b, scn4)

View File

@@ -0,0 +1,83 @@
###
# 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/>.
###
import unittest
try:
from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
except ImportError:
from diffcalc.gdasupport.minigda.scannable import DummyPD
from diffcalc.gdasupport.scannable.mock import MockMotor
from diffcalc.gdasupport.minigda.scannable import \
SingleFieldDummyScannable
from diffcalc.gdasupport.minigda.scannable import Scannable
from diffcalc.gdasupport.scannable.base import ScannableGroup
class TestScannable(object):
def setup_method(self):
self.scannable = Scannable()
def testSomethingUnrelated(self):
a = SingleFieldDummyScannable('a')
print isinstance(a, Scannable)
def createDummyAxes(names):
result = []
for name in names:
result.append(DummyPD(name))
return result
class TestScannableGroup(object):
def setup_method(self):
self.a = MockMotor('a')
self.b = MockMotor('bbb')
self.c = MockMotor('c')
self.sg = ScannableGroup('abc', (self.a, self.b, self.c))
def testInit(self):
assert list(self.sg.getInputNames()) == ['a', 'bbb', 'c']
assert self.sg.getPosition() == [0.0, 0.0, 0.0]
def testAsynchronousMoveTo(self):
self.sg.asynchronousMoveTo([1, 2.0, 3])
assert self.sg.getPosition() == [1.0, 2.0, 3.0]
def testAsynchronousMoveToWithNones(self):
self.sg.asynchronousMoveTo([1.0, 2.0, 3.0])
self.sg.asynchronousMoveTo([None, None, 3.2])
assert self.sg.getPosition() == [1.0, 2.0, 3.2]
def testGetPosition(self):
# implicitely tested above
pass
def testIsBusy(self):
assert not self.sg.isBusy()
self.sg.asynchronousMoveTo([1.0, 2.0, 3.0])
assert self.sg.isBusy()
self.b.makeNotBusy()
assert self.sg.isBusy()
self.a.makeNotBusy()
self.c.makeNotBusy()
assert not self.sg.isBusy()

View File

@@ -0,0 +1,55 @@
###
# 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/>.
###
class MockParameterManager:
def __init__(self):
self.params = {}
def set_constraint(self, name, value):
self.params[name] = value
def get_constraint(self, name):
return self.params[name]
class MockDiffcalc:
def __init__(self, numberAngles):
self.numberAngles = numberAngles
self.parameter_manager = MockParameterManager()
def hkl_to_angles(self, h, k, l):
params = {}
params['theta'] = 1.
params['2theta'] = 12.
params['Bin'] = 123.
params['Bout'] = 1234.
params['azimuth'] = 12345.
return ([h] * self.numberAngles, params)
def angles_to_hkl(self, pos):
if len(pos) != self.numberAngles: raise ValueError
params = {}
params['theta'] = 1.
params['2theta'] = 12.
params['Bin'] = 123.
params['Bout'] = 1234.
params['azimuth'] = 12345.
return ([pos[0]] * 3, params)

View File

@@ -0,0 +1,169 @@
###
# 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/>.
###
import unittest
from mock import Mock
from diffcalc.gdasupport.scannable.slave_driver import SlaveScannableDriver
from diffcalc.gdasupport.scannable.diffractometer import \
DiffractometerScannableGroup
from diffcalc.gdasupport.scannable.mock import MockMotor
from test.diffcalc.gdasupport.scannable.mockdiffcalc import MockDiffcalc
try:
from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
except ImportError:
from diffcalc.gdasupport.minigda.scannable import DummyPD
try:
from gda.device.scannable.scannablegroup import ScannableGroup
except ImportError:
from diffcalc.gdasupport.minigda.scannable import ScannableGroup
def createDummyAxes(names):
result = []
for name in names:
result.append(DummyPD(name))
return result
class MockSlaveScannableDriver(object):
def __init__(self):
self.busy = False
self.lastPosition = None
def isBusy(self):
return self.busy
def triggerAsynchronousMove(self, position):
self.lastPosition = position
def getPositions(self):
return 90, 91
class TestDiffractometerScannableGroup(object):
def setup_method(self):
self.a = MockMotor()
self.b = MockMotor()
self.c = MockMotor()
self.d = MockMotor()
self.e = MockMotor()
self.f = MockMotor()
self.grp = ScannableGroup(
'grp', [self.a, self.b, self.c, self.d, self.e, self.f])
self.grp.configure()
self.sg = DiffractometerScannableGroup(
'sixc', MockDiffcalc(6), self.grp)
def testInit(self):
assert list(self.sg.getPosition()) == [0., 0., 0., 0., 0., 0.]
def testAsynchronousMoveTo(self):
self.sg.asynchronousMoveTo([1, 2.0, 3, 4, 5, 6])
assert list(self.sg.getPosition()) == [1., 2., 3., 4., 5., 6.]
def testAsynchronousMoveToWithNones(self):
self.sg.asynchronousMoveTo([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
self.sg.asynchronousMoveTo([None, None, 3.2, None, 5.2, None])
assert list(self.sg.getPosition()) == [1., 2., 3.2, 4., 5.2, 6.]
def testGetPosition(self):
#implicitely tested above
pass
def testWhereMoveTo(self):
# just check for exceptions
print self.sg.simulateMoveTo((1.23, 2, 3, 4, 5, 6))
def testIsBusy(self):
assert not self.sg.isBusy()
self.sg.asynchronousMoveTo([1.0, 2.0, 3.0, 4, 5, 6])
assert self.sg.isBusy()
self.b.makeNotBusy()
assert self.sg.isBusy()
self.a.makeNotBusy()
self.c.makeNotBusy()
self.d.makeNotBusy()
self.e.makeNotBusy()
self.f.makeNotBusy()
assert not self.sg.isBusy()
def testRepr(self):
print self.sg.__repr__()
class TestDiffractometerScannableGroupWithSlave(
TestDiffractometerScannableGroup):
def setup_method(self):
TestDiffractometerScannableGroup.setup_method(self)
self.mock_driver = Mock(spec=SlaveScannableDriver)
self.mock_driver.getPositions.return_value = 90, 91
self.mock_driver.isBusy.return_value = False
self.mock_driver.getScannableNames.return_value = 'a', 'b'
self.sg.slave_driver = self.mock_driver
def test__init__(self):
sg = DiffractometerScannableGroup(
'sixc', MockDiffcalc(6), self.grp, self.mock_driver)
assert sg.slave_driver == self.mock_driver
def testAsynchronousMoveToWithNones(self):
self.sg.asynchronousMoveTo([1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
self.sg.asynchronousMoveTo([None, None, 3.2, None, 5.2, None])
assert list(self.sg.getPosition()) == [1., 2., 3.2, 4., 5.2, 6., 90, 91]
self.mock_driver.triggerAsynchronousMove.assert_called_with(
[None, None, 3.2, None, 5.2, None])
def testIsBusyWithSlave(self):
self.mock_driver.isBusy.return_value = True
assert self.sg.isBusy()
### overridden
def testInit(self):
assert list(self.sg.getPosition()) == [0., 0., 0., 0., 0., 0., 90, 91]
def testAsynchronousMoveTo(self):
self.sg.asynchronousMoveTo([1, 2.0, 3, 4, 5, 6])
assert list(self.sg.getPosition()) == [1., 2., 3., 4., 5., 6., 90, 91]
class TestDiffractometerScannableGroupWithFailingAngleCalculator(object):
def setup_method(self):
class BadMockAngleCalculator:
def angles_to_hkl(self, pos):
raise Exception("Problem")
dummy = createDummyAxes(['alpha', 'delta', 'gamma', 'omega', 'chi',
'phi'])
self.group = ScannableGroup('grp', dummy)
self.group.configure()
self.sg = DiffractometerScannableGroup(
'sixc', BadMockAngleCalculator(), self.group)
def testGetPosition(self):
self.sg.getPosition()
def testSimulateMoveTo(self):
assert (self.sg.simulateMoveTo([1., 2., 3., 4., 5., 6.])
== "Error: Problem")

View File

@@ -0,0 +1,222 @@
###
# 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/>.
###
import mock
import nose
import unittest
from diffcalc.gdasupport.scannable.diffractometer import \
DiffractometerScannableGroup
from diffcalc.gdasupport.scannable.hkl import Hkl
from test.diffcalc.gdasupport.scannable.mockdiffcalc import MockDiffcalc
import pytest
try:
from gda.device.scannable.scannablegroup import ScannableGroup
except ImportError:
from diffcalc.gdasupport.minigda.scannable import ScannableGroup
try:
from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
except ImportError:
from diffcalc.gdasupport.minigda.scannable import DummyPD
def createDummyAxes(names):
result = []
for name in names:
result.append(DummyPD(name))
return result
PARAM_DICT = {'theta': 1, '2theta': 12., 'Bin': 123., 'Bout': 1234.,
'azimuth': 12345}
class Popper:
def __init__(self, *items):
self.items = list(items)
def __call__(self, *args):
return self.items.pop(0)
class TestHkl(object):
def setup_method(self):
self.mock_dc_module = mock.Mock()
self.mockSixc = mock.Mock(spec=DiffractometerScannableGroup)
self.hkl = Hkl('hkl', self.mockSixc, self.mock_dc_module)
def testInit(self):
self.mock_dc_module.angles_to_hkl.return_value = ([1, 2, 3], PARAM_DICT)
assert self.hkl.getPosition() == [1, 2, 3]
def testAsynchronousMoveTo(self):
self.mock_dc_module.hkl_to_angles.return_value = ([6, 5, 4, 3, 2, 1],
None)
self.hkl.asynchronousMoveTo([1, 0, 1])
self.mock_dc_module.hkl_to_angles.assert_called_with(1, 0, 1)
self.mockSixc.asynchronousMoveTo.assert_called_with([6, 5, 4, 3, 2, 1])
def testGetPosition(self):
self.mockSixc.getPosition.return_value = [6, 5, 4, 3, 2, 1]
self.mock_dc_module.angles_to_hkl.return_value = ([1, 0, 1], PARAM_DICT)
assert self.hkl.getPosition() == [1, 0, 1]
self.mock_dc_module.angles_to_hkl.assert_called_with([6, 5, 4, 3, 2, 1])
def testAsynchronousMoveToWithNonesOutsideScan(self):
self.mockSixc.getPosition.return_value = [6, 5, 4, 3, 2, 1]
self.mock_dc_module.angles_to_hkl.return_value = ([1, 0, 1],
PARAM_DICT)
self.mock_dc_module.hkl_to_angles.return_value = ([12, 5, 4, 3, 2, 1],
PARAM_DICT) # <- 2,0,1
self.hkl.asynchronousMoveTo([2, 0, None])
self.mock_dc_module.angles_to_hkl.assert_called_with([6, 5, 4, 3, 2, 1])
self.mock_dc_module.hkl_to_angles.assert_called_with(2, 0, 1)
self.mockSixc.asynchronousMoveTo.assert_called_with(
[12, 5, 4, 3, 2, 1])
def testAsynchronousMoveToWithNonesInScan(self):
self.mockSixc.getPosition.return_value = [6, 5, 4, 3, 2, 1]
self.mock_dc_module.angles_to_hkl.return_value = ([1, 0, 1], PARAM_DICT)
self.hkl.atScanStart()
# should not be used:
self.mockSixc.getPosition.return_value = [6.1, 5.1, 4.1, 3.1, 2.1, 1.1]
self.mock_dc_module.hkl_to_angles.return_value = ([12, 5, 4, 3, 2, 1],
PARAM_DICT)
self.hkl.asynchronousMoveTo([2, 0, None])
# atScanStart:
self.mock_dc_module.angles_to_hkl.assert_called_with([6, 5, 4, 3, 2, 1])
self.mock_dc_module.hkl_to_angles.assert_called_with(2, 0, 1)
self.mockSixc.asynchronousMoveTo.assert_called_with(
[12, 5, 4, 3, 2, 1])
def testAsynchronousMoveToWithNonesInScanAfterCommandFailure(self):
# should be forgotten:
self.mockSixc.getPosition.return_value = [6, 5, 4, 3, 2, 1]
self.mock_dc_module.angles_to_hkl.return_value = ([1, 0, 1], PARAM_DICT)
self.hkl.atScanStart()
self.hkl.atCommandFailure()
self.mockSixc.getPosition.return_value = [6.1, 5.1, 4.1, 3.1, 2.1, 1.1]
self.mock_dc_module.hkl_to_angles.return_value = (
[12.1, 5.1, 4.1, 3.1, 2.1, 1.1], PARAM_DICT)
self.hkl.asynchronousMoveTo([2, 0, None])
self.mock_dc_module.angles_to_hkl.assert_called_with(
[6.1, 5.1, 4.1, 3.1, 2.1, 1.1])
self.mock_dc_module.hkl_to_angles.assert_called_with(2, 0, 1)
self.mockSixc.asynchronousMoveTo.assert_called_with(
[12.1, 5.1, 4.1, 3.1, 2.1, 1.1])
def testAsynchronousMoveToWithNonesInScanAfterAtScanEnd(self):
self.mockSixc.getPosition.return_value = [6, 5, 4, 3, 2, 1]
self.mock_dc_module.angles_to_hkl.return_value = ([1, 0, 1], PARAM_DICT)
self.hkl.atScanStart()
self.hkl.atScanEnd()
self.mockSixc.getPosition.return_value = [6.1, 5.1, 4.1, 3.1, 2.1, 1.1]
self.mock_dc_module.hkl_to_angles.return_value = (
[12.1, 5.1, 4.1, 3.1, 2.1, 1.1], PARAM_DICT)
self.hkl.asynchronousMoveTo([2, 0, None])
self.mock_dc_module.angles_to_hkl.assert_called_with(
[6.1, 5.1, 4.1, 3.1, 2.1, 1.1])
self.mock_dc_module.hkl_to_angles.assert_called_with(2, 0, 1)
self.mockSixc.asynchronousMoveTo.assert_called_with(
[12.1, 5.1, 4.1, 3.1, 2.1, 1.1])
def testIsBusy(self):
self.mockSixc.isBusy.return_value = False
assert not self.hkl.isBusy()
self.mockSixc.isBusy.assert_called()
def testWaitWhileBusy(self):
self.hkl.waitWhileBusy()
self.mockSixc.waitWhileBusy.assert_called()
def testWhereMoveTo(self):
# just check for exceptions
self.mock_dc_module.hkl_to_angles.return_value = ([6, 5, 4, 3, 2, 1],
PARAM_DICT)
self.mockSixc.getName.return_value = 'sixc'
self.mockSixc.getInputNames.return_value = ['alpha', 'delta', 'gamma',
'omega', 'chi', 'phi']
print self.hkl.simulateMoveTo((1.23, 0, 0))
def testDisp(self):
print self.hkl.__repr__()
class TestHklReturningVirtualangles(TestHkl):
def setup_method(self):
TestHkl.setup_method(self)
self.hkl = Hkl('hkl', self.mockSixc, self.mock_dc_module,
['theta', '2theta', 'Bin', 'Bout', 'azimuth'])
def testInit(self):
self.mock_dc_module.angles_to_hkl.return_value = ([1, 0, 1], PARAM_DICT)
assert self.hkl.getPosition() == [1, 0, 1, 1, 12, 123, 1234, 12345]
def testGetPosition(self):
self.mockSixc.getPosition.return_value = [6, 5, 4, 3, 2, 1]
self.mock_dc_module.angles_to_hkl.return_value = ([1, 0, 1], PARAM_DICT)
assert self.hkl.getPosition() == [1, 0, 1, 1, 12, 123, 1234, 12345]
self.mock_dc_module.angles_to_hkl.assert_called_with([6, 5, 4, 3, 2, 1])
class TestHklWithFailingAngleCalculator(object):
def setup_method(self):
class BadMockAngleCalculator:
def angles_to_hkl(self, pos):
raise Exception("Problem in angles_to_hkl")
dummy = createDummyAxes(['alpha', 'delta', 'gamma', 'omega', 'chi',
'phi'])
self.group = ScannableGroup('grp', dummy)
self.SixCircleGammaOnArmGeometry = DiffractometerScannableGroup(
'SixCircleGammaOnArmGeometry', MockDiffcalc(6), self.group)
self.hkl = Hkl('hkl', self.SixCircleGammaOnArmGeometry,
BadMockAngleCalculator())
def testGetPosition(self):
with pytest.raises(Exception):
self.hkl.getPosition(None)
def test__repr__(self):
assert self.hkl.__repr__() == "<hkl: Problem in angles_to_hkl>"
def test__str__(self):
assert self.hkl.__str__() == "<hkl: Problem in angles_to_hkl>"
def testComponentGetPosition(self):
with pytest.raises(Exception):
self.hkl.h.getPosition(None)
def testComponent__repr__(self):
raise nose.SkipTest()
assert self.hkl.h.__repr__() == "<h: Problem in angles_to_hkl>"
def testComponent__str__(self):
raise nose.SkipTest()
assert self.hkl.h.__str__() == "<h: Problem in angles_to_hkl>"

View File

@@ -0,0 +1,38 @@
###
# 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/>.
###
import unittest
from diffcalc.gdasupport.scannable.parameter import \
DiffractionCalculatorParameter
from test.diffcalc.gdasupport.scannable.mockdiffcalc import \
MockParameterManager
class TestDiffractionCalculatorParameter(object):
def setup_method(self):
self.dcp = DiffractionCalculatorParameter('dcp', 'betain',
MockParameterManager())
def testAsynchronousMoveToAndGetPosition(self):
self.dcp.asynchronousMoveTo(12.3)
assert self.dcp.getPosition() == 12.3
def testIsBusy(self):
assert not self.dcp.isBusy()

View File

@@ -0,0 +1,102 @@
###
# 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
import unittest
from pytest import approx
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.gdasupport.scannable.simulation import SimulatedCrystalCounter, \
Gaussian
from diffcalc.hkl.vlieg.geometry import Fourc
from diffcalc.util import nearlyEqual
from test.tools import mneq_
class MockScannable(object):
def __init__(self):
self.pos = None
def getPosition(self):
return self.pos
class MockEquation(object):
def __call__(self, dh, dk, dl):
self.dHkl = dh, dk, dl
return 1
class TestSimulatedCrystalCounter(object):
def setup_method(self):
self.diff = MockScannable()
self.wl = MockScannable()
self.wl.pos = 1.
self.eq = MockEquation()
self.scc = SimulatedCrystalCounter('det', self.diff, Fourc(), self.wl,
self.eq)
def testInit(self):
assert list(self.scc.getInputNames()) == ['det_count']
assert list(self.scc.getExtraNames()) == []
assert self.scc.chiMissmount == 0.
assert self.scc.phiMissmount == 0.
def testCalcUB(self):
UB = matrix([[2 * pi, 0, 0], [0, 2 * pi, 0], [0, 0, 2 * pi]])
mneq_(self.scc.UB, UB)
def testGetHkl(self):
self.diff.pos = [60, 30, 0, 0]
hkl = self.scc.getHkl()
assert hkl == approx((1, 0, 0))
self.diff.pos = [60, 31, 0, 0]
hkl = self.scc.getHkl()
assert hkl == approx((0.999847695156391, 0.017452406437283574, 0))
def testGetPosition(self):
self.diff.pos = [60, 30, 0, 0]
self.scc.asynchronousMoveTo(2)
count = self.scc.getPosition()
assert self.eq.dHkl == approx((0, 0, 0))
assert count == 2
self.diff.pos = [60, 31, 0, 0]
count = self.scc.getPosition()
dHkl = (0.999847695156391 - 1, .017452406437283574, 0)
assert self.eq.dHkl == approx(dHkl)
assert count == 2
def test__repr__(self):
self.diff.pos = [60, 30, 0, 0]
print self.scc.__repr__()
class TestGaussianEquation(object):
def setup_method(self):
self.eq = Gaussian(1.)
def test__call__(self):
assert self.eq(0, 0, 0) == 0.3989422804014327

View File

@@ -0,0 +1,40 @@
###
# 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/>.
###
import unittest
from diffcalc.gdasupport.scannable.wavelength import Wavelength
try:
from gdascripts.pd.dummy_pds import DummyPD
except ImportError:
from diffcalc.gdasupport.minigda.scannable import DummyPD
class TestWavelength(object):
def setup_method(self):
self.en = DummyPD('en')
self.wl = Wavelength('wl', self.en)
def testIt(self):
self.en.asynchronousMoveTo(12.39842)
assert self.wl.getPosition() == 1
self.wl.asynchronousMoveTo(1.)
assert self.wl.getPosition() == 1.
assert self.en.getPosition() == 12.39842

View File

@@ -0,0 +1,180 @@
###
# 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 nose.tools import eq_, raises # @UnresolvedImport
from nose.plugins.skip import Skip, SkipTest # @UnresolvedImport
from diffcalc.hardware import ScannableHardwareAdapter
from diffcalc.gdasupport.minigda.scannable import SingleFieldDummyScannable,\
ScannableGroup
from diffcalc.hkl.you.geometry import SixCircle
from diffcalc.ub.persistence import UbCalculationNonPersister
import diffcalc.util # @UnusedImport
try:
from numpy import matrix
except ImportError:
from numjy import matrix
import diffcalc.gdasupport.minigda.command
from test.tools import mneq_
from diffcalc import settings
import diffcalc.hkl.you.calc
diffcalc.gdasupport.minigda.command.ROOT_NAMESPACE_DICT = globals()
pos = diffcalc.gdasupport.minigda.command.Pos()
en = SingleFieldDummyScannable('en') # keV
mu = SingleFieldDummyScannable('mu')
delta = SingleFieldDummyScannable('delta')
gam = SingleFieldDummyScannable('gam')
eta = SingleFieldDummyScannable('eta')
chi = SingleFieldDummyScannable('chi')
phi = SingleFieldDummyScannable('phi')
sixc_group = ScannableGroup('sixc', (mu, delta, gam, eta, chi, phi))
ubcalc_no = 1
you = None
def setup_module():
global you
settings.hardware = ScannableHardwareAdapter(sixc_group, en)
settings.geometry = SixCircle()
settings.ubcalc_persister = UbCalculationNonPersister()
settings.axes_scannable_group = sixc_group
settings.energy_scannable = en
settings.ubcalc_strategy = diffcalc.hkl.you.calc.YouUbCalcStrategy()
settings.angles_to_hkl_function = diffcalc.hkl.you.calc.youAnglesToHkl
from diffcalc.gdasupport import you
reload(you)
"""
All the components used here are well tested. This integration test is
mainly to get output for the manual, to help when tweaking the user
interface, and to make sure it all works together.
"""
#
# PRINT_WITH_USER_SYNTAX = True
# for name, obj in self.objects.iteritems():
# if inspect.ismethod(obj):
# globals()[name] = wrap_command_to_print_calls(
# obj, PRINT_WITH_USER_SYNTAX)
# else:
# globals()[name] = obj
# pos = wrap_command_to_print_calls(Pos(globals()), PRINT_WITH_USER_SYNTAX)
def call_scannable(scn):
print '\n>>> %s' % scn.name
print scn.__str__()
def test_help_visually():
print "\n>>> help ub"
help(you.ub)
print "\n>>> help hkl"
help(you.hkl)
print "\n>>> help newub"
help(you.newub)
def test_axes():
call_scannable(you.sixc) # @UndefinedVariable
call_scannable(phi)
def test_with_no_ubcalc():
you.ub()
you.showref()
call_scannable(you.hkl)
def _orient():
global ubcalc_no
pos(you.wl, 1)
call_scannable(en) # like typing en (or en())
you.newub('test' + str(ubcalc_no))
ubcalc_no += 1
you.setlat('cubic', 1, 1, 1, 90, 90, 90)
you.c2th([1, 0, 0])
pos(you.sixc, [0, 60, 0, 30, 0, 0]) # @UndefinedVariable
you.addref([1, 0, 0], 'ref1')
you.c2th([0, 1, 0])
pos(phi, 90)
you.addref([0, 1, 0], 'ref2')
def test__orientation_phase():
_orient()
you.ub()
you.checkub()
you.showref()
U = matrix('1 0 0; 0 1 0; 0 0 1')
UB = U * 2 * pi
mneq_(you.ubcalc.U, U)
mneq_(you.ubcalc.UB, UB)
def test_hkl_read():
_orient()
call_scannable(you.hkl)
def test_help_con():
help(you.con)
def test_constraint_mgmt():
diffcalc.util.DEBUG = True
you.con() # TODO: show constrained values underneath
def test_hkl_move_no_constraints():
raise SkipTest()
_orient()
pos(you.hkl, [1, 0, 0])
def test_hkl_move_no_values():
raise SkipTest()
_orient()
you.con(mu)
you.con(gam)
you.con('a_eq_b')
you.con('a_eq_b')
pos(you.hkl, [1, 0, 0])
def test_hkl_move_okay():
_orient()
you.ub()
you.con(mu)
you.con(gam)
you.con('a_eq_b')
pos(you.mu_con, 0)
pos(you.gam_con, 0) # TODO: Fails with qaz=90
pos(you.hkl, [1, 1, 0]) # TODO: prints DEGENERATE. necessary?
call_scannable(you.sixc) # @UndefinedVariable
@raises(TypeError)
def test_usage_error_signature():
you.c2th('wrong arg', 'wrong arg')
@raises(TypeError)
def test_usage_error_inside():
you.setlat('wrong arg', 'wrong arg')

View File

@@ -0,0 +1,253 @@
###
# 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/>.
###
import random
import unittest
from math import pi
from mock import Mock
from test.tools import mneq_
import pytest
try:
from numpy import matrix
from numpy.linalg import norm
except ImportError:
from numjy import matrix
from numjy.linalg import norm
from diffcalc.hkl.vlieg.calc import VliegHklCalculator, \
_findOmegaAndChiToRotateHchiIntoQalpha, check
from diffcalc.hkl.vlieg.geometry import createVliegMatrices
from diffcalc.util import DiffcalcException
from test.diffcalc import scenarios
TORAD = pi / 180
TODEG = 180 / pi
def createMockUbcalc(UB):
ubcalc = Mock()
ubcalc.tau = 0
ubcalc.sigma = 0
ubcalc.UB = UB
ubcalc.n_phi = matrix([[0], [0], [1]])
return ubcalc
def createMockHardwareMonitor():
hardware = Mock()
hardware.get_position.return_value = (0.0, 0.0, 0.0)
hardware.get_axes_names.return_value = 'madeup', 'alpha', 'gamma'
return hardware
def createMockDiffractometerGeometry():
geometry = Mock()
geometry.parameter_fixed.return_value = False
geometry.supports_mode_group.return_value = True
geometry.fixed_parameters = {}
geometry.name = 'mock'
geometry.gamma_location = 'arm'
return geometry
class TestVliegCoreMathBits(object):
def setup_method(self):
self.many = [-91, -90, -89, -46, -45, -44, -1,
0, 1, 44, 45, 46, 89, 90, 91]
self.many = (self.many +
map(lambda x: x + 180, self.many) +
map(lambda x: x - 180, self.many))
def test_check(self):
check(True, 'Should not throw')
with pytest.raises(Exception):
check(False, 'string')
with pytest.raises(DiffcalcException):
check(False, DiffcalcException('dce'))
def acallable(toPrint=None):
if toPrint is None:
print "Not throwing exception"
else:
print toPrint
check(False, acallable)
check(False, acallable, 'this should be printed')
# TODO: Removed 2017-03-06, deprecated started code failing -- RobW.
def SKIP__findOmegaAndChiToRotateHchiIntoQalpha_WithIntegerValues(self):
for omega in self.many:
for chi in self.many:
print str(omega), ",", str(chi)
self.try__findOmegaAndChiToRotateHchiIntoQalpha(omega, chi)
def SKIP_findOmegaAndChiToRotateHchiIntoQalpha_WithRandomValues(self):
for _ in range(10):
for omega in self.many:
for chi in self.many:
omega = omega + random.uniform(-.001, .001)
chi = chi + random.uniform(-.001, .001)
self.try__findOmegaAndChiToRotateHchiIntoQalpha(omega, chi)
#print str(omega), ",", str(chi)
def test__findOmegaAndChiToRotateHchiIntoQalpha_WithTrickyOnes(self):
tricky_ones = [(-45., -180.), (45., -180.), (135., -180.), (2000, 0.),
(225., 0.), (225., -180.), (-225., 0.), (-225., 0.),
(-225., -180.), (-135., -180.), (89.998894, -44.999218)]
for omega, chi in tricky_ones:
self.try__findOmegaAndChiToRotateHchiIntoQalpha(omega, chi)
def try__findOmegaAndChiToRotateHchiIntoQalpha(self, omega, chi):
h_chi = matrix([[1], [1], [1]])
h_chi = h_chi * (1 / norm(h_chi))
[_, _, _, OMEGA, CHI, _] = createVliegMatrices(
None, None, None, omega * TORAD, chi * TORAD, None)
q_alpha = OMEGA * CHI * h_chi
try:
omega_calc, chi_calc = _findOmegaAndChiToRotateHchiIntoQalpha(
h_chi, q_alpha)
except ValueError, e:
raise ValueError(str(e) + "\n, resulting from test where omega:%f"
" chi%f" % (self.omega, self.chi))
[_, _, _, OMEGA, CHI, _] = createVliegMatrices(
None, None, None, omega_calc, chi_calc, None)
self.assertArraysNearlyEqual(OMEGA * CHI * h_chi, q_alpha, .000001,
"omega: %f chi:%f" % (omega, chi))
def assertArraysNearlyEqual(self, first, second, tolerance,
contextString=''):
"""
Fail if the norm of the difference between two arrays is greater than
the given tolerance.
"""
diff = first - second
if norm(diff) >= tolerance:
raise self.failureException(
'\n%r !=\n %r\ncontext: %s' %
(first.tolist(), second.tolist(), contextString))
class BaseTestHklCalculator():
def setSessionAndCalculation(self):
raise Exception("Abstract")
def setup_method(self):
self.ac = VliegHklCalculator(None, createMockDiffractometerGeometry(),
createMockHardwareMonitor())
self.ac.raiseExceptionsIfAnglesDoNotMapBackToHkl = True
self.setSessionAndCalculation()
def testAnglesToHkl(self):
mockUbcalc = createMockUbcalc(
matrix(self.sess.umatrix) * matrix(self.sess.bmatrix))
self.ac = VliegHklCalculator(mockUbcalc,
createMockDiffractometerGeometry(),
createMockHardwareMonitor())
self.ac.raiseExceptionsIfAnglesDoNotMapBackToHkl = True
# Check the two given reflections
(hklactual1, params) = self.ac.anglesToHkl(self.sess.ref1.pos,
self.sess.ref1.wavelength)
del params
(hklactual2, params) = self.ac.anglesToHkl(self.sess.ref2.pos,
self.sess.ref2.wavelength)
mneq_(matrix([hklactual1]), matrix([self.sess.ref1calchkl]), 3)
mneq_(matrix([hklactual2]), matrix([self.sess.ref2calchkl]), 3)
# ... znd in each calculation through the hkl/posiiont pairs
if self.calc:
for hkl, pos, param in zip(self.calc.hklList,
self.calc.posList,
self.calc.paramList):
(hkl_actual, params) = self.ac.anglesToHkl(pos,
self.calc.wavelength)
note = ("wrong hkl calcualted for scenario.name=%s, "
"calculation.tag=%s\n expected hkl=(%f,%f,%f)\n"
"calculated hkl=(%f,%f,%f)" %
(self.sess.name, self.calc.tag, hkl[0], hkl[1], hkl[2],
hkl_actual[0], hkl_actual[1], hkl_actual[2]))
mneq_(matrix([hkl_actual]), matrix([hkl]), 3, note=note)
print "***anglesToHkl***"
print "*** ", str(hkl), " ***"
print params
print param
def testHklToAngles(self):
if self.calc:
# Configure the angle calculator for this session scenario
UB = matrix(self.sess.umatrix) * matrix(self.sess.bmatrix)
mockUbcalc = createMockUbcalc(UB)
hw = createMockHardwareMonitor()
ac = VliegHklCalculator(mockUbcalc,
createMockDiffractometerGeometry(), hw)
ac.raiseExceptionsIfAnglesDoNotMapBackToHkl = True
## configure the angle calculator for this calculation
ac.mode_selector.setModeByName(self.calc.modeToTest)
# Set fixed parameters
if self.calc.modeToTest in ('4cBeq', '4cFixedw'):
#ac.setParameter('alpha', self.calc.alpha )
ac.parameter_manager.setTrackParameter('alpha', True)
hw.get_position.return_value = 888, self.calc.alpha, 999
ac.parameter_manager.set_constraint('gamma', self.calc.gamma)
# Test each hkl/position pair
for idx in range(len(self.calc.hklList)):
hkl = self.calc.hklList[idx]
expectedpos = self.calc.posList[idx]
(pos, params) = ac.hklToAngles(hkl[0], hkl[1], hkl[2],
self.calc.wavelength)
note = ("wrong positions calculated for TestScenario=%s, "
"AngleTestScenario=%s, hkl=(%f,%f,%f):\n"
" expected pos=%s;\n"
" returned pos=%s " %
(self.sess.name, self.calc.tag, hkl[0], hkl[1], hkl[2],
str(expectedpos), str(pos)))
assert pos.nearlyEquals(expectedpos, 0.01), note
print "*** hklToAngles ***"
print "*** ", str(hkl), " ***"
print params
try:
print self.calc.paramList[idx]
except IndexError: # Not always specified
pass
class TestVliegHklCalculatorSess1NoCalc(BaseTestHklCalculator):
def setSessionAndCalculation(self):
self.sess = scenarios.session1
self.calc = None
class TestVliegHklCalculatorSess2Calc0(BaseTestHklCalculator):
def setSessionAndCalculation(self):
self.sess = scenarios.session2
self.calc = scenarios.session2.calculations[0]
class TestVliegHklCalculatorSess3Calc0(
BaseTestHklCalculator):
def setSessionAndCalculation(self):
self.sess = scenarios.session3
self.calc = scenarios.session3.calculations[0]

View File

@@ -0,0 +1,92 @@
###
# 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/>.
###
import unittest
from diffcalc.hkl.vlieg.constraints import ModeSelector, VliegParameterManager
from diffcalc.util import DiffcalcException
from test.diffcalc.hkl.vlieg.test_calc import \
createMockHardwareMonitor, createMockDiffractometerGeometry
import pytest
class TestModeSelector(object):
def setup_method(self):
self.ms = ModeSelector(createMockDiffractometerGeometry(),
parameterManager=None)
self.pm = VliegParameterManager(createMockDiffractometerGeometry(),
None, self.ms)
self.ms.setParameterManager(self.pm)
def testSetModeByIndex(self):
self.ms.setModeByIndex(0)
assert self.ms.getMode().name == '4cFixedw'
self.ms.setModeByIndex(1)
assert self.ms.getMode().name == '4cBeq'
def testGetMode(self):
# tested implicetely by testSetmode
pass
def testShowAvailableModes(self):
print self.ms.reportAvailableModes()
class TestParameterManager(object):
def setup_method(self):
self.hw = createMockHardwareMonitor()
self.ms = ModeSelector(createMockDiffractometerGeometry())
self.pm = VliegParameterManager(createMockDiffractometerGeometry(),
self.hw, self.ms)
def testDefaultParameterValues(self):
assert self.pm.get_constraint('alpha') == 0
assert self.pm.get_constraint('gamma') == 0
with pytest.raises(DiffcalcException):
self.pm.get_constraint('not-a-parameter-name')
def testSetParameter(self):
self.pm.set_constraint('alpha', 10.1)
assert self.pm.get_constraint('alpha') == 10.1
def testSetTrackParameter_isParameterChecked(self):
assert not self.pm.isParameterTracked('alpha')
self.pm.set_constraint('alpha', 9)
self.pm.setTrackParameter('alpha', True)
assert self.pm.isParameterTracked('alpha') == True
with pytest.raises(DiffcalcException):
self.pm.set_constraint('alpha', 10)
self.hw.get_position.return_value = 888, 11, 999
assert self.pm.get_constraint('alpha') == 11
print self.pm.reportAllParameters()
print "**"
print self.ms.reportCurrentMode()
print self.pm.reportParametersUsedInCurrentMode()
self.pm.setTrackParameter('alpha', False)
assert not self.pm.isParameterTracked('alpha')
assert self.pm.get_constraint('alpha') == 11
self.hw.get_position.return_value = 888, 12, 999
assert self.pm.get_constraint('alpha') == 11
self.pm.set_constraint('alpha', 13)
assert self.pm.get_constraint('alpha') == 13

View File

@@ -0,0 +1,248 @@
###
# 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/>.
###
import random
import unittest
from math import pi
try:
from numpy import matrix
from numpy.linalg import norm
except ImportError:
from numjy import matrix
from numjy.linalg import norm
from test.tools import mneq_
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry, \
gammaOnArmToBase, gammaOnBaseToArm, SixCircleGeometry, Fivec, Fourc
from diffcalc.hkl.vlieg.geometry import createVliegMatrices
from diffcalc.hkl.vlieg.geometry import VliegPosition
from diffcalc.util import nearlyEqual, radiansEquivilant as radeq
random.seed() # uses time
TORAD = pi / 180
TODEG = 180 / pi
class TestSixCirclePlugin(object):
def setup_method(self):
self.geometry = SixCircleGeometry()
def testGetName(self):
assert self.geometry.name == "sixc"
def testPhysicalAnglesToInternalPosition(self):
pos = [0, 0, 0, 0, 0, 0]
expected = self.geometry.physical_angles_to_internal_position(pos)
assert VliegPosition(*pos) == expected
def testInternalPositionToPhysicalAngles(self):
pos = VliegPosition(0, 0, 0, 0, 0, 0)
result = self.geometry.internal_position_to_physical_angles(pos)
assert norm(matrix([pos.totuple()]) - matrix([result])) < 0.001
def testGammaOn(self):
assert self.geometry.gamma_location == 'base'
def testSupportsModeGroup(self):
assert self.geometry.supports_mode_group('fourc')
assert not self.geometry.supports_mode_group('made up mode')
def testGetFixedParameters(self):
self.geometry.fixed_parameters # check for exceptions
def isParamaterUnchangable(self):
assert not self.geometry.isParamaterUnchangable('made up parameter')
class TestSixCircleGammaOnArmGeometry(object):
def setup_method(self):
self.geometry = SixCircleGammaOnArmGeometry()
def testGetName(self):
assert self.geometry.name == "sixc_gamma_on_arm"
def testPhysicalAnglesToInternalPosition(self):
pos = [1, 2, 3, 4, 5, 6]
expected = self.geometry.physical_angles_to_internal_position(pos)
assert VliegPosition(*pos) == expected
def testInternalPositionToPhysicalAngles(self):
pos = VliegPosition(1, 2, 3, 4, 5, 6)
result = self.geometry.internal_position_to_physical_angles(pos)
mneq_(matrix([pos.totuple()]), matrix([result]), 4)
def testSupportsModeGroup(self):
assert self.geometry.supports_mode_group('fourc')
assert not self.geometry.supports_mode_group('made up mode')
def testGetFixedParameters(self):
self.geometry.fixed_parameters # check for exceptions
def isParamaterUnchangable(self):
assert not self.geometry.isParamaterUnchangable('made up parameter')
y_vector = matrix([[0], [1], [0]])
TOLERANCE = 1e-5
def armAnglesToLabVector(alpha, delta, gamma):
[ALPHA, DELTA, GAMMA, _, _, _] = createVliegMatrices(
alpha, delta, gamma, None, None, None)
return ALPHA * DELTA * GAMMA * y_vector
def baseAnglesToLabVector(delta, gamma):
[_, DELTA, GAMMA, _, _, _] = createVliegMatrices(
None, delta, gamma, None, None, None)
return GAMMA * DELTA * y_vector
def checkGammaOnArmToBase(alpha, deltaA, gammaA):
deltaB, gammaB = gammaOnArmToBase(deltaA, gammaA, alpha)
labA = armAnglesToLabVector(alpha, deltaA, gammaA)
labB = baseAnglesToLabVector(deltaB, gammaB)
if not nearlyEqual(labA, labB, TOLERANCE):
strLabA = ("[%f, %f, %f]" %
(labA.get(0, 0), labA.get(1, 0), labA.get(2, 0)))
strLabB = ("[%f, %f, %f]" %
(labB.get(0, 0), labB.get(1, 0), labB.get(2, 0)))
rep = ("alpha=%f, delta=%f, gamma=%f" %
(alpha * TODEG, deltaB * TODEG, gammaB * TODEG))
raise AssertionError('\nArm-->Base ' + rep + '\n' +
"arm (delta, gamma) = (%f,%f) <==>\t labA = %s\n" %
(deltaA * TODEG, gammaA * TODEG, strLabA) +
"base(delta, gamma) = (%f,%f) <==>\t labB = %s\n" %
(deltaB * TODEG, gammaB * TODEG, strLabB))
def checkBaseArmBaseReciprocity(alpha, delta_orig, gamma_orig):
(deltaB, gammaB) = (delta_orig, gamma_orig)
(deltaA, gammaA) = gammaOnBaseToArm(deltaB, gammaB, alpha)
(deltaB, gammaB) = gammaOnArmToBase(deltaA, gammaA, alpha)
if ((not radeq(deltaB, delta_orig, TOLERANCE)) or
(not radeq(gammaB, gamma_orig, TOLERANCE))):
s = "\nBase-Arm-Base reciprocity\n"
s += 'alpha=%f\n' % (alpha * TODEG,)
s += (' (deltaB, gammaB) = (%f, %f)\n' %
(delta_orig * TODEG, gamma_orig * TODEG))
s += (' ->(deltaA, gammaA) = (%f, %f)\n' %
(deltaA * TODEG, gammaA * TODEG))
s += (' ->(deltaB, gammaB) = (%f, %f)\n' %
(deltaB * TODEG, gammaB * TODEG))
raise AssertionError(s)
def checkArmBaseArmReciprocity(alpha, delta_orig, gamma_orig):
(deltaA, gammaA) = (delta_orig, gamma_orig)
(deltaB, gammaB) = gammaOnArmToBase(deltaA, gammaA, alpha)
(deltaA, gammaA) = gammaOnBaseToArm(deltaB, gammaB, alpha)
if ((not radeq(deltaA, delta_orig, TOLERANCE)) or
(not radeq(gammaA, gamma_orig, TOLERANCE))):
s = "\nArm-Base-Arm reciprocity\n"
s += "alpha=%f\n" % (alpha * TODEG,)
s += (" (deltaA, gammaA) = (%f, %f)\n" %
(delta_orig * TODEG, gamma_orig * TODEG))
s += (" ->(deltaB, gammaB) = (%f, %f)\n" %
(deltaB * TODEG, gammaB * TODEG))
s += (" ->(deltaA, gammaA) = (%f, %f)\n" %
(deltaA * TODEG, gammaA * TODEG))
raise AssertionError(s)
def test_generator_for_cases():
for alpha in [-89.9, -45, -1, 0, 1, 45, 89.9]:
for gamma in [-89.9, -46, -45, -44, -1, 0, 1, 44, 45, 46, 89.9]:
for delta in [-179.9, -135, -91, -89.9, -89, -46, -45, -44, -1, 0,
1, 44, 45, 46, 89, 89.9, 91, 135, 179.9]:
yield (checkGammaOnArmToBase, alpha * TORAD, delta * TORAD,
gamma * TORAD)
yield (checkArmBaseArmReciprocity, alpha * TORAD,
delta * TORAD, gamma * TORAD)
class TestFiveCirclePlugin(object):
def setup_method(self):
self.geometry = Fivec()
def testGetName(self):
assert self.geometry.name == "fivec"
def testPhysicalAnglesToInternalPosition(self):
expected = self.geometry.physical_angles_to_internal_position(
(1, 2, 4, 5, 6))
assert VliegPosition(1, 2, 0, 4, 5, 6) == expected
def testInternalPositionToPhysicalAngles(self):
result = self.geometry.internal_position_to_physical_angles(
VliegPosition(1, 2, 0, 4, 5, 6))
assert (norm(matrix([[1, 2, 4, 5, 6]]) - (matrix([list(result)])))
< 0.001)
def testSupportsModeGroup(self):
assert self.geometry.supports_mode_group('fourc')
assert not self.geometry.supports_mode_group('fivecFixedAlpha')
assert self.geometry.supports_mode_group('fivecFixedGamma')
def testGetFixedParameters(self):
self.geometry.fixed_parameters # check for exceptions
def testisParamaterFixed(self):
assert not self.geometry.parameter_fixed('made up parameter')
assert self.geometry.parameter_fixed('gamma')
class TestFourCirclePlugin(object):
def setup_method(self):
self.geometry = Fourc()
def testGetName(self):
assert self.geometry.name == "fourc"
def testPhysicalAnglesToInternalPosition(self):
expected = self.geometry.physical_angles_to_internal_position((2, 4, 5, 6))
assert VliegPosition(0, 2, 0, 4, 5, 6) == expected
def testInternalPositionToPhysicalAngles(self):
result = self.geometry.internal_position_to_physical_angles(
VliegPosition(0, 2, 0, 4, 5, 6))
assert (norm(matrix([[2, 4, 5, 6]]) - matrix([list(result)]))
< 0.001)
def testSupportsModeGroup(self):
assert self.geometry.supports_mode_group('fourc')
assert not self.geometry.supports_mode_group('fivecFixedAlpha')
assert not self.geometry.supports_mode_group('fivecFixedGamma')
def testGetFixedParameters(self):
self.geometry.fixed_parameters # check for exceptions
def testisParamaterFixed(self):
assert not self.geometry.parameter_fixed('made up parameter')
assert self.geometry.parameter_fixed('gamma')
assert self.geometry.parameter_fixed('alpha')

View File

@@ -0,0 +1,84 @@
###
# 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/>.
###
import unittest
from mock import Mock
import diffcalc.util # @UnusedImport to overide raw_input
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry
from diffcalc.hardware import DummyHardwareAdapter
from diffcalc.util import MockRawInput
from diffcalc.hkl.vlieg.calc import VliegHklCalculator
from diffcalc.ub.calc import UBCalculation
from diffcalc.ub.persistence import UbCalculationNonPersister
import pytest
try:
from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
except ImportError:
from diffcalc.gdasupport.minigda.scannable import DummyPD
def prepareRawInput(listOfStrings):
diffcalc.util.raw_input = MockRawInput(listOfStrings)
prepareRawInput([])
class TestHklCommands(object):
def setup_method(self):
self.geometry = SixCircleGammaOnArmGeometry()
dummy = 'alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'
self.hardware = DummyHardwareAdapter(dummy)
self.mock_ubcalc = Mock(spec=UBCalculation)
self.hklcalc = VliegHklCalculator(self.mock_ubcalc, self.geometry,
self.hardware, True)
from diffcalc import settings
settings.hardware = self.hardware
settings.geometry = self.geometry
settings.ubcalc_persister = UbCalculationNonPersister()
from diffcalc.hkl.vlieg import hkl
reload(hkl)
hkl.hklcalc = self.hklcalc
self.hkl = hkl
prepareRawInput([])
def testHklmode(self):
with pytest.raises(TypeError):
self.hkl.hklmode(1, 2)
with pytest.raises(ValueError):
self.hkl.hklmode('unwanted_string')
print self.hkl.hklmode()
print self.hkl.hklmode(1)
def testSetWithString(self):
self.hkl.setpar()
self.hkl.setpar('alpha')
self.hkl.setpar('alpha', 1)
self.hkl.setpar('alpha', 1.1)
pm = self.hkl.hklcalc.parameter_manager
assert pm.get_constraint('alpha') == 1.1
def testSetWithScannable(self):
alpha = DummyPD('alpha')
self.hkl.setpar(alpha, 1.1)
pm = self.hkl.hklcalc.parameter_manager
assert pm.get_constraint('alpha') == 1.1

View File

@@ -0,0 +1,463 @@
###
# 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 nose.tools import eq_
import unittest
from mock import Mock
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry
from diffcalc.hardware import DummyHardwareAdapter
from diffcalc.hkl.vlieg.geometry import VliegPosition as P, \
VliegPosition as Pos
from diffcalc.hkl.vlieg.transform import TransformA, TransformB, TransformC, \
transformsFromSector, TransformCommands, \
VliegTransformSelector, VliegPositionTransformer
import diffcalc.util # @UnusedImport
import pytest
class TestVliegPositionTransformer(object):
def setup_method(self):
names = 'a', 'd', 'g', 'o', 'c', 'phi'
self.hardware = DummyHardwareAdapter(names)
self.geometry = SixCircleGammaOnArmGeometry()
self.transform_selector = VliegTransformSelector()
self.transformer = VliegPositionTransformer(
self.geometry, self.hardware, self.transform_selector)
self.transform_commands = TransformCommands(self.transform_selector)
diffcalc.util.RAISE_EXCEPTIONS_FOR_ALL_ERRORS = True
def map(self, pos): # @ReservedAssignment
pos = self.transformer.transform(pos)
angle_tuple = self.geometry.internal_position_to_physical_angles(pos)
angle_tuple = self.hardware.cut_angles(angle_tuple)
return angle_tuple
def testMapDefaultSector(self):
eq_(self.map(Pos(1, 2, 3, 4, 5, 6)),
(1, 2, 3, 4, 5, 6))
eq_(self.map(Pos(-180, -179, 0, 179, 180, 359)),
(-180, -179, 0, 179, 180, 359))
eq_(self.map(Pos(0, 0, 0, 0, 0, 0)),
(0, 0, 0, 0, 0, 0))
eq_(self.map(Pos(-270, 270, 0, 0, 0, -90)),
(90, -90, 0, 0, 0, 270))
def testMapSector1(self):
self.transform_commands._sectorSelector.setSector(1)
eq_(self.map(Pos(1, 2, 3, 4, 5, 6)),
(1, 2, 3, 4 - 180, -5, (6 - 180) + 360))
eq_(self.map(Pos(-180, -179, 0, 179, 180, 359)),
(-180, -179, 0, 179 - 180, -180, 359 - 180))
eq_(self.map(Pos(0, 0, 0, 0, 0, 0)),
(0, 0, 0, 0 - 180, 0, (0 - 180) + 360))
eq_(self.map(Pos(-270, 270, 0, 0, 0, -90)),
(90, -90, 0, 0 - 180, 0, 270 - 180))
def testMapAutoSector(self):
self.transform_commands._sectorSelector.addAutoTransorm(1)
self.hardware.set_lower_limit('c', 0)
eq_(self.map(Pos(1, 2, 3, 4, -5, 6)),
(1, 2, 3, 4 - 180, 5, (6 - 180) + 360))
eq_(self.map(Pos(-180, -179, 0, 179, -180, 359)),
(-180, -179, 0, 179 - 180, 180, 359 - 180))
eq_(self.map(Pos(0, 0, 0, 0, -5, 0)),
(0, 0, 0, 0 - 180, 5, (0 - 180) + 360))
eq_(self.map(Pos(-270, 270, 0, 0, -5, -90)),
(90, -90, 0, 0 - 180, 5, 270 - 180))
def testTransform(self):
# mapper
self.transform_commands.transform() # should print its state
with pytest.raises(TypeError):
self.transform_commands.transform(1)
with pytest.raises(TypeError):
self.transform_commands.transform('a', 1)
def testTransformsOnOff(self):
# transforma [on/off/auto/manual]
ss = self.transform_commands._sectorSelector
self.transform_commands.transforma() # should print mapper state
eq_(ss.transforms, [], "test assumes transforms are off to start")
self.transform_commands.transforma('on')
eq_(ss.transforms, ['a'])
self.transform_commands.transformb('on')
eq_(ss.transforms, ['a', 'b'])
self.transform_commands.transformc('off')
eq_(ss.transforms, ['a', 'b'])
self.transform_commands.transformb('off')
eq_(ss.transforms, ['a'])
def testTransformsAuto(self):
ss = self.transform_commands._sectorSelector
eq_(ss.autotransforms, [], "test assumes transforms are off to start")
self.transform_commands.transforma('auto')
eq_(ss.autotransforms, ['a'])
self.transform_commands.transformb('auto')
eq_(ss.autotransforms, ['a', 'b'])
self.transform_commands.transformc('manual')
eq_(ss.autotransforms, ['a', 'b'])
self.transform_commands.transformb('manual')
eq_(ss.autotransforms, ['a'])
def testTransformsBadInput(self):
transforma = self.transform_commands.transforma
with pytest.raises(TypeError):
transforma(1)
with pytest.raises(TypeError):
transforma('not_valid')
with pytest.raises(TypeError):
transforma('auto', 1)
def testSector(self):
#sector [0-7]
ss = self.transform_commands._sectorSelector
self.transform_commands.sector() # should print mapper state
eq_(ss.sector, 0, "test assumes sector is 0 to start")
self.transform_commands.sector(1)
eq_(ss.sector, 1)
with pytest.raises(TypeError):
self.transform_commands.sector(1, 2)
with pytest.raises(TypeError):
self.transform_commands.sector('a')
def testAutosectors(self):
#autosector [0-7]
ss = self.transform_selector
self.transform_commands.autosector() # should print mapper state
eq_(ss.autosectors, [], "test assumes no auto sectors to start")
self.transform_commands.autosector(1)
eq_(ss.autosectors, [1])
self.transform_commands.autosector(1, 2)
eq_(ss.autosectors, [1, 2])
self.transform_commands.autosector(1)
eq_(ss.autosectors, [1])
self.transform_commands.autosector(3)
eq_(ss.autosectors, [3])
with pytest.raises(TypeError):
self.transform_commands.autosector(1, 'a')
with pytest.raises(TypeError):
self.transform_commands.autosector('a')
class MockLimitChecker(object):
def __init__(self):
self.okay = True
def isPoswithiLimits(self, pos):
return self.okay
def isDeltaNegative(self, pos):
return pos.delta <= 0
class TestVliegTransformSelector(object):
def setup_method(self):
self.limitChecker = MockLimitChecker()
self.ss = VliegTransformSelector()
self.ss.limitCheckerFunction = self.limitChecker.isPoswithiLimits
def test__init__(self):
assert (self.ss.sector, 0)
def testCutPosition(self):
d = .1
tocut = P(-180., 180., 180. - d, 180. + d, -180. + d, -180. - d)
expected = P(-180., 180., 180. - d, -180. + d, -180. + d, 180. - d)
assert (self.ss.cutPosition(tocut) == expected)
def testTransformNWithoutCut(self):
pos = P(1, 2, 3, 4, 5, 6)
assert (self.ss.transformNWithoutCut(0, pos) == pos)
def testTransformPosition(self):
pos = P(0 - 360, .1 + 360, .2 - 360, .3 + 360, .4, 5)
res = self.ss.transformPosition(pos)
des = P(0, .1, .2, .3, .4, 5)
assert (res == des, '%s!=\n%s' % (res, des))
def testSetSector(self):
self.ss.setSector(4)
assert (self.ss.sector, 4)
assert (self.ss.transforms, ['b', 'c'])
def testSetTransforms(self):
self.ss.setTransforms(('c', 'b'))
assert (self.ss.sector, 4)
assert (self.ss.transforms, ['b', 'c'])
def testAddAutoTransormWithBadInput(self):
assert (self.ss.autosectors, [])
assert (self.ss.autotransforms, [])
with pytest.raises(ValueError):
self.ss.addAutoTransorm('not transform')
with pytest.raises(ValueError):
self.ss.addAutoTransorm(9999)
with pytest.raises(ValueError):
self.ss.addAutoTransorm([])
def testAddAutoTransormWithTransforms(self):
self.ss.autosectors = [1, 2, 3, 4, 5]
self.ss.addAutoTransorm('a')
print "Should now print a warning..."
self.ss.addAutoTransorm('a') # twice
self.ss.addAutoTransorm('b')
assert (self.ss.autosectors, [])
assert (self.ss.autotransforms, ['a', 'b'])
def testAddAutoTransormWithSectors(self):
self.ss.autotransforms = ['a', 'c']
self.ss.addAutoTransorm(2)
print "Should now print a warning..."
self.ss.addAutoTransorm(2) # twice
self.ss.addAutoTransorm(3)
assert (self.ss.autosectors, [2, 3])
assert (self.ss.autotransforms, [])
def testis_position_within_limits(self):
assert (self.ss.is_position_within_limits(None), True)
self.limitChecker.okay = False
assert (self.ss.is_position_within_limits(None), False)
def test__repr__(self):
self.ss.setSector(0)
print "************************"
print self.ss
print "************************"
self.ss.setTransforms('a')
print self.ss
print "************************"
self.ss.setTransforms(('a', 'b', 'c'))
print self.ss
print "************************"
class TestSectorSelectorAutoCode(object):
def setup_method(self):
self.limitChecker = MockLimitChecker()
self.ss = VliegTransformSelector()
self.ss.limitCheckerFunction = self.limitChecker.isDeltaNegative
self.pos = P(0, .1, .2, .3, .4, 5)
self.pos_in2 = self.ss.cutPosition(
self.ss.transformNWithoutCut(2, self.pos))
self.pos_in3 = self.ss.cutPosition(
self.ss.transformNWithoutCut(3, self.pos))
def testAddautoTransformWithSectors(self):
self.ss.addAutoTransorm(2)
self.ss.addAutoTransorm(3)
assert (self.ss.autosectors, [2, 3])
assert (self.ss.autotransforms, [])
self.ss.removeAutoTransform(3)
assert (self.ss.autosectors, [2])
def testAddautoTransformTransforms(self):
self.ss.addAutoTransorm('a')
self.ss.addAutoTransorm('b')
assert (self.ss.autosectors, [])
assert (self.ss.autotransforms, ['a', 'b'])
def testRemoveAutoTransformWithSectors(self):
self.ss.addAutoTransorm(2)
self.ss.addAutoTransorm(3)
self.ss.removeAutoTransform(3)
assert (self.ss.autosectors, [2])
self.ss.removeAutoTransform(2)
assert (self.ss.autosectors, [])
def testRemoveAutoTransformTransforms(self):
self.ss.addAutoTransorm('a')
self.ss.addAutoTransorm('b')
self.ss.removeAutoTransform('b')
assert (self.ss.autotransforms, ['a'])
self.ss.removeAutoTransform('a')
assert (self.ss.autotransforms, [])
def testTransformPosition(self):
# Check that with no transforms set to autoapply, the limit
# checker function is ignored
ss = VliegTransformSelector()
ss.limitCheckerFunction = self.limitChecker.isPoswithiLimits
self.limitChecker.okay = False
ss.transformPosition(P(0, .1, .2, .3, .4, 5))
def testMockLimitChecker(self):
assert not self.limitChecker.isDeltaNegative(P(0, .1, .2, .3, .4, 5))
assert self.limitChecker.isDeltaNegative(P(0, -.1, .2, .3, .4, 5))
def testAutoTransformPositionWithSectors(self):
self.ss.addAutoTransorm(2)
print "Should print 'INFO: Autosector changed sector from 0 to 2':"
result = self.ss.autoTransformPositionBySector(self.pos)
assert (result == self.pos_in2)
assert (self.ss.sector, 2)
def testAutoTransformPositionWithSectorChoice(self):
self.ss.addAutoTransorm(2)
self.ss.addAutoTransorm(3)
print "Should print 'WARNING: Autosector found multiple sectors...':"
print "Should print 'INFO: Autosector changed sector from 0 to 2':"
result = self.ss.autoTransformPositionBySector(self.pos)
assert (result == self.pos_in2)
assert (self.ss.sector, 2)
def testAutoTransformPositionWithSectorsFails(self):
self.ss.addAutoTransorm(0)
self.ss.addAutoTransorm(1)
self.ss.addAutoTransorm(4)
self.ss.addAutoTransorm(5)
print "Should print 'INFO: Autosector changed sector from 0 to 2':"
with pytest.raises(Exception):
self.ss.autoTransformPositionBySector(self.pos)
#self.ss.autoTransformPositionBySector(self.pos)
assert (self.ss.sector, 0) # unchanged
def testCreateListOfPossibleTransforms(self):
self.ss.addAutoTransorm('a')
assert (self.ss.createListOfPossibleTransforms(),
[(), ['a', ]])
self.ss.addAutoTransorm('b')
assert (self.ss.createListOfPossibleTransforms(),
[(), ['b', ], ['a', ], ['a', 'b']])
self.ss.transforms = ['a', 'c']
def testAutoTransformPositionWithTransforms(self):
self.ss.addAutoTransorm('a')
print "Should print 'INFO: ':"
result = self.ss.autoTransformPositionByTransforms(self.pos)
assert (result == self.pos_in2)
assert (self.ss.sector, 2)
def testAutoTransformPositionWithTansformsChoice(self):
self.ss.addAutoTransorm('a')
self.ss.addAutoTransorm('c')
print "Should print 'WARNING:':"
print "Should print 'INFO: ':"
result = self.ss.autoTransformPositionByTransforms(self.pos)
assert (result == self.pos_in2)
assert (self.ss.sector, 2)
def testTransformPositionWithAutoTransforms(self):
self.ss.addAutoTransorm('a')
assert (self.ss.transformPosition(self.pos) == self.pos_in2)
assert (self.ss.sector, 2)
print "Should not print 'INFO...'"
assert (self.ss.transformPosition(self.pos) == self.pos_in2)
assert (self.ss.sector, 2)
def testTransformPositionWithAutoTransforms2(self):
self.ss.addAutoTransorm(2)
assert (self.ss.transformPosition(self.pos) == self.pos_in2)
assert (self.ss.sector, 2)
print "Should not print 'INFO...'"
assert (self.ss.transformPosition(self.pos) == self.pos_in2)
assert (self.ss.sector, 2)
def test__repr__(self):
self.ss.setSector(0)
print "************************"
print self.ss
print "************************"
self.ss.setTransforms('a')
print self.ss
print "************************"
self.ss.setTransforms(('a', 'b', 'c'))
print self.ss
print "************************"
self.ss.addAutoTransorm(1)
self.ss.addAutoTransorm(2)
self.ss.addAutoTransorm(3)
print self.ss
print "************************"
self.ss.addAutoTransorm('a')
self.ss.addAutoTransorm('c')
print self.ss
print "************************"
class TestTransforms(object):
def setup_method(self):
self.limitCheckerFunction = Mock()
self.ss = VliegTransformSelector()
self.ss.limitCheckerFunction = self.limitCheckerFunction
def applyTransforms(self, transforms, pos):
result = pos.clone()
for transform in transforms:
if transform == 'a':
result = TransformA().transform(result)
if transform == 'b':
result = TransformB().transform(result)
if transform == 'c':
result = TransformC().transform(result)
return self.ss.cutPosition(result)
def _testTransformN(self, n):
transforms = transformsFromSector[n]
pos = P(1, 2, 3, 4, 5, 6)
self.ss.setSector(n)
fromss = self.ss.transformPosition(pos)
fromhere = self.applyTransforms(transforms, pos)
assert (fromss == fromhere,
("sector: %i\ntransforms:%s\n%s !=\n%s" %
(n, transforms, fromss, fromhere)))
def testTransform0(self):
self._testTransformN(0)
def testTransform1(self):
self._testTransformN(1)
def testTransform2(self):
self._testTransformN(2)
def testTransform3(self):
self._testTransformN(3)
def testTransform4(self):
self._testTransformN(5)
def testTransform5(self):
self._testTransformN(5)
def testTransform6(self):
self._testTransformN(6)
def testTransform7(self):
self._testTransformN(7)

View File

@@ -0,0 +1,323 @@
###
# 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/>.
###
# TODO: class largely copied from test_calc
from math import pi
from mock import Mock
from nose.tools import raises
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.hkl.willmott.calc import \
WillmottHorizontalUbCalcStrategy, WillmottHorizontalCalculator, \
WillmottHorizontalPosition as Pos, WillmottHorizontalGeometry
from test.tools import assert_array_almost_equal, \
assert_second_dict_almost_in_first, matrixeq_
from diffcalc.ub.calc import UBCalculation
from diffcalc.ub.crystal import CrystalUnderTest
from diffcalc.ub.persistence import UbCalculationNonPersister
from diffcalc.util import DiffcalcException
from test.diffcalc.test_hardware import SimpleHardwareAdapter
from test.diffcalc.hkl.vlieg.test_calc import createMockUbcalc, \
createMockDiffractometerGeometry
import diffcalc.hkl.willmott.calc # @UnusedImport
TORAD = pi / 180
TODEG = 180 / pi
class _BaseTest():
def setup_method(self):
self.mock_ubcalc = createMockUbcalc(None)
self.mock_geometry = createMockDiffractometerGeometry()
self.mock_hardware = SimpleHardwareAdapter(
['delta', 'gamma', 'omegah', 'phi'])
self.constraints = Mock()
self.calc = WillmottHorizontalCalculator(self.mock_ubcalc,
self.mock_geometry, self.mock_hardware, self.constraints)
self.places = 12
def _check_hkl_to_angles(self, testname, zrot, yrot, hkl, pos_expected,
wavelength, virtual_expected={}):
print ('_check_hkl_to_angles(%s, %.1f, %.1f, %s, %s, %.2f, %s)'
% (testname, zrot, yrot, hkl, pos_expected, wavelength,
virtual_expected))
self.zrot, self.yrot = zrot, yrot
self._configure_ub()
pos, virtual = self.calc.hklToAngles(hkl[0], hkl[1], hkl[2],
wavelength)
assert_array_almost_equal(pos.totuple(), pos_expected.totuple(),
self.places)
assert_second_dict_almost_in_first(virtual, virtual_expected)
def _check_angles_to_hkl(self, testname, zrot, yrot, hkl_expected, pos,
wavelength, virtual_expected={}):
print ('_check_angles_to_hkl(%s, %.1f, %.1f, %s, %s, %.2f, %s)' %
(testname, zrot, yrot, hkl_expected, pos, wavelength,
virtual_expected))
self.zrot, self.yrot = zrot, yrot
self._configure_ub()
hkl, virtual = self.calc.anglesToHkl(pos, wavelength)
assert_array_almost_equal(hkl, hkl_expected, self.places)
assert_second_dict_almost_in_first(virtual, virtual_expected)
@raises(DiffcalcException)
def _check_hkl_to_angles_fails(self, *args):
self._check_hkl_to_angles(*args)
# Primary and secondary reflections found with the help of DDIF on Diamond's
# i07 on Jan 27 2010
Si_5_5_12_WAVELENGTH = 0.6358
Si_5_5_12_HKL0 = 2, 19, 32
Si_5_5_12_REF0 = Pos(delta=21.975, gamma=4.419, omegah=2, phi=326.2)
Si_5_5_12_HKL1 = 0, 7, 22
Si_5_5_12_REF1 = Pos(delta=11.292, gamma=2.844, omegah=2, phi=124.1)
# This is U matrix displayed by DDIF
U_FROM_DDIF = matrix([[0.233140, 0.510833, 0.827463],
[-0.65596, -0.545557, 0.521617],
[0.717888, -0.664392, 0.207894]])
# This is the version that Diffcalc comes up with ( see following test)
Si_5_5_12_U_DIFFCALC = matrix([[-0.7178876, 0.6643924, -0.2078944],
[-0.6559596, -0.5455572, 0.5216170],
[0.2331402, 0.5108327, 0.8274634]])
class TestUBCalculationWithWillmotStrategy_Si_5_5_12():
def setup_method(self):
hardware = Mock()
hardware.get_axes_names.return_value = ('d', 'g', 'oh', 'p')
self.ubcalc = UBCalculation(hardware, WillmottHorizontalGeometry(),
UbCalculationNonPersister(),
WillmottHorizontalUbCalcStrategy())
def testAgainstResultsFromJan_27_2010(self):
self.ubcalc.start_new('test')
self.ubcalc.set_lattice('Si_5_5_12', 7.68, 53.48, 75.63, 90, 90, 90)
self.ubcalc.add_reflection(
Si_5_5_12_HKL0[0], Si_5_5_12_HKL0[1], Si_5_5_12_HKL0[2],
Si_5_5_12_REF0, 12.39842 / Si_5_5_12_WAVELENGTH, 'ref0', None)
self.ubcalc.add_reflection(
Si_5_5_12_HKL1[0], Si_5_5_12_HKL1[1], Si_5_5_12_HKL1[2],
Si_5_5_12_REF1, 12.39842 / Si_5_5_12_WAVELENGTH, 'ref1', None)
self.ubcalc.calculate_UB()
print "U: ", self.ubcalc.U
print "UB: ", self.ubcalc.UB
matrixeq_(self.ubcalc.U, Si_5_5_12_U_DIFFCALC)
class TestSurfaceNormalVertical_Si_5_5_12_PosGamma(_BaseTest):
def setup_method(self):
_BaseTest.setup_method(self)
self.constraints.reference = {'betain': 2}
self.wavelength = 0.6358
B = CrystalUnderTest('xtal', 7.68, 53.48,
75.63, 90, 90, 90).B
self.UB = Si_5_5_12_U_DIFFCALC * B
diffcalc.hkl.willmott.calc.CHOOSE_POSITIVE_GAMMA = True
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
self._check_angles_to_hkl('', 999, 999, hkl, pos, self.wavelength,
virtual_expected)
if fails:
self._check_hkl_to_angles_fails('', 999, 999, hkl, pos,
self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles('', 999, 999, hkl, pos, self.wavelength,
virtual_expected)
def testHkl_2_19_32_found_orientation_setting(self):
'''Check that the or0 reflection maps back to the assumed hkl'''
self.places = 2
self._check_angles_to_hkl('', 999, 999, Si_5_5_12_HKL0,
Si_5_5_12_REF0,
self.wavelength, {'betain': 2})
def testHkl_0_7_22_found_orientation_setting(self):
'''Check that the or1 reflection maps back to the assumed hkl'''
self.places = 0
self._check_angles_to_hkl('', 999, 999, Si_5_5_12_HKL1,
Si_5_5_12_REF1,
self.wavelength, {'betain': 2})
def testHkl_2_19_32_calculated_from_DDIF(self):
self.places = 3
self._check((2, 19, 32),
Pos(delta=21.974, gamma=4.419, omegah=2, phi=-33.803),
{'betain': 2})
def testHkl_0_7_22_calculated_from_DDIF(self):
self.places = 3
self._check((0, 7, 22),
Pos(delta=11.242, gamma=3.038, omegah=2, phi=123.064),
{'betain': 2})
def testHkl_2_m5_12_calculated_from_DDIF(self):
self.places = 3
self._check((2, -5, 12),
Pos(delta=5.224, gamma=10.415, omegah=2, phi=-1.972),
{'betain': 2})
# conlcusion:
# given or1 from testHkl_2_19_32_found_orientation_setting and,
# or1 from testHkl_0_7_22_found_orientation_setting
# we can calculate a U matrix which agrees with that from diff except for
# signs and row order
# We can also calculate values for 2_19_32 and 0_7_22 that match those
# calculated by DDIF to the number of recorded decimal places (3)
class SkipTestSurfaceNormalVertical_Si_5_5_12_NegGamma(
TestSurfaceNormalVertical_Si_5_5_12_PosGamma):
"""When choosing -ve gamma delta ends up being -ve too"""
def setup_method(self):
_BaseTest.setup_method(self)
self.constraints.reference = {'betain': 2 * TORAD}
self.wavelength = 0.6358
B = CrystalUnderTest('xtal', 7.68, 53.48,
75.63, 90, 90, 90).B
self.UB = Si_5_5_12_U_DIFFCALC * B
diffcalc.hkl.willmott.calc.CHOOSE_POSITIVE_GAMMA = False
##################################################################
# Primary and secondary reflections found with the help of DDIF on Diamond's
# i07 on Jan 28/29 2010
Pt531_HKL0 = -1.000, 1.000, 6.0000
Pt531_REF0 = Pos(delta=9.465, gamma=16.301, omegah=2,
phi=307.94 - 360)
Pt531_REF0_DIFFCALC = Pos(
9.397102509657, 16.181230279320, 2.000000000000, -52.139290474913)
Pt531_HKL1 = -2.000, -1.000, 7.0000
Pt531_REF1 = Pos(delta=11.094, gamma=11.945, omegah=2, phi=238.991 - 360)
Pt531_REF1_DIFFCALC = Pos(
11.012695836306, 11.863612760237, 2.000000000000, -121.215597507237)
Pt531_HKL2 = 1, 1, 9
Pt531_REF2 = Pos(delta=14.272, gamma=7.806, omegah=2,
phi=22.9)
Pt531_REF2_DIFFCALC = Pos(
14.188161709766, 7.758593908726, 2.000000000000, 23.020313153847)
Pt531_WAVELENGTH = 0.6358
# This is U matrix displayed by DDIF
U_FROM_DDIF = matrix([[-0.00312594, -0.00063417, 0.99999491],
[0.99999229, -0.00237817, 0.00312443],
[0.00237618, 0.99999697, 0.00064159]])
# This is the version that Diffcalc comes up with ( see following test)
Pt531_U_DIFFCALC = matrix([[-0.0023763, -0.9999970, -0.0006416],
[0.9999923, -0.0023783, 0.0031244],
[-0.0031259, -0.0006342, 0.9999949]])
class TestUBCalculationWithWillmotStrategy_Pt531():
def setup_method(self):
hardware = Mock()
hardware.get_axes_names.return_value = ('d', 'g', 'oh', 'p')
self.ubcalc = UBCalculation(hardware, WillmottHorizontalGeometry(),
UbCalculationNonPersister(),
WillmottHorizontalUbCalcStrategy())
def testAgainstResultsFromJan_27_2010(self):
self.ubcalc.start_new('test')
self.ubcalc.set_lattice('Pt531', 6.204, 4.806, 23.215, 90, 90, 49.8)
self.ubcalc.add_reflection(
Pt531_HKL0[0], Pt531_HKL0[1], Pt531_HKL0[2], Pt531_REF0,
12.39842 / Pt531_WAVELENGTH, 'ref0', None)
self.ubcalc.add_reflection(
Pt531_HKL1[0], Pt531_HKL1[1], Pt531_HKL1[2], Pt531_REF1,
12.39842 / Pt531_WAVELENGTH, 'ref1', None)
self.ubcalc.calculate_UB()
print "U: ", self.ubcalc.U
print "UB: ", self.ubcalc.UB
matrixeq_(self.ubcalc.U, Pt531_U_DIFFCALC)
class TestSurfaceNormalVertical_Pt531_PosGamma(_BaseTest):
def setup_method(self):
_BaseTest.setup_method(self)
self.constraints.reference = {'betain': 2}
self.wavelength = Pt531_WAVELENGTH
cut = CrystalUnderTest('Pt531', 6.204, 4.806, 23.215, 90, 90, 49.8)
B = cut.B
self.UB = Pt531_U_DIFFCALC * B
diffcalc.hkl.willmott.calc.CHOOSE_POSITIVE_GAMMA = True
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
# self._check_angles_to_hkl('', 999, 999, hkl, pos, self.wavelength,
# virtual_expected)
if fails:
self._check_hkl_to_angles_fails('', 999, 999, hkl, pos,
self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles('', 999, 999, hkl, pos, self.wavelength,
virtual_expected)
def testHkl_0_found_orientation_setting(self):
'''Check that the or0 reflection maps back to the assumed hkl'''
self.places = 1
self._check_angles_to_hkl('', 999, 999, Pt531_HKL0,
Pt531_REF0,
self.wavelength, {'betain': 2})
def testHkl_1_found_orientation_setting(self):
'''Check that the or1 reflection maps back to the assumed hkl'''
self.places = 0
self._check_angles_to_hkl('', 999, 999, Pt531_HKL1,
Pt531_REF1,
self.wavelength, {'betain': 2})
def testHkl_0_predicted_versus_found_during_oriantation_phase(self):
self._check(Pt531_HKL0,
Pt531_REF0_DIFFCALC, # inspected as close to Pt531_REF0
{'betain': 2})
def testHkl_1_predicted_versus_found_during_oriantation_phase(self):
self._check(Pt531_HKL1,
Pt531_REF1_DIFFCALC, # inspected as close to Pt531_REF1,
{'betain': 2})
def testHkl_2_predicted_versus_found_during_oriantation_phase(self):
self._check(Pt531_HKL2,
Pt531_REF2_DIFFCALC, # inspected as close to Pt531_REF2
{'betain': 2})

View File

@@ -0,0 +1,824 @@
###
# 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, cos, sin
from nose.tools import raises
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.hkl.you.calc import YouHklCalculator
from diffcalc.hkl.you.constraints import YouConstraintManager
from test.tools import assert_array_almost_equal, \
assert_second_dict_almost_in_first
from diffcalc.ub.crystal import CrystalUnderTest
from diffcalc.util import y_rotation, z_rotation, DiffcalcException
from test.diffcalc.test_hardware import SimpleHardwareAdapter
from test.diffcalc.hkl.vlieg.test_calc import \
createMockDiffractometerGeometry, createMockUbcalc
from diffcalc.hkl.you.geometry import YouPosition as Pos, YouPosition as P,\
YouPosition
from test.tools import arrayeq_
from diffcalc.hkl.you.calc import youAnglesToHkl
TORAD = pi / 180
TODEG = 180 / pi
I = matrix('1 0 0; 0 1 0; 0 0 1')
from diffcalc.hkl.you.constraints import NUNAME
class Pair:
def __init__(self, name, hkl, position, fails=False):
self.name = name
self.hkl = hkl
self.position = position
self.fails = fails
class _BaseTest():
def setup_method(self):
self.mock_ubcalc = createMockUbcalc(None)
self.mock_geometry = createMockDiffractometerGeometry()
names = ['delta', NUNAME, 'mu', 'eta', 'chi', 'phi']
self.mock_hardware = SimpleHardwareAdapter(names)
self.constraints = YouConstraintManager(self.mock_hardware)
self.calc = YouHklCalculator(self.mock_ubcalc, self.mock_geometry,
self.mock_hardware, self.constraints)
self.mock_hardware.set_lower_limit('delta', 0)
self.mock_hardware.set_upper_limit('delta', 179.999)
self.mock_hardware.set_lower_limit(NUNAME, 0)
self.mock_hardware.set_upper_limit(NUNAME, 179.999)
self.mock_hardware.set_lower_limit('mu', 0)
self.mock_hardware.set_lower_limit('eta', 0)
self.mock_hardware.set_lower_limit('chi', -10)
self.places = 11
def _configure_ub(self):
ZROT = z_rotation(self.zrot * TORAD) # -PHI
YROT = y_rotation(self.yrot * TORAD) # +CHI
U = ZROT * YROT
UB = U * self.B
self.mock_ubcalc.UB = UB
def _check_hkl_to_angles(self, testname, zrot, yrot, hkl, pos_expected,
wavelength, virtual_expected={}):
print ('_check_hkl_to_angles(%s, %.1f, %.1f, %s, %s, %.2f, %s)' %
(testname, zrot, yrot, hkl, pos_expected, wavelength,
virtual_expected))
self.zrot, self.yrot = zrot, yrot
self._configure_ub()
pos, virtual = self.calc.hklToAngles(hkl[0], hkl[1], hkl[2],
wavelength)
assert_array_almost_equal(pos.totuple(), pos_expected.totuple(),
self.places)
assert_second_dict_almost_in_first(virtual, virtual_expected)
def _check_angles_to_hkl(self, testname, zrot, yrot, hkl_expected, pos,
wavelength, virtual_expected={}):
print ('_check_angles_to_hkl(%s, %.1f, %.1f, %s, %s, %.2f, %s)' %
(testname, zrot, yrot, hkl_expected, pos, wavelength,
virtual_expected))
self.zrot, self.yrot = zrot, yrot
self._configure_ub()
hkl, virtual = self.calc.anglesToHkl(pos, wavelength)
assert_array_almost_equal(hkl, hkl_expected, self.places, note="***Test (not diffcalc!) incorrect*** : the desired settings do not map to the target hkl")
assert_second_dict_almost_in_first(virtual, virtual_expected)
@raises(DiffcalcException)
def _check_hkl_to_angles_fails(self, *args):
self._check_hkl_to_angles(*args)
def case_generator(self):
for case in self.cases:
yield (self._check_angles_to_hkl, case.name, self.zrot, self.yrot,
case.hkl, case.position, self.wavelength, {})
test_method = (self._check_hkl_to_angles_fails if case.fails else
self._check_hkl_to_angles)
yield (test_method, case.name, self.zrot, self.yrot, case.hkl,
case.position, self.wavelength, {})
class _TestCubic(_BaseTest):
def setup_method(self):
_BaseTest.setup_method(self)
self.B = I * 2 * pi
class _TestCubicVertical(_TestCubic):
def setup_method(self):
_TestCubic.setup_method(self)
def makes_cases(self, zrot, yrot):
self.zrot = zrot
self.yrot = yrot
self.wavelength = 1
self.cases = (
Pair('100', (1, 0, 0),
Pos(mu=0, delta=60, nu=0, eta=30, chi=0 - self.yrot,
phi=0 + self.zrot)),
Pair('100-->001', (cos(4 * TORAD), 0, sin(4 * TORAD)),
Pos(mu=0, delta=60, nu=0, eta=30, chi=4 - self.yrot,
phi=0 + self.zrot),),
Pair('010', (0, 1, 0),
Pos(mu=0, delta=60, nu=0, eta=30, chi=0, phi=90 + self.zrot)),
Pair('001', (0, 0, 1),
Pos(mu=0, delta=60, nu=0, eta=30, chi=90 - self.yrot,
phi=0 + self.zrot)),
Pair('0.1 0 1.5', (0.1, 0, 1.5), # cover case where delta > 90 !
Pos(mu=0, delta=97.46959231642, nu=0,
eta=97.46959231642/2, chi=86.18592516571 - self.yrot,
phi=0 + self.zrot)),
Pair('001-->100', (cos(86 * TORAD), 0, sin(86 * TORAD)),
Pos(mu=0, delta=60, nu=0, eta=30, chi=86 - self.yrot,
phi=0 + self.zrot)),
)
self.case_dict = {}
for case in self.cases:
self.case_dict[case.name] = case
def test_pairs_zrot0_yrot0(self):
self.makes_cases(0, 0)
self.case_dict['001'].fails = True # q||n
for case_tuple in self.case_generator():
yield case_tuple
def test_pairs_various_zrot_and_yrot0(self):
for zrot in [0, 2, -2, 45, -45, 90, -90]: # -180, 180 work if recut
self.makes_cases(zrot, 0)
self.case_dict['001'].fails = True # q||n
for case_tuple in self.case_generator():
yield case_tuple
def test_hkl_to_angles_zrot1_yrot2(self):
self.makes_cases(1, 2)
for case_tuple in self.case_generator():
yield case_tuple
def test_hkl_to_angles_zrot1_yrotm2(self):
self.makes_cases(1, -2)
for case_tuple in self.case_generator():
yield case_tuple
def testHklDeltaGreaterThan90(self):
wavelength = 1
hkl = (0.1, 0, 1.5)
pos = P(mu=0, delta=97.46959231642, nu=0,
eta=97.46959231642/2, chi=86.18592516571,
phi=0)
self._check_hkl_to_angles('', 0, 0, hkl, pos, wavelength)
class TestCubicVertical_aeqb(_TestCubicVertical):
def setup_method(self):
_TestCubicVertical.setup_method(self)
self.constraints._constrained = {'a_eq_b': None, 'mu': 0, NUNAME: 0}
class TestCubicVertical_psi_90(_TestCubicVertical):
'''mode psi=90 should be the same as mode a_eq_b'''
def setup_method(self):
_TestCubicVertical.setup_method(self)
self.constraints._constrained = {'psi': 90 * TORAD, 'mu': 0, NUNAME: 0}
class TestCubicVertical_qaz_90(_TestCubicVertical):
'''mode psi=90 should be the same as mode a_eq_b'''
def setup_method(self):
_TestCubicVertical.setup_method(self)
self.constraints._constrained = {'a_eq_b': None, 'mu': 0,
'qaz': 90 * TORAD}
class SkipTestYouHklCalculatorWithCubicMode_aeqb_delta_60(_TestCubicVertical):
'''
Works to 4-5 decimal places but chooses different solutions when phi||eta .
Skip all tests.
'''
def setup_method(self):
_TestCubicVertical.setup_method(self)
self.constraints._constrained = {'a_eq_b': None, 'mu': 0,
'delta': 60 * TORAD}
self.places = 5
class _TestCubicHorizontal(_TestCubic):
def setup_method(self):
_TestCubic.setup_method(self)
def makes_cases(self, zrot, yrot):
self.zrot = zrot
self.yrot = yrot
self.wavelength = 1
self.cases = (
Pair('100', (1, 0, 0),
Pos(mu=30, delta=0, nu=60, eta=0, chi=90 + self.yrot,
phi=-180 + self.zrot)),
Pair('100-->001', (cos(4 * TORAD), 0, sin(4 * TORAD)),
Pos(mu=30, delta=0, nu=60, eta=0, chi=90 - 4 + self.yrot,
phi=-180 + self.zrot)),
Pair('010', (0, 1, 0),
Pos(mu=30, delta=0, nu=60, eta=0, chi=90,
phi=-90 + self.zrot)), # no yrot as chi||q
Pair('001', (0, 0, 1),
Pos(mu=30, delta=0, nu=60, eta=0, chi=0 - self.yrot,
phi=0 + self.zrot)),
Pair('001-->100', (cos(86 * TORAD), 0, sin(86 * TORAD)),
Pos(mu=30, delta=0, nu=60, eta=0, chi=0 - 4 - self.yrot,
phi=0 + self.zrot)),
)
self.case_dict = {}
for case in self.cases:
self.case_dict[case.name] = case
def test_pairs_zrot0_yrot0(self):
self.makes_cases(0, 0)
self.case_dict['001'].fails = True # q||n
self.case_dict['100'].position.phi = 180 # not -180
self.case_dict['100-->001'].position.phi = 180 # not -180
for case_tuple in self.case_generator():
yield case_tuple
# def test_pairs_various_zrot_and_yrot0(self):
# for zrot in [0, 2, -2, 45, -45, 90, -90]:
# -180, 180 work but with cut problem
# self.makes_cases(zrot, 0)
# self.case_dict['001'].fails = True # q||n
# for case_tuple in self.case_generator():
# yield case_tuple
def test_hkl_to_angles_zrot1_yrot2(self):
self.makes_cases(1, 2)
for case_tuple in self.case_generator():
yield case_tuple
def test_hkl_to_angles_zrot1_yrotm2(self):
self.makes_cases(1, -2)
for case_tuple in self.case_generator():
yield case_tuple
class TestCubicHorizontal_qaz0_aeqb(_TestCubicHorizontal):
def setup_method(self):
_TestCubicHorizontal.setup_method(self)
self.constraints._constrained = {'a_eq_b': None, 'qaz': 0, 'eta': 0}
class TestCubicHorizontal_delta0_aeqb(_TestCubicHorizontal):
def setup_method(self):
_TestCubicHorizontal.setup_method(self)
self.constraints._constrained = {'a_eq_b': None, 'delta': 0, 'eta': 0}
class TestAgainstSpecSixcB16_270608(_BaseTest):
'''NOTE: copied from test.diffcalc.scenarios.session3'''
def setup_method(self):
_BaseTest.setup_method(self)
U = matrix(((0.997161, -0.062217, 0.042420),
(0.062542, 0.998022, -0.006371),
(-0.041940, 0.009006, 0.999080)))
B = matrix(((1.636204, 0, 0),
(0, 1.636204, 0),
(0, 0, 1.156971)))
self.UB = U * B
self.constraints._constrained = {'a_eq_b': None, 'mu': 0, NUNAME: 0}
self.places = 2 # TODO: the Vlieg code got this to 3 decimal places
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def makes_cases(self, zrot, yrot):
del zrot, yrot # not used
self.wavelength = 1.24
self.cases = (
Pair('7_9_13', (0.7, 0.9, 1.3),
Pos(mu=0, delta=27.352179, nu=0, eta=13.676090,
chi=37.774500, phi=53.965500)),
Pair('100', (1, 0, 0),
Pos(mu=0, delta=18.580230, nu=0, eta=9.290115,
chi=-2.403500, phi=3.589000)),
Pair('010', (0, 1, 0),
Pos(mu=0, delta=18.580230, nu=0, eta=9.290115,
chi=0.516000, phi=93.567000)),
Pair('110', (1, 1, 0),
Pos(mu=0, delta=26.394192, nu=0, eta=13.197096,
chi=-1.334500, phi=48.602000)),
)
self.case_dict = {}
for case in self.cases:
self.case_dict[case.name] = case
def case_generator(self):
zrot, yrot = 999, 999
for case in self.cases:
yield (self._check_angles_to_hkl, case.name, zrot, yrot, case.hkl,
case.position, self.wavelength, {})
test_method = (self._check_hkl_to_angles_fails if case.fails else
self._check_hkl_to_angles)
yield (test_method, case.name, zrot, yrot, case.hkl, case.position,
self.wavelength, {})
def test_hkl_to_angles_given_UB(self):
self.makes_cases(None, None) # xrot, yrot unused
for case_tuple in self.case_generator():
yield case_tuple
class SkipTestThreeTwoCircleForDiamondI06andI10(_BaseTest):
"""
This is a three circle diffractometer with only delta and omega axes
and a chi axis with limited range around 90. It is operated with phi
fixed and can only reach reflections with l (or z) component.
The data here is taken from an experiment performed on Diamonds I06
beamline.
"""
def setup_method(self):
_BaseTest.setup_method(self)
self.constraints._constrained = {'phi': -pi / 2, NUNAME: 0, 'mu': 0}
self.wavelength = 12.39842 / 1.650
def _configure_ub(self):
U = matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
B = CrystalUnderTest('xtal', 5.34, 5.34, 13.2, 90, 90, 90).B
self.mock_ubcalc.UB = U * B
def testHkl001(self):
hkl = (0, 0, 1)
pos = Pos(mu=0, delta=33.07329403295449, nu=0, eta=16.536647016477247,
chi=90, phi=-90)
self._check_angles_to_hkl(
'001', 999, 999, hkl, pos, self.wavelength, {})
self._check_hkl_to_angles(
'001', 999, 999, hkl, pos, self.wavelength, {})
def testHkl100(self):
hkl = (1, 0, 0)
pos = Pos(mu=0, delta=89.42926563609406, nu=0, eta=134.71463281804702,
chi=90, phi=-90)
self._check_angles_to_hkl(
'100', 999, 999, hkl, pos, self.wavelength, {})
self._check_hkl_to_angles(
'100', 999, 999, hkl, pos, self.wavelength, {})
def testHkl101(self):
hkl = (1, 0, 1)
pos = Pos(mu=0, delta=98.74666191021282, nu=0, eta=117.347760720783,
chi=90, phi=-90)
self._check_angles_to_hkl(
'101', 999, 999, hkl, pos, self.wavelength, {})
self._check_hkl_to_angles(
'101', 999, 999, hkl, pos, self.wavelength, {})
class TestFixedChiPhiPsiMode_DiamondI07SurfaceNormalHorizontal(_TestCubic):
"""
The data here is taken from an experiment performed on Diamonds I07
beamline, obtained using Vlieg's DIF software"""
def setup_method(self):
_TestCubic.setup_method(self)
self.mock_hardware.set_lower_limit(NUNAME, 0)
self.mock_hardware.set_upper_limit('delta', 90)
self.constraints._constrained = {'chi': 0, 'phi': 0, 'a_eq_b': None}
self.wavelength = 1
self.UB = I * 2 * pi
self.places = 4
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
self._check_angles_to_hkl(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
if fails:
self._check_hkl_to_angles_fails(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
def testHkl001(self):
self._check((0, 0, 1), # betaout=30
P(mu=30, delta=0, nu=60, eta=90, chi=0, phi=0), fails=True)
def testHkl010(self):
self._check((0, 1, 0), # betaout=0
P(mu=0, delta=60, nu=0, eta=120, chi=0, phi=0))
def testHkl011(self):
self._check((0, 1, 1), # betaout=30
P(mu=30, delta=54.7356, nu=90, eta=125.2644, chi=0, phi=0))
def testHkl100(self):
self._check((1, 0, 0), # betaout=0
P(mu=0, delta=60, nu=0, eta=30, chi=0, phi=0))
def testHkl101(self):
self._check((1, 0, 1), # betaout=30
P(mu=30, delta=54.7356, nu=90, eta=35.2644, chi=0, phi=0))
def testHkl110(self):
self._check((1, 1, 0), # betaout=0
P(mu=0, delta=90, nu=0, eta=90, chi=0, phi=0))
def testHkl11nearly0(self):
self.places = 3
self._check((1, 1, .0001), # betaout=0
P(mu=0.0029, delta=89.9971, nu=90.0058, eta=90, chi=0,
phi=0))
def testHkl111(self):
self._check((1, 1, 1), # betaout=30
P(mu=30, delta=54.7356, nu=150, eta=99.7356, chi=0, phi=0))
def testHklover100(self):
self._check((1.1, 0, 0), # betaout=0
P(mu=0, delta=66.7340, nu=0, eta=33.3670, chi=0, phi=0))
def testHklunder100(self):
self._check((.9, 0, 0), # betaout=0
P(mu=0, delta=53.4874, nu=0, eta=26.7437, chi=0, phi=0))
def testHkl788(self):
self._check((.7, .8, .8), # betaout=23.5782
P(mu=23.5782, delta=59.9980, nu=76.7037, eta=84.2591,
chi=0, phi=0))
def testHkl789(self):
self._check((.7, .8, .9), # betaout=26.7437
P(mu=26.74368, delta=58.6754, nu=86.6919, eta=85.3391,
chi=0, phi=0))
def testHkl7810(self):
self._check((.7, .8, 1), # betaout=30
P(mu=30, delta=57.0626, nu=96.86590, eta=86.6739, chi=0,
phi=0))
class SkipTestFixedChiPhiPsiModeSurfaceNormalVertical(_TestCubic):
def setup_method(self):
_TestCubic.setup_method(self)
self.mock_hardware.set_lower_limit(NUNAME, 0)
self.constraints._constrained = {'chi': 90 * TORAD, 'phi': 0,
'a_eq_b': None}
self.wavelength = 1
self.UB = I * 2 * pi
self.places = 4
self.mock_hardware.set_lower_limit('mu', None)
self.mock_hardware.set_lower_limit('eta', None)
self.mock_hardware.set_lower_limit('chi', None)
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
self._check_angles_to_hkl(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
if fails:
self._check_hkl_to_angles_fails(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
def testHkl001(self):
self._check((0, 0, 1), # betaout=30
P(mu=30, delta=0, nu=60, eta=90, chi=0, phi=0), fails=True)
def testHkl010(self):
self._check((0, 1, 0), # betaout=0
P(mu=120, delta=0, nu=60, eta=0, chi=90, phi=0))
def testHkl011(self):
self._check((0, 1, 1), # betaout=30
P(mu=30, delta=54.7356, nu=90, eta=125.2644, chi=0, phi=0))
def testHkl100(self):
self._check((1, 0, 0), # betaout=0
P(mu=0, delta=60, nu=0, eta=30, chi=0, phi=0))
def testHkl101(self):
self._check((1, 0, 1), # betaout=30
P(mu=30, delta=54.7356, nu=90, eta=35.2644, chi=0, phi=0))
def testHkl110(self):
self._check((1, 1, 0), # betaout=0
P(mu=0, delta=90, nu=0, eta=90, chi=0, phi=0))
def testHkl11nearly0(self):
self.places = 3
self._check((1, 1, .0001), # betaout=0
P(mu=0.0029, delta=89.9971, nu=90.0058, eta=90, chi=0,
phi=0))
def testHkl111(self):
self._check((1, 1, 1), # betaout=30
P(mu=30, delta=54.7356, nu=150, eta=99.7356, chi=0, phi=0))
def testHklover100(self):
self._check((1.1, 0, 0), # betaout=0
P(mu=0, delta=66.7340, nu=0, eta=33.3670, chi=0, phi=0))
def testHklunder100(self):
self._check((.9, 0, 0), # betaout=0
P(mu=0, delta=53.4874, nu=0, eta=26.7437, chi=0, phi=0))
def testHkl788(self):
self._check((.7, .8, .8), # betaout=23.5782
P(mu=23.5782, delta=59.9980, nu=76.7037, eta=84.2591,
chi=0, phi=0))
def testHkl789(self):
self._check((.7, .8, .9), # betaout=26.7437
P(mu=26.74368, delta=58.6754, nu=86.6919, eta=85.3391,
chi=0, phi=0))
def testHkl7810(self):
self._check((.7, .8, 1), # betaout=30
P(mu=30, delta=57.0626, nu=96.86590, eta=86.6739, chi=0,
phi=0))
class SkipTestFixedChiPhiPsiModeSurfaceNormalVerticalI16(_TestCubic):
# testing with Chris N. for pre christmas 2012 i16 experiment
def setup_method(self):
_TestCubic.setup_method(self)
self.mock_hardware.set_lower_limit('nu', 0)
self.constraints._constrained = {'chi': 90 * TORAD, 'phi': 0,
'a_eq_b': None}
self.wavelength = 1
self.UB = I * 2 * pi
self.places = 4
self.mock_hardware.set_lower_limit('mu', None)
self.mock_hardware.set_lower_limit('eta', None)
self.mock_hardware.set_lower_limit('chi', None)
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
# self._check_angles_to_hkl(
# '', 999, 999, hkl, pos, self.wavelength, virtual_expected)
if fails:
self._check_hkl_to_angles_fails(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
def testHkl_1_1_0(self):
self._check((1, 1, 0.001), # betaout=0
P(mu=0, delta=60, nu=0, eta=30, chi=0, phi=0))
#(-89.9714, 89.9570, 90.0382, 90.0143, 90.0000, 0.0000)
def testHkl_1_1_05(self):
self._check((1, 1, 0.5), # betaout=0
P(mu=0, delta=60, nu=0, eta=30, chi=0, phi=0))
def testHkl_1_1_1(self):
self._check((1, 1, 1), # betaout=0
P(mu=0, delta=60, nu=0, eta=30, chi=0, phi=0))
# (-58.6003, 42.7342, 132.9004, 106.3249, 90.0000, 0.0000
def testHkl_1_1_15(self):
self._check((1, 1, 1.5), # betaout=0
P(mu=0, delta=60, nu=0, eta=30, chi=0, phi=0))
class TestConstrain3Sample_ChiPhiEta(_TestCubic):
def setup_method(self):
_TestCubic.setup_method(self)
self.mock_hardware.set_lower_limit(NUNAME, 0)
self.constraints._constrained = {'chi': 90 * TORAD, 'phi': 0,
'a_eq_b': None}
self.wavelength = 1
self.UB = I * 2 * pi
self.places = 4
self.mock_hardware.set_lower_limit('mu', None)
self.mock_hardware.set_lower_limit('eta', None)
self.mock_hardware.set_lower_limit('chi', None)
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
self._check_angles_to_hkl(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
if fails:
self._check_hkl_to_angles_fails(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
def testHkl_all0_001(self):
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0}
self._check((0, 0, 1),
P(mu=30, delta=0, nu=60, eta=0, chi=0, phi=0))
def testHkl_all0_010(self):
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0}
self._check((0, 1, 0),
P(mu=120, delta=0, nu=60, eta=0, chi=0, phi=0))
def testHkl_all0_011(self):
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0}
self._check((0, 1, 1),
P(mu=90, delta=0, nu=90, eta=0, chi=0, phi=0))
def testHkl_phi30_100(self):
self.constraints._constrained = {'chi': 0, 'phi': 30 * TORAD, 'eta': 0}
self._check((1, 0, 0),
P(mu=0, delta=60, nu=0, eta=0, chi=0, phi=30))
def testHkl_eta30_100(self):
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 30 * TORAD}
self._check((1, 0, 0),
P(mu=0, delta=60, nu=0, eta=30, chi=0, phi=0))
def testHkl_phi90_110(self):
self.constraints._constrained = {'chi': 0, 'phi': 90 * TORAD, 'eta': 0}
self._check((1, 1, 0),
P(mu=0, delta=90, nu=0, eta=0, chi=0, phi=90))
def testHkl_eta90_110(self):
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 90 * TORAD}
self._check((1, 1, 0),
P(mu=0, delta=90, nu=0, eta=90, chi=0, phi=0))
def testHkl_all0_1(self):
self.mock_hardware.set_upper_limit('delta', 91)
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0 * TORAD}
self._check((.01, .01, .1),
P(mu=8.6194, delta=0.5730, nu=5.7607, eta=0, chi=0, phi=0))
def testHkl_all0_2(self):
self.mock_hardware.set_upper_limit('delta', 91)
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0 * TORAD}
self._check((0, 0, .1),
P(mu=2.8660, delta=0, nu=5.7320, eta=0, chi=0, phi=0))
def testHkl_all0_3(self):
self.mock_hardware.set_upper_limit('delta', 91)
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0 * TORAD}
self._check((.1, 0, .01),
P(mu=30.3314, delta=5.7392, nu= 0.4970, eta=0, chi=0, phi=0))
def testHkl_show_all_solutionsall0_3(self):
self.mock_hardware.set_upper_limit('delta', 91)
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0 * TORAD}
self._check((.1, 0, .01),
P(mu=30.3314, delta=5.7392, nu= 0.4970, eta=0, chi=0, phi=0))
print self.calc.hkl_to_all_angles(.1, 0, .01, 1)
def testHkl_all0_010to001(self):
self.constraints._constrained = {'chi': 0, 'phi': 0, 'eta': 0}
self._check((0, cos(4 * TORAD), sin(4 * TORAD)),
P(mu=120-4, delta=0, nu=60, eta=0, chi=0, phi=0))
def testHkl_1(self):
self.wavelength = .1
self.constraints._constrained = {'chi': 0, 'phi': 0 * TORAD, 'eta': 0}
self._check((0, 0, 1),
P(mu=2.8660, delta=0, nu=5.7320, eta=0, chi=0, phi=0))
def testHkl_2(self):
self.wavelength = .1
self.constraints._constrained = {'chi': 0, 'phi': 0 * TORAD, 'eta': 0}
self._check((0, 0, 1),
P(mu=2.8660, delta=0, nu=5.7320, eta=0, chi=0, phi=0))
def testHkl_3(self):
self.mock_hardware.set_upper_limit('delta', 91)
self.wavelength = .1
self.constraints._constrained = {'chi': 0, 'phi': 0 * TORAD, 'eta': 0}
self._check((1, 0, .1),
P(mu= 30.3314, delta=5.7392, nu= 0.4970, eta=0, chi=0, phi=0))
class TestHorizontalDeltaNadeta0_JiraI16_32_failure(_BaseTest):
"""
The data here is taken from a trial experiment which failed. Diamond's internal Jira:
http://jira.diamond.ac.uk/browse/I16-32"""
def setup_method(self):
_BaseTest.setup_method(self)
self.mock_hardware.set_lower_limit(NUNAME, 0)
self.wavelength = 12.39842 / 8
self.UB = matrix([[ -1.46410390e+00, -1.07335571e+00, 2.44799214e-03],
[ 3.94098508e-01, -1.07091934e+00, -6.41132943e-04],
[ 7.93297438e-03, 4.01315826e-03, 4.83650166e-01]])
self.places = 3
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False, skip_test_pair_verification=False):
if not skip_test_pair_verification:
self._check_angles_to_hkl(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
if fails:
self._check_hkl_to_angles_fails(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles(
'', 999, 999, hkl, pos, self.wavelength, virtual_expected)
def test_hkl_bisecting_works_okay_on_i16(self):
self.constraints._constrained = {'delta': 0, 'a_eq_b': None, 'eta': 0}
self._check([-1.1812112493619709, -0.71251524866987204, 5.1997083010199221],
P(mu=26, delta=0, nu=52, eta=0, chi=45.2453, phi=186.6933-360), fails=False)
def test_hkl_psi90_works_okay_on_i16(self):
# This is failing here but on the live one. Suggesting some extreme sensitivity?
self.constraints._constrained = {'delta': 0, 'psi': 90 * TORAD, 'eta': 0}
self._check([-1.1812112493619709, -0.71251524866987204, 5.1997083010199221],
P(mu=26, delta=0, nu=52, eta=0, chi=45.2453, phi=186.6933-360), fails=False)
def test_hkl_alpha_17_9776_used_to_fail(self):
# This is failing here but on the live one. Suggesting some extreme sensitivity?
self.constraints._constrained = {'delta': 0, 'alpha': 17.9776 * TORAD, 'eta': 0}
self._check([-1.1812112493619709, -0.71251524866987204, 5.1997083010199221],
P(mu=26, delta=0, nu=52, eta=0, chi=45.2453, phi=186.6933-360), fails=False)
def test_hkl_alpha_17_9776_failing_after_bigger_small(self):
# This is failing here but on the live one. Suggesting some extreme sensitivity?
self.constraints._constrained = {'delta': 0, 'alpha': 17.8776 * TORAD, 'eta': 0}
self._check([-1.1812112493619709, -0.71251524866987204, 5.1997083010199221],
P(mu=25.85, delta=0, nu=52, eta=0, chi=45.2453, phi=-173.518), fails=False)
#skip_test_pair_verification
def posFromI16sEuler(phi, chi, eta, mu, delta, gamma):
return YouPosition(mu, delta, gamma, eta, chi, phi)
class TestAnglesToHkl_I16Examples():
def __init__(self):
self.UB1 = matrix((
(0.9996954135095477, -0.01745240643728364, -0.017449748351250637),
(0.01744974835125045, 0.9998476951563913, -0.0003045864904520898),
(0.017452406437283505, -1.1135499981271473e-16, 0.9998476951563912))
) * (2 * pi)
self.WL1 = 1 # Angstrom
def test_anglesToHkl_mu_0_gam_0(self):
pos = posFromI16sEuler(1, 1, 30, 0, 60, 0).inRadians()
arrayeq_(youAnglesToHkl(pos, self.WL1, self.UB1), [1, 0, 0])
def test_anglesToHkl_mu_0_gam_10(self):
pos = posFromI16sEuler(1, 1, 30, 0, 60, 10).inRadians()
arrayeq_(youAnglesToHkl(pos, self.WL1, self.UB1),
[1.00379806, -0.006578435, 0.08682408])
def test_anglesToHkl_mu_10_gam_0(self):
pos = posFromI16sEuler(1, 1, 30, 10, 60, 0).inRadians()
arrayeq_(youAnglesToHkl(pos, self.WL1, self.UB1),
[0.99620193, 0.0065784359, 0.08682408])
def test_anglesToHkl_arbitrary(self):
pos = posFromI16sEuler(1.9, 2.9, 30.9, 0.9, 60.9, 2.9).inRadians()
arrayeq_(youAnglesToHkl(pos, self.WL1, self.UB1),
[1.01174189, 0.02368622, 0.06627361])

View File

@@ -0,0 +1,707 @@
###
# 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/>.
###
import math
from math import pi, sin, cos
from nose.plugins.skip import SkipTest
from nose.tools import assert_almost_equal, raises, eq_ # @UnresolvedImport
from mock import Mock
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.hkl.you.calc import YouHklCalculator, I, \
_calc_angle_between_naz_and_qaz, merge_nearly_equal_pairs
from test.tools import assert_matrix_almost_equal, \
assert_2darray_almost_equal, aneq_
from diffcalc.hkl.you.geometry import YouPosition
from test.diffcalc.hkl.vlieg.test_calc import \
createMockDiffractometerGeometry, createMockHardwareMonitor, \
createMockUbcalc
from test.diffcalc.test_hardware import SimpleHardwareAdapter
from diffcalc.util import DiffcalcException
from diffcalc.hkl.you.constraints import NUNAME
TORAD = pi / 180
TODEG = 180 / pi
x = matrix('1; 0; 0')
y = matrix('0; 1; 0')
z = matrix('0; 0; 1')
def isnan(n):
# math.isnan was introduced only in python 2.6 and is not in Jython (2.5.2)
try:
return math.isnan(n)
except AttributeError:
return n != n # for Jython
class Test_anglesToVirtualAngles():
def setup_method(self):
constraints = Mock()
constraints.is_fully_constrained.return_value = True
self.calc = YouHklCalculator(createMockUbcalc(None),
createMockDiffractometerGeometry(),
createMockHardwareMonitor(),
constraints)
def check_angle(self, name, expected, mu=-99, delta=99, nu=99,
eta=99, chi=99, phi=99):
"""All in degrees"""
pos = YouPosition(mu, delta, nu, eta, chi, phi)
pos.changeToRadians()
calculated = self.calc._anglesToVirtualAngles(pos, None)[name] * TODEG
assert_almost_equal(calculated, expected)
# theta
def test_theta0(self):
self.check_angle('theta', 0, delta=0, nu=0)
def test_theta1(self):
self.check_angle('theta', 1, delta=2, nu=0)
def test_theta2(self):
self.check_angle('theta', 1, delta=0, nu=2)
def test_theta3(self):
self.check_angle('theta', 1, delta=-2, nu=0)
def test_theta4(self):
self.check_angle('theta', 1, delta=0, nu=-2)
# qaz
def test_qaz0_degenerate_case(self):
self.check_angle('qaz', 0, delta=0, nu=0)
def test_qaz1(self):
self.check_angle('qaz', 90, delta=2, nu=0)
def test_qaz2(self):
self.check_angle('qaz', 90, delta=90, nu=0)
def test_qaz3(self):
self.check_angle('qaz', 0, delta=0, nu=1,)
# Can't see one by eye
# def test_qaz4(self):
# pos = YouPosition(delta=20*TORAD, nu=20*TORAD)#.inRadians()
# assert_almost_equal(
# self.calc._anglesToVirtualAngles(pos, None)['qaz']*TODEG, 45)
#alpha
def test_defaultReferenceValue(self):
# The following tests depemd on this
assert_matrix_almost_equal(self.calc._ubcalc.n_phi, matrix([[0], [0], [1]]))
def test_alpha0(self):
self.check_angle('alpha', 0, mu=0, eta=0, chi=0, phi=0)
def test_alpha1(self):
self.check_angle('alpha', 0, mu=0, eta=0, chi=0, phi=10)
def test_alpha2(self):
self.check_angle('alpha', 0, mu=0, eta=0, chi=0, phi=-10)
def test_alpha3(self):
self.check_angle('alpha', 2, mu=2, eta=0, chi=0, phi=0)
def test_alpha4(self):
self.check_angle('alpha', -2, mu=-2, eta=0, chi=0, phi=0)
def test_alpha5(self):
self.check_angle('alpha', 2, mu=0, eta=90, chi=2, phi=0)
#beta
def test_beta0(self):
self.check_angle('beta', 0, delta=0, nu=0, mu=0, eta=0, chi=0, phi=0)
def test_beta1(self):
self.check_angle('beta', 0, delta=10, nu=0, mu=0, eta=6, chi=0, phi=5)
def test_beta2(self):
self.check_angle('beta', 10, delta=0, nu=10, mu=0, eta=0, chi=0, phi=0)
def test_beta3(self):
self.check_angle('beta', -10, delta=0, nu=-10, mu=0, eta=0, chi=0,
phi=0)
def test_beta4(self):
self.check_angle('beta', 5, delta=0, nu=10, mu=5, eta=0, chi=0, phi=0)
# azimuth
def test_naz0(self):
self.check_angle('naz', 0, mu=0, eta=0, chi=0, phi=0)
def test_naz1(self):
self.check_angle('naz', 0, mu=0, eta=0, chi=0, phi=10)
def test_naz3(self):
self.check_angle('naz', 0, mu=10, eta=0, chi=0, phi=10)
def test_naz4(self):
self.check_angle('naz', 2, mu=0, eta=0, chi=2, phi=0)
def test_naz5(self):
self.check_angle('naz', -2, mu=0, eta=0, chi=-2, phi=0)
#tau
def test_tau0(self):
self.check_angle('tau', 0, mu=0, delta=0, nu=0, eta=0, chi=0, phi=0)
#self.check_angle('tau_from_dot_product', 90, mu=0, delta=0,
#nu=0, eta=0, chi=0, phi=0)
def test_tau1(self):
self.check_angle('tau', 90, mu=0, delta=20, nu=0, eta=10, chi=0, phi=0)
#self.check_angle('tau_from_dot_product', 90, mu=0, delta=20,
#nu=0, eta=10, chi=0, phi=0)
def test_tau2(self):
self.check_angle('tau', 90, mu=0, delta=20, nu=0, eta=10, chi=0, phi=3)
#self.check_angle('tau_from_dot_product', 90, mu=0, delta=20,
#nu=0, eta=10, chi=0, phi=3)
def test_tau3(self):
self.check_angle('tau', 88, mu=0, delta=20, nu=0, eta=10, chi=2, phi=0)
#self.check_angle('tau_from_dot_product', 88, mu=0, delta=20,
#nu=0, eta=10, chi=2, phi=0)
def test_tau4(self):
self.check_angle('tau', 92, mu=0, delta=20, nu=0, eta=10, chi=-2,
phi=0)
#self.check_angle('tau_from_dot_product', 92, mu=0, delta=20,
#nu=0, eta=10, chi=-2, phi=0)
def test_tau5(self):
self.check_angle('tau', 10, mu=0, delta=0, nu=20, eta=0, chi=0, phi=0)
#self.check_angle('tau_from_dot_product', 10, mu=0, delta=0,
#nu=20, eta=0, chi=0, phi=0)
#psi
def test_psi0(self):
pos = YouPosition(0, 0, 0, 0, 0, 0)
assert isnan(self.calc._anglesToVirtualAngles(pos, None)['psi'])
def test_psi1(self):
self.check_angle('psi', 90, mu=0, delta=11, nu=0, eta=0, chi=0, phi=0)
def test_psi2(self):
self.check_angle(
'psi', 100, mu=10, delta=.00000001, nu=0, eta=0, chi=0, phi=0)
def test_psi3(self):
self.check_angle(
'psi', 80, mu=-10, delta=.00000001, nu=0, eta=0, chi=0, phi=0)
def test_psi4(self):
self.check_angle(
'psi', 90, mu=0, delta=11, nu=0, eta=0, chi=0, phi=12.3)
def test_psi5(self):
#self.check_angle('psi', 0, mu=10, delta=.00000001,
#nu=0, eta=0, chi=90, phi=0)
pos = YouPosition(0, .00000001, 0, 0, 90, 0)
pos.changeToRadians()
assert isnan(self.calc._anglesToVirtualAngles(pos, None)['psi'])
def test_psi6(self):
self.check_angle(
'psi', 90, mu=0, delta=0.00000001, nu=0, eta=90, chi=0, phi=0)
def test_psi7(self):
self.check_angle(
'psi', 92, mu=0, delta=0.00000001, nu=0, eta=90, chi=2, phi=0)
def test_psi8(self):
self.check_angle(
'psi', 88, mu=0, delta=0.00000001, nu=0, eta=90, chi=-2, phi=0)
class Test_calc_theta():
def setup_method(self):
self.calc = YouHklCalculator(createMockUbcalc(I * 2 * pi),
createMockDiffractometerGeometry(),
createMockHardwareMonitor(),
Mock())
self.e = 12.398420 # 1 Angstrom
def test_100(self):
h_phi = matrix([[1], [0], [0]])
assert_almost_equal(self.calc._calc_theta(h_phi * 2 * pi, 1) * TODEG,
30)
@raises(DiffcalcException)
def test_too_short(self):
h_phi = matrix([[1], [0], [0]])
self.calc._calc_theta(h_phi * 0, 1)
@raises(DiffcalcException)
def test_too_long(self):
h_phi = matrix([[1], [0], [0]])
self.calc._calc_theta(h_phi * 2 * pi, 10)
class Test_calc_remaining_reference_angles_given_one():
# TODO: These are very incomplete due to either totally failing inutuition
# or code!
def setup_method(self):
self.calc = YouHklCalculator(createMockUbcalc(None),
createMockDiffractometerGeometry(),
createMockHardwareMonitor(),
Mock())
def check(self, name, value, theta, tau, psi_e, alpha_e, beta_e):
# all in deg
psi, alpha, beta = self.calc._calc_remaining_reference_angles(
name, value * TORAD, theta * TORAD, tau * TORAD)
print 'psi', psi * TODEG, ' alpha:', alpha * TODEG,\
' beta:', beta * TODEG
if psi_e is not None:
assert_almost_equal(psi * TODEG, psi_e)
if alpha_e is not None:
assert_almost_equal(alpha * TODEG, alpha_e)
if beta_e is not None:
assert_almost_equal(beta * TODEG, beta_e)
def test_psi_given0(self):
self.check('psi', 90, theta=10, tau=90, psi_e=90,
alpha_e=0, beta_e=0)
def test_psi_given1(self):
self.check('psi', 92, theta=0, tau=90, psi_e=92,
alpha_e=2, beta_e=-2)
def test_psi_given3(self):
self.check('psi', 88, theta=0, tau=90, psi_e=88,
alpha_e=-2, beta_e=2)
def test_psi_given4(self):
self.check('psi', 0, theta=0, tau=90, psi_e=0,
alpha_e=-90, beta_e=90)
def test_psi_given4a(self):
self.check('psi', 180, theta=0, tau=90, psi_e=180,
alpha_e=90, beta_e=-90)
def test_psi_given5(self):
raise SkipTest
# TODO: I don't understand why this one passes!
self.check('psi', 180, theta=0, tau=80,
psi_e=180, alpha_e=80, beta_e=-80)
self.check('psi', 180, theta=0, tau=80,
psi_e=180, alpha_e=90, beta_e=-90)
def test_a_eq_b0(self):
self.check('a_eq_b', 9999, theta=0, tau=90,
psi_e=90, alpha_e=0, beta_e=0)
def test_alpha_given(self):
self.check('alpha', 2, theta=0, tau=90,
psi_e=92, alpha_e=2, beta_e=-2)
def test_beta_given(self):
self.check('beta', 2, theta=0, tau=90,
psi_e=88, alpha_e=-2, beta_e=2)
# def test_a_eq_b1(self):
# self.check('a_eq_b', 9999, theta=20, tau=90,
# psi_e=90, alpha_e=10, beta_e=10)
# def test_psi_given0(self):
# self.check('psi', 90, theta=10, tau=45, psi_e=90,
# alpha_e=7.0530221302831952, beta_e=7.0530221302831952)
def test_merge_nearly_equal_detector_angle_pairs_different(self):
pairs = [(1,2), (1,2.1)]
assert_2darray_almost_equal(
merge_nearly_equal_pairs(pairs), pairs)
def test_merge_nearly_equal_detector_angle_pairs_1(self):
pairs = [(1, 2), (1, 2)]
assert_2darray_almost_equal(
merge_nearly_equal_pairs(pairs), [(1, 2)])
def test_merge_nearly_equal_detector_angle_pairs_2(self):
pairs = [(1, 2), (1, 2), (1, 2)]
assert_2darray_almost_equal(
merge_nearly_equal_pairs(pairs), [(1, 2)])
def test_merge_nearly_equal_detector_angle_pairs_3(self):
pairs = [(1, 2.2), (1, 2), (1, 2), (1, 2)]
assert_2darray_almost_equal(
merge_nearly_equal_pairs(pairs), [(1, 2.2), (1, 2)])
def test_merge_nearly_equal_detector_angle_pairs_4(self):
pairs = [(1, 2.2), (1, 2), (1, 2), (1, 2.2)]
assert_2darray_almost_equal(
merge_nearly_equal_pairs(pairs), [(1, 2.2), (1, 2)])
class Test_calc_detector_angles_given_one():
def setup_method(self):
self.calc = YouHklCalculator(createMockUbcalc(None),
createMockDiffractometerGeometry(),
createMockHardwareMonitor(),
Mock())
def check(self, name, value, theta, delta_e, nu_e, qaz_e):
# all in deg
delta, nu, qaz = self.calc._calc_remaining_detector_angles(
name, value * TORAD, theta * TORAD)
assert_almost_equal(delta * TODEG, delta_e)
assert_almost_equal(nu * TODEG, nu_e)
if qaz_e is not None:
assert_almost_equal(qaz * TODEG, qaz_e)
def test_nu_given0(self):
self.check(NUNAME, 0, theta=3, delta_e=6, nu_e=0, qaz_e=90)
def test_nu_given1(self):
self.check(NUNAME, 10, theta=7.0530221302831952,
delta_e=10, nu_e=10, qaz_e=None)
def test_nu_given2(self):
self.check(NUNAME, 6, theta=3, delta_e=0, nu_e=6, qaz_e=0)
def test_delta_given0(self):
self.check('delta', 0, theta=3, delta_e=0, nu_e=6, qaz_e=0)
def test_delta_given1(self):
self.check('delta', 10, theta=7.0530221302831952,
delta_e=10, nu_e=10, qaz_e=None)
def test_delta_given2(self):
self.check('delta', 6, theta=3, delta_e=6, nu_e=0, qaz_e=90)
def test_qaz_given0(self):
self.check('qaz', 90, theta=3, delta_e=6, nu_e=0, qaz_e=90)
def test_qaz_given2(self):
self.check('qaz', 0, theta=3, delta_e=0, nu_e=6, qaz_e=0)
class Test_calc_angle_between_naz_and_qaz():
def test1(self):
diff = _calc_angle_between_naz_and_qaz(
theta=0, alpha=0, tau=90 * TORAD)
assert_almost_equal(diff * TODEG, 90)
def test2(self):
diff = _calc_angle_between_naz_and_qaz(
theta=0 * TORAD, alpha=0, tau=80 * TORAD)
assert_almost_equal(diff * TODEG, 80)
class Test_calc_remaining_sample_angles_given_one():
#_calc_remaining_detector_angles_given_one
def setup_method(self):
self.calc = YouHklCalculator(createMockUbcalc(None),
createMockDiffractometerGeometry(),
createMockHardwareMonitor(),
Mock())
def check(self, name, value, Q_lab, n_lab, Q_phi, n_phi,
phi_e, chi_e, eta_e, mu_e):
phi, chi, eta, mu = self.calc._calc_remaining_sample_angles(
name, value * TORAD, Q_lab, n_lab, Q_phi, n_phi)
print 'phi', phi * TODEG, ' chi:', chi * TODEG, ' eta:', eta * TODEG,\
' mu:', mu * TODEG
if phi_e is not None:
assert_almost_equal(phi * TODEG, phi_e)
if chi_e is not None:
assert_almost_equal(chi * TODEG, chi_e)
if eta_e is not None:
assert_almost_equal(eta * TODEG, eta_e)
if mu_e is not None:
assert_almost_equal(mu * TODEG, mu_e)
@raises(ValueError)
def test_constrain_xx_degenerate(self):
self.check('mu', 0, Q_lab=x, n_lab=x, Q_phi=x, n_phi=x,
phi_e=0, chi_e=0, eta_e=0, mu_e=0)
def test_constrain_mu_0(self):
raise SkipTest()
self.check('mu', 0, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=0, chi_e=0, eta_e=0, mu_e=0)
def test_constrain_mu_10(self):
raise SkipTest()
self.check('mu', 10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=-90, chi_e=10, eta_e=-90, mu_e=10)
def test_constrain_mu_n10(self):
raise SkipTest()
self.check('mu', -10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=90, chi_e=10, eta_e=90, mu_e=-10)
def test_constrain_eta_10_wasfailing(self):
# Required the choice of a different equation
self.check('eta', 10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=-10, chi_e=0, eta_e=10, mu_e=0)
def test_constrain_eta_n10(self):
self.check('eta', -10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=10, chi_e=0, eta_e=-10, mu_e=0)
def test_constrain_eta_20_with_theta_20(self):
theta = 20 * TORAD
Q_lab = matrix([[cos(theta)], [-sin(theta)], [0]])
self.check('eta', 20, Q_lab=Q_lab, n_lab=z, Q_phi=x, n_phi=z,
phi_e=0, chi_e=0, eta_e=20, mu_e=0)
@raises(ValueError)
def test_constrain_chi_0_degenerate(self):
self.check('chi', 0, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=0, chi_e=0, eta_e=0, mu_e=0)
def test_constrain_chi_10(self):
self.check('chi', 10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=-90, chi_e=10, eta_e=90, mu_e=-10)
def test_constrain_chi_90(self):
# mu is off by 180, but youcalc tries +-x and 180+-x anyway
raise SkipTest()
self.check('chi', 90, Q_lab=z * (-1), n_lab=x, Q_phi=x, n_phi=z,
phi_e=0, chi_e=90, eta_e=0, mu_e=0)
def test_constrain_phi_0(self):
self.check('phi', 0, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=0, chi_e=0, eta_e=0, mu_e=0)
def test_constrain_phi_10(self):
self.check('phi', 10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=10, chi_e=0, eta_e=-10, mu_e=0)
def test_constrain_phi_n10(self):
self.check('phi', -10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=-10, chi_e=0, eta_e=10, mu_e=0)
def test_constrain_phi_20_with_theta_20(self):
theta = 20 * TORAD
Q_lab = matrix([[cos(theta)], [-sin(theta)], [0]])
self.check('phi', 20, Q_lab=Q_lab, n_lab=z, Q_phi=x, n_phi=z,
phi_e=20, chi_e=0, eta_e=0, mu_e=0)
class TestSolutionGenerator():
def setup_method(self):
names = ['delta', NUNAME, 'mu', 'eta', 'chi', 'phi']
self.hardware = SimpleHardwareAdapter(names)
self.calc = YouHklCalculator(createMockUbcalc(None),
createMockDiffractometerGeometry(),
self.hardware,
Mock())
# constraint could have been 'delta', NUNAME, 'qaz' or 'naz'.
def test_generate_possible_det_soln_no_limits_constrained_qaz_or_naz(self):
# we will enfoce the order too, incase this later effects heuristically
# made choices
expected = (
(.1, .2),
(.1, -.2),
(.1, .2 - pi),
(.1, pi - .2),
(-.1, .2),
(-.1, -.2),
(-.1, .2 - pi),
(-.1, pi - .2),
(.1 - pi, .2), # pi + x cuts to x-pi
(.1 - pi, -.2),
(.1 - pi, .2 - pi),
(.1 - pi, pi - .2),
(pi - .1, .2),
(pi - .1, -.2),
(pi - .1, .2 - pi),
(pi - .1, pi - .2),
)
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(.1, .2), ('delta', NUNAME), ('naz',)))
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(.1, .2), ('delta', NUNAME), ('qaz',)))
def test_generate_poss_det_soln_no_lim_cons_qaz_or_naz_delta_and_nu_at_zro(self): # @IgnorePep8
# we will enfoce the order too, incase this later effects hearistically
# made choices
expected = (
(0., 0,),
(0., pi),
(pi, 0.),
(pi, pi)
)
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(-2e-9, 2e-9), ('delta', NUNAME), ('naz',)))
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(-2e-9, 2e-9), ('delta', NUNAME), ('qaz',)))
def test_generate_possible_det_solutions_no_limits_constrained_delta(self):
expected = (
(.1, .2),
(.1, -.2),
(.1, .2 - pi),
(.1, pi - .2),
)
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(.1, .2), ('delta', NUNAME), ('delta',)))
def test_generate_possible_det_solutions_no_limits_constrained_nu(self):
expected = (
(.1, .2),
(-.1, .2),
(.1 - pi, .2),
(pi - .1, .2),
)
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(.1, .2), ('delta', NUNAME), (NUNAME,)))
def test_generate_possible_det_soln_with_limits_constrained_delta(self):
self.hardware.set_lower_limit(NUNAME, 0)
expected = (
(.1, .2),
(.1, pi - .2),
)
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(.1, .2), ('delta', NUNAME), ('delta',)))
def test_generate_possible_det_solutions_with_limits_constrained_nu(self):
self.hardware.set_upper_limit('delta', 0)
expected = (
(-.1, .2),
(.1 - pi, .2), # cuts to .1-pi
)
assert_2darray_almost_equal(expected,
self.calc._generate_possible_solutions(
(.1, .2), ('delta', NUNAME), (NUNAME,)))
def test_generate_poss_det_soln_with_limits_overly_constrained_nu(self):
self.hardware.set_lower_limit('delta', .3)
self.hardware.set_upper_limit('delta', .31)
eq_(len(self.calc._generate_possible_solutions(
(.1, .2), ('delta', NUNAME), (NUNAME,))), 0)
def test_generate_possible_sample_solutions(self):
result = self.calc._generate_possible_solutions(
(.1, .2, .3, .4), ('mu', 'eta', 'chi', 'phi'), ('naz',))
generated = self._hardcoded_generate_possible_sample_solutions(
.1, .2, .3, .4, 'naz')
assert_2darray_almost_equal(generated, result)
eq_(4 ** 4, len(result))
def test_generate_possible_sample_solutions_fixed_chi(self):
result = self.calc._generate_possible_solutions(
(.1, .2, .3, .4), ('mu', 'eta', 'chi', 'phi'), ('chi',))
generated = self._hardcoded_generate_possible_sample_solutions(
.1, .2, .3, .4, 'chi')
assert_2darray_almost_equal(generated, result)
eq_(4 ** 3, len(result))
def test_generate_possible_sample_solutions_fixed_chi_positive_mu(self):
self.hardware.set_lower_limit('mu', 0)
result = self.calc._generate_possible_solutions(
(.1, .2, .3, .4), ('mu', 'eta', 'chi', 'phi'), ('chi',))
generated = self._hardcoded_generate_possible_sample_solutions(
.1, .2, .3, .4, 'chi')
assert_2darray_almost_equal(generated, result)
eq_(2 * (4 ** 2), len(result))
def _hardcoded_generate_possible_sample_solutions(self, mu, eta, chi, phi,
sample_constraint_name):
possible_solutions = []
_identity = lambda x: x
_transforms = (_identity,
lambda x: -x,
lambda x: pi + x,
lambda x: pi - x)
_transforms_for_zero = (lambda x: 0.,
lambda x: pi,)
SMALL = 1e-8
def cut_at_minus_pi(value):
if value < (-pi - SMALL):
return value + 2 * pi
if value >= pi + SMALL:
return value - 2 * pi
return value
def is_small(x):
return abs(x) < SMALL
name = sample_constraint_name
for transform in ((_identity,) if name == 'mu' else
_transforms if not is_small(mu) else
_transforms_for_zero):
transformed_mu = (transform(mu))
if not self.hardware.is_axis_value_within_limits('mu',
self.hardware.cut_angle('mu', transformed_mu * TODEG)):
continue
for transform in ((_identity,) if name == 'eta' else
_transforms if not is_small(eta) else
_transforms_for_zero):
transformed_eta = transform(eta)
if not self.hardware.is_axis_value_within_limits('eta',
self.hardware.cut_angle('eta', transformed_eta * TODEG)):
continue
for transform in ((_identity,) if name == 'chi' else
_transforms if not is_small(chi) else
_transforms_for_zero):
transformed_chi = transform(chi)
if not self.hardware.is_axis_value_within_limits('chi',
self.hardware.cut_angle('chi',
transformed_chi * TODEG)):
continue
for transform in ((_identity,) if name == 'phi' else
_transforms if not is_small(phi) else
_transforms_for_zero):
transformed_phi = transform(phi)
if not self.hardware.is_axis_value_within_limits('phi',
self.hardware.cut_angle('phi',
transformed_phi * TODEG)):
continue
possible_solutions.append((
cut_at_minus_pi(transformed_mu),
cut_at_minus_pi(transformed_eta),
cut_at_minus_pi(transformed_chi),
cut_at_minus_pi(transformed_phi)))
return possible_solutions

View File

@@ -0,0 +1,472 @@
###
# 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/>.
###
# TODO: class largely copied from test_calc
from math import pi
from mock import Mock
from nose.plugins.skip import SkipTest
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.hkl.you.geometry import SixCircle
from diffcalc.hkl.willmott.calc import \
WillmottHorizontalPosition as WillPos
from diffcalc.hkl.you.geometry import YouPosition as YouPos
from diffcalc.hkl.you.calc import YouUbCalcStrategy
from test.tools import matrixeq_
from diffcalc.ub.calc import UBCalculation
from diffcalc.ub.crystal import CrystalUnderTest
from diffcalc.ub.persistence import UbCalculationNonPersister
from test.diffcalc.hkl.you.test_calc import _BaseTest
from diffcalc.hkl.you.constraints import NUNAME
TORAD = pi / 180
TODEG = 180 / pi
I = matrix('1 0 0; 0 1 0; 0 0 1')
class SkipTestSurfaceNormalVerticalCubic(_BaseTest):
def setup_method(self):
_BaseTest.setup_method(self)
self.constraints._constrained = {'a_eq_b': None, 'mu': -pi / 2,
'eta': 0}
self.wavelength = 1
self.UB = I * 2 * pi
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
if pos is not None:
self._check_angles_to_hkl('', 999, 999, hkl, pos, self.wavelength,
virtual_expected)
if fails:
self._check_hkl_to_angles_fails('', 999, 999, hkl, pos,
self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles('', 999, 999, hkl, pos, self.wavelength,
virtual_expected)
def testHkl001(self):
pos = YouPos(mu=-90, delta=60, nu=0, eta=0, chi=90 + 30, phi=-90)
self._check((0, 0, 1), pos, {'alpha': 30, 'beta': 30})
def testHkl011(self):
# raise SkipTest()
# skipped because we can't calculate values to check against by hand
pos = YouPos(mu=-90, delta=90, nu=0, eta=0, chi=90 + 90, phi=-90)
self._check((0, 1, 1), pos, {'alpha': 45, 'beta': 45})
def testHkl010fails(self):
self._check((0, 1, 0),
None,
{'alpha': 30, 'beta': 30}, fails=True)
def testHkl100fails(self):
self._check((1, 0, 0),
None,
{'alpha': 30, 'beta': 30}, fails=True)
def testHkl111(self):
raise SkipTest()
# skipped because we can't calculate values to check against by hand
pos = YouPos(mu=-90, delta=90, nu=0, eta=0, chi=90 + 90, phi=-90)
self._check((1, 1, 1), pos, {'alpha': 45, 'beta': 45})
# Primary and secondary reflections found with the help of DDIF on Diamond's
# i07 on Jan 27 2010
HKL0 = 2, 19, 32
REF0 = WillPos(delta=21.975, gamma=4.419, omegah=2, phi=326.2)
HKL1 = 0, 7, 22
REF1 = WillPos(delta=11.292, gamma=2.844, omegah=2, phi=124.1)
WAVELENGTH = 0.6358
ENERGY = 12.39842 / WAVELENGTH
# This is the version that Diffcalc comes up with ( see following test)
U_DIFFCALC = matrix([[-0.7178876, 0.6643924, -0.2078944],
[-0.6559596, -0.5455572, 0.5216170],
[0.2331402, 0.5108327, 0.8274634]])
#class WillmottHorizontalGeometry(VliegGeometry):
#
# def __init__(self):
# VliegGeometry.__init__(self,
# name='willmott_horizontal',
# supported_mode_groups=[],
# fixed_parameters={},
# gamma_location='base'
# )
#
# def physical_angles_to_internal_position(self, physicalAngles):
# assert (len(physicalAngles) == 4), "Wrong length of input list"
# return WillPos(*physicalAngles)
#
# def internal_position_to_physical_angles(self, internalPosition):
# return internalPosition.totuple()
def willmott_to_you_fixed_mu_eta(pos):
pos = YouPos(mu=-90,
delta=pos.delta,
nu=pos.gamma,
eta=0,
chi=90 + pos.omegah,
phi=-90 - pos.phi)
if pos.phi > 180:
pos.phi -= 360
elif pos.phi < -180:
pos.phi += 360
return pos
class TestUBCalculationWithWillmotStrategy_Si_5_5_12_FixedMuEta():
def setup_method(self):
hardware = Mock()
hardware.get_axes_names.return_value = ('m', 'd', 'n', 'e', 'c',
'p')
self.ubcalc = UBCalculation(hardware, SixCircle(),
UbCalculationNonPersister(),
YouUbCalcStrategy())
def testAgainstResultsFromJan_27_2010(self):
self.ubcalc.start_new('test')
self.ubcalc.set_lattice('Si_5_5_12', 7.68, 53.48, 75.63, 90, 90, 90)
self.ubcalc.add_reflection(
HKL0[0], HKL0[1], HKL0[2], willmott_to_you_fixed_mu_eta(REF0),
ENERGY, 'ref0', None)
self.ubcalc.add_reflection(
HKL1[0], HKL1[1], HKL1[2], willmott_to_you_fixed_mu_eta(REF1),
ENERGY, 'ref1', None)
self.ubcalc.calculate_UB()
print "U: ", self.ubcalc.U
print "UB: ", self.ubcalc.UB
matrixeq_(self.ubcalc.U, U_DIFFCALC)
class TestFixedMuEta(_BaseTest):
def setup_method(self):
_BaseTest.setup_method(self)
self._configure_constraints()
self.wavelength = 0.6358
B = CrystalUnderTest('xtal', 7.68, 53.48,
75.63, 90, 90, 90).B
self.UB = U_DIFFCALC * B
self._configure_limits()
def _configure_constraints(self):
self.constraints._constrained = {'alpha': 2 * TORAD, 'mu': -pi / 2,
'eta': 0}
def _configure_limits(self):
self.mock_hardware.set_lower_limit(NUNAME, None)
self.mock_hardware.set_upper_limit('delta', 90)
self.mock_hardware.set_lower_limit('mu', None)
self.mock_hardware.set_lower_limit('eta', None)
self.mock_hardware.set_lower_limit('chi', None)
def _convert_willmott_pos(self, willmott_pos):
return willmott_to_you_fixed_mu_eta(willmott_pos)
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
self._check_angles_to_hkl('', 999, 999, hkl, pos, self.wavelength)
# virtual_expected)
if fails:
self._check_hkl_to_angles_fails('', 999, 999, hkl, pos,
self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles('', 999, 999, hkl, pos, self.wavelength,
virtual_expected)
def testHkl_2_19_32_found_orientation_setting(self):
'''Check that the or0 reflection maps back to the assumed hkl'''
self.places = 2
self._check_angles_to_hkl('', 999, 999, HKL0,
self._convert_willmott_pos(REF0),
self.wavelength, {'alpha': 2})
def testHkl_0_7_22_found_orientation_setting(self):
'''Check that the or1 reflection maps back to the assumed hkl'''
self.places = 0
self._check_angles_to_hkl('', 999, 999, HKL1,
self._convert_willmott_pos(REF1),
self.wavelength, {'alpha': 2})
def testHkl_2_19_32_calculated_from_DDIF(self):
raise SkipTest() # diffcalc finds a different soln (with -ve gamma)
self.places = 3
willpos = WillPos(delta=21.974, gamma=4.419, omegah=2, phi=-33.803)
self._check((2, 19, 32),
self._convert_willmott_pos(willpos),
{'alpha': 2})
def testHkl_0_7_22_calculated_from_DDIF(self):
raise SkipTest() # diffcalc finds a different soln (with -ve gamma)
self.places = 3
willpos = WillPos(delta=11.241801854649, gamma=-3.038407637123,
omegah=2, phi=-3.436557497330)
self._check((0, 7, 22),
self._convert_willmott_pos(willpos),
{'alpha': 2})
def testHkl_2_m5_12_calculated_from_DDIF(self):
raise SkipTest() # diffcalc finds a different soln (with -ve gamma)
self.places = 3
willpos = WillPos(delta=5.224, gamma=10.415, omegah=2, phi=-1.972)
self._check((2, -5, 12),
self._convert_willmott_pos(willpos),
{'alpha': 2})
def testHkl_2_19_32_calculated_predicted_with_diffcalc_and_found(self):
willpos = WillPos(delta=21.974032376045, gamma=-4.418955754003,
omegah=2, phi=64.027358409574)
self._check((2, 19, 32),
self._convert_willmott_pos(willpos),
{'alpha': 2})
def testHkl_0_7_22_calculated_predicted_with_diffcalc_and_found(self):
willpos = WillPos(delta=11.241801854649, gamma=-3.038407637123,
omegah=2, phi=-86.563442502670)
self._check((0, 7, 22),
self._convert_willmott_pos(willpos),
{'alpha': 2})
def testHkl_2_m5_12_calculated_predicted_with_diffcalc_and_found(self):
willpos = WillPos(delta=5.223972025344, gamma=-10.415435905622,
omegah=2, phi=-90 - 102.995854571805)
self._check((2, -5, 12),
self._convert_willmott_pos(willpos),
{'alpha': 2})
###############################################################################
def willmott_to_you_fixed_mu_chi(pos):
pos = YouPos(mu=-0,
delta=pos.delta,
nu=pos.gamma,
eta=pos.omegah,
chi=90,
phi=-pos.phi)
if pos.phi > 180:
pos.phi -= 360
elif pos.phi < -180:
pos.phi += 360
return pos
class TestUBCalculationWithWillmotStrategy_Si_5_5_12_FixedMuChi():
def setup_method(self):
hardware = Mock()
names = 'm', 'd', 'n', 'e', 'c', 'p'
hardware.get_axes_names.return_value = names
self.ubcalc = UBCalculation(hardware, SixCircle(),
UbCalculationNonPersister(),
YouUbCalcStrategy())
def testAgainstResultsFromJan_27_2010(self):
self.ubcalc.start_new('test')
self.ubcalc.set_lattice('Si_5_5_12', 7.68, 53.48, 75.63, 90, 90, 90)
self.ubcalc.add_reflection(
HKL0[0], HKL0[1], HKL0[2], willmott_to_you_fixed_mu_chi(REF0),
ENERGY, 'ref0', None)
self.ubcalc.add_reflection(
HKL1[0], HKL1[1], HKL1[2], willmott_to_you_fixed_mu_chi(REF1),
ENERGY, 'ref1', None)
self.ubcalc.calculate_UB()
print "U: ", self.ubcalc.U
print "UB: ", self.ubcalc.UB
matrixeq_(self.ubcalc.U, U_DIFFCALC)
class Test_Fixed_Mu_Chi(TestFixedMuEta):
def _configure_constraints(self):
self.constraints._constrained = {'alpha': 2 * TORAD, 'mu': 0,
'chi': pi / 2}
def _convert_willmott_pos(self, willmott_pos):
return willmott_to_you_fixed_mu_chi(willmott_pos)
# Primary and secondary reflections found with the help of DDIF on Diamond's
# i07 on Jan 28/29 2010
Pt531_HKL0 = -1.000, 1.000, 6.0000
Pt531_REF0 = WillPos(delta=9.3971025, gamma=-16.1812303, omegah=2,
phi=108.5510712)
Pt531_HKL1 = -2.000, -1.000, 7.0000
Pt531_REF1 = WillPos(delta=11.0126958, gamma=-11.8636128, omegah=2,
phi=40.3803393)
Pt531_HKL2 = 1, 1, 9
Pt531_REF2 = WillPos(delta=14.1881617, gamma=-7.7585939, omegah=2,
phi=176.5348540)
Pt531_WAVELENGTH = 0.6358
# This is U matrix displayed by DDIF
U_FROM_DDIF = matrix([[-0.00312594, -0.00063417, 0.99999491],
[0.99999229, -0.00237817, 0.00312443],
[0.00237618, 0.99999697, 0.00064159]])
# This is the version that Diffcalc comes up with ( see following test)
Pt531_U_DIFFCALC = matrix([[-0.0023763, -0.9999970, -0.0006416],
[0.9999923, -0.0023783, 0.0031244],
[-0.0031259, -0.0006342, 0.9999949]])
class TestUBCalculationWithYouStrategy_Pt531_FixedMuChi():
def setup_method(self):
hardware = Mock()
names = 'm', 'd', 'n', 'e', 'c', 'p'
hardware.get_axes_names.return_value = names
self.ubcalc = UBCalculation(hardware, SixCircle(),
UbCalculationNonPersister(),
YouUbCalcStrategy())
def testAgainstResultsFromJan_28_2010(self):
self.ubcalc.start_new('test')
self.ubcalc.set_lattice('Pt531', 6.204, 4.806, 23.215, 90, 90, 49.8)
self.ubcalc.add_reflection(Pt531_HKL0[0], Pt531_HKL0[1], Pt531_HKL0[2],
willmott_to_you_fixed_mu_chi(Pt531_REF0),
12.39842 / Pt531_WAVELENGTH,
'ref0', None)
self.ubcalc.add_reflection(Pt531_HKL1[0], Pt531_HKL1[1], Pt531_HKL1[2],
willmott_to_you_fixed_mu_chi(Pt531_REF1),
12.39842 / Pt531_WAVELENGTH,
'ref1', None)
self.ubcalc.calculate_UB()
print "U: ", self.ubcalc.U
print "UB: ", self.ubcalc.UB
matrixeq_(self.ubcalc.U, Pt531_U_DIFFCALC)
class Test_Pt531_FixedMuChi(_BaseTest):
def setup_method(self):
_BaseTest.setup_method(self)
self._configure_constraints()
self.wavelength = Pt531_WAVELENGTH
CUT = CrystalUnderTest('Pt531', 6.204, 4.806, 23.215, 90, 90, 49.8)
B = CUT.B
self.UB = Pt531_U_DIFFCALC * B
self._configure_limits()
def _configure_constraints(self):
self.constraints._constrained = {'alpha': 2 * TORAD, 'mu': 0,
'chi': pi / 2}
def _configure_limits(self):
self.mock_hardware.set_lower_limit(NUNAME, None)
#self.mock_hardware.set_lower_limit('delta', None)
self.mock_hardware.set_upper_limit('delta', 90)
self.mock_hardware.set_lower_limit('mu', None)
self.mock_hardware.set_lower_limit('eta', None)
self.mock_hardware.set_lower_limit('chi', None)
def _convert_willmott_pos(self, willmott_pos):
return willmott_to_you_fixed_mu_chi(willmott_pos)
def _configure_ub(self):
self.mock_ubcalc.UB = self.UB
def _check(self, hkl, pos, virtual_expected={}, fails=False):
# self._check_angles_to_hkl('', 999, 999, hkl, pos, self.wavelength,
# virtual_expected)
if fails:
self._check_hkl_to_angles_fails('', 999, 999, hkl, pos,
self.wavelength, virtual_expected)
else:
self._check_hkl_to_angles('', 999, 999, hkl, pos, self.wavelength,
virtual_expected)
def testHkl_0_found_orientation_setting(self):
'''Check that the or0 reflection maps back to the assumed hkl'''
self.places = 1
self._check_angles_to_hkl('', 999, 999, Pt531_HKL0,
self._convert_willmott_pos(Pt531_REF0),
self.wavelength, {'alpha': 2})
def testHkl_1_found_orientation_setting(self):
'''Check that the or1 reflection maps back to the assumed hkl'''
self.places = 0
self._check_angles_to_hkl('', 999, 999, Pt531_HKL1,
self._convert_willmott_pos(Pt531_REF1),
self.wavelength, {'alpha': 2})
def testHkl_0_calculated_from_DDIF(self):
self.places = 7
pos_expected = self._convert_willmott_pos(Pt531_REF0)
self._check(Pt531_HKL0,
pos_expected,
{'alpha': 2})
def testHkl_1_calculated_from_DDIF(self):
self.places = 7
self._check(Pt531_HKL1,
self._convert_willmott_pos(Pt531_REF1),
{'alpha': 2})
def testHkl_2_calculated_from_DDIF(self):
self.places = 7
self._check(Pt531_HKL2,
self._convert_willmott_pos(Pt531_REF2),
{'alpha': 2})
def testHkl_2_m1_0_16(self):
self.places = 7
pos = WillPos(delta=25.7990976, gamma=-6.2413545, omegah=2,
phi=47.4624380)
# pos.phi -= 360
self._check((-1, 0, 16),
self._convert_willmott_pos(pos),
{'alpha': 2})
class Test_Pt531_Fixed_Mu_eta_(Test_Pt531_FixedMuChi):
def _configure_constraints(self):
self.constraints._constrained = {'alpha': 2 * TORAD, 'mu': -pi / 2,
'eta': 0}
def _convert_willmott_pos(self, willmott_pos):
return willmott_to_you_fixed_mu_eta(willmott_pos)

View File

@@ -0,0 +1,575 @@
###
# 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 nose.tools import eq_ # @UnresolvedImport
from mock import Mock
from diffcalc.hkl.you.constraints import YouConstraintManager
from diffcalc.util import DiffcalcException
from nose.tools import raises
from nose.tools import assert_raises # @UnresolvedImport
from diffcalc.hkl.you.constraints import NUNAME
import diffcalc.util
def joined(d1, d2):
d1.update(d2)
return d1
class TestConstraintManager:
def setup_method(self):
diffcalc.util.COLOURISE_TERMINAL_OUTPUT = False
self.hardware_monitor = Mock()
self.hardware_monitor.get_position.return_value = (1.,) * 6
self.hardware_monitor.get_axes_names.return_value = [
'mu', 'delta', NUNAME, 'eta', 'chi', 'phi']
self.cm = YouConstraintManager(self.hardware_monitor)
def test_init(self):
eq_(self.cm.all, {})
eq_(self.cm.detector, {})
eq_(self.cm.reference, {})
eq_(self.cm.sample, {})
eq_(self.cm.naz, {})
def test_build_display_table(self):
self.cm.constrain('qaz')
self.cm.constrain('alpha')
self.cm.constrain('eta')
self.cm.set_constraint('qaz', 1.234)
self.cm.set_constraint('eta', 99.)
print '\n'.join(self.cm.build_display_table_lines())
eq_(self.cm.build_display_table_lines(),
[' DET REF SAMP',
' ------ ------ ------',
' delta a_eq_b mu',
' %s o-> alpha --> eta' % NUNAME.ljust(6),
'--> qaz beta chi',
' naz psi phi',
' mu_is_%s' % NUNAME])
#"""
# DET REF SAMP Available:
# ====== ====== ======
# delta a_eq_b mu 3x samp: 80 of 80
# nu o-> alpha --> eta 2x samp and ref: chi & phi
#--> qaz beta chi mu & eta
# naz psi phi chi=90 & mu=0
# mu_is_nu 2x samp and det: 0 of 6
# 3x samp: 0 of 4
#"""[1:-1]
def test_unconstrain_okay(self):
eq_(self.cm.all, {})
self.cm.constrain('delta')
self.cm.constrain('mu')
eq_(self.cm.all, {'delta': None, 'mu': None})
eq_(self.cm.unconstrain('delta'), None)
eq_(self.cm.all, {'mu': None})
def test_clear_constraints(self):
self.cm.constrain('delta')
self.cm.constrain('mu')
self.cm.clear_constraints()
eq_(self.cm.all, {})
def test_unconstrain_bad(self):
eq_(self.cm.all, {})
eq_(self.cm.unconstrain('delta'), "Delta was not already constrained.")
def test_constrain_det(self, pre={}):
eq_(self.cm.all, pre)
eq_(self.cm.constrain('delta'), None)
eq_(self.cm.all, joined({'delta': None}, pre))
eq_(self.cm.constrain('delta'), 'Delta is already constrained.')
eq_(self.cm.all, joined({'delta': None}, pre))
eq_(self.cm.constrain('naz'), 'Delta constraint replaced.')
eq_(self.cm.all, joined({'naz': None}, pre))
eq_(self.cm.constrain('delta'), 'Naz constraint replaced.')
eq_(self.cm.all, joined({'delta': None}, pre))
def test_constrain_det_one_preexisting_ref(self):
self.cm.constrain('alpha')
self.test_constrain_det({'alpha': None})
def test_constrain_det_one_preexisting_samp(self):
self.cm.constrain('phi')
self.test_constrain_det({'phi': None})
def test_constrain_det_one_preexisting_samp_and_ref(self):
self.cm.constrain('alpha')
self.cm.constrain('phi')
self.test_constrain_det({'alpha': None, 'phi': None})
def test_constrain_det_two_preexisting_samp(self):
self.cm.constrain('chi')
self.cm.constrain('phi')
self.test_constrain_det({'chi': None, 'phi': None})
def test_constrain_det_three_preexisting_other(self):
self.cm.constrain('alpha')
self.cm.constrain('phi')
self.cm.constrain('chi')
try:
self.cm.constrain('delta')
assert False
except DiffcalcException, e:
eq_(e.args[0], (
"Delta could not be constrained. First un-constrain one of the"
"\nangles alpha, chi or phi (with 'uncon')"))
def test_constrain_det_three_preexisting_samp(self):
self.cm.constrain('phi')
self.cm.constrain('chi')
self.cm.constrain('eta')
try:
self.cm.constrain('delta')
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Delta could not be constrained. First un-constrain one of the"
"\nangles eta, chi or phi (with 'uncon')")
def test_constrain_ref(self, pre={}):
eq_(self.cm.all, pre)
eq_(self.cm.constrain('alpha'), None)
eq_(self.cm.all, joined({'alpha': None}, pre))
eq_(self.cm.constrain('alpha'), 'Alpha is already constrained.')
eq_(self.cm.all, joined({'alpha': None}, pre))
eq_(self.cm.constrain('beta'), 'Alpha constraint replaced.')
eq_(self.cm.all, joined({'beta': None}, pre))
def test_constrain_ref_one_preexisting_det(self):
self.cm.constrain('delta')
self.test_constrain_ref({'delta': None})
def test_constrain_ref_one_preexisting_samp(self):
self.cm.constrain('phi')
self.test_constrain_ref({'phi': None})
def test_constrain_ref_one_preexisting_samp_and_det(self):
self.cm.constrain('delta')
self.cm.constrain('phi')
self.test_constrain_ref({'delta': None, 'phi': None})
def test_constrain_ref_two_preexisting_samp(self):
self.cm.constrain('chi')
self.cm.constrain('phi')
self.test_constrain_ref({'chi': None, 'phi': None})
def test_constrain_ref_three_preexisting_other(self):
self.cm.constrain('delta')
self.cm.constrain('phi')
self.cm.constrain('chi')
try:
self.cm.constrain('alpha'),
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Alpha could not be constrained. First un-constrain one of the"
"\nangles delta, chi or phi (with 'uncon')")
def test_constrain_ref_three_preexisting_samp(self):
self.cm.constrain('phi')
self.cm.constrain('chi')
self.cm.constrain('eta')
try:
self.cm.constrain('delta')
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Delta could not be constrained. First un-constrain one of the"
"\nangles eta, chi or phi (with 'uncon')")
def test_constrain_samp_when_one_free(self, pre={}):
eq_(self.cm.all, pre)
eq_(self.cm.constrain('phi'), None)
eq_(self.cm.all, joined({'phi': None}, pre))
eq_(self.cm.constrain('phi'), 'Phi is already constrained.')
eq_(self.cm.all, joined({'phi': None}, pre))
def test_constrain_samp_one_preexisting_samp(self):
self.cm.constrain('chi')
self.test_constrain_samp_when_one_free({'chi': None})
def test_constrain_samp_two_preexisting_samp(self):
self.cm.constrain('chi')
self.cm.constrain('eta')
self.test_constrain_samp_when_one_free({'chi': None, 'eta': None})
def test_constrain_samp_two_preexisting_other(self):
self.cm.constrain('delta')
self.cm.constrain('alpha')
self.test_constrain_samp_when_one_free({'delta': None, 'alpha': None})
def test_constrain_samp_two_preexisting_one_det(self):
self.cm.constrain('delta')
self.cm.constrain('eta')
self.test_constrain_samp_when_one_free({'delta': None, 'eta': None})
def test_constrain_samp_two_preexisting_one_ref(self):
self.cm.constrain('alpha')
self.cm.constrain('eta')
self.test_constrain_samp_when_one_free({'alpha': None, 'eta': None})
def test_constrain_samp_three_preexisting_only_one_samp(self):
self.cm.constrain('delta')
self.cm.constrain('alpha')
self.cm.constrain('eta')
eq_(self.cm.constrain('phi'), 'Eta constraint replaced.')
eq_(self.cm.all, {'delta': None, 'alpha': None, 'phi': None})
eq_(self.cm.constrain('phi'), 'Phi is already constrained.')
eq_(self.cm.all, {'delta': None, 'alpha': None, 'phi': None})
def test_constrain_samp_three_preexisting_two_samp_one_det(self):
self.cm.constrain('delta')
self.cm.constrain('eta')
self.cm.constrain('chi')
try:
self.cm.constrain('phi')
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Phi could not be constrained. First un-constrain one of the"
"\nangles delta, eta or chi (with 'uncon')")
def test_constrain_samp_three_preexisting_two_samp_one_ref(self):
self.cm.constrain('alpha')
self.cm.constrain('eta')
self.cm.constrain('chi')
try:
self.cm.constrain('phi')
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Phi could not be constrained. First un-constrain one of the"
"\nangles alpha, eta or chi (with 'uncon')")
def test_constrain_samp_three_preexisting_samp(self):
self.cm.constrain('mu')
self.cm.constrain('eta')
self.cm.constrain('chi')
try:
self.cm.constrain('phi')
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Phi could not be constrained. First un-constrain one of the"
"\nangles mu, eta or chi (with 'uncon')")
def test_report_constraints_none(self):
eq_(self.cm.report_constraints_lines(),
['! 3 more constraints required'])
def test_report_constraints_one_with_value(self):
self.cm.constrain(NUNAME)
self.cm.set_constraint(NUNAME, 9.12343)
eq_(self.cm.report_constraints_lines(),
['! 2 more constraints required',
' %s : 9.1234' % NUNAME])
def test_report_constraints_one_with_novalue(self):
self.cm.constrain(NUNAME)
print '! 2 more constraints required\n! %s: ---' % NUNAME
eq_(self.cm.report_constraints_lines(),
['! 2 more constraints required',
'! %s : ---' % NUNAME])
def test_report_constraints_one_with_valueless(self):
self.cm.constrain('a_eq_b')
eq_(self.cm.report_constraints_lines(),
['! 2 more constraints required',
' a_eq_b'])
def test_report_constraints_one_with_two(self):
self.cm.constrain('naz')
self.cm.set_constraint('naz', 9.12343)
self.cm.constrain('a_eq_b')
eq_(self.cm.report_constraints_lines(),
['! 1 more constraint required',
' naz : 9.1234',
' a_eq_b'])
def test_report_constraints_one_with_three(self):
self.cm.constrain('naz')
self.cm.set_constraint('naz', 9.12343)
self.cm.constrain('a_eq_b')
self.cm.constrain('mu')
self.cm.set_constraint('mu', 9.12343)
eq_(self.cm.report_constraints_lines(),
[' naz : 9.1234',
' a_eq_b',
' mu : 9.1234'])
def _constrain(self, *args):
for con in args:
self.cm.constrain(con)
@raises(ValueError)
def test_is_implemented_invalid(self):
self._constrain('naz')
self.cm.is_current_mode_implemented()
# 1 samp
def test_is_implemented_1_samp_naz(self):
self._constrain('naz', 'alpha', 'mu')
eq_(self.cm.is_current_mode_implemented(), True)
def test_is_implemented_1_samp_det(self):
self._constrain('qaz', 'alpha', 'mu')
eq_(self.cm.is_current_mode_implemented(), True)
# 2 samp + ref
def test_is_implemented_2_samp_ref_mu_chi(self):
self._constrain('beta', 'mu', 'chi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_ref_mu90_chi0(self):
self._constrain('beta', 'mu', 'chi')
self.cm.set_constraint('mu', 0)
self.cm.set_constraint('chi', 90)
eq_(self.cm.is_current_mode_implemented(), True)
def test_is_implemented_2_samp_ref_mu_eta(self):
self._constrain('beta', 'mu', 'eta')
eq_(self.cm.is_current_mode_implemented(), True)
def test_is_implemented_2_samp_ref_mu_phi(self):
self._constrain('beta', 'mu', 'phi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_ref_eta_chi(self):
self._constrain('beta', 'eta', 'chi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_ref_eta_phi(self):
self._constrain('beta', 'eta', 'phi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_ref_chi_phi(self):
self._constrain('beta', 'chi', 'phi')
eq_(self.cm.is_current_mode_implemented(), True)
# 2 samp + det
def test_is_implemented_2_samp_det_mu_chi(self):
self._constrain('qaz', 'mu', 'chi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_det_mu_eta(self):
self._constrain('qaz', 'mu', 'eta')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_det_mu_phi(self):
self._constrain('qaz', 'mu', 'phi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_det_eta_chi(self):
self._constrain('qaz', 'eta', 'chi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_det_eta_phi(self):
self._constrain('qaz', 'eta', 'phi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_2_samp_det_chi_phi(self):
self._constrain('qaz', 'chi', 'phi')
eq_(self.cm.is_current_mode_implemented(), False)
# 3 samp
def test_is_implemented_3_samp_no_mu(self):
self._constrain('eta', 'chi', 'phi')
eq_(self.cm.is_current_mode_implemented(), True)
def test_is_implemented_3_samp_no_eta(self):
self._constrain('mu', 'chi', 'phi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_3_samp_no_chi(self):
self._constrain('mu', 'eta', 'phi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_is_implemented_3_samp_no_phi(self):
self._constrain('mu', 'eta', 'chi')
eq_(self.cm.is_current_mode_implemented(), False)
def test_set_fails(self):
try:
self.cm.set_constraint('not_a_constraint', object())
assert False
except DiffcalcException, e:
eq_(e.args[0], "Could not set not_a_constraint. This is not an "
"available constraint.")
try:
self.cm.set_constraint('delta', object())
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Could not set delta. This is not currently constrained.")
self.cm.constrain('a_eq_b')
try:
self.cm.set_constraint('a_eq_b', object())
assert False
except DiffcalcException, e:
eq_(e.args[0],
"Could not set a_eq_b. This constraint takes no value.")
# self.cm.constrain('delta')
# self.cm.track('delta')
# try:
# self.cm.set('delta', object())
# assert False
# except DiffcalcException, e:
# eq_(e.args[0], ("Could not set delta as this constraint is "
# "configured to track its associated\n"
# "physical angle. First remove this tracking "
# "(use 'untrack delta')."))
def test_set(self):
#"%s: %s --> %f %s"
self.cm.constrain('alpha')
eq_(self.cm.set_constraint('alpha', 1.), 'alpha : --- --> 1.0')
eq_(self.cm.set_constraint('alpha', 2.), 'alpha : 1.0 --> 2.0')
# def test_track_fails(self):
# try:
# self.cm.track('not_a_constraint')
# assert False
# except DiffcalcException, e:
# eq_(e.args[0], "Could not track not_a_constraint as this is not "
# "an available constraint.")
#
# try:
# self.cm.track('delta')
# assert False
# except DiffcalcException, e:
# eq_(e.args[0],
# "Could not track delta as this is not currently constrained.")
#
# self.cm.constrain('a_eq_b')
# try:
# self.cm.track('a_eq_b')
# assert False
# except DiffcalcException, e:
# eq_(e.args[0],
# "Could not track a_eq_b as this constraint takes no value.")
#
# self.cm.constrain('alpha')
# try:
# self.cm.track('alpha')
# assert False
# except DiffcalcException, e:
# eq_(e.args[0], ("Could not configure alpha to track as this "
# "constraint is not associated with a\n"
# "physical angle."))
#
# def test_track(self):
# #"%s: %s --> %f %s"
# self.cm.constrain('delta')
# eq_(self.cm.track('delta'), 'delta : --- ~~> 1.0 (tracking)')
# eq_(self.cm.track('delta'), 'Delta was already configured to track.')
# self.cm.untrack('delta')
# self.cm.set_constraint('delta', 2.)
# eq_(self.cm.track('delta'), 'delta : 2.0 ~~> 1.0 (tracking)')
class TestConstraintManagerWithFourCircles:
def setup_method(self):
self.cm = YouConstraintManager(None, {NUNAME: 0, 'mu': 0})
def test_init(self):
eq_(self.cm.all, {NUNAME: 0, 'mu': 0})
eq_(self.cm.detector, {NUNAME: 0})
eq_(self.cm.reference, {})
eq_(self.cm.sample, {'mu': 0})
eq_(self.cm.naz, {})
def test_build_initial_display_table_with_fixed_detector(self):
self.cm = YouConstraintManager(None, {NUNAME: 0})
print self.cm.build_display_table_lines()
eq_(self.cm.build_display_table_lines(),
[' REF SAMP',
' ------ ------',
' a_eq_b mu',
' alpha eta',
' beta chi',
' psi phi'])
def test_build_initial_display_table_with_fixed_sample(self):
self.cm = YouConstraintManager(None, {'mu': 0})
print self.cm.build_display_table_lines()
eq_(self.cm.build_display_table_lines(),
[' DET REF SAMP',
' ------ ------ ------',
' delta a_eq_b eta',
' %s alpha chi' % NUNAME.ljust(6),
' qaz beta phi',
' naz psi'])
def test_build_initial_display_table_for_four_circle(self):
self.cm = YouConstraintManager(None, {'mu': 0, NUNAME: 0})
print self.cm.build_display_table_lines()
eq_(self.cm.build_display_table_lines(),
[' REF SAMP',
' ------ ------',
' a_eq_b eta',
' alpha chi',
' beta phi',
' psi'])
def test_constrain_fixed_detector_angle(self):
assert_raises(DiffcalcException, self.cm.constrain, 'delta')
assert_raises(DiffcalcException, self.cm.constrain, NUNAME)
assert_raises(DiffcalcException, self.cm.constrain, 'naz')
assert_raises(DiffcalcException, self.cm.constrain, 'qaz')
def test_unconstrain_fixed_detector_angle(self):
assert_raises(DiffcalcException, self.cm.unconstrain, 'delta')
assert_raises(DiffcalcException, self.cm.unconstrain, NUNAME)
assert_raises(DiffcalcException, self.cm.unconstrain, 'naz')
assert_raises(DiffcalcException, self.cm.unconstrain, 'qaz')
def test_set_constrain_fixed_detector_angle(self):
assert_raises(DiffcalcException, self.cm.set_constraint, 'delta', 0)
assert_raises(DiffcalcException, self.cm.set_constraint, NUNAME, 0)
assert_raises(DiffcalcException, self.cm.set_constraint, 'naz', 0)
assert_raises(DiffcalcException, self.cm.set_constraint, 'qaz', 0)
@raises(DiffcalcException)
def test_constrain_fixed_sample_angle(self):
self.cm.constrain('mu')
@raises(DiffcalcException)
def test_unconstrain_fixed_sample_angle(self):
self.cm.unconstrain('mu')
@raises(DiffcalcException)
def test_set_constrain_fixed_sample_angle(self):
self.cm.set_constraint('mu', 0)

View File

@@ -0,0 +1,95 @@
###
# 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 mock import Mock, call
from diffcalc import settings
import diffcalc
diffcalc.util.DEBUG = True
hkl = None
def setup_module():
global hkl
settings.hardware=Mock()
settings.geometry=Mock()
settings.angles_to_hkl_function=Mock()
settings.ubcalc_strategy=Mock()
settings.geometry.fixed_constraints = {}
from diffcalc.hkl.you import hkl
reload(hkl)
hkl.hklcalc = Mock()
hkl.hklcalc.constraints.report_constraints_lines.return_value = ['report1', 'report2']
def test_con_with_1_constraint():
hkl.con('cona')
hkl.hklcalc.constraints.constrain.assert_called_with('cona')
def test_con_with_1_constraint_with_value():
hkl.con('cona', 123)
hkl.hklcalc.constraints.constrain.assert_called_with('cona')
hkl.hklcalc.constraints.set_constraint.assert_called_with('cona', 123)
def test_con_with_3_constraints():
hkl.con('cona', 'conb', 'conc')
hkl.hklcalc.constraints.clear_constraints.assert_called()
calls = [call('cona'), call('conb'), call('conc')]
hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
def test_con_with_3_constraints_first_val():
hkl.con('cona', 1, 'conb', 'conc')
hkl.hklcalc.constraints.clear_constraints.assert_called()
calls = [call('cona'), call('conb'), call('conc')]
hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
hkl.hklcalc.constraints.set_constraint.assert_called_with('cona', 1)
def test_con_with_3_constraints_second_val():
hkl.con('cona', 'conb', 2, 'conc')
hkl.hklcalc.constraints.clear_constraints.assert_called()
calls = [call('cona'), call('conb'), call('conc')]
hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
hkl.hklcalc.constraints.set_constraint.assert_called_with('conb', 2)
def test_con_with_3_constraints_third_val():
hkl.con('cona', 'conb', 'conc', 3)
hkl.hklcalc.constraints.clear_constraints.assert_called()
calls = [call('cona'), call('conb'), call('conc')]
hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
hkl.hklcalc.constraints.set_constraint.assert_called_with('conc', 3)
def test_con_with_3_constraints_all_vals():
hkl.con('cona', 1, 'conb', 2, 'conc', 3)
hkl.hklcalc.constraints.clear_constraints.assert_called()
calls = [call('cona'), call('conb'), call('conc')]
hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
calls = [call('cona', 1), call('conb', 2), call('conc', 3)]
hkl.hklcalc.constraints.set_constraint.assert_has_calls(calls)
def test_con_messages_and_help_visually():
hkl.con()
print "**"
print hkl.con.__doc__
def test_con_message_display_whenn_selecting_an_unimplmented_mode():
hkl.hklcalc.constraints.is_fully_constrained.return_value = True
hkl.hklcalc.constraints.is_current_mode_implemented.return_value = False
hkl.con('phi', 'chi', 'eta')

View File

@@ -0,0 +1,180 @@
###
# 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 datetime import datetime
from diffcalc.ub.reflections import _Reflection
from diffcalc.hkl.vlieg.geometry import VliegPosition as P
class SessionScenario:
"""
A test scenario. The test case must have __name, lattice and bmatrix set
and if umatrix is set then so must ref 1 and ref 2. Matrices should be 3*3
python arrays of lists and ref1 and ref2 in the format (h, k, l, position,
energy, tag)."""
def __init__(self):
self.name = None
self.lattice = None
self.bmatrix = None
self.ref1 = None
self.ref2 = None
self.umatrix = None
self.calculations = [] # CalculationScenarios
def __str__(self):
toReturn = "\nTestScenario:"
toReturn += "\n name: " + self.name
toReturn += "\n lattice:" + str(self.lattice)
toReturn += "\n bmatrix:" + str(self.bmatrix)
toReturn += "\n ref1:" + str(self.ref1)
toReturn += "\n ref2:" + str(self.ref2)
toReturn += "\n umatrix:" + str(self.umatrix)
return toReturn
class CalculationScenario:
"""
Used as part of a test scenario. A UB matrix appropriate for this
calcaultion will have been calculated or loaded
"""
def __init__(self, tag, package, mode, energy, modeToTest, modeNumber):
self.tag = tag
self.package = package
self.mode = mode
self.energy = energy
self.wavelength = 12.39842 / energy
self.modeToTest = modeToTest
self.modeNumber = modeNumber
self.hklList = None # hkl triples
self.posList = []
self.paramList = []
############################ SESSION0 ############################
# From the dif_init.mat next to dif_dos.exe on Vlieg'session2 cd
#session2 = SessionScenario()
#session2.name = 'latt1'
#session2.lattice = ([4.0004, 4.0004, 2.270000, 90, 90, 90])
#session2.bmatrix = (((1.570639, 0, 0) ,(0.0, 1.570639, 0) ,
# (0.0, 0.0, 2.767923)))
#self.scenarios.append(session2)
############################ SESSION1 ############################
# From b16 on 27June2008 (From Chris Nicklin)
session1 = SessionScenario()
session1.name = "b16_270608"
session1.time = datetime.now()
session1.lattice = ((3.8401, 3.8401, 5.43072, 90, 90, 90))
session1.bmatrix = (((1.636204, 0, 0), (0, 1.636204, 0), (0, 0, 1.156971)))
session1.ref1 = _Reflection(1, 0, 1.0628,
P(5.000, 22.790, 0.000, 1.552, 22.400, 14.255),
10, 'ref1', session1.time)
session1.ref2 = _Reflection(0, 1, 1.0628,
P(5.000, 22.790, 0.000, 4.575, 24.275, 101.320),
10, 'ref2', session1.time)
session1.umatrix = ((0.997161, -0.062217, 0.042420),
(0.062542, 0.998022, -0.006371),
(-0.041940, 0.009006, 0.999080))
session1.ref1calchkl = (1, 0, 1.0628) # Must match the guessed value!
session1.ref2calchkl = (-0.0329, 1.0114, 1.04)
############################ SESSION2 ############################
# cubic crystal from bliss tutorial
session2 = SessionScenario()
session2.name = "cubic_from_bliss_tutorial"
session2.time = datetime.now()
session2.lattice = ((1.54, 1.54, 1.54, 90, 90, 90))
session2.ref1 = _Reflection(1, 0, 0, P(0, 60, 0, 30, 0, 0),
12.39842 / 1.54, 'ref1', session2.time)
session2.ref2 = _Reflection(0, 1, 0, P(0, 60, 0, 30, 0, -90),
12.39842 / 1.54, 'ref2', session2.time)
session2.bmatrix = (((4.07999, 0, 0), (0, 4.07999, 0), (0, 0, 4.07999)))
session2.umatrix = (((1, 0, 0), (0, -1, 0), (0, 0, -1)))
session2.ref1calchkl = (1, 0, 0) # Must match the guessed value!
session2.ref2calchkl = (0, 1, 0)
# sixc-0a : fixed omega = 0
c = CalculationScenario('sixc-0a', 'sixc', '0', 12.39842 / 1.54, '4cBeq', 1)
c.alpha = 0
c.gamma = 0
c.w = 0
#c.hklList=((0.7, 0.9, 1.3), (1,0,0), (0,1,0), (1, 1, 0))
c.hklList = ((0.7, 0.9, 1.3),)
c.posList.append(
P(0.000000, 119.669750, 0.000000, 59.834875, -48.747500, 307.874983651098))
#c.posList.append(P(0.000000, 60.000000, 0.000000, 30.000, 0.000000, 0.000000))
#c.posList.append(P(0.000000, 60.000000, 0.000000, 30.000, 0.000000, -90.0000))
#c.posList.append(P(0.000000, 90.000000, 0.000000, 45.000, 0.000000, -45.0000))
session2.calculations.append(c)
############################ SESSION3 ############################
# AngleCalc scenarios from SPEC sixc. using crystal and alignment
session3 = SessionScenario()
session3.name = "spec_sixc_b16_270608"
session3.time = datetime.now()
session3.lattice = ((3.8401, 3.8401, 5.43072, 90, 90, 90))
session3.bmatrix = (((1.636204, 0, 0), (0, 1.636204, 0), (0, 0, 1.156971)))
session3.umatrix = ((0.997161, -0.062217, 0.042420),
(0.062542, 0.998022, -0.006371),
(-0.041940, 0.009006, 0.999080))
session3.ref1 = _Reflection(1, 0, 1.0628,
P(5.000, 22.790, 0.000, 1.552, 22.400, 14.255),
12.39842 / 1.24, 'ref1', session3.time)
session3.ref2 = _Reflection(0, 1, 1.0628,
P(5.000, 22.790, 0.000, 4.575, 24.275, 101.320),
12.39842 / 1.24, 'ref2', session3.time)
session3.ref1calchkl = (1, 0, 1.0628)
session3.ref2calchkl = (-0.0329, 1.0114, 1.04)
# sixc-0a : fixed omega = 0
ac = CalculationScenario('sixc-0a', 'sixc', '0', 12.39842 / 1.24, '4cBeq', 1)
ac.alpha = 0
ac.gamma = 0
ac.w = 0
### with 'omega_low':-90, 'omega_high':270, 'phi_low':-180, 'phi_high':180
ac.hklList = []
ac.hklList.append((0.7, 0.9, 1.3))
ac.posList.append(P(0.0, 27.352179, 0.000000, 13.676090, 37.774500, 53.965500))
ac.paramList.append({'Bin': 8.3284, 'Bout': 8.3284, 'rho': 36.5258,
'eta': 0.1117, 'twotheta': 27.3557})
ac.hklList.append((1, 0, 0))
ac.posList.append(P(0., 18.580230, 0.000000, 9.290115, -2.403500, 3.589000))
ac.paramList.append({'Bin': -0.3880, 'Bout': -0.3880, 'rho': -2.3721,
'eta': -0.0089, 'twotheta': 18.5826})
ac.hklList.append((0, 1, 0))
ac.posList.append(P(0., 18.580230, 0.000000, 9.290115, 0.516000, 93.567000))
ac.paramList.append({'Bin': 0.0833, 'Bout': 0.0833, 'rho': 0.5092,
'eta': -0.0414, 'twotheta': 18.5826})
ac.hklList.append((1, 1, 0))
ac.posList.append(P(0., 26.394192, 0.000000, 13.197096, -1.334500, 48.602000))
ac.paramList.append({'Bin': -0.3047, 'Bout': -0.3047, 'rho': -1.2992,
'eta': -0.0351, 'twotheta': 26.3976})
session3.calculations.append(ac)
########################################################################
def sessions():
return (session1, session2, session3)

View File

@@ -0,0 +1,246 @@
###
# 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/>.
###
import unittest
from diffcalc import settings
import pytest
try:
from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
except ImportError:
from diffcalc.gdasupport.minigda.scannable import DummyPD
from diffcalc.gdasupport.scannable.base import ScannableGroup
from diffcalc.gdasupport.scannable.diffractometer import \
DiffractometerScannableGroup
from diffcalc.gdasupport.scannable.mock import MockMotor
from diffcalc.hardware import DummyHardwareAdapter
from diffcalc.hardware import HardwareAdapter
from diffcalc.hardware import ScannableHardwareAdapter
from nose.tools import eq_, assert_raises # @UnresolvedImport
from test.diffcalc.gdasupport.scannable.mockdiffcalc import MockDiffcalc
class SimpleHardwareAdapter(HardwareAdapter):
def get_position(self):
return [1, 2, 3]
def get_energy(self):
return 1.
class TestHardwareAdapterBase(object):
def setup_method(self):
self.hardware = SimpleHardwareAdapter(['a', 'b', 'c'])
def test__init__Andget_axes_names(self):
assert self.hardware.get_axes_names() == ('a', 'b', 'c')
def test__repr__(self):
print self.hardware.__repr__()
def testSetGetPosition(self):
pass
def testSetGetEnergyWavelength(self):
pass
def testget_position_by_name(self):
assert self.hardware.get_position_by_name('c') == 3
with pytest.raises(ValueError):
self.hardware.get_position_by_name('not an angle name')
def testLowerLimitSetAndGet(self):
self.hardware.set_lower_limit('a', -1)
self.hardware.set_lower_limit('b', -2)
self.hardware.set_lower_limit('c', -3)
with pytest.raises(ValueError):
self.hardware.set_lower_limit('not an angle', 1)
self.hardware.set_lower_limit('b', None)
print "Shoule print WARNING:"
self.hardware.set_lower_limit('b', None)
assert self.hardware.get_lower_limit('a') == -1
assert self.hardware.get_lower_limit('c') == -3
def testUpperLimitSetAndGet(self):
self.hardware.set_upper_limit('a', 1)
self.hardware.set_upper_limit('b', 2)
self.hardware.set_upper_limit('c', 3)
with pytest.raises(ValueError):
self.hardware.set_upper_limit('not an angle', 1)
self.hardware.set_upper_limit('b', None)
print "Shoule print WARNING:"
self.hardware.set_upper_limit('b', None)
assert self.hardware.get_upper_limit('a') == 1
assert self.hardware.get_upper_limit('c') == 3
def testis_position_within_limits(self):
self.hardware.set_upper_limit('a', 1)
self.hardware.set_upper_limit('b', 2)
self.hardware.set_lower_limit('a', -1)
assert self.hardware.is_position_within_limits([0, 0, 999])
assert self.hardware.is_position_within_limits([1, 2, 999])
assert self.hardware.is_position_within_limits([-1, -999, 999])
assert not self.hardware.is_position_within_limits([1.01, 0, 999])
assert not self.hardware.is_position_within_limits([0, 2.01, 999])
assert not self.hardware.is_position_within_limits([-1.01, 0, 999])
def testIsAxisWithinLimits(self):
self.hardware.set_upper_limit('a', 1)
self.hardware.set_upper_limit('b', 2)
self.hardware.set_lower_limit('a', -1)
assert self.hardware.is_axis_value_within_limits('a', 0)
assert self.hardware.is_axis_value_within_limits('b', 0)
assert self.hardware.is_axis_value_within_limits('c', 999)
assert self.hardware.is_axis_value_within_limits('a', 1)
assert self.hardware.is_axis_value_within_limits('b', 2)
assert self.hardware.is_axis_value_within_limits('c', 999)
assert self.hardware.is_axis_value_within_limits('a', -1)
assert self.hardware.is_axis_value_within_limits('b', -999)
assert not self.hardware.is_axis_value_within_limits('a', 1.01)
assert not self.hardware.is_axis_value_within_limits('b', 2.01)
assert not self.hardware.is_axis_value_within_limits('a', 1.01)
def setCutAndGetCuts(self):
self.hardware.setCut('a', 2)
self.hardware.setCut('b', 2)
self.hardware.setCut('c', 2)
assert self.hardware.get_cuts() == {'a': 1, 'b': 2, 'c': 3}
self.assertRaises(KeyError, self.hardware.setCut, 'not_a_key', 1)
def test__configureCuts(self):
hardware = SimpleHardwareAdapter(['a', 'b', 'c'])
assert hardware.get_cuts() == {'a': -180, 'b': -180, 'c': -180}
hardware = SimpleHardwareAdapter(['a', 'phi', 'c'])
assert hardware.get_cuts() == {'a': -180, 'phi': 0, 'c': -180}
def test__configureCutsWithDefaults(self):
hardware = SimpleHardwareAdapter(['a', 'b', 'c'], {'a': 1, 'b': 2})
assert hardware.get_cuts() == {'a': 1, 'b': 2, 'c': -180}
hardware = SimpleHardwareAdapter(['a', 'phi', 'c'],
{'a': 1, 'phi': 2})
assert hardware.get_cuts() == {'a': 1, 'phi': 2, 'c': -180}
with pytest.raises(KeyError):
SimpleHardwareAdapter(['a', 'b', 'c'], {'a': 1, 'not_a_key': 2})
def testCut(self):
assert self.hardware.cut_angles((1, 2, 3)) == (1, 2, 3)
assert self.hardware.cut_angles((-181, 0, 181)) == (179, 0, -179)
assert self.hardware.cut_angles((-180, 0, 180,)) == (-180, 0, 180)
assert self.hardware.cut_angles((-360, 0, 360)) == (0, 0, 0)
class TestHardwareCommands():
def setup_method(self):
self.hardware = SimpleHardwareAdapter(['a', 'b', 'c'])
settings.hardware = self.hardware
from diffcalc import hardware
reload(hardware)
self.commands = hardware
def testSetcut(self):
print "*******"
self.commands.setcut()
print "*******"
self.commands.setcut('a')
print "*******"
self.commands.setcut('a', -181)
print "*******"
eq_(self.hardware.get_cuts()['a'], -181)
assert_raises(
ValueError, self.commands.setcut, 'a', 'not a number')
assert_raises(
KeyError, self.commands.setcut, 'not an axis', 1)
def test_set_lim(self):
self.commands.setmin('a', -1)
print "*******"
self.commands.setmin()
print "*******"
self.commands.setmax()
print "*******"
class TestDummyHardwareAdapter(object):
def setup_method(self):
self.hardware = DummyHardwareAdapter(
['alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'])
def test__init__(self):
assert self.hardware.get_position() == [0.] * 6
assert self.hardware.get_energy() == 12.39842
assert self.hardware.get_wavelength() == 1.
assert (self.hardware.get_axes_names()
== ('alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'))
def test__repr__(self):
print self.hardware.__repr__()
def testSetGetPosition(self):
pass
def testSetGetEnergyWavelength(self):
pass
def testget_position_by_name(self):
self.hardware.position = [1., 2., 3., 4., 5., 6.]
assert self.hardware.get_position_by_name('gamma') == 3
with pytest.raises(ValueError):
self.hardware.get_position_by_name('not an angle name')
def createDummyAxes(names):
result = []
for name in names:
result.append(DummyPD(name))
return result
class TestGdaHardwareMonitor(object):
def setup_method(self):
dummy = createDummyAxes(['a', 'b', 'c', 'd', 'e', 'f'])
self.grp = ScannableGroup('grp', dummy)
self.diffhw = DiffractometerScannableGroup('sixc', MockDiffcalc(6),
self.grp)
self.energyhw = MockMotor()
self.hardware = ScannableHardwareAdapter(self.diffhw, self.energyhw)
def test__init__Andget_axes_names(self):
assert self.hardware.get_axes_names() == ('a', 'b', 'c', 'd', 'e', 'f')
def testGetPosition(self):
self.diffhw.asynchronousMoveTo((1, 2, 3, 4, 5, 6))
assert self.hardware.get_position() == [1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
def testGetEnergy(self):
self.energyhw.asynchronousMoveTo(1.0)
assert self.hardware.get_energy() == 1.0
def testGetWavelength(self):
self.energyhw.asynchronousMoveTo(1.0)
assert self.hardware.get_wavelength() == 12.39842 / 1.0

View File

@@ -0,0 +1,127 @@
###
# 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/>.
###
import unittest
from diffcalc.hkl.vlieg.geometry import VliegPosition
from diffcalc.util import MockRawInput, \
getInputWithDefault, differ, nearlyEqual, degreesEquivilant
import diffcalc.util # @UnusedImport
import pytest
class TestUtils(object):
def testMockRawInput(self):
raw_input = MockRawInput('a') # @ReservedAssignment
assert raw_input('?') == 'a'
raw_input = MockRawInput(['a', '1234', '1 2 3']) # @ReservedAssignment
assert raw_input('?') == 'a'
assert raw_input('?') == '1234'
assert raw_input('?') == '1 2 3'
with pytest.raises(IndexError):
raw_input('?')
raw_input = MockRawInput(1) # @ReservedAssignment
with pytest.raises(TypeError):
raw_input('?')
def testGetInputWithDefaultWithStrings(self):
diffcalc.util.raw_input = MockRawInput('reply')
print">>>"
assert getInputWithDefault('enter a thing', 'default') == 'reply'
print">>>"
diffcalc.util.raw_input = MockRawInput('')
assert getInputWithDefault('enter a thing', 'default') == 'default'
print">>>"
diffcalc.util.raw_input = MockRawInput('1.23 1 a')
assert getInputWithDefault('enter a thing', 'default') == '1.23 1 a'
def testGetInputWithDefaultWithNumbers(self):
diffcalc.util.raw_input = MockRawInput('')
assert getInputWithDefault('enter a thing', 1) == 1.0
diffcalc.util.raw_input = MockRawInput('')
assert getInputWithDefault('enter a thing', 1.23) == 1.23
diffcalc.util.raw_input = MockRawInput('1')
assert getInputWithDefault('enter a thing', 'default') == 1.0
diffcalc.util.raw_input = MockRawInput('1.23')
assert getInputWithDefault('enter a thing', 'default') == 1.23
def testGetInputWithDefaultWithLists(self):
diffcalc.util.raw_input = MockRawInput('')
assert (getInputWithDefault('enter a thing', (1, 2.0, 3.1))
== (1.0, 2.0, 3.1))
diffcalc.util.raw_input = MockRawInput('1 2.0 3.1')
assert getInputWithDefault('enter a thing', 'default') == [1.0, 2.0, 3.1]
def testDiffer(self):
assert not differ([1., 2., 3.], [1., 2., 3.], .0000000000000001)
assert not differ(1, 1.0, .000000000000000001)
assert (differ([2., 4., 6.], [1., 2., 3.], .1)
== '(2.0, 4.0, 6.0)!=(1.0, 2.0, 3.0)')
assert not differ(1., 1.2, .2)
assert differ(1., 1.2, .1999999999999) == '1.0!=1.2'
assert not differ(1., 1.2, 1.20000000000001)
def testNearlyEqual(self):
assert nearlyEqual([1, 2, 3], [1, 2, 3], .000000000000000001)
assert nearlyEqual(1, 1.0, .000000000000000001)
assert not nearlyEqual([2, 4, 6], [1, 2, 3], .1)
assert nearlyEqual(1, 1.2, .2)
assert not nearlyEqual(1, 1.2, .1999999999999)
assert nearlyEqual(1, 1.2, 1.20000000000001)
def testDegreesEqual(self):
tol = .001
assert degreesEquivilant(1, 1, tol)
assert degreesEquivilant(1, -359, tol)
assert degreesEquivilant(359, -1, tol)
assert not degreesEquivilant(1.1, 1, tol)
assert not degreesEquivilant(1.1, -359, tol)
assert not degreesEquivilant(359.1, -1, tol)
class TestPosition(object):
def testCompare(self):
# Test the compare method
pos1 = VliegPosition(1, 2, 3, 4, 5, 6)
pos2 = VliegPosition(1.1, 2.1, 3.1, 4.1, 5.1, 6.1)
assert pos1 == pos1
assert pos1 != pos2
def testNearlyEquals(self):
pos1 = VliegPosition(1, 2, 3, 4, 5, 6)
pos2 = VliegPosition(1.1, 2.1, 3.1, 4.1, 5.1, 6.1)
assert pos1.nearlyEquals(pos2, 0.11)
assert not pos1.nearlyEquals(pos2, 0.1)
def testClone(self):
pos = VliegPosition(1, 2, 3, 4., 5., 6.)
copy = pos.clone()
assert pos == copy
pos.alpha = 10
pos.omega = 4.1

View File

@@ -0,0 +1,174 @@
###
# 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 diffcalc.hkl.you.calc import YouUbCalcStrategy
from diffcalc.hkl.you.geometry import SixCircle, YouPosition
from diffcalc.ub.calc import UBCalculation
from diffcalc.ub.persistence import UBCalculationJSONPersister
from math import pi
from mock import Mock
from nose.tools import eq_
from test.tools import matrixeq_
import tempfile
import datetime
try:
from numpy import matrix
except ImportError:
from numjy import matrix
def posFromI16sEuler(phi, chi, eta, mu, delta, gamma):
return YouPosition(mu, delta, gamma, eta, chi, phi)
UB1 = matrix(
((0.9996954135095477, -0.01745240643728364, -0.017449748351250637),
(0.01744974835125045, 0.9998476951563913, -0.0003045864904520898),
(0.017452406437283505, -1.1135499981271473e-16, 0.9998476951563912))
) * (2 * pi)
EN1 = 12.39842
REF1a = posFromI16sEuler(1, 1, 30, 0, 60, 0)
REF1b = posFromI16sEuler(1, 91, 30, 0, 60, 0)
class TestUBCalculationWithYouStrategy():
"""Testing the math only here.
"""
def setup_method(self):
self.tempdir = tempfile.mkdtemp()
geometry = SixCircle() # pass through
hardware = Mock()
names = 'm', 'd', 'n', 'e', 'c', 'p'
hardware.get_axes_names.return_value = names
self.tmpdir = tempfile.mkdtemp()
print self.tmpdir
self.ubcalc = UBCalculation(hardware,
geometry,
UBCalculationJSONPersister(self.tmpdir),
YouUbCalcStrategy())
def testAgainstI16Results(self):
self.ubcalc.start_new('cubcalc')
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.add_reflection(1, 0, 0, REF1a, EN1, '100', None)
self.ubcalc.add_reflection(0, 0, 1, REF1b, EN1, '001', None)
matrixeq_(self.ubcalc.UB, UB1)
def test_save_and_restore_empty_ubcalc_with_one_already_started(self):
NAME = 'test_save_and_restore_empty_ubcalc_with_one_already_started'
self.ubcalc.start_new(NAME)
self.ubcalc.start_new(NAME)
def test_save_and_restore_empty_ubcalc(self):
NAME = 'test_save_and_restore_empty_ubcalc'
self.ubcalc.start_new(NAME)
self.ubcalc.start_new(NAME + '2')
self.ubcalc.load(NAME)
eq_(self.ubcalc.name, NAME)
def test_save_and_restore_ubcalc_with_lattice(self):
NAME = 'test_save_and_restore_ubcalc_with_lattice'
self.ubcalc.start_new(NAME)
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.start_new(NAME + '2')
self.ubcalc.load(NAME)
eq_(self.ubcalc._state.crystal.getLattice(), ('latt', 1, 1, 1, 90, 90, 90))
def test_save_and_restore_ubcalc_with_reflections(self):
NAME = 'test_save_and_restore_ubcalc_with_reflections'
self.ubcalc.start_new(NAME)
now = datetime.datetime.now()
self.ubcalc.add_reflection(1, 0, 0, REF1a, EN1, '100', now)
self.ubcalc.add_reflection(0, 0, 1, REF1b, EN1, '001', now)
self.ubcalc.add_reflection(0, 0, 1.5, REF1b, EN1, '001_5', now)
ref1 = self.ubcalc.get_reflection(1)
ref2 = self.ubcalc.get_reflection(2)
ref3 = self.ubcalc.get_reflection(3)
eq_(self.ubcalc.get_reflection(1), ref1)
eq_(self.ubcalc.get_reflection(2), ref2)
eq_(self.ubcalc.get_reflection(3), ref3)
self.ubcalc.start_new(NAME + '2')
self.ubcalc.load(NAME)
eq_(self.ubcalc.get_reflection(1), ref1)
eq_(self.ubcalc.get_reflection(2), ref2)
eq_(self.ubcalc.get_reflection(3), ref3)
def test_save_and_restore_ubcalc_with_UB_from_two_ref(self):
NAME = 'test_save_and_restore_ubcalc_with_UB_from_two_ref'
self.ubcalc.start_new(NAME)
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.add_reflection(1, 0, 0, REF1a, EN1, '100', None)
self.ubcalc.add_reflection(0, 0, 1, REF1b, EN1, '001', None)
matrixeq_(self.ubcalc.UB, UB1)
self.ubcalc.start_new(NAME + '2')
self.ubcalc.load(NAME)
matrixeq_(self.ubcalc.UB, UB1)
def test_save_and_restore_ubcalc_with_UB_from_one_ref(self):
NAME = 'test_save_and_restore_ubcalc_with_UB_from_one_ref'
self.ubcalc.start_new(NAME)
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.add_reflection(1, 0, 0, REF1a, EN1, '100', None)
self.ubcalc.calculate_UB_from_primary_only()
matrixeq_(self.ubcalc.UB, UB1, places=2)
self.ubcalc.start_new(NAME + '2')
self.ubcalc.load(NAME)
matrixeq_(self.ubcalc.UB, UB1, places=2)
def test_save_and_restore_ubcalc_with_manual_ub(self):
NAME = 'test_save_and_restore_ubcalc_with_manual_ub'
UB = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
self.ubcalc.start_new(NAME)
self.ubcalc.set_UB_manually(UB)
matrixeq_(self.ubcalc.UB, UB)
self.ubcalc.start_new(NAME + '2')
self.ubcalc.load(NAME)
matrixeq_(self.ubcalc.UB, UB)
def test_save_and_restore_ubcalc_with_manual_u(self):
NAME = 'test_save_and_restore_ubcalc_with_manual_u'
U = matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
self.ubcalc.start_new(NAME)
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.set_U_manually(U)
matrixeq_(self.ubcalc.UB, U * 2 * pi)
self.ubcalc.start_new(NAME + '2')
self.ubcalc.load(NAME)
matrixeq_(self.ubcalc.UB, U * 2 * pi)

View File

@@ -0,0 +1,380 @@
###
# 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/>.
###
import unittest
from datetime import datetime
from math import cos, sin, pi
from mock import Mock
from nose.tools import raises
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry
from diffcalc.hkl.vlieg.geometry import VliegPosition as Pos
from test.tools import matrixeq_, mneq_
from diffcalc.ub.calc import UBCalculation
from diffcalc.ub.persistence import UbCalculationNonPersister
from diffcalc.util import DiffcalcException
from diffcalc.hkl.vlieg.calc import VliegUbCalcStrategy
from test.diffcalc import scenarios
I = matrix('1 0 0; 0 1 0; 0 0 1')
TORAD = pi / 180
class TestUBCalculationWithSixCircleGammaOnArm(object):
def setup_method(self):
self.geometry = SixCircleGammaOnArmGeometry()
mock_hardware = Mock()
mock_hardware.get_axes_names.return_value = ('a', 'd', 'g', 'o', 'c', 'p')
self.ubcalc = UBCalculation(
mock_hardware, self.geometry, UbCalculationNonPersister(),
VliegUbCalcStrategy())
self.time = datetime.now()
### State ###
def testNewCalculation(self):
self.ubcalc.start_new('testcalc')
assert self.ubcalc.name, 'testcalc' == "Name not set by newCalcualtion"
@raises(DiffcalcException)
def testNewCalculationHasNoU(self):
self.ubcalc.start_new('testcalc')
print self.ubcalc.U
@raises(DiffcalcException)
def testNewCalculationHasNoUB(self):
self.ubcalc.start_new('testcalc')
print self.ubcalc.UB
### Lattice ###
def testSetLattice(self):
# Not much to test, just make sure no exceptions
self.ubcalc.start_new('testcalc')
self.ubcalc.set_lattice('testlattice', 4.0004, 4.0004, 2.27, 90, 90, 90)
### Calculations ###
def testset_U_manually(self):
# Test the calculations with U=I
U = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
for sess in scenarios.sessions():
self.setup_method()
self.ubcalc.start_new('testcalc')
self.ubcalc.set_lattice(sess.name, *sess.lattice)
self.ubcalc.set_U_manually(U)
# Check the U matrix
mneq_(self.ubcalc.U, matrix(U), 4,
note="wrong U after manually setting U")
# Check the UB matrix
if sess.bmatrix is None:
continue
print "U: ", U
print "actual ub: ", self.ubcalc.UB.tolist()
print " desired b: ", sess.bmatrix
mneq_(self.ubcalc.UB, matrix(sess.bmatrix), 4,
note="wrong UB after manually setting U")
@raises(DiffcalcException)
def testGetUMatrix(self):
self.ubcalc.start_new('testcalc')
print self.ubcalc.U
@raises(DiffcalcException)
def testGetUBMatrix(self):
self.ubcalc.start_new('testcalc')
print self.ubcalc.UB
def testCalculateU(self):
for sess in scenarios.sessions():
self.setup_method()
self.ubcalc.start_new('testcalc')
# Skip this test case unless it contains a umatrix
if sess.umatrix is None:
continue
self.ubcalc.set_lattice(sess.name, *sess.lattice)
ref1 = sess.ref1
ref2 = sess.ref2
t = sess.time
self.ubcalc.add_reflection(
ref1.h, ref1.k, ref1.l, ref1.pos, ref1.energy, ref1.tag, t)
self.ubcalc.add_reflection(
ref2.h, ref2.k, ref2.l, ref2.pos, ref2.energy, ref2.tag, t)
self.ubcalc.calculate_UB()
returned = self.ubcalc.U.tolist()
print "*Required:"
print sess.umatrix
print "*Returned:"
print returned
mneq_(self.ubcalc.U, matrix(sess.umatrix), 4,
note="wrong U calulated for sess.name=" + sess.name)
def test__str__(self):
sess = scenarios.sessions()[0]
print "***"
print self.ubcalc.__str__()
print "***"
self.ubcalc.start_new('test')
print self.ubcalc.__str__()
print "***"
self.ubcalc.set_lattice(sess.name, *sess.lattice)
print self.ubcalc.__str__()
print "***"
ref1 = sess.ref1
ref2 = sess.ref2
t = sess.time
self.ubcalc.add_reflection(
ref1.h, ref1.k, ref1.l, ref1.pos, ref1.energy, ref1.tag, t)
self.ubcalc.add_reflection(
ref2.h, ref2.k, ref2.l, ref2.pos, ref2.energy, ref2.tag, t)
print self.ubcalc.__str__()
print "***"
self.ubcalc.calculate_UB()
print self.ubcalc.__str__()
def x_rotation(mu_or_alpha):
mu_or_alpha *= TORAD
return matrix(((1, 0, 0),
(0, cos(mu_or_alpha), -sin(mu_or_alpha)),
(0, sin(mu_or_alpha), cos(mu_or_alpha))))
def y_rotation(chi):
chi *= TORAD
return matrix(((cos(chi), 0, sin(chi)),
(0, 1, 0),
(-sin(chi), 0, cos(chi))))
def z_rotation(th):
eta = -th * TORAD
return matrix(((cos(eta), sin(eta), 0),
(-sin(eta), cos(eta), 0),
(0, 0, 1)))
CUBIC_EN = 12.39842
CUBIC = (1, 1, 1, 90, 90, 90)
ROT = 29
class TestUBCalcWithCubic(object):
def setup_method(self):
print "TestUBCalcWithCubic.setup_method"
hardware = Mock()
hardware.get_axes_names.return_value = \
('a', 'd', 'g', 'o', 'c', 'p')
self.ubcalc = UBCalculation(hardware,
SixCircleGammaOnArmGeometry(),
UbCalculationNonPersister(),
VliegUbCalcStrategy())
self.ubcalc.start_new('xtalubcalc')
self.ubcalc.set_lattice("xtal", *CUBIC)
self.energy = CUBIC_EN
def addref(self, hklref):
hkl, position = hklref
now = datetime.now()
self.ubcalc.add_reflection(
hkl[0], hkl[1], hkl[2], position, self.energy, "ref", now)
class TestUBCalcWithCubicTwoRef(TestUBCalcWithCubic):
def check(self, testname, hklref1, hklref2, expectedUMatrix):
self.addref(hklref1)
self.addref(hklref2)
matrixeq_(expectedUMatrix, self.ubcalc.U)
def test_with_squarely_mounted(self):
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0, phi=0))
lref = ((0, 0, 1),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90, phi=0))
pairs = (("hl", href, lref, I),
("lh", lref, href, I))
for testname, ref1, ref2, u in pairs:
yield self.check, testname, ref1, ref2, u
def test_with_x_mismount(self):
U = x_rotation(ROT)
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0, phi=0))
kref = ((0, 1, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30 - ROT + 90, chi=90,
phi=0))
lref = ((0, 0, 1),
Pos(alpha=0, delta=60, gamma=0, omega=30 - ROT, chi=90, phi=0))
pairs = (("hk", href, kref, U),
("hl", href, lref, U),
("kh", kref, href, U),
("kl", kref, lref, U),
("lk", lref, kref, U),
("lh", lref, href, U))
for testname, ref1, ref2, u in pairs:
yield self.check, testname, ref1, ref2, u
def test_with_y_mismount(self):
U = y_rotation(ROT)
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0 - ROT, phi=0))
lref = ((0, 0, 1),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90 - ROT, phi=0))
pairs = (("hl", href, lref, U),
("lh", lref, href, U))
for testname, ref1, ref2, u in pairs:
yield self.check, testname, ref1, ref2, u
def test_with_z_mismount(self):
U = z_rotation(ROT)
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0, phi=0 + ROT))
lref = ((0, 0, 1), # phi degenerate
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90, phi=67))
pairs = (("hl", href, lref, U),
("lh", lref, href, U))
for testname, ref1, ref2, u in pairs:
yield self.check, testname, ref1, ref2, u
def test_with_zy_mismount(self):
U = z_rotation(ROT) * y_rotation(ROT)
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0 - ROT,
phi=0 + ROT))
lref = ((0, 0, 1),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90 - ROT,
phi=ROT)) # chi degenerate
pairs = (("hl", href, lref, U),
("lh", lref, href, U))
for testname, ref1, ref2, u in pairs:
yield self.check, testname, ref1, ref2, u
class TestUBCalcWithcubicOneRef(TestUBCalcWithCubic):
def check(self, testname, hklref, expectedUMatrix):
print testname
self.addref(hklref)
self.ubcalc.calculate_UB_from_primary_only()
matrixeq_(expectedUMatrix, self.ubcalc.U)
def test_with_squarely_mounted(self):
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0, phi=0))
href_b = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30 + 90, chi=90,
phi=-90))
lref = ((0, 0, 1), # degenerate in phi
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90, phi=67))
pairs = (("h", href, I),
("hb", href_b, I),
("l", lref, I))
for testname, ref, u in pairs:
yield self.check, testname, ref, u
def test_with_x_mismount_h(self):
U = x_rotation(ROT)
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0, phi=0))
self.check("h", href, I)
def test_with_x_mismount_k(self):
U = x_rotation(ROT)
kref = ((0, 1, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30 - ROT + 90, chi=90,
phi=0))
self.check("k", kref, U)
def test_with_x_mismount_l(self):
U = x_rotation(ROT)
lref = ((0, 0, 1),
Pos(alpha=0, delta=60, gamma=0, omega=30 - ROT, chi=90, phi=0))
self.check("l", lref, U)
def test_with_y_mismount_h(self):
U = y_rotation(ROT)
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0 - ROT, phi=0))
self.check("h", href, U)
def test_with_y_mismount_k(self):
U = y_rotation(ROT)
kref = ((0, 1, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30 + 90, chi=90, phi=0))
self.check("k", kref, I) # TODO: can't pass - word instructions
def test_with_y_mismount_l(self):
U = y_rotation(ROT)
lref = ((0, 0, 1),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90 - ROT, phi=0))
self.check("l", lref, U)
def test_with_z_mismount_h(self):
U = z_rotation(ROT)
href = ((1, 0, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0, phi=0 + ROT))
self.check("h", href, U)
def test_with_z_mismount_k(self):
U = z_rotation(ROT)
kref = ((0, 1, 0),
Pos(alpha=0, delta=60, gamma=0, omega=30 + 90, chi=0,
phi=0 + ROT))
self.check("k", kref, U),
def test_with_z_mismount_l(self):
U = z_rotation(ROT)
lref = ((0, 0, 1), # phi degenerate
Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90, phi=67))
self.check("l", lref, I) # TODO: can't pass - word instructions
#Probably lost cause, conclusion is be careful and return the angle and
#direction of resulting u matrix
# def skip_test_with_zy_mismount(self):
# U = z_rotation(ROT) * y_rotation(ROT)
# href = ((1, 0, 0),
# Pos(alpha=0, delta=60, gamma=0, omega=30, chi=0 - ROT,
# phi=0 + ROT))
# kref = ((0, 1, 0),
# Pos(alpha=0, delta=60, gamma=0, omega=30 + 90, chi=90 - ROT,
# phi=0 + ROT))
# lref = ((0, 0, 1),
# Pos(alpha=0, delta=60, gamma=0, omega=30, chi=90 - ROT,
# phi=ROT)) # chi degenerate
# pairs = (("h", href, U),
# ("k", kref, U),
# ("l", lref, U))
# for testname, ref, u in pairs:
# yield self.check, testname, ref, u

View File

@@ -0,0 +1,83 @@
###
# 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 mock import Mock
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from diffcalc.hkl.you.geometry import SixCircle
from diffcalc.hkl.you.geometry import YouPosition
from diffcalc.hkl.you.calc import YouUbCalcStrategy
from test.tools import matrixeq_
from diffcalc.ub.calc import UBCalculation
from diffcalc.ub.persistence import UbCalculationNonPersister
#newub 'cubic' <--> reffile('cubic)
#setlat 'cubic' 1 1 1 90 90 90 <--> latt([1,1,1,90,90,90])
#pos wl 1 <--> BLi.setWavelength(1)
# <--> c2th([0,0,1]) --> 60
#pos sixc [0 60 0 30 1 1] <--> pos euler [1 1 30 0 60 0]
#addref 1 0 0 <--> saveref('100',[1, 0, 0])
#pos chi 91 <-->
#addref 0 0 1 <--> saveref('100',[1, 0, 0]) ; showref()
# ubm('100','001')
# ubm() ->
#array('d', [0.9996954135095477, -0.01745240643728364, -0.017449748351250637,
#0.01744974835125045, 0.9998476951563913, -0.0003045864904520898,
#0.017452406437283505, -1.1135499981271473e-16, 0.9998476951563912])
def posFromI16sEuler(phi, chi, eta, mu, delta, gamma):
return YouPosition(mu, delta, gamma, eta, chi, phi)
UB1 = matrix(
((0.9996954135095477, -0.01745240643728364, -0.017449748351250637),
(0.01744974835125045, 0.9998476951563913, -0.0003045864904520898),
(0.017452406437283505, -1.1135499981271473e-16, 0.9998476951563912))
) * (2 * pi)
EN1 = 12.39842
REF1a = posFromI16sEuler(1, 1, 30, 0, 60, 0)
REF1b = posFromI16sEuler(1, 91, 30, 0, 60, 0)
class TestUBCalculationWithYouStrategy():
"""Testing the math only here.
"""
def setup_method(self):
geometry = SixCircle() # pass through
hardware = Mock()
names = 'm', 'd', 'n', 'e', 'c', 'p'
hardware.get_axes_names.return_value = names
self.ubcalc = UBCalculation(hardware,
geometry,
UbCalculationNonPersister(),
YouUbCalcStrategy())
def testAgainstI16Results(self):
self.ubcalc.start_new('cubcalc')
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.add_reflection(1, 0, 0, REF1a, EN1, '100', None)
self.ubcalc.add_reflection(0, 0, 1, REF1b, EN1, '001', None)
self.ubcalc.calculate_UB()
matrixeq_(self.ubcalc.UB, UB1)

View File

@@ -0,0 +1,62 @@
###
# 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/>.
###
import unittest
try:
from numpy import matrix
except ImportError:
from numjy import matrix
from test.tools import assert_dict_almost_equal, mneq_
from diffcalc.ub.crystal import CrystalUnderTest
from test.diffcalc import scenarios
class TestCrystalUnderTest(object):
def setup_method(self):
self.tclatt = []
self.tcbmat = []
# From the dif_init.mat next to dif_dos.exe on Vlieg's cd
#self.tclatt.append([4.0004, 4.0004, 2.270000, 90, 90, 90])
#self.tcbmat.append([[1.570639, 0, 0] ,[0.0, 1.570639, 0] ,
# [0.0, 0.0, 2.767923]])
# From b16 on 27June2008 (From Chris Nicklin)
# self.tclatt.append([3.8401, 3.8401, 5.43072, 90, 90, 90])
# self.tcbmat.append([[1.636204, 0, 0],[0, 1.636204, 0],
# [0, 0, 1.156971]])
def testGetBMatrix(self):
# Check the calculated B Matrix
for sess in scenarios.sessions():
if sess.bmatrix is None:
continue
cut = CrystalUnderTest('tc', *sess.lattice)
desired = matrix(sess.bmatrix)
print desired.tolist()
answer = cut.B
print answer.tolist()
note = "Incorrect B matrix calculation for scenario " + sess.name
mneq_(answer, desired, 4, note=note)
def test__str__(self):
cut = CrystalUnderTest("HCl", 1, 2, 3, 4, 5, 6)
print cut.__str__()

View File

@@ -0,0 +1,100 @@
###
# 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/>.
###
import os
import shutil
import unittest
import tempfile
import time
from nose.tools import eq_ # @UnresolvedImport
try:
from gda.configuration.properties import LocalProperties
except ImportError:
print "Could not import LocalProperties to configure database locations."
from diffcalc.ub.persistence import UbCalculationNonPersister, UBCalculationJSONPersister
def prepareEmptyGdaVarFolder():
vartest_dir = os.path.join(os.getcwd(), 'var_test')
LocalProperties.set('gda.var', vartest_dir)
if os.path.exists(vartest_dir):
print "Removing existing gda.var: ", vartest_dir
shutil.rmtree(vartest_dir)
print "Creating gda.var: ", vartest_dir
os.mkdir(vartest_dir)
class TestUBCalculationNonPersister(object):
def setup_method(self):
self.persister = UbCalculationNonPersister()
def testSaveAndLoad(self):
self.persister.save('string1', 'ub1')
class TestUBCalculationJSONPersister(object):
def setup_method(self):
self.tmpdir = tempfile.mkdtemp()
print self.tmpdir
self.persister = UBCalculationJSONPersister(self.tmpdir)
f = open(os.path.join(self.tmpdir, 'unexpected_file'), 'w')
f.close()
def test_list_with_empty_dir(self):
eq_(self.persister.list(), [])
def test_save_load(self):
d = {'a' : 1, 'b': 2}
self.persister.save(d, 'first')
eq_(self.persister.load('first'), d)
def test_save_overwites(self):
d1 = {'a' : 1, 'b': 2}
self.persister.save(d1, 'first')
eq_(self.persister.load('first'), d1)
d2 = {'a' : 3, 'b': 4, 'c' : 5}
self.persister.save(d2, 'first')
eq_(self.persister.load('first'), d2)
def test_list(self):
d = {'a' : 1, 'b': 2}
self.persister.save(d, 'first')
eq_(self.persister.list(), ['first'])
def test_multiple_list(self):
d = {'a' : 1, 'b': 2}
self.persister.save(d, 'first_written')
time.sleep(.5)
self.persister.save(d, 'second_written')
time.sleep(.5)
self.persister.save(d, 'third_written')
eq_(self.persister.list(), ['third_written', 'second_written', 'first_written'])
def test_remove_list(self):
d = {'a' : 1, 'b': 2}
self.persister.save(d, 'first')
self.persister.remove('first')
eq_(self.persister.list(), [])

View File

@@ -0,0 +1,61 @@
###
# 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 mock import Mock
from diffcalc.ub.reference import YouReference
from test.tools import assert_array_almost_equal, assert_2darray_almost_equal
try:
from numpy import matrix, hstack
from numpy.linalg import norm
except ImportError:
from numjy import matrix, hstack
from numjy.linalg import norm
class TestYouReference():
def setup_method(self):
self.get_UB = Mock()
self.reference = YouReference(self.get_UB)
self.get_UB.return_value = matrix('1 0 0; 0 1 0; 0 0 1')
def test_default_n_phi(self):
assert_2darray_almost_equal(self.reference.n_phi.tolist(), matrix('0; 0; 1').tolist())
def test__str__with_phi_configured(self):
print self.reference
def test__str__with_hkl_configured(self):
self.reference.n_hkl_configured = matrix('0; 1; 1')
print self.reference
def test_n_phi_from_hkl_with_unity_matrix_001(self):
self.get_UB.return_value = matrix('1 0 0; 0 1 0; 0 0 1')
self.reference.n_hkl_configured = matrix('0; 0; 1')
assert_2darray_almost_equal(self.reference.n_phi.tolist(), matrix('0; 0; 1').tolist())
def test_n_phi_from_hkl_with_unity_matrix_010(self):
self.get_UB.return_value = matrix('1 0 0; 0 1 0; 0 0 1')
self.reference.n_hkl_configured = matrix('0; 1; 0')
assert_2darray_almost_equal(self.reference.n_phi.tolist(), matrix('0; 1; 0').tolist())

View File

@@ -0,0 +1,91 @@
###
# 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 datetime import datetime
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry
from diffcalc.ub.reflections import ReflectionList
from diffcalc.hkl.vlieg.geometry import VliegPosition as Pos
import unittest
class TestReflectionList(object):
def setup_method(self):
self._geometry = SixCircleGammaOnArmGeometry()
self.reflist = ReflectionList(self._geometry,
['a', 'd', 'g', 'o', 'c', 'p'])
self.time = datetime.now()
pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
self.reflist.add_reflection(1, 2, 3, pos, 1000, "ref1", self.time)
pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66)
self.reflist.add_reflection(1.1, 2.2, 3.3, pos, 1100, "ref2", self.time)
def test_add_reflection(self):
assert len(self.reflist) == 2
def testGetReflection(self):
answered = self.reflist.getReflection(1)
pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
desired = ([1, 2, 3], pos, 1000, "ref1", self.time)
assert answered == desired
def testRemoveReflection(self):
self.reflist.removeReflection(1)
answered = self.reflist.getReflection(1)
pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66)
desired = ([1.1, 2.2, 3.3], pos, 1100, "ref2", self.time)
assert answered == desired
def testedit_reflection(self):
ps = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
self.reflist.edit_reflection(1, 10, 20, 30, ps, 1000, "new1", self.time)
assert (self.reflist.getReflection(1)
== ([10, 20, 30], ps, 1000, "new1", self.time))
pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66)
assert (self.reflist.getReflection(2)
== ([1.1, 2.2, 3.3], pos, 1100, "ref2", self.time))
def testSwapReflection(self):
self.reflist.swap_reflections(1, 2)
pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66)
assert (self.reflist.getReflection(1)
== ([1.1, 2.2, 3.3], pos, 1100, "ref2", self.time))
pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
assert (self.reflist.getReflection(2)
== ([1, 2, 3], pos, 1000, "ref1", self.time))
def createRefStateDicts(self):
ref_0 = {
'h': 1,
'k': 2,
'l': 3,
'position': (0.1, 0.2, 0.3, 0.4, 0.5, 0.6),
'energy': 1000,
'tag': "ref1",
'time': repr(self.time)
}
ref_1 = {
'h': 1.1,
'k': 2.2,
'l': 3.3,
'position': (0.11, 0.22, 0.33, 0.44, 0.55, 0.66),
'energy': 1100,
'tag': "ref2",
'time': repr(self.time)
}
return ref_0, ref_1

View File

@@ -0,0 +1,465 @@
###
# 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 nose.tools import eq_ # @UnresolvedImport
import tempfile
import os.path
import pytest
try:
from numpy import matrix
except ImportError:
from numjy import matrix
import diffcalc.util # @UnusedImport
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry
from diffcalc.hardware import DummyHardwareAdapter
from test.tools import assert_iterable_almost_equal, mneq_, arrayeq_
from diffcalc.ub.persistence import UbCalculationNonPersister,\
UBCalculationJSONPersister
from diffcalc.util import DiffcalcException, MockRawInput
from diffcalc.ub.calc import UBCalculation
from diffcalc.hkl.vlieg.calc import VliegUbCalcStrategy
from test.diffcalc import scenarios
import diffcalc.hkl.vlieg.calc
diffcalc.util.DEBUG = True
def prepareRawInput(listOfStrings):
diffcalc.util.raw_input = MockRawInput(listOfStrings)
prepareRawInput([])
from diffcalc import settings
from diffcalc.hkl.you.geometry import SixCircle
from mock import Mock
from diffcalc.ub.persistence import UbCalculationNonPersister
class TestUBCommandsBase():
def setup_method(self):
names = 'alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'
self.hardware = DummyHardwareAdapter(names)
_geometry = SixCircleGammaOnArmGeometry()
_ubcalc_persister = self._createPersister()
settings.hardware = self.hardware
settings.geometry = _geometry
settings.ubcalc_persister = _ubcalc_persister
#settings.set_engine_name('vlieg')
settings.ubcalc_strategy = diffcalc.hkl.vlieg.calc.VliegUbCalcStrategy()
settings.angles_to_hkl_function = diffcalc.hkl.vlieg.calc.vliegAnglesToHkl
from diffcalc.ub import ub
reload(ub)
self.ub = ub
#self.ub.ubcalc = ub.ubcalc
prepareRawInput([])
diffcalc.util.RAISE_EXCEPTIONS_FOR_ALL_ERRORS = True
class TestUbCommands(TestUBCommandsBase):
def _createPersister(self):
return UbCalculationNonPersister()
def testNewUb(self):
self.ub.newub('test1')
eq_(self.ub.ubcalc._state.name, 'test1')
with pytest.raises(TypeError):
self.ub.newub(1)
def testNewUbInteractively(self):
prepareRawInput(['ubcalcname', 'xtal', '1', '2', '3', '91', '92',
'93'])
self.ub.newub()
def testLoadub(self):
with pytest.raises(TypeError):
self.ub.loadub((1, 2))
def testSaveubcalcas(self):
with pytest.raises(TypeError):
self.ub.saveubas(1)
with pytest.raises(TypeError):
self.ub.saveubas((1, 2))
self.ub.saveubas('blarghh')
def testUb(self):
with pytest.raises(TypeError):
self.ub.showref((1))
self.ub.ub()
self.ub.newub('testubcalc')
self.ub.ub()
def testSetlat(self):
# "Exception should result if no UBCalculation started")
with pytest.raises(DiffcalcException):
self.ub.setlat('HCl', 2)
self.ub.newub('testing_setlat')
with pytest.raises(TypeError):
self.ub.setlat(1)
with pytest.raises(TypeError):
self.ub.setlat(1, 2)
with pytest.raises(TypeError):
self.ub.setlat('HCl')
self.ub.setlat('NaCl', 1.1)
ubcalc = self.ub.ubcalc
eq_(('NaCl', 1.1, 1.1, 1.1, 90, 90, 90), ubcalc._state.crystal.getLattice())
self.ub.setlat('NaCl', 1.1, 2.2)
eq_(('NaCl', 1.1, 1.1, 2.2, 90, 90, 90), ubcalc._state.crystal.getLattice())
self.ub.setlat('NaCl', 1.1, 2.2, 3.3)
eq_(('NaCl', 1.1, 2.2, 3.3, 90, 90, 90), ubcalc._state.crystal.getLattice())
self.ub.setlat('NaCl', 1.1, 2.2, 3.3, 91)
eq_(('NaCl', 1.1, 2.2, 3.3, 90, 90, 91), ubcalc._state.crystal.getLattice())
with pytest.raises(TypeError):
self.ub.setlat(('NaCl', 1.1, 2.2, 3.3, 91, 92))
self.ub.setlat('NaCl', 1.1, 2.2, 3.3, 91, 92, 93)
assert_iterable_almost_equal(
('NaCl', 1.1, 2.2, 3.3, 91, 92, 92.99999999999999),
ubcalc._state.crystal.getLattice())
def testSetlatInteractive(self):
self.ub.newub('testing_setlatinteractive')
prepareRawInput(['xtal', '1', '2', '3', '91', '92', '93'])
self.ub.setlat()
getLattice = self.ub.ubcalc._state.crystal.getLattice
assert_iterable_almost_equal(getLattice(),
('xtal', 1., 2., 3., 91, 92, 92.999999999999986))
#Defaults:
prepareRawInput(['xtal', '', '', '', '', '', ''])
self.ub.setlat()
getLattice = self.ub.ubcalc._state.crystal.getLattice
eq_(getLattice(), ('xtal', 1., 1., 1., 90, 90, 90))
def testShowref(self):
with pytest.raises(TypeError):
self.ub.showref((1))
eq_(self.ub.showref(), None) # No UBCalculation loaded
# will be tested, for exceptions at least, implicitely below
self.ub.newub('testing_showref')
eq_(self.ub.showref(), None) # No UBCalculation loaded"
def testAddref(self):
with pytest.raises(TypeError):
self.ub.addref(1)
with pytest.raises(TypeError):
self.ub.addref(1, 2)
with pytest.raises(TypeError):
self.ub.addref(1, 2, 'blarghh')
# start new ubcalc
self.ub.newub('testing_addref')
reflist = self.ub.ubcalc._state.reflist # for conveniance
pos1 = (1.1, 1.2, 1.3, 1.4, 1.5, 1.6)
pos2 = (2.1, 2.2, 2.3, 2.4, 2.5, 2.6)
pos3 = (3.1, 3.2, 3.3, 3.4, 3.5, 3.6)
pos4 = (4.1, 4.2, 4.3, 4.4, 4.5, 4.6)
#
self.hardware.energy = 1.10
self.hardware.position = pos1
self.ub.addref([1.1, 1.2, 1.3])
result = reflist.get_reflection_in_external_angles(1)
eq_(result[:-1], ([1.1, 1.2, 1.3], pos1, 1.10, None))
self.hardware.energy = 2.10
self.hardware.position = pos2
self.ub.addref([2.1, 2.2, 2.3], 'atag')
result = reflist.get_reflection_in_external_angles(2)
eq_(result[:-1], ([2.1, 2.2, 2.3], pos2, 2.10, 'atag'))
self.ub.addref([3.1, 3.2, 3.3], pos3, 3.10)
result = reflist.get_reflection_in_external_angles(3)
eq_(result[:-1], ([3.1, 3.2, 3.3], pos3, 3.10, None))
self.ub.addref([4.1, 4.2, 4.3], pos4, 4.10, 'tag2')
result = reflist.get_reflection_in_external_angles(4)
eq_(result[:-1], ([4.1, 4.2, 4.3], pos4, 4.10, 'tag2'))
def testAddrefInteractively(self):
prepareRawInput([])
# start new ubcalc
self.ub.newub('testing_addref')
reflist = self.ub.ubcalc._state.reflist # for conveniance
pos1 = (1.1, 1.2, 1.3, 1.4, 1.5, 1.6)
pos2 = (2.1, 2.2, 2.3, 2.4, 2.5, 2.6)
pos3 = (3.1, 3.2, 3.3, 3.4, 3.5, 3.6)
pos3s = ['3.1', '3.2', '3.3', '3.4', '3.5', '3.6']
pos4 = (4.1, 4.2, 4.3, 4.4, 4.5, 4.6)
pos4s = ['4.1', '4.2', '4.3', '4.4', '4.5', '4.6']
#
self.hardware.energy = 1.10
self.hardware.position = pos1
prepareRawInput(['1.1', '1.2', '1.3', '', ''])
self.ub.addref()
result = reflist.get_reflection_in_external_angles(1)
eq_(result[:-1], ([1.1, 1.2, 1.3], pos1, 1.10, None))
self.hardware.energy = 2.10
self.hardware.position = pos2
prepareRawInput(['2.1', '2.2', '2.3', '', 'atag'])
self.ub.addref()
result = reflist.get_reflection_in_external_angles(2)
eq_(result[:-1], ([2.1, 2.2, 2.3], pos2, 2.10, 'atag'))
prepareRawInput(['3.1', '3.2', '3.3', 'n'] + pos3s + ['3.10', ''])
self.ub.addref()
result = reflist.get_reflection_in_external_angles(3)
eq_(result[:-1], ([3.1, 3.2, 3.3], pos3, 3.10, None))
prepareRawInput(['4.1', '4.2', '4.3', 'n'] + pos4s + ['4.10', 'tag2'])
self.ub.addref()
result = reflist.get_reflection_in_external_angles(4)
eq_(result[:-1], ([4.1, 4.2, 4.3], pos4, 4.10, 'tag2'))
def testEditRefInteractivelyWithCurrentPosition(self):
pos1 = (1.1, 1.2, 1.3, 1.4, 1.5, 1.6)
pos2 = (2.1, 2.2, 2.3, 2.4, 2.5, 2.6)
self.ub.newub('testing_editref')
self.ub.addref([1, 2, 3], pos1, 10, 'tag1')
self.hardware.energy = 11
self.hardware.position = pos2
prepareRawInput(['1.1', '', '3.1', 'y', ''])
self.ub.editref(1)
reflist = self.ub.ubcalc._state.reflist # for conveniance
result = reflist.get_reflection_in_external_angles(1)
eq_(result[:-1], ([1.1, 2, 3.1], pos2, 11, 'tag1'))
def testEditRefInteractivelyWithEditedPosition(self):
pos1 = (1.1, 1.2, 1.3, 1.4, 1.5, 1.6)
pos2 = (2.1, 2.2, 2.3, 2.4, 2.5, 2.6)
pos2s = ['2.1', '2.2', '2.3', '2.4', '2.5', '2.6']
self.ub.newub('testing_editref')
self.ub.addref([1, 2, 3], pos1, 10, 'tag1')
prepareRawInput(['1.1', '', '3.1', 'n'] + pos2s + ['12', 'newtag'])
self.ub.editref(1)
reflist = self.ub.ubcalc._state.reflist
result = reflist.get_reflection_in_external_angles(1)
eq_(result[:-1], ([1.1, 2, 3.1], pos2, 12, 'newtag'))
def testSwapref(self):
with pytest.raises(TypeError):
self.ub.swapref(1)
with pytest.raises(TypeError):
self.ub.swapref(1, 2, 3)
with pytest.raises(TypeError):
self.ub.swapref(1, 1.1)
self.ub.newub('testing_swapref')
pos = (1.1, 1.2, 1.3, 1.4, 1.5, 1.6)
self.ub.addref([1, 2, 3], pos, 10, 'tag1')
self.ub.addref([1, 2, 3], pos, 10, 'tag2')
self.ub.addref([1, 2, 3], pos, 10, 'tag3')
self.ub.swapref(1, 3)
self.ub.swapref(1, 3)
self.ub.swapref(3, 1) # end flipped
reflist = self.ub.ubcalc._state.reflist
tag1 = reflist.get_reflection_in_external_angles(1)[3]
tag2 = reflist.get_reflection_in_external_angles(2)[3]
tag3 = reflist.get_reflection_in_external_angles(3)[3]
eq_(tag1, 'tag3')
eq_(tag2, 'tag2')
eq_(tag3, 'tag1')
self.ub.swapref()
tag1 = reflist.get_reflection_in_external_angles(1)[3]
tag2 = reflist.get_reflection_in_external_angles(2)[3]
eq_(tag1, 'tag2')
eq_(tag2, 'tag3')
def testDelref(self):
self.ub.newub('testing_swapref')
pos = (1.1, 1.2, 1.3, 1.4, 1.5, 1.6)
self.ub.addref([1, 2, 3], pos, 10, 'tag1')
reflist = self.ub.ubcalc._state.reflist
reflist.get_reflection_in_external_angles(1)
self.ub.delref(1)
with pytest.raises(IndexError):
reflist.get_reflection_in_external_angles(1)
def testSetu(self):
# just test calling this method
#self.ub.setu([[1,2,3],[1,2,3],[1,2,3]])
self.ub.newub('testsetu')
setu = self.ub.setu
with pytest.raises(TypeError):
setu(1, 2)
with pytest.raises(TypeError):
setu(1)
with pytest.raises(TypeError):
setu('a')
with pytest.raises(TypeError):
setu([1, 2, 3])
with pytest.raises(TypeError):
setu([[1, 2, 3], [1, 2, 3], [1, 2]])
# diffCalcException expected if no lattice set yet
with pytest.raises(DiffcalcException):
setu([[1, 2, 3], [1, 2, 3], [1, 2, 3]])
self.ub.setlat('NaCl', 1.1)
setu([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) # check no exceptions only
setu(((1, 2, 3), (1, 2, 3), (1, 2, 3))) # check no exceptions only
def testSetuInteractive(self):
self.ub.newub('testsetu')
self.ub.setlat('NaCl', 1.1)
prepareRawInput(['1 2 3', '4 5 6', '7 8 9'])
self.ub.setu()
a = self.ub.ubcalc.U.tolist()
eq_([list(a[0]), list(a[1]), list(a[2])],
[[1, 2, 3], [4, 5, 6], [7, 8, 9]])
prepareRawInput(['', ' 9 9.9 99', ''])
self.ub.setu()
a = self.ub.ubcalc.U.tolist()
eq_([list(a[0]), list(a[1]), list(a[2])],
[[1, 0, 0], [9, 9.9, 99], [0, 0, 1]])
def testSetub(self):
# just test calling this method
self.ub.newub('testsetub')
setub = self.ub.setub
with pytest.raises(TypeError):
setub(1, 2)
with pytest.raises(TypeError):
setub(1)
with pytest.raises(TypeError):
setub('a')
with pytest.raises(TypeError):
setub([1, 2, 3])
with pytest.raises(TypeError):
setub([[1, 2, 3], [1, 2, 3], [1, 2]])
setub([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) # check no exceptions only
setub(((1, 2, 3), (1, 2, 3), (1, 2, 3))) # check no exceptions only
def testSetUbInteractive(self):
self.ub.newub('testsetu')
self.ub.setlat('NaCl', 1.1)
prepareRawInput(['1 2 3', '4 5 6', '7 8 9'])
self.ub.setub()
a = self.ub.ubcalc.UB.tolist()
eq_([list(a[0]), list(a[1]), list(a[2])],
[[1, 2, 3], [4, 5, 6], [7, 8, 9]])
prepareRawInput(['', ' 9 9.9 99', ''])
self.ub.setub()
a = self.ub.ubcalc.UB.tolist()
eq_([list(a[0]), list(a[1]), list(a[2])],
[[1, 0, 0], [9, 9.9, 99], [0, 0, 1]])
def testCalcub(self):
with pytest.raises(TypeError):
self.ub.calcub(1) # wrong input
# no ubcalc started:
with pytest.raises(DiffcalcException):
self.ub.calcub()
self.ub.newub('testcalcub')
# not enougth reflections:
with pytest.raises(DiffcalcException):
self.ub.calcub()
s = scenarios.sessions()[0]
self.ub.setlat(s.name, *s.lattice)
r = s.ref1
self.ub.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
r = s.ref2
self.ub.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
self.ub.calcub()
mneq_(self.ub.ubcalc.UB, matrix(s.umatrix) * matrix(s.bmatrix),
4, note="wrong UB matrix after calculating U")
def testC2th(self):
self.ub.newub('testcalcub')
self.ub.setlat('cube', 1, 1, 1, 90, 90, 90)
assert self.ub.c2th((0, 0, 1)) == pytest.approx(60)
def testSigtau(self):
# sigtau [sig tau]
with pytest.raises(TypeError):
self.ub.sigtau(1)
with pytest.raises(ValueError):
self.ub.sigtau(1, 'a')
self.ub.sigtau(1, 2)
self.ub.sigtau(1, 2.0)
eq_(self.ub.ubcalc.sigma, 1)
eq_(self.ub.ubcalc.tau, 2.0)
def testSigtauInteractive(self):
prepareRawInput(['1', '2.'])
self.ub.sigtau()
eq_(self.ub.ubcalc.sigma, 1)
eq_(self.ub.ubcalc.tau, 2.0)
#Defaults:
prepareRawInput(['', ''])
self.hardware.position = [None, None, None, None, 3, 4.]
self.ub.sigtau()
eq_(self.ub.ubcalc.sigma, -3.)
eq_(self.ub.ubcalc.tau, -4.)
def testSetWithString(self):
with pytest.raises(TypeError):
self.ub.setlat('alpha', 'a')
with pytest.raises(TypeError):
self.ub.setlat('alpha', 1, 'a')
def test_setnphihkl_at_various_phases(self):
self.ub.setnphi([1, 0, 1])
self.ub.setnhkl([1, 0, 1])
self.ub.newub('test')
self.ub.setnphi([1, 0, 1])
self.ub.setnhkl([1, 0, 1])
self.ub.setlat('cube', 1, 1, 1, 90, 90, 90)
self.ub.setnphi([1, 0, 1])
self.ub.setnhkl([1, 0, 1])
self.ub.setu([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
self.ub.setnphi([1, 0, 1])
self.ub.setnhkl([1, 0, 1])
class TestUbCommandsJsonPersistence(TestUBCommandsBase):
def _createPersister(self):
self.tmpdir = tempfile.mkdtemp()
print self.tmpdir
self.persister = UBCalculationJSONPersister(self.tmpdir)
f = open(os.path.join(self.tmpdir, 'unexpected_file'), 'w')
f.close()
return self.persister
def testNewUb(self):
self.ub.newub('test1')
self.ub.loadub('test1')
self.ub.ub()
def test_n_phi_persistance(self):
self.ub.newub('test1')
self.ub.setnphi([0, 1, 0])
arrayeq_(self.ub.ubcalc.n_phi.T.tolist()[0], [0, 1, 0])
self.ub.loadub('test1')
arrayeq_(self.ub.ubcalc.n_phi.T.tolist()[0], [0, 1, 0])

View File

@@ -0,0 +1,172 @@
from nose.tools import assert_sequence_equal # @UnresolvedImport
from nose.tools import eq_
from nose import SkipTest
try:
import IPython.core.magic # @UnusedImport
from diffcmd.ipython import parse
IPYTHON = True
except ImportError:
IPYTHON = False
class CallableNamedObject(object):
def __init__(self, name, val):
self._name = name
self._val = val
def method(self):
return self._val
def __repr__(self):
return self._name
def __call__(self):
return self._val
o1 = CallableNamedObject('o1', 1)
o2 = CallableNamedObject('o2', 2)
o3 = CallableNamedObject('o3', 3)
c = 4
d = {
'o1' : o1,
'o2' : o2,
'o3' : o3,
'c' : 4
}
def check(s, *expected):
assert_sequence_equal(parse(s, d), expected)
def assert_raises_syntax_error_with_message(msg, func, *args, **kwargs):
try:
func(*args, **kwargs)
raise AssertionError()
except SyntaxError as e:
eq_(e.message, msg)
def setup_module():
if not IPYTHON:
raise SkipTest('ipython not available')
def test_parse_spaces():
check('')
check(' ')
check(' ')
def test_parse_commas():
assert_raises_syntax_error_with_message(
'unexpected comma', parse, '1 2, 3', d)
def test_parse_numbers():
check('1', 1)
check('10', 10)
check('10 2 3', 10, 2, 3)
def test_parse_negative_numbers():
check('-1', -1)
check('-10', -10)
check('-10 2 -3', -10, 2, -3)
def test_parse_negative_number_with_space_between_sign_and_digit():
msg = 'could not evaluate: "-"'
assert_raises_syntax_error_with_message(msg, parse, '- 1', d)
assert_raises_syntax_error_with_message(msg, parse, '1 - 1', d)
def test_parse_strings():
check("'s1'", 's1')
check("'s1' 's2'", 's1', 's2')
check('"s1"', 's1')
check('"s1" "s2"', 's1', 's2')
def test_parse_strings_containing_spaces():
check("'ab cd'", 'ab cd')
check("' ab cd '", ' ab cd ')
def test_parse_strings_containing_commas():
check("'ab,cd'", 'ab,cd')
check("', ab, cd, '", ', ab, cd, ')
def test_parse_strings_containing_hashes():
check("'ab #cd'", 'ab #cd')
check("' ab cd# '", ' ab cd# ')
def test_parse_strings_containing_strings():
check(''' 1 'ab cd' 2''', 1, 'ab cd', 2)
check(''' 1 '"ab" cd' 2''', 1, '"ab" cd', 2)
def test_parse_strings_containing_square_brackets():
check("'ab[cd'", 'ab[cd')
check("'[ ab cd ]'", '[ ab cd ]')
def test_parse_objects_and_numbers():
check('o1', o1)
check('c', 4)
check('o1 o2', o1, o2)
check('1 o1 o2 2 c', 1, o1, o2, 2, 4)
def test_parse_numbers_with_math():
check('1+1', 2)
check('-1 1-1 1 1+1', -1, 0, 1, 2)
def test_parse_callables_and_methods():
check('o1()', 1)
check('o1.method()', 1)
def test_parse_objects_numbers_and_strings():
check(" o1 's2'", o1, 's2')
check("1 's1' 's2' -2 o2", 1, 's1', 's2', -2, o2)
def test_parse_objects_and_numbers_and_extra_spaces():
check(' o1 ', o1)
check(' o1 o2 ', o1, o2)
check('1 o1 o2 -2 ', 1, o1, o2, -2)
def test_parse_lists():
check('[]', [])
check('[1]', [1])
check('[-1 2 3]', [-1, 2, 3])
check('[1 2 -3][4]', [1, 2, -3], [4])
check('[1 2 3][4 -5]', [1, 2, 3], [4, -5])
def test_parse_nested_lists():
check('[[]]', [[]])
check('[[1]]', [[1]])
check('[[1 2 3]]', [[1, 2, 3]])
check('[[1 2 3] [4 5 6]]', [[1, 2, 3], [4, 5, 6]])
check('[[1 2 3][4 5 6]]', [[1, 2, 3], [4, 5, 6]])
check('[[1 2 3][4 5 [6 7]]]', [[1, 2, 3], [4, 5, [6, 7]]])
def test_parse_lists_and_others():
check('[[]]', [[]])
check('[[o1]]', [[o1]])
check('[[o1 o2() -3]]', [[o1, 2, -3]])
def test_parse_unexpected_list_closure():
msg = 'could not evaluate: "1, 2], 3"'
assert_raises_syntax_error_with_message(msg, parse, '1 2] 3', d)
assert_raises_syntax_error_with_message(msg, parse, '1 2 ] 3', d)
assert_raises_syntax_error_with_message(msg, parse, '1 2 ]3', d)
def test_parse_with_trailing_comments():
check('1# comment', 1)
check('1 # comment', 1)
check('1# comment # comment2', 1)
check('o1# comment', o1)
check('o1()# comment', 1)
check('-1# comment', -1)
check('1-1# comment', 0)
def test_parse_with_only_comments():
check('# comment')
check(' # comment')
check(' # comment')

View File

@@ -0,0 +1,690 @@
###
# 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/>.
###
#!Go to lattice menu to set lattice parameters
#lattice
#a1 3.840100
#a2 3.840100
#a3 5.430720
#a4 90.000000
#a5 90.000000
#a6 90.000000
#compute return
#!Go to fixed parameter menu to set parameters
#fixed
#alpha 0
#gamma 0.000000
#incoming 0
#outgoing 0
#h_crystal 0.000000
#k_crystal 0.000000
#l_crystal 1.000000
#wave 5.067085
#mirror 1
#return
#!Go to circle limits menu
#limits
#alpha -2.1430 27.8570
#delta -2.3070 125.0000
#gamma -50.0000 50.0000
#omega -185.0000 30.0000
#chi -14.0000 14.0000
#phi -400.0000 400.0000
#return
#!Go to orientation menu to set parameters
#orient
#sigma -1.350000 # zeroed for some
#tau -106.000000 #zeroed for some
#surfhkl -4.86513e-03 1.67605e-04 8.64299e-01 #zeroed for some
#input
#orient 1 1.000 0.000 1.0628
# 5.000 22.790 0.000 1.552 22.400 14.255
#orient 2 0.000 1.000 1.0628
# 5.000 22.790 0.000 4.575 24.275 101.320
#DIF.ORIENT>li
# 0.997161 -0.062217 0.042420
# U = 0.062542 0.998022 -0.006371
# -0.041940 0.009006 0.999080
#
#sigma = 0.0000
#tau = 0.0000
#Surface normal in hkl frame = (0.000e+00,0.000e+00,1.000e+00)
#DIF.FIX>li
#alpha = 0.0000
#gamma = 0.0000
#beta_in = 8.0000
#beta_out = 1.0000
#wavevector = 5.0671 <=> lambda = 1.2400
#mirror = +1
#h_crystal = 0.0000
#k_crystal = 0.0000
#l_crystal = 1.0000
#DIF.MODE>li
#Incidence angle equals outgoing angle
#Alpha and gamma fixed
{1}
#DIF>cal .7 .9 1.3
#DEBUGFILE = difbug.txt*** SURFMODE = 1
#<<< entering angcal.do_hkl_to_angles >>>
# -> h,k,l = 0.700000 0.900000 1.300000
# -> alpha_fix = 0.000000
# -> gamma_fix = 0.000000
# -> difmode = 3
# -> BETMODE = 3
#<- beta_in = 0.145358
#<-delta_comp = 0.477448
#<- h_phi_norm:
# 0.464987 0.639188 0.612557
# - q_alpha_norm:
# 0.971641 -0.236463 0.000000
# -> a =
# 0.464987 0.639188 0.612557
# -> b =
# 0.971641 -0.236463 0.000000
# <- coxi = 0.300656
# <- xi = 1.265416
# - r0_matrix:
# 0.316787 0.797295 0.513776
# -0.664730 0.573015 -0.479361
# -0.676594 -0.189667 0.711510
# -> a =
# 0.971641 -0.236463 0.000000
# -> b =
# 1.000000 0.000000 0.000000
# <- coxi = 0.971641
# <- xi = 0.238724
# - t_matrix:
# 0.971641 -0.236463 0.000000
# 0.236463 0.971641 0.000000
# 0.000000 0.000000 1.000000
# - surf_norm_phi:
# 0.000000 -0.000000 1.000000
# - surf_psi:
# 0.612557 -0.344278 0.711510
# - v21=-0.236463 - v22=0.971641 - v23=0.000000 - a=-0.334514 - b=0.691332 - c=0.
#000000
# psi=0.450660←[0;1;33;44mWARNING, chi outside limits←[0;1;37;44m
# h k l alpha delta gamma omega chi phi
# 0.700 0.900 1.300 0.0000 27.3557 0.0000 13.6779 37.7746 53.9654
#
# beta_in beta_out rho eta twotheta
# 8.3284 8.3284 36.5258 0.1117 27.3557
{2}
#DIF.FIX>al
#Rotary table angle (if fixed): 5
#DIF.FIX>re
#DIF>calc .7 .9 1.3
#DEBUGFILE = difbug.txt*** SURFMODE = 1
#<<< entering angcal.do_hkl_to_angles >>>
# -> h,k,l = 0.700000 0.900000 1.300000
# -> alpha_fix = 0.087266
# -> gamma_fix = 0.000000
# -> difmode = 3
# -> BETMODE = 3
#<- beta_in = 0.145358
#<-delta_comp = 0.470011
#<- h_phi_norm:
# 0.464987 0.639188 0.612557
# - q_alpha_norm:
# 0.957647 -0.221243 0.184291
# -> a =
# 0.464987 0.639188 0.612557
# -> b =
# 0.957647 -0.221243 0.184291
# <- coxi = 0.416766
# <- xi = 1.140911
# - r0_matrix:
# 0.462060 0.804557 0.373079
# -0.625426 0.593875 -0.506117
# -0.628763 0.000523 0.777597
# -> a =
# 0.957647 -0.221243 0.184291
# -> b =
# 1.000000 0.000000 0.000000
# <- coxi = 0.957647
# <- xi = 0.292079
# - t_matrix:
# 0.957647 -0.221243 0.184291
# 0.221243 0.974996 0.020828
# -0.184291 0.020828 0.982651
# - surf_norm_phi:
# 0.000000 -0.000000 1.000000
# - surf_psi:
# 0.612557 -0.394726 0.684811
# - v21=-0.236463 - v22=0.969471 - v23=-0.064895 - a=-0.427116 - b=0.638288 - c=0
#.000000
# psi=0.589726←[0;1;33;44mWARNING, chi outside limits←[0;1;37;44m
# h k l alpha delta gamma omega chi phi
# 0.700 0.900 1.300 5.0000 26.9296 0.0000 8.4916 27.2563 59.5855
#
# beta_in beta_out rho eta twotheta
# 8.3284 8.3284 26.9332 0.1117 27.3557
{3}
#DIF>cal .7 .9 1.3
#DEBUGFILE = difbug.txt*** SURFMODE = 1
#<<< entering angcal.do_hkl_to_angles >>>
# -> h,k,l = 0.700000 0.900000 1.300000
# -> alpha_fix = 0.087266
# -> gamma_fix = 0.174533
# -> difmode = 3
# -> BETMODE = 3
#<- beta_in = 0.145358
#<-delta_comp = 0.400814
#<- h_phi_norm:
# 0.464987 0.639188 0.612557
# - q_alpha_norm:
# 0.812475 -0.189119 0.551469
# -> a =
# 0.464987 0.639188 0.612557
# -> b =
# 0.812475 -0.189119 0.551469
# <- coxi = 0.594714
# <- xi = 0.933886
# - r0_matrix:
# 0.732257 0.678116 0.062920
# -0.536408 0.631214 -0.560210
# -0.419603 0.376467 0.825958
# -> a =
# 0.812475 -0.189119 0.551469
# -> b =
# 1.000000 0.000000 0.000000
# <- coxi = 0.812475
# <- xi = 0.622411
# - t_matrix:
# 0.812475 -0.189119 0.551469
# 0.189119 0.980267 0.057542
# -0.551469 0.057542 0.832208
# - surf_norm_phi:
# 0.000000 -0.000000 1.000000
# - surf_psi:
# 0.612557 -0.489729 0.620435
# - v21=-0.236463 - v22=0.971522 - v23=-0.015209 - a=-0.485218 - b=0.595318 - c=0
#.000000
# psi=0.683855 h k l alpha delta gamma omega c
#hi phi
# 0.700 0.900 1.300 5.0000 22.9649 10.0000-137.7796 -4.9721 203.0655
#
# beta_in beta_out rho eta twotheta
# 8.3284 8.3284 3.6800 0.1117 27.3557
{4}
#DIF>fi
#DIF.FIX>li
#alpha = 5.0000
#gamma = 10.0000
#beta_in = 4.0000
#beta_out = 1.0000
#wavevector = 5.0671 <=> lambda = 1.2400
#mirror = +1
#h_crystal = 0.0000
#k_crystal = 0.0000
#l_crystal = 1.0000
#DIF.FIX>re
#DIF>mo
#DIF.MODE>li
#Fixed angle of incidence
#Alpha and gamma fixed
#DIF>calc .7 .9 1.3
#DEBUGFILE = difbug.txt*** SURFMODE = 1
#<<< entering angcal.do_hkl_to_angles >>>
# -> h,k,l = 0.700000 0.900000 1.300000
# -> alpha_fix = 0.087266
# -> gamma_fix = 0.174533
# -> difmode = 3
# -> BETMODE = 123
#<- beta_in = 0.069813
#<-delta_comp = 0.400814
#<- h_phi_norm:
# 0.464987 0.639188 0.612557
# - q_alpha_norm:
# 0.812475 -0.189119 0.551469
# -> a =
# 0.464987 0.639188 0.612557
# -> b =
# 0.812475 -0.189119 0.551469
# <- coxi = 0.594714
# <- xi = 0.933886
# - r0_matrix:
# 0.732257 0.678116 0.062920
# -0.536408 0.631214 -0.560210
# -0.419603 0.376467 0.825958
# -> a =
# 0.812475 -0.189119 0.551469
# -> b =
# 1.000000 0.000000 0.000000
# <- coxi = 0.812475
# <- xi = 0.622411
# - t_matrix:
# 0.812475 -0.189119 0.551469
# 0.189119 0.980267 0.057542
# -0.551469 0.057542 0.832208
# - surf_norm_phi:
# 0.000000 -0.000000 1.000000
# - surf_psi:
# 0.612557 -0.489729 0.620435
# - v21=-0.236463 - v22=0.971522 - v23=-0.015209 - a=-0.485218 - b=0.595318 - c=0
#.075090
# psi=0.781784 h k l alpha delta gamma omega c
#hi phi
# 0.700 0.900 1.300 5.0000 22.9649 10.0000 -11.8850 4.7799 80.4416
#
# beta_in beta_out rho eta twotheta
# 4.0000 12.7054 4.6772 0.1866 27.3557
{5}
DIF>or
DIF.ORIENT>li
0.997161 -0.062217 0.042420
U = 0.062542 0.998022 -0.006371
-0.041940 0.009006 0.999080
sigma = -1.3500
tau = -106.0000
Surface normal in hkl frame = (0.000e+00,0.000e+00,0.000e+00)
DIF.ORIENT>fi
←[0;1;33;44mERROR, command "fi" not recognized←[0;1;37;44m
DIF.ORIENT>re
DIF>fi
DIF.FIX>li
alpha = 5.0000
gamma = 10.0000
beta_in = 4.0000
beta_out = 1.0000
wavevector = 5.0671 <=> lambda = 1.2400
mirror = +1
h_crystal = 0.0000
k_crystal = 0.0000
l_crystal = 1.0000
Incidence angle equals outgoing angle
Alpha and gamma fixed
DIF.MODE>re
DIF>calc .7 .9 1.3
DEBUGFILE = difbug.txt*** SURFMODE = 1
<<< entering angcal.do_hkl_to_angles >>>
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.174533
-> difmode = 3
-> BETMODE = 3
<- beta_in = 0.142580
<-delta_comp = 0.400814
<- h_phi_norm:
0.464987 0.639188 0.612557
- q_alpha_norm:
0.812475 -0.189119 0.551469
-> a =
0.464987 0.639188 0.612557
-> b =
0.812475 -0.189119 0.551469
<- coxi = 0.594714
<- xi = 0.933886
- r0_matrix:
0.732257 0.678116 0.062920
-0.536408 0.631214 -0.560210
-0.419603 0.376467 0.825958
-> a =
0.812475 -0.189119 0.551469
-> b =
1.000000 0.000000 0.000000
<- coxi = 0.812475
<- xi = 0.622411
- t_matrix:
0.812475 -0.189119 0.551469
0.189119 0.980267 0.057542
-0.551469 0.057542 0.832208
- surf_norm_phi:
0.006494 -0.022647 0.999722
- surf_psi:
0.600931 -0.509673 0.615724
- v21=-0.236463 - v22=0.971522 - v23=-0.015209 - a=-0.504523 - b=0.590437 - c=0
.000000
psi=0.707095 h k l alpha delta gamma omega c
hi phi
0.700 0.900 1.300 5.0000 22.9649 10.0000 30.6586 4.5295 35.4036
beta_in beta_out rho eta twotheta
8.1693 8.1693 2.8586 0.1294 27.3557
{6}
Fixed angle of incidence
Alpha and gamma fixed
DIF.MODE>re
DIF>calc .7 .9 1.3
DEBUGFILE = difbug.txt*** SURFMODE = 1
<<< entering angcal.do_hkl_to_angles >>>
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.174533
-> difmode = 3
-> BETMODE = 123
<- beta_in = 0.104720
<-delta_comp = 0.400814
<- h_phi_norm:
0.464987 0.639188 0.612557
- q_alpha_norm:
0.812475 -0.189119 0.551469
-> a =
0.464987 0.639188 0.612557
-> b =
0.812475 -0.189119 0.551469
<- coxi = 0.594714
<- xi = 0.933886
- r0_matrix:
0.732257 0.678116 0.062920
-0.536408 0.631214 -0.560210
-0.419603 0.376467 0.825958
-> a =
0.812475 -0.189119 0.551469
-> b =
1.000000 0.000000 0.000000
<- coxi = 0.812475
<- xi = 0.622411
- t_matrix:
0.812475 -0.189119 0.551469
0.189119 0.980267 0.057542
-0.551469 0.057542 0.832208
- surf_norm_phi:
0.006494 -0.022647 0.999722
- surf_psi:
0.600931 -0.509673 0.615724
- v21=-0.236463 - v22=0.971522 - v23=-0.015209 - a=-0.504523 - b=0.590437 - c=0
.037569
psi=0.755489 h k l alpha delta gamma omega c
hi phi
0.700 0.900 1.300 5.0000 22.9649 10.0000 2.2388 4.3898 65.4395
beta_in beta_out rho eta twotheta
6.0000 10.3504 3.3267 0.1664 27.3557
{7}
DIF.FIX>re
DIF>calc .7 .9 1.3
DEBUGFILE = difbug.txt*** SURFMODE = 1
<<< entering angcal.do_hkl_to_angles >>>
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.174533
-> difmode = 3
-> BETMODE = 2
<- beta_in = 0.163048
<-delta_comp = 0.400814
<- h_phi_norm:
0.464987 0.639188 0.612557
- q_alpha_norm:
0.812475 -0.189119 0.551469
-> a =
0.464987 0.639188 0.612557
-> b =
0.812475 -0.189119 0.551469
<- coxi = 0.594714
<- xi = 0.933886
- r0_matrix:
0.732257 0.678116 0.062920
-0.536408 0.631214 -0.560210
-0.419603 0.376467 0.825958
-> a =
0.812475 -0.189119 0.551469
-> b =
1.000000 0.000000 0.000000
<- coxi = 0.812475
<- xi = 0.622411
- t_matrix:
0.812475 -0.189119 0.551469
0.189119 0.980267 0.057542
-0.551469 0.057542 0.832208
- surf_norm_phi:
0.006494 -0.022647 0.999722
- surf_psi:
0.600931 -0.509673 0.615724
- v21=-0.236463 - v22=0.971522 - v23=-0.015209 - a=-0.504523 - b=0.590437 - c=-
0.020228
psi=0.681046 h k l alpha delta gamma omega c
hi phi
0.700 0.900 1.300 5.0000 22.9649 10.0000 43.4628 5.0387 21.7292
beta_in beta_out rho eta twotheta
9.3419 7.0000 2.6310 0.1095 27.3557
{8}
8.1693 8.1693 0.0000 0.1294 27.3557
DIF>mo
DIF.MODE>li
Incidence angle equals outgoing angle
Out-of-plane angle (gamma) fixed
Surface normal horizontal
DIF.MODE>re
DIF>fi
DIF.FIX>li
alpha = 5.0000
gamma = 10.0000
beta_in = 8.0000
beta_out = 1.0000
wavevector = 5.0671 <=> lambda = 1.2400
mirror = +1
h_crystal = 0.0000
k_crystal = 0.0000
l_crystal = 1.0000
DIF.FIX>re
DIF>or
DIF.ORIENT>li
0.997161 -0.062217 0.042420
U = 0.062542 0.998022 -0.006371
-0.041940 0.009006 0.999080
sigma = -1.3500
tau = -106.0000
Surface normal in hkl frame = (0.000e+00,0.000e+00,0.000e+00)
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.174533
-> difmode = 2
-> BETMODE = 3
- beta_in = 0.142580
-> a =
0.006494 -0.022647 0.999722
-> b =
0.000000 -0.142098 0.989853
<- coxi = 0.992796
<- xi = 0.120106
-delta_comp = 0.386317
- h_phi_norm:
0.464987 0.639188 0.612557
- q_alpha_norm:
0.784595 -0.173246 0.595312
-> a =
0.464987 0.639188 0.612557
-> b =
0.784595 -0.173246 0.595312
<- coxi = 0.618753
<- xi = 0.903642
- r0_matrix:
0.765049 0.643327 0.028814
-0.520794 0.644410 -0.559919
-0.378779 0.413359 0.828046
-> a =
0.784595 -0.173246 0.595312
-> b =
1.000000 0.000000 0.000000
<- coxi = 0.784595
<- xi = 0.668754
- t_matrix:
0.784595 -0.173246 0.595312
0.173246 0.983182 0.057792
-0.595312 0.057792 0.801413
- surf_norm_phi:
0.006494 -0.022647 0.999722
- surf_psi:
0.600931 -0.517538 0.609128
- v21=-0.236463 - v22=0.971207 - v23=-0.029010 - a=-0.520308 - b=0.576575 - c=-
.000000
psi=0.734145 h k l alpha delta gamma omega c
i phi
0.700 0.900 1.300 6.1937 22.1343 10.0000 46.9523 1.5102 18.8112
beta_in beta_out rho eta twotheta
8.1693 8.1693 0.0000 0.1294 27.3557
{9}
DIF>mo
DIF.MODE>li
Incidence angle equals outgoing angle
Rotary table (alpha) fixed
Surface normal horizontal
DIF.MODE>re
DIF>fi
DIF.FIX>li
alpha = 5.0000
gamma = 10.0000
beta_in = 8.0000
beta_out = 1.0000
wavevector = 5.0671 <=> lambda = 1.2400
mirror = +1
h_crystal = 0.0000
k_crystal = 0.0000
l_crystal = 1.0000
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.174533
-> difmode = 123
-> BETMODE = 3
- beta_in = 0.142580
-> a =
0.006494 -0.022647 0.999722
-> b =
0.000000 -0.142098 0.989853
<- coxi = 0.992796
<- xi = 0.120106
-delta_comp = 0.387782
- h_phi_norm:
0.464987 0.639188 0.612557
- q_alpha_norm:
0.784595 -0.185610 0.591574
-> a =
0.464987 0.639188 0.612557
-> b =
0.784595 -0.185610 0.591574
<- coxi = 0.608560
<- xi = 0.916552
- r0_matrix:
0.758937 0.650653 0.025810
-0.524967 0.634822 -0.566931
-0.385260 0.416716 0.823361
-> a =
0.784595 -0.185610 0.591574
-> b =
1.000000 0.000000 0.000000
<- coxi = 0.784595
<- xi = 0.668754
- t_matrix:
0.784595 -0.185610 0.591574
0.185610 0.980695 0.061528
-0.591574 0.061528 0.803900
- surf_norm_phi:
0.006494 -0.022647 0.999722
- surf_psi:
0.600931 -0.520396 0.606688
- v21=-0.236463 - v22=0.971601 - v23=-0.008771 - a=-0.510938 - b=0.584895 - c=0
000000
psi=0.718011 h k l alpha delta gamma omega c
i phi
0.700 0.900 1.300 5.0000 22.2183 11.1054 65.8276 2.5180 -0.0749
beta_in beta_out rho eta twotheta
8.1693 8.1693 -0.0000 0.1294 27.3557
{10}
DIF.MODE>Zaxis
DIF.MODE>li
Incidence angle equals outgoing angle
Z-axis mode
Surface normal horizontal
DIF.MODE>re
DIF>fi
DIF.FIX>li
alpha = 5.0000
gamma = 10.0000
beta_in = 8.0000
beta_out = 1.0000
wavevector = 5.0671 <=> lambda = 1.2400
mirror = +1
h_crystal = 0.0000
k_crystal = 0.0000
l_crystal = 1.0000
DIF>calc .7 .9 1.3
DEBUGFILE = difbug.txt*** SURFMODE = 1
<<< entering angcal.do_hkl_to_angles >>>
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.174533
-> difmode = 4
-> BETMODE = 3<-delta_comp = 0.384244
h k l alpha delta gamma omega chi phi
0.700 0.900 1.300 8.1693 22.0156 8.1693 -40.2188 1.3500 106.0000
beta_in beta_out rho eta twotheta
8.1693 8.1693 -0.0000 0.1294 27.3557
{11}
DIF>mo
DIF.MODE>in
DIF.MODE>re
DIF>calc .7 .9 1.3
DEBUGFILE = difbug.txt*** SURFMODE = 1
<<< entering angcal.do_hkl_to_angles >>>
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.000000
-> difmode = 4
-> BETMODE = 123<-delta_comp = 0.384245
h k l alpha delta gamma omega chi phi
0.700 0.900 1.300 8.0000 22.0156 8.3386 -40.0939 1.3500 106.0000
beta_in beta_out rho eta twotheta
8.0000 8.3386 -0.0000 0.1322 27.3557
{12}
DIF>mo
DIF.MODE>out
DIF.MODE>re
DIF>calc .7 .9 1.3
DEBUGFILE = difbug.txt*** SURFMODE = 1
<<< entering angcal.do_hkl_to_angles >>>
-> h,k,l = 0.700000 0.900000 1.300000
-> alpha_fix = 0.087266
-> gamma_fix = 0.000000
-> difmode = 4
-> BETMODE = 2<-delta_comp = 0.385708
h k l alpha delta gamma omega chi phi
0.700 0.900 1.300 15.4706 22.0994 1.0000 -45.5521 1.3500 106.0000
beta_in beta_out rho eta twotheta
15.4706 1.0000 -0.0000 0.0079 27.3557

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/>.
###
reffile('cubic')
latt([1,1,1,90,90,90])
pos mywl 1
c2th([0,0,1])
#60
pos euler [1 1 30 0 60 0] # delta + gam not moved
pos delta 60
pos gam 0
saveref('100',[1, 0, 0])
pos chi 91 <-->
saveref('001',[0, 0, 1]) ; showref()
ubm('100','001')
# array('d', [0.9996954135095477, -0.01745240643728364, -0.017449748351250637, 0.01744974835125045, 0.9998476951563913, -0.0003045864904520898, 0.017452406437283505, -1.1135499981271473e-16, 0.9998476951563912])
############################################################################################
mode euler 1
scan mywl .9 1.1 .02 hkl [1 0 0] euler psi
#0.900000 1.0000 0.0000 -0.0000 1.0000 1.0000 26.744 0.0000 53.487 0.0000 90.000
#0.920000 1.0000 0.0000 -0.0000 1.0000 1.0000 27.387 0.0000 54.774 0.0000 90.000
#0.940000 1.0000 -0.0000 -0.0000 1.0000 1.0000 28.034 0.0000 56.069 0.0000 90.000
#0.960000 1.0000 0.0000 -0.0000 1.0000 1.0000 28.685 0.0000 57.371 0.0000 90.000
#0.980000 1.0000 -0.0000 -0.0000 1.0000 1.0000 29.341 0.0000 58.681 0.0000 90.000
#1.000000 1.0000 -0.0000 -0.0000 1.0000 1.0000 30.000 0.0000 60.000 0.0000 90.000
#1.020000 1.0000 -0.0000 -0.0000 1.0000 1.0000 30.664 0.0000 61.328 0.0000 90.000
#1.040000 1.0000 0.0000 -0.0000 1.0000 1.0000 31.332 0.0000 62.665 0.0000 90.000
#1.060000 1.0000 -0.0000 -0.0000 1.0000 1.0000 32.005 0.0000 64.011 0.0000 90.000
#1.080000 1.0000 0.0000 -0.0000 1.0000 1.0000 32.684 0.0000 65.367 0.0000 90.000
#1.100000 1.0000 0.0000 -0.0000 1.0000 1.0000 33.367 0.0000 66.734 0.0000 90.000
pos mywl 2
pos hkl [0 1 0]
psi()
# 179.00
pos hkl [0 0 1]
psi()
# 90.000
pos hkl [1 0 0]
#Warning::Vector and Azimuthal reference //, azimuthal reference not used
#Move completed: hkl : h: 1.0000 k: 0.0000 l: -0.0000
psi()
90.000
pos mywl 2
mode euler 2
scan phi -19 21 2 hkl [0 0 1] euler
#Writing data to file:/home/zrb13439/gda/dev/config-i16/users_test/data/4.dat
# value h k l phi chi eta mu delta gamma
#-19.000 0.0000 0.0000 1.0000 -19.000 90.940 29.658 0.0000 60.000 0.0000
#-17.000 -0.0000 0.0000 1.0000 -17.000 90.951 29.691 0.0000 60.000 0.0000
#-15.000 -0.0000 0.0000 1.0000 -15.000 90.961 29.724 0.0000 60.000 0.0000
#-13.000 0.0000 -0.0000 1.0000 -13.000 90.970 29.758 0.0000 60.000 0.0000
#-11.000 -0.0000 -0.0000 1.0000 -11.000 90.978 29.792 0.0000 60.000 0.0000
#-9.0000 -0.0000 -0.0000 1.0000 -9.0000 90.985 29.826 0.0000 60.000 0.0000
#-7.0000 0.0000 0.0000 1.0000 -7.0000 90.990 29.861 0.0000 60.000 0.0000
#-5.0000 -0.0000 0.0000 1.0000 -5.0000 90.995 29.895 0.0000 60.000 0.0000
#-3.0000 -0.0000 -0.0000 1.0000 -3.0000 90.998 29.930 0.0000 60.000 0.0000
#-1.0000 0.0000 0.0000 1.0000 -1.0000 90.999 29.965 0.0000 60.000 0.0000
#1.0000 0.0000 0.0000 1.0000 1.0000 91.000 30.000 0.0000 60.000 0.0000
#3.0000 0.0000 -0.0000 1.0000 3.0000 90.999 30.035 0.0000 60.000 0.0000
#5.0000 -0.0000 -0.0000 1.0000 5.0000 90.998 30.070 0.0000 60.000 0.0000
#7.0000 -0.0000 0.0000 1.0000 7.0000 90.995 30.105 0.0000 60.000 0.0000
#9.0000 -0.0000 0.0000 1.0000 9.0000 90.990 30.139 0.0000 60.000 0.0000
#11.000 -0.0000 0.0000 1.0000 11.000 90.985 30.174 0.0000 60.000 0.0000
#13.000 -0.0000 -0.0000 1.0000 13.000 90.978 30.208 0.0000 60.000 0.0000
#15.000 0.0000 0.0000 1.0000 15.000 90.970 30.242 0.0000 60.000 0.0000
#17.000 0.0000 -0.0000 1.0000 17.000 90.961 30.276 0.0000 60.000 0.0000
#19.000 -0.0000 0.0000 1.0000 19.000 90.951 30.309 0.0000 60.000 0.0000
#21.000 0.0000 -0.0000 1.0000 21.000 90.940 30.342 0.0000 60.000 0.0000
scan phi -19 21 2 hkl [0 0 1] euler psi
#Writing data to file:/home/zrb13439/gda/dev/config-i16/users_test/data/16.dat
# value h k l phi chi eta mu delta gamma value
#-19.000 0.0000 0.0000 1.0000 -19.000 90.940 29.658 0.0000 60.000 0.0000 -70.003
#-17.000 -0.0000 0.0000 1.0000 -17.000 90.951 29.691 0.0000 60.000 0.0000 -72.003
#-15.000 -0.0000 0.0000 1.0000 -15.000 90.961 29.724 0.0000 60.000 0.0000 -74.002
#-13.000 0.0000 -0.0000 1.0000 -13.000 90.970 29.758 0.0000 60.000 0.0000 -76.002
#-11.000 -0.0000 -0.0000 1.0000 -11.000 90.978 29.792 0.0000 60.000 0.0000 -78.002
#-9.0000 -0.0000 -0.0000 1.0000 -9.0000 90.985 29.826 0.0000 60.000 0.0000 -80.001
#-7.0000 0.0000 0.0000 1.0000 -7.0000 90.990 29.861 0.0000 60.000 0.0000 -82.001
#-5.0000 -0.0000 0.0000 1.0000 -5.0000 90.995 29.895 0.0000 60.000 0.0000 -84.001
#-3.0000 -0.0000 -0.0000 1.0000 -3.0000 90.998 29.930 0.0000 60.000 0.0000 -86.001
#-1.0000 0.0000 0.0000 1.0000 -1.0000 90.999 29.965 0.0000 60.000 0.0000 -88.000
#1.0000 0.0000 0.0000 1.0000 1.0000 91.000 30.000 0.0000 60.000 0.0000 -90.000
#3.0000 0.0000 -0.0000 1.0000 3.0000 90.999 30.035 0.0000 60.000 0.0000 -92.000
#5.0000 -0.0000 -0.0000 1.0000 5.0000 90.998 30.070 0.0000 60.000 0.0000 -93.999
#7.0000 -0.0000 0.0000 1.0000 7.0000 90.995 30.105 0.0000 60.000 0.0000 -95.999
#9.0000 -0.0000 0.0000 1.0000 9.0000 90.990 30.139 0.0000 60.000 0.0000 -97.999
#11.000 -0.0000 0.0000 1.0000 11.000 90.985 30.174 0.0000 60.000 0.0000 -99.999
#13.000 -0.0000 -0.0000 1.0000 13.000 90.978 30.208 0.0000 60.000 0.0000 -102.00
#15.000 0.0000 0.0000 1.0000 15.000 90.970 30.242 0.0000 60.000 0.0000 -104.00
#17.000 0.0000 -0.0000 1.0000 17.000 90.961 30.276 0.0000 60.000 0.0000 -106.00
#19.000 -0.0000 0.0000 1.0000 19.000 90.951 30.309 0.0000 60.000 0.0000 -108.00
#21.000 0.0000 -0.0000 1.0000 21.000 90.940 30.342 0.0000 60.000 0.0000 -110.00
####################################################################################
mode euler 3
scan psic -19 21 2 hkl [0 0 1] euler psi
#Writing data to file:/home/zrb13439/gda/dev/config-i16/users_test/data/18.dat
#value h k l phi chi eta mu delta gamma value
# -19 0.0000 -0.0000 1.0000 -70.003 90.326 29.054 0.0000 60.000 0.0000 -19.000
#-17.000 0.0000 -0.0000 1.0000 -72.002 90.292 29.044 0.0000 60.000 0.0000 -17.000
#-15.000 0.0000 -0.0000 1.0000 -74.002 90.259 29.034 0.0000 60.000 0.0000 -15.000
#-13.000 -0.0000 -0.0000 1.0000 -76.002 90.225 29.026 0.0000 60.000 0.0000 -13.000
#-11.000 -0.0000 -0.0000 1.0000 -78.002 90.191 29.018 0.0000 60.000 0.0000 -11.000
#-9.0000 -0.0000 0.0000 1.0000 -80.001 90.156 29.012 0.0000 60.000 0.0000 -9.0000
#-7.0000 0.0000 0.0000 1.0000 -82.001 90.122 29.007 0.0000 60.000 0.0000 -7.0000
#-5.0000 0.0000 -0.0000 1.0000 -84.001 90.087 29.004 0.0000 60.000 0.0000 -5.0000
#-3.0000 -0.0000 0.0000 1.0000 -86.000 90.052 29.001 0.0000 60.000 0.0000 -3.0000
#-1.0000 -0.0000 0.0000 1.0000 -88.000 90.017 29.000 0.0000 60.000 0.0000 -1.0000
#1.0000 0.0000 -0.0000 1.0000 -90.000 89.983 29.000 0.0000 60.000 0.0000 1.0000
#3.0000 -0.0000 -0.0000 1.0000 268.00 89.948 29.001 0.0000 60.000 0.0000 3.0000
#5.0000 0.0000 -0.0000 1.0000 266.00 89.913 29.004 0.0000 60.000 0.0000 5.0000
#7.0000 0.0000 0.0000 1.0000 264.00 89.878 29.007 0.0000 60.000 0.0000 7.0000
#9.0000 -0.0000 -0.0000 1.0000 262.00 89.844 29.012 0.0000 60.000 0.0000 9.0000
#11.000 0.0000 0.0000 1.0000 260.00 89.809 29.018 0.0000 60.000 0.0000 11.000
#13.000 -0.0000 0.0000 1.0000 258.00 89.775 29.026 0.0000 60.000 0.0000 13.000
#15.000 -0.0000 0.0000 1.0000 256.00 89.741 29.034 0.0000 60.000 0.0000 15.000
#17.000 0.0000 -0.0000 1.0000 254.00 89.708 29.044 0.0000 60.000 0.0000 17.000
#19.000 0.0000 -0.0000 1.0000 252.00 89.674 29.054 0.0000 60.000 0.0000 19.000
#21.000 -0.0000 -0.0000 1.0000 250.00 89.642 29.066 0.0000 60.000 0.0000 21.000
#Scan complete.
##########################################################################################
# Move gamma and mu and read back hkl positions
mode euler 1
pos hkl [1 0 0]
#Warning::Vector and Azimuthal reference //, azimuthal reference not used
#Move completed: hkl : h: 1.0000 k: -0.0000 l: -0.0000
hkl()
#[0.9999999999999998, -3.8988661640799736e-17, -1.457167719820518e-16]
euler()
#[0.9999999999999994, 0.9999999999999912, 30.000000000000007, 0.0, 60.00000000000001, 0.0]
pos gam 10
euler()
#[0.9999999999999994, 0.9999999999999912, 30.000000000000007, 0.0, 60.00000000000001, 10.0]
hkl()
#[1.0037980617469482, -0.006578435915997894, 0.08682408883346501]
>>>pos mu 10
Move completed: mu : 10.000
>>>hkl()
[0.996201938253052, 0.006578435915997645, 0.08682408883346503]
# arbitrary position:
>>>euler()
[1.9, 2.9, 30.9, 0.9, 60.9, 2.9]
>>>hkl()
[1.0117418909164064, 0.02368622807445844, 0.06627361269425353]
>>>az.getAzimuthalReference().array
array([D, [array('d', [1.0]), array('d', [0.0]), array('d', [0.0])])
>>>az.calcN_L()
[0.8494223227931345, -0.5260858416846694, -0.04141744462963532]
>>>az.calcPsi()
[-109.75394072042344, -109.7539407204235]
>>>az.getAlpha()
31.741370382777166
>>>az.getBeta()
29.055463912559212
>>>az.getPhi_az()
-87.20849481167566
>>>az.calcPsi()
[-109.75394072042344, -109.7539407204235]
>>>az.getTau()
0.06945050942570621

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,247 @@
'''
Created on 28 Feb 2017
@author: zrb13439
'''
import unittest
from diffcalc.gdasupport.scannable.mock import MockMotor
from startup.beamlinespecific.i21 import I21SampleStage, calc_tp_lab,\
I21DiffractometerStage, I21TPLab, move_lab_origin_into_phi
import mock
from diffcalc.gdasupport.minigda.scannable import Scannable, ScannableBase
from nose.tools import eq_
from test.tools import assert_array_almost_equal as aneq_, aneq_
from math import sqrt
def mock_scannable(name='mock', pos=0):
scn = mock.Mock(ScannableBase)
scn.getName.return_value = name
scn.getPosition.return_value = pos
return scn
class TestI21SampleStageBase(unittest.TestCase):
def setUp(self):
self.sapol = mock_scannable('sapol', 1)
self.satilt = mock_scannable('satilt', 2)
self.saaz = mock_scannable('saaz',3 )
self.xyz_eta = mock_scannable('xyz_eta', [10, 11, 12])
self.sa = I21SampleStage('sa', self.sapol, self.satilt, self.saaz,
self.xyz_eta)
class TestI21SampleStageNoTp(TestI21SampleStageBase):
def testGetInputNames(self):
eq_(self.sa.getInputNames(), ['sapol', 'satilt', 'saaz'])
def testGetPosition(self):
eq_(self.sa.getPosition(), [1, 2, 3])
def testAsynchronousMoveTo(self):
self.sa.asynchronousMoveTo([4, 5, 6])
self.sapol.asynchronousMoveTo.assert_called_with(4)
self.satilt.asynchronousMoveTo.assert_called_with(5)
self.saaz.asynchronousMoveTo.assert_called_with(6)
def test__str__(self):
self.sa.tp_phi = [1, 2, 3]
self.sapol.getPosition.return_value = 0
self.satilt.getPosition.return_value = -90 # chi = 0
self.saaz.getPosition.return_value = 0
self.xyz_eta.getPosition.return_value = [10, 20, 30]
print self.sa.__str__()
desired = \
"""sa:
sapolar: 0.00000 (eta) tp_phi : 1.0000 2.0000 3.0000 (set)
satilt: -90.00000 (chi-90) tp_lab : 11.0000 22.0000 33.0000
saazimuth: 0.00000 (phi) xyz_eta: 10.0000 20.0000 30.0000"""
result_lines = self.sa.__str__().split('\n')[0:4]
print 'Result:'
print '\n'.join(result_lines)
print '---'
eq_('\n'.join(result_lines), desired)
def test_tp_scannable_get(self):
self.sa.tp_phi = [1, 2, 3]
eq_(self.sa.tp_phi_scannable.getPosition(), [1, 2, 3])
def test_tp_scannable_set(self):
self.sa.tp_phi_scannable.asynchronousMoveTo([4, 5, 6])
eq_(self.sa.tp_phi, [4, 5, 6])
class TestI21DiffractometerStage(unittest.TestCase):
def setUp(self):
self.delta = mock_scannable('delta', 1 )
self.sa = mock_scannable('sa', [2, 3, 4])
self.fourc = I21DiffractometerStage('four', self.delta, self.sa, 90)
def testGetPosition(self):
aneq_(self.fourc.getPosition(), [1, 2, 93, 4])
def testAsynchMoveToComplete(self):
self.fourc.asynchronousMoveTo([1, 2, 93, 4])
self.delta.asynchronousMoveTo.assert_called_with(1)
self.sa.asynchronousMoveTo.assert_called_with([2, 3, 4])
def testAsynchMoveToDeltaOnly(self):
self.fourc.asynchronousMoveTo([1, None, None, None])
self.delta.asynchronousMoveTo.assert_called_with(1)
self.sa.asynchronousMoveTo.assert_not_called()
def testAsynchMoveToEtaOnly(self):
self.fourc.asynchronousMoveTo([None, 2, None, None])
self.delta.asynchronousMoveTo.assert_not_called()
self.sa.asynchronousMoveTo.assert_called_with([2, None, None])
def testAsynchMoveToChiOnly(self):
self.fourc.asynchronousMoveTo([None, None, 93, None])
self.delta.asynchronousMoveTo.assert_not_called()
self.sa.asynchronousMoveTo.assert_called_with([None, 3, None])
class TestI21TPLab(unittest.TestCase):
def setUp(self):
self.delta = mock_scannable('delta', 1 )
self.sa = mock.Mock()
self.sa.tp_phi = [1, 2, 3]
self.sa.xyz_eta_scn.getPosition.return_value = [10, 20, 30]
self.sa.getEulerPosition.return_value = [0, 0, 0]
self.tp_lab = I21TPLab('tp_lab', self.sa)
def testGetPosition(self):
aneq_(self.tp_lab.getPosition(), [11, 22, 33])
def testAsynchMoveToComplete(self):
self.tp_lab.asynchronousMoveTo([11, 22, 33])
self.sa.xyz_eta_scn.asynchronousMoveTo.assert_called_with([10, 20, 30])
class TestCalcTpLab_No_xyz_eta(unittest.TestCase):
def test_calc_tp_lab__tp_phi_0(self):
eq_(calc_tp_lab([0, 0, 0], 0, 0, 0), [0, 0, 0])
eq_(calc_tp_lab([0, 0, 0], 1, 2, 3), [0, 0, 0])
def test_calc_tp_lab__lab_eq_phi_frame(self):
eq_(calc_tp_lab([1, 2, 3], 0, 0, 0), [1, 2, 3])
def test_calc_tp_lab__lab_z_parallel_to_phi_and_eta(self):
eq_(calc_tp_lab([0, 0, 1], 1, 0, 0), [0, 0, 1])
eq_(calc_tp_lab([0, 0, 1], 0, 0, 1), [0, 0, 1])
eq_(calc_tp_lab([0, 0, 1], 1, 0, 1), [0, 0, 1])
def test_calc_tp_lab_eta0_chi90(self):
aneq_(calc_tp_lab([0, 0, 1], 0, 90, 0), [1, 0, 0])
aneq_(calc_tp_lab([0, 0, 1], 0, 90, 1), [1, 0, 0])
eq_(calc_tp_lab([0, 0, 1], 1, 0, 1), [0, 0, 1])
def test_calc_tp_lab_eta0_eta90(self):
aneq_(calc_tp_lab([0, 1, 0], 90, 0, 0), [1, 0, 0])
aneq_(calc_tp_lab([0, 1, 0], 90, 1, 0), [1, 0, 0])
def test_calc_tp_lab_tp_phi_101(self):
aneq_(calc_tp_lab([1, 0, 1], 0, 45, 0), [sqrt(2), 0, 0])
def test_calc_tp_lab_tp_phi_110(self):
aneq_(calc_tp_lab([1, 1, 0], 45, 0, 0), [sqrt(2), 0, 0])
aneq_(calc_tp_lab([1, 1, 0], 0, 0, 45), [sqrt(2), 0, 0])
aneq_(calc_tp_lab([1, 1, 0], 46, 0, -1), [sqrt(2), 0, 0])
class TestCalcTpLabWithXyzEta(unittest.TestCase):
def test_calc_tp_lab__tp_phi_0(self):
eq_(calc_tp_lab([0, 0, 0], 0, 0, 0, [0, 0, 0]), [0, 0, 0])
eq_(calc_tp_lab([0, 0, 0], 0, 0, 0, [4, 5, 6]), [4, 5, 6])
eq_(calc_tp_lab([10, 20, 30], 0, 0, 0, [1, 2, 3]), [11, 22, 33])
def test_calc_tp_lab__lab_eq_phi_frame(self):
eq_(calc_tp_lab([0, 0, 1], 0, 0, 99, [1, 2, 3]), [1, 2, 4])
eq_(calc_tp_lab([0, 0, 1], 0, 0, 99, [0, 0, 0]), [0, 0, 1])
eq_(calc_tp_lab([0, 0, 1], 1, 0, 99, [0, 0, 0]), [0, 0, 1])
def test_calc_tp_lab_eta0_chi90(self):
aneq_(calc_tp_lab([0, 0, 1], 0, 90, 0, [0, 0, 0]), [1, 0, 0])
aneq_(calc_tp_lab([0, 0, 1], 0, 90, 1, [0, 0, 0]), [1, 0, 0])
aneq_(calc_tp_lab([0, 0, 1], 1, 00, 1, [0, 0, 0]), [0, 0, 1])
#
# def test_calc_tp_lab_eta0_eta90(self):
# aneq_(calc_tp_lab([0, 1, 0], 90, 0, 0), [1, 0, 0])
# aneq_(calc_tp_lab([0, 1, 0], 90, 1, 0), [1, 0, 0])
#
# def test_calc_tp_lab_tp_phi_101(self):
# aneq_(calc_tp_lab([1, 0, 1], 0, 45, 0), [sqrt(2), 0, 0])
#
# def test_calc_tp_lab_tp_phi_110(self):
# aneq_(calc_tp_lab([1, 1, 0], 45, 0, 0), [sqrt(2), 0, 0])
# aneq_(calc_tp_lab([1, 1, 0], 0, 0, 45), [sqrt(2), 0, 0])
# aneq_(calc_tp_lab([1, 1, 0], 46, 0, -1), [sqrt(2), 0, 0])
#
class TestMoveLabOriginIntoPhi(unittest.TestCase):
def test_xyz_eta_0(self):
aneq_(move_lab_origin_into_phi(0, 0, [0, 0, 0]), [0, 0, 0])
aneq_(move_lab_origin_into_phi(1, 2, [0, 0, 0]), [0, 0, 0])
def test_chi_phi_0(self):
aneq_(move_lab_origin_into_phi(0, 0, [1, 2, 3]), [-1, -2, -3])
aneq_(move_lab_origin_into_phi(0, 0, [-3, -2, -1]), [3, 2, 1])
def test_stable_about_phi(self):
aneq_(move_lab_origin_into_phi(0, 99, [0, 0, 3]), [0, 0, -3])
def test_stable_about_chi(self):
aneq_(move_lab_origin_into_phi(99, 0, [0, 3, 0]), [0, -3, 0])
def test_rotate_about_phi(self):
aneq_(move_lab_origin_into_phi(0, 45, [0, 1, 4]),
[sqrt(.5), -sqrt(.5), -4])
class TestI21SampleStageWithTP(TestI21SampleStageBase):
# Npte all are independent of eta
# Note tp_phi is the TARGET tool point to end up at the diffractometer centre
def _move(self, tp_phi, pol, tilt, az):
self.sa.tp_phi = tp_phi
self.sa.asynchronousMoveTo([pol, tilt, az])
def _check(self, desired_xyz):
called_with_xyz = self.xyz_eta.asynchronousMoveTo.call_args[0][0]
aneq_(called_with_xyz, desired_xyz)
def testAsynchronousMoveTo_tp_phi_0(self):
self._move([0, 0, 0], 99, 2 - 90, 3); self._check([0, 0, 0])
def test_calc_tp_lab__tp_phi_0(self):
self._move([0, 0, 0], 99, 0 - 90, 0); self._check([0, 0, 0])
self._move([0, 0, 0], 99, 2 - 90, 3); self._check([0, 0, 0])
def test_calc_tp_lab__lab_eq_phi_frame(self):
self._move([1, 2, 3], 99, 0 - 90, 0); self._check([-1, -2, -3])
def test_calc_tp_lab__lab_z_parallel_to_phi_and_eta(self):
self._move([0, 0, 1], 99, 0 - 90, 0); self._check([0, 0, -1])
self._move([0, 0, 1], 99, 0 - 90, 1); self._check([0, 0, -1])
self._move([0, 0, 1], 99, 0 - 90, 1); self._check([0, 0, -1])
def test_calc_tp_lab_eta0_chi90(self):
self._move([0, 0, 1], 99, 90 - 90, 0); self._check([-1, 0, 0])
self._move([0, 0, 1], 99, 90 - 90, 1); self._check([-1, 0, 0])
self._move([0, 0, 1], 99, 0 - 90, 1); self._check([0, 0, -1])
def test_calc_tp_lab_tp_phi_101(self):
self._move([1, 0, 1], 99, 45 - 90, 0); self._check([-sqrt(2), 0, 0])
#
def test_calc_tp_lab_tp_phi_110(self):
self._move([1, 1, 0], 99, 0 - 90, 45); self._check([-sqrt(2), 0, 0])

View File

@@ -0,0 +1,245 @@
###
# 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 nose.tools import eq_, ok_, assert_almost_equal # @UnresolvedImport
from nose.plugins.skip import SkipTest
try:
import numpy
__NUMPY_AVAILABLE__ = True
except ImportError:
__NUMPY_AVAILABLE__ = False
try:
import numjy
import Jama
__NUMJY_AVAILABLE__ = True
except ImportError:
__NUMJY_AVAILABLE__ = False
from test.tools import assert_2darray_almost_equal, meq_
class _TestNumpyMatrix():
def m(self, args):
raise NotImplementedError()
def test__init__(self):
m = self.m([[1, 2], [3, 4]])
meq_(self.m('1 2;3 4'), m)
meq_(self.m('1 2; 3 4'), m)
meq_(self.m('1, 2; 3, 4'), m)
meq_(self.m('1, 2; 3 4'), m)
meq_(self.m('1 , 2; 3 4 '), m)
def test__init__with_row_vector(self):
meq_(self.m([1, 2]), self.m([[1, 2]]))
def test_shape(self):
shape = self.m('1 2 3; 4 5 6').shape
eq_(len(shape), 2)
eq_(shape[0], 2)
eq_(shape[1], 3)
def test_len(self):
eq_(len(self.m('1 2 3; 4 5 6')), 2)
def test_2dslice(self):
m = self.m('0 1; 10 11')
eq_(m[0, 0], 00)
eq_(m[0, 1], 01)
eq_(m[1, 0], 10)
eq_(m[1, 1], 11)
def test_set_2dslice(self):
m = self.m('1 2; 3 4')
m[1, 1] = 40
meq_(m, self.m('1 2; 3 40'))
def test_tolist(self):
l = [[1, 2], [3, 4]]
assert_2darray_almost_equal(self.m(l).tolist(), l)
def test__str__(self):
eq_(str(self.m('1.234 2.; 3.1 4.')),
'[[ 1.234 2. ]\n [ 3.1 4. ]]')
def test__repr__(self):
eq_(repr(self.m('1. 2.; 3. 4.')),
'matrix([[ 1., 2.],\n [ 3., 4.]])')
def test_all(self):
ok_(self.m([[True, True], [True, True]]).all())
ok_(not self.m([[True, False], [True, True]]).all())
def test_eq(self):
meq_(self.m('1 2; 3 4'),
self.m('1 2; 3 4.'))
def test_eq_false(self):
ok_(not (self.m('1 2; 3 4') == self.m('1 2; 3 5')).all())
def test__eq__(self):
meq_(self.m('1 2; 3 4') == self.m('1 2; 3 4.1'),
self.m([[True, True], [True, False]]))
def test__mul__matrix(self):
meq_(self.m('1 2; 3 4') * self.m('5 6; 7 8'),
self.m('19 22; 43 50'))
def test__mul__vector(self):
meq_(self.m('1 2; 3 4') * self.m('5; 7'),
self.m('19; 43'))
def test__mul__scaler(self):
meq_(self.m('1, 2; 3, 4') * 10,
self.m('10 20; 30 40'))
def test__sum__(self):
meq_(self.m('1 2; 3 4') + self.m('5 6; 7 8'),
self.m(' 6 8; 10 12'))
def test__sum__scaler(self):
meq_(self.m('1 2; 3 4') + 10,
self.m('11 12; 13 14'))
def test__sub__(self):
meq_(self.m('1 2; 3 4') - self.m('5 6; 7 8'),
self.m('-4 -4; -4 -4'))
def test__sub__scaler(self):
meq_(self.m('11 12; 13 14') - 10,
self.m('1 2; 3 4'))
def test__div__(self):
r = self.m('1 2; 3 4') / self.m('5. 6.; 7. 8.')
assert_almost_equal(r[0, 0], .2)
assert_almost_equal(r[0, 1], .33333333)
assert_almost_equal(r[1, 0], 0.42857143)
assert_almost_equal(r[1, 1], .5)
def test__div__scaler(self):
meq_(self.m('10 20; 30 40') / 10.,
self.m('1 2; 3 4'))
def test_I(self):
inverse = self.m('1 2; 3 4').I
assert_almost_equal(inverse[0, 0], -2)
assert_almost_equal(inverse[0, 1], 1)
assert_almost_equal(inverse[1, 0], 1.5)
assert_almost_equal(inverse[1, 1], -.5)
def test_T(self):
meq_(self.m('1 2; 3 4').T,
self.m('1 3; 2 4'))
def test_sum(self):
eq_(self.m('1 2; 3 4').sum(), 10)
class _TestLinalg():
def matrix(self, args):
raise NotImplementedError()
def norm(self, args):
raise NotImplementedError()
def test_norm_frobenius(self):
m1 = self.matrix('1 1 1; 1 1 1; 1 1 1')
assert_almost_equal(self.norm(m1), 3, places=13)
m2 = self.matrix('1 2 3; 4 5 6; 7 8 9')
assert_almost_equal(self.norm(m2), 16.881943016134134, places=13)
class _TestNumpy():
def matrix(self, args):
raise NotImplementedError()
def hstack(self, args):
raise NotImplementedError()
def test_hstack(self):
v1 = self.matrix('1;2;3')
v2 = self.matrix('4;5;6')
v3 = self.matrix('7;8;9')
meq_(self.hstack([v1, v2, v3]), self.matrix('1,4,7;2,5,8;3,6,9'))
if __NUMPY_AVAILABLE__:
class TestNumpyMatrix(_TestNumpyMatrix):
def m(self, args):
return numpy.matrix(args)
class TestLinalgNumpy(_TestLinalg):
def matrix(self, args):
return numpy.matrix(args)
def norm(self, args):
return numpy.linalg.norm(args)
class TestNumpy(_TestNumpy):
def matrix(self, args):
return numpy.matrix(args)
def hstack(self, args):
return numpy.hstack(args)
if __NUMJY_AVAILABLE__:
class TestNumjyMatrix(_TestNumpyMatrix):
def m(self, args):
return numjy.matrix(args)
def test__str__(self):
eq_(str(self.m('1.234 2.0; 3.1 4.0')),
'[[1.234 2.0]\n [3.1 4.0]]')
def test__repr__(self):
print repr(self.m('1. 2.; 3. 4.'))
eq_(repr(self.m('1. 2.; 3. 4.')),
'matrix([[1.0 2.0]\n [3.0 4.0]])')
def test__div__(self):
raise SkipTest()
class TestLinalgNumjy(_TestLinalg):
def matrix(self, args):
return numjy.matrix(args)
def norm(self, args):
return numjy.linalg.norm(args)
def hstack(self, args):
return numjy.hstack(args)
class TestNumjy(_TestNumpy):
def matrix(self, args):
return numjy.matrix(args)
def hstack(self, args):
return numjy.hstack(args)

View File

@@ -0,0 +1,177 @@
###
# 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 test.tools import assert_almost_equal, assert_array_almost_equal, \
assert_2darray_almost_equal, assert_matrix_almost_equal, \
assert_dict_almost_equal
from nose.tools import eq_ # @UnresolvedImport
try:
from numpy import matrix
except ImportError:
from numjy import matrix
class test_assert_almost_equal():
def test_fails(self):
try:
assert_almost_equal(1, 1.0000001)
assert False
except AssertionError:
# eq_(e.args[0], '1 != 1.0000001000000001 within 7 places')
pass
def test__passes(self):
assert_almost_equal(1, 1.00000001)
assert_almost_equal(1, 1.0000001, 6)
class test_assert_array_almost_equal():
def test__passes(self):
assert_array_almost_equal((1, 2, 3), (1.00000001, 2, 3.))
assert_array_almost_equal((1, 2, 3), (1.0000001, 2, 3.), 6)
assert_array_almost_equal((1, 2, 3), [1, 2, 3])
assert_array_almost_equal((), ())
assert_array_almost_equal([], ())
def test_wrong_length(self):
try:
assert_array_almost_equal((1, 2, 3), (1, 2))
assert False
except AssertionError, e:
eq_(e.args[0], '(1, 2, 3) != (1, 2) as lengths differ')
def test_wrong_value(self):
try:
assert_array_almost_equal((3, 2, 1), (3, 2, 1.0000001))
assert False
except AssertionError:
pass
class test_assert_2darray_almost_equal():
def test__passes(self):
assert_2darray_almost_equal(((1, 2), (3, 4)),
((1.00000001, 2), (3, 4)))
assert_2darray_almost_equal(((1, 2), (3, 4)),
((1.0000001, 2), (3, 4)), 6)
assert_2darray_almost_equal(((1, 2), (3, 4)),
[(1, 2), [3, 4]])
assert_2darray_almost_equal(((), ()), ((), ()))
assert_2darray_almost_equal([(), []], ([], ()))
def test_wrong_length(self):
try:
assert_2darray_almost_equal(((1, 2), (3, 4)), ((1, 2), (3, 4, 5)))
assert False
except AssertionError, e:
eq_(e.args[0],
'((1, 2), (3, 4)) != ((1, 2), (3, 4, 5)) as sizes differ')
def test_wrong_value(self):
try:
assert_2darray_almost_equal(((1, 2), (3, 4)),
((1.0000001, 2), (3, 4)))
assert False
except AssertionError:
pass
class test_assert_matrix_almost_equal():
def test__passes(self):
assert_matrix_almost_equal(matrix([[1, 2], [3, 4]]),
matrix([[1.00000001, 2], [3, 4]]))
assert_matrix_almost_equal(matrix([[1, 2], [3, 4]]),
matrix([[1.0000001, 2], [3, 4]]), 6)
def test_wrong_length(self):
try:
assert_matrix_almost_equal(matrix([[1, 2], [3, 4]]),
matrix([[1, 2, 3], [4, 5, 6]]))
assert False
except AssertionError:
pass
def test_wrong_value(self):
try:
assert_matrix_almost_equal(matrix([[1, 2], [3, 4]]),
matrix([[1.0000001, 2], [3, 4]]))
assert False
except AssertionError:
pass
class test_assert_dict_almost_equal():
def test__passes(self):
assert_dict_almost_equal({}, {})
assert_dict_almost_equal({'a': 1}, {'a': 1})
assert_dict_almost_equal({'a': 1.}, {'a': 1.})
assert_dict_almost_equal({'a': 1.00000001}, {'a': 1.00000001})
def test_wrong_keys(self):
try:
assert_dict_almost_equal({'a': 1}, {'a': 1, 'b': 2})
assert False
except AssertionError:
pass
def test_wrong_object(self):
try:
assert_dict_almost_equal({'a': 1}, {'a': '1'})
assert False
except AssertionError, e:
eq_(e.args[0], "For key 'a', 1 != '1'")
def test_wrong_int(self):
try:
assert_dict_almost_equal({'a': 1}, {'a': 2})
assert False
except AssertionError, e:
eq_(e.args[0], "For key 'a', 1 != 2")
def test_wrong_float1(self):
try:
assert_dict_almost_equal({'a': 1.}, {'a': 2.})
assert False
except AssertionError, e:
eq_(e.args[0], "For key 'a', 1.0 != 2.0 within 7 places")
def test_wrong_float2(self):
try:
assert_dict_almost_equal({'a': 1}, {'a': 2.})
assert False
except AssertionError, e:
eq_(e.args[0], "For key 'a', 1 != 2.0 within 7 places")
def test_wrong_float3(self):
try:
assert_dict_almost_equal({'a': 1.}, {'a': 2})
assert False
except AssertionError, e:
eq_(e.args[0], "For key 'a', 1.0 != 2 within 7 places")
def test_okay_differing_types1(self):
assert_dict_almost_equal({'a': 1.}, {'a': 1})
def test_okay_differing_types2(self):
assert_dict_almost_equal({'a': 1}, {'a': 1.})

View File

@@ -0,0 +1,164 @@
###
# 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 nose.tools import assert_almost_equal # @UnresolvedImport
from nose.tools import ok_
from functools import wraps
try:
from numpy import matrix
except ImportError:
from numjy import matrix
def format_note(note):
return " # %s" % note if note else ""
def assert_array_almost_equal(first, second, places=7, msg=None, note=None):
err = "%r != %r as lengths differ%s" % (first, second, format_note(note))
assert len(first) == len(second), err
for f, s in zip(first, second):
default_msg = (
"\n%r != \n%r within %i places%s" % (format_array(first, places),
format_array(second, places), places, format_note(note)))
assert_almost_equal(f, s, places, msg or default_msg)
def format_array(a, places):
fmt = '% .' + str(places) + 'f'
return '(' + ', '.join((fmt % el) for el in a) + ')'
aneq_ = arrayeq_ = assert_array_almost_equal
def assert_2darray_almost_equal(first, second, places=7, msg=None, note=None):
err = "%r != %r as sizes differ%s" % (first, second, format_note(note))
assert len(first) == len(second), err
for f2, s2 in zip(first, second):
err = "%r != %r as sizes differ%s" % (first, second, format_note(note))
assert len(f2) == len(s2), err
for f, s in zip(f2, s2):
message = "within %i places%s" % (places, format_note(note))
message += '\n' + format_2darray(first, places) + "!=\n"
message += format_2darray(second, places)
assert_almost_equal(f, s, places, msg or message)
def format_2darray(array, places):
fmt = '% .' + str(places) + 'f'
s = ""
for row in array:
line = [fmt % el for el in row]
s += '[' + ', '.join(line) + ']\n'
return s
def _array(m):
if isinstance(m, matrix): # numpy
return m.tolist()
else: # assume Jama
return m.array
def assert_matrix_almost_equal(first, second, places=7, msg=None, note=None):
assert_2darray_almost_equal(_array(first), _array(second), places, msg)
def assert_dict_almost_equal(first, second, places=7, msg=None, note=None):
def_msg = "%r != %r as keys differ%s" % (first, second, format_note(note))
assert set(first.keys()) == set(second.keys()), msg or def_msg
keys = first.keys()
keys.sort()
for key in keys:
f = first[key]
s = second[key]
if isinstance(f, float) or isinstance(s, float):
def_msg = ("For key %s, %r != %r within %i places%s" %
(repr(key), f, s, places, format_note(note)))
assert_almost_equal(f, s, places, msg or def_msg)
else:
if f != s:
raise AssertionError(
"For key %s, %r != %r%s" %
(repr(key), f, s, format_note(note)))
dneq_ = assert_dict_almost_equal
def assert_second_dict_almost_in_first(value, expected, places=7, msg=None):
value = value.copy()
for key in value.keys():
if key not in expected.keys():
del value[key]
assert_dict_almost_equal(value, expected, places=7, msg=None)
def assert_iterable_almost_equal(first, second, places=7, msg=None, note=None):
def_msg = ("%r != %r as lengths differ%s" %
(first, second, format_note(note)))
assert len(first) == len(second), msg or def_msg
for f, s in zip(first, second):
if isinstance(f, float) or isinstance(s, float):
assert_almost_equal(f, s, places, msg)
else:
if f != s:
raise AssertionError("%r != %r%s" % (f, s, format_note(note)))
mneq_ = matrixeq_ = assert_matrix_almost_equal
def meq_(a, b):
ok_((a == b).all(), '\n%s\n !=\n%s' % (a, b))
def wrap_command_to_print_calls(f, user_syntax=True):
def print_with_user_syntax(f, args):
arg_strings = []
for arg in args:
if isinstance(arg, list):
element_as_strings = (str(el) for el in arg)
arg_strings.append('[%s]' % ' '.join(element_as_strings))
else:
try:
arg_strings.append(arg.name) # Scannable
except AttributeError:
arg_strings.append(repr(arg)) # e.g. number or string
print '\n>>>', f.__name__, ' '.join(arg_strings)
def print_with_python_syntax(f, args):
print '\n>>> %s(%s)' % (f.__name__, ', '.join(args))
def print_and_call_command(f, args):
if user_syntax:
print_with_user_syntax(f, args)
else:
print_with_python_syntax(f, args)
result = f(*args)
if result is not None:
print result
return result
@wraps(f)
def wrapper(*args, **kwds):
return print_and_call_command(f, args)
return wrapper