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.sessions()[1]
self.calc = self.sess.calculations[0]
class TestDiffractionCalculatorHklWithDataSess3Calc0(
BaseTestDiffractionCalculatorWithData):
def setSessionAndCalculation(self):
self.sess = scenarios.sessions()[2]
self.calc = self.sess.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, 'bin': 0, 'bout': 0}
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, 'bin': 0, 'bout': 0}
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.minigda.scannable 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,256 @@
###
# 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
from diffcalc import settings
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):
settings.geometry = createMockDiffractometerGeometry()
settings.hardware = createMockHardwareMonitor()
self.ac = VliegHklCalculator(None)
self.ac.raiseExceptionsIfAnglesDoNotMapBackToHkl = True
self.setSessionAndCalculation()
def testAnglesToHkl(self):
mockUbcalc = createMockUbcalc(
matrix(self.sess.umatrix) * matrix(self.sess.bmatrix))
settings.geometry = createMockDiffractometerGeometry()
settings.hardware = createMockHardwareMonitor()
self.ac = VliegHklCalculator(mockUbcalc)
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()
settings.geometry = createMockDiffractometerGeometry()
settings.hardware = hw
ac = VliegHklCalculator(mockUbcalc)
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.sessions()[0]
self.calc = None
class TestVliegHklCalculatorSess2Calc0(BaseTestHklCalculator):
def setSessionAndCalculation(self):
self.sess = scenarios.sessions()[1]
self.calc = self.sess.calculations[0]
class TestVliegHklCalculatorSess3Calc0(
BaseTestHklCalculator):
def setSessionAndCalculation(self):
self.sess = scenarios.sessions()[2]
self.calc = self.sess.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,81 @@
###
# 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):
from diffcalc import settings
settings.geometry = SixCircleGammaOnArmGeometry()
dummy = 'alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'
settings.hardware = DummyHardwareAdapter(dummy)
self.mock_ubcalc = Mock(spec=UBCalculation)
self.hklcalc = VliegHklCalculator(self.mock_ubcalc, True)
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,328 @@
###
# 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
from diffcalc import settings
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()
settings.geometry = self.mock_geometry
settings.hardware = self.mock_hardware
self.calc = WillmottHorizontalCalculator(self.mock_ubcalc, 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')
settings.geometry = WillmottHorizontalGeometry()
settings.hardware = hardware
self.ubcalc = UBCalculation(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')
settings.geometry = WillmottHorizontalGeometry()
settings.hardware = hardware
self.ubcalc = UBCalculation(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})

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,482 @@
###
# 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
from diffcalc import settings
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
from test.tools import assert_array_almost_equal, \
assert_matrix_almost_equal
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
settings.hardware = createMockHardwareMonitor()
settings.geometry = createMockDiffractometerGeometry()
self.calc = YouHklCalculator(createMockUbcalc(None), 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, unit='DEG')
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, 'DEG')
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=.001, nu=0, eta=0, chi=0, phi=0)
def test_psi3(self):
self.check_angle(
'psi', 80, mu=-10, delta=.001, 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, 0, 0, 0, 90, 0, 'DEG')
pos.changeToRadians()
assert isnan(self.calc._anglesToVirtualAngles(pos, None)['psi'])
def test_psi6(self):
self.check_angle(
'psi', 90, mu=0, delta=0.001, nu=0, eta=90, chi=0, phi=0)
def test_psi7(self):
self.check_angle(
'psi', 92, mu=0, delta=0.001, nu=0, eta=90, chi=2, phi=0)
def test_psi8(self):
self.check_angle(
'psi', 88, mu=0, delta=0.001, nu=0, eta=90, chi=-2, phi=0)
class Test_calc_theta():
def setup_method(self):
settings.hardware = createMockHardwareMonitor()
settings.geometry = createMockDiffractometerGeometry()
self.calc = YouHklCalculator(createMockUbcalc(I * 2 * pi),
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):
settings.hardware = createMockHardwareMonitor()
settings.geometry = createMockDiffractometerGeometry()
self.calc = YouHklCalculator(createMockUbcalc(None),
Mock())
def check(self, name, value, theta, tau, psi_e, alpha_e, beta_e, places=7):
# all in deg
alpha, beta = self.calc._calc_remaining_reference_angles(
name, value * TORAD, theta * TORAD, tau * TORAD)
if alpha_e is not None:
assert_almost_equal(alpha * TODEG, alpha_e, places)
if beta_e is not None:
assert_almost_equal(beta * TODEG, beta_e, places)
psi_vals = list(self.calc._calc_psi(alpha, theta * TORAD, tau * TORAD))
if psi_e is not None:
assert_array_almost_equal(sorted([v * TODEG for v in psi_vals]), sorted(psi_e))
for psi in psi_vals:
print 'psi', psi * TODEG, ' alpha:', alpha * TODEG,\
' beta:', beta * TODEG
def test_psi_given0(self):
self.check('psi', 90, theta=10, tau=90, psi_e=[-90, 90],
alpha_e=0, beta_e=0)
def test_psi_given1(self):
self.check('psi', 92, theta=0.001, tau=90, psi_e=[-92, 92],
alpha_e=2, beta_e=-2)
def test_psi_given3(self):
self.check('psi', 88, theta=0.001, tau=90, psi_e=[-88, 88],
alpha_e=-2, beta_e=2)
def test_psi_given4(self):
self.check('psi', 0, theta=0.001, tau=90, psi_e=[0,],
alpha_e=-90, beta_e=90, places=2)
def test_psi_given4a(self):
self.check('psi', 180, theta=0.001, tau=90, psi_e=[-180, 180],
alpha_e=90, beta_e=-90, places=2)
def test_psi_given5(self):
self.check('psi', 180, theta=0.001, tau=80,
psi_e=[-180, 180], alpha_e=80, beta_e=-80, places=2)
def test_a_eq_b0(self):
self.check('a_eq_b', 9999, theta=0.001, tau=90,
psi_e=[-90, 90], alpha_e=0, beta_e=0)
def test_alpha_given(self):
self.check('alpha', 2, theta=0.001, tau=90,
psi_e=[-92, 92], alpha_e=2, beta_e=-2)
def test_beta_given(self):
self.check('beta', 2, theta=0.001, tau=90,
psi_e=[-88, 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)
class Test_calc_detector_angles_given_one():
def setup_method(self):
settings.hardware = createMockHardwareMonitor()
settings.geometry = createMockDiffractometerGeometry()
self.calc = YouHklCalculator(createMockUbcalc(None),
Mock())
def check(self, name, value, theta, delta_e, nu_e, qaz_e):
# all in deg
delta, nu, qaz = zip(*self.calc._calc_remaining_detector_angles(
name, value * TORAD, theta * TORAD))
for delta_, nu_, qaz_ in zip(delta, nu, qaz):
print 'delta:', delta_ * TODEG, ' nu:', nu_ * TODEG, ' qaz:', qaz_ * TODEG
assert_array_almost_equal([v * TODEG for v in delta], delta_e)
assert_array_almost_equal([v * TODEG for v in nu], nu_e)
if qaz_e is not None:
assert_array_almost_equal([v * TODEG for v in qaz], qaz_e)
def test_nu_given0(self):
self.check(NUNAME, 0, theta=3, delta_e=[6, -6], nu_e=[0, 0], qaz_e=[90, -90])
def test_nu_given1(self):
self.check(NUNAME, 10, theta=7.0530221302831952,
delta_e=[10, -10], nu_e=[10, 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, 0], nu_e=[6, -6], qaz_e=[0, 180])
def test_delta_given1(self):
self.check('delta', 10, theta=7.0530221302831952,
delta_e=[10, 10], nu_e=[10, -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, 174], nu_e=[0, -180], qaz_e=[90, 90])
def test_qaz_given2(self):
self.check('qaz', 0, theta=3, delta_e=[0, 180], nu_e=[6, -174], qaz_e=[0, 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):
settings.hardware = createMockHardwareMonitor()
settings.geometry = createMockDiffractometerGeometry()
self.calc = YouHklCalculator(createMockUbcalc(None),
Mock())
def check(self, name, value, Q_lab, n_lab, Q_phi, n_phi,
phi_e, chi_e, eta_e, mu_e):
mu, eta, chi, phi = zip(*self.calc._calc_remaining_sample_angles(
name, value * TORAD, Q_lab, n_lab, Q_phi, n_phi))
for mu_, eta_, chi_, phi_ in zip(mu, eta, chi, phi):
print 'phi', phi_ * TODEG, ' chi:', chi_ * TODEG, ' eta:', eta_ * TODEG,\
' mu:', mu_ * TODEG
if phi_e is not None:
assert_array_almost_equal([v * TODEG for v in phi], phi_e)
if chi_e is not None:
assert_array_almost_equal([v * TODEG for v in chi], chi_e)
if eta_e is not None:
assert_array_almost_equal([v * TODEG for v in eta], eta_e)
if mu_e is not None:
assert_array_almost_equal([v * TODEG for v in mu], mu_e)
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):
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):
self.check('mu', 10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=[90, -90], chi_e=[10, -10], eta_e=[-90, 90], mu_e=[10, 10])
def test_constrain_mu_n10(self):
self.check('mu', -10, Q_lab=x, n_lab=z, Q_phi=x, n_phi=z,
phi_e=[-90, 90], chi_e=[10, -10], eta_e=[90, -90], mu_e=[-10, -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, -170], chi_e=[0, 180], eta_e=[10, 10], mu_e=[0, -180])
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, 170], chi_e=[0, 180], eta_e=[-10, -10], mu_e=[0, 180])
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, -140], chi_e=[0, 180], eta_e=[20, 20], mu_e=[0, -180])
@raises(DiffcalcException)
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, 90], chi_e=[10, 10], eta_e=[90, -90], mu_e=[-10, 10])
@raises(DiffcalcException)
def test_constrain_chi_90(self):
self.check('chi', 90, Q_lab=z * (-1), n_lab=x, Q_phi=x, n_phi=z,
phi_e=[0, 0], chi_e=[90, 90], eta_e=[0, 0], mu_e=[-180, 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, 0], chi_e=[0, -180], eta_e=[0, 180], mu_e=[0, -180])
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, 10], chi_e=[0, -180], eta_e=[-10, 190], mu_e=[0, -180])
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, -10], chi_e=[0, -180], eta_e=[10, 170], mu_e=[0, -180])
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, 20], chi_e=[0, -180], eta_e=[0, 180], mu_e=[0, -180])

View File

@@ -0,0 +1,561 @@
###
# 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
from diffcalc import settings
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, unit='DEG')
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, unit='DEG')
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, unit='DEG')
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,
unit='DEG')
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')
settings.hardware = hardware
settings.geometry = SixCircle()
self.ubcalc = UBCalculation(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):
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):
self.places = 3
willpos = WillPos(delta=11.241801854649, gamma=-3.038407637123,
omegah=2, phi=-86.56344250267)
self._check((0, 7, 22),
self._convert_willmott_pos(willpos),
{'alpha': 2})
def testHkl_2_m5_12_calculated_from_DDIF(self):
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=-33.80254)
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 + 88.02751)
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,
unit='DEG')
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
settings.hardware = hardware
settings.geometry = SixCircle()
self.ubcalc = UBCalculation(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)
def willmott_to_you_fixed_eta_chi(pos):
pos = YouPos(mu=pos.omegah,
delta=-pos.gamma,
nu=pos.delta,
eta=0,
chi=0,
phi=-pos.phi,
unit='DEG')
if pos.phi > 180:
pos.phi -= 360
elif pos.phi < -180:
pos.phi += 360
return pos
class Test_Fixed_Eta_Chi(TestFixedMuEta):
def _configure_constraints(self):
self.constraints._constrained = {'alpha': 2 * TORAD, 'eta': 0,
'chi': 0}
def _convert_willmott_pos(self, willmott_pos):
return willmott_to_you_fixed_eta_chi(willmott_pos)
def testHkl_2_19_32_found_orientation_setting(self):
SkipTest()
def testHkl_0_7_22_found_orientation_setting(self):
SkipTest()
def testHkl_2_19_32_calculated_from_DDIF(self):
SkipTest()
def testHkl_0_7_22_calculated_from_DDIF(self):
SkipTest()
def testHkl_2_m5_12_calculated_from_DDIF(self):
SkipTest()
def testHkl_2_19_32_calculated_predicted_with_diffcalc_and_found(self):
willpos = WillPos(delta=22.0332862, gamma=-4.0973643,
omegah=2, phi=--64.0273584)
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.2572236, gamma=-2.9800571,
omegah=2, phi=-86.5634425)
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.3109941, gamma=-10.3716944,
omegah=2, phi=167.0041454)
self._check((2, -5, 12),
self._convert_willmott_pos(willpos),
{'alpha': 2})
# 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=-52.1392905)
Pt531_HKL1 = -2.000, -1.000, 7.0000
Pt531_REF1 = WillPos(delta=11.0126958, gamma=-11.8636128, omegah=2,
phi=40.3803393)
Pt531_REF12 = WillPos(delta=11.0126958, gamma=11.8636128, omegah=2,
phi=-121.2155975)
Pt531_HKL2 = 1, 1, 9
Pt531_REF2 = WillPos(delta=14.1881617, gamma=7.7585939, omegah=2,
phi=23.0203132)
Pt531_REF22 = WillPos(delta=14.1881617, gamma=-7.7585939, omegah=2,
phi=-183.465146)
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
settings.hardware = hardware
settings.geometry = SixCircle()
self.ubcalc = UBCalculation(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)
def testHkl_1_calculated_from_DDIF(self):
self.places = 7
self._check(Pt531_HKL1,
self._convert_willmott_pos(Pt531_REF12),
{'alpha': 2})
def testHkl_2_calculated_from_DDIF(self):
self.places = 7
self._check(Pt531_HKL2,
self._convert_willmott_pos(Pt531_REF22),
{'alpha': 2})
def testHkl_2_m1_0_16(self):
self.places = 7
pos = WillPos(delta=25.7990976, gamma=6.2413545, omegah=2,
phi=-47.4949600)
# pos.phi -= 360
self._check((-1, 0, 16),
self._convert_willmott_pos(pos),
{'alpha': 2})

View File

@@ -0,0 +1,591 @@
###
# 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 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
from diffcalc.hkl.you.geometry import SixCircle
from diffcalc import settings
def joined(d1, d2):
d1.update(d2)
return d1
class TestConstraintManager:
def setup_method(self):
diffcalc.util.COLOURISE_TERMINAL_OUTPUT = False
self.cm = YouConstraintManager()
settings.geometry = SixCircle()
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,
' bisect',
' omega'])
#"""
# 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(), True)
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(), True)
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(), True)
def test_is_implemented_2_samp_det_mu_phi(self):
self._constrain('qaz', 'mu', 'phi')
eq_(self.cm.is_current_mode_implemented(), True)
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(), True)
def test_is_implemented_2_samp_det_chi_phi(self):
self._constrain('qaz', 'chi', 'phi')
eq_(self.cm.is_current_mode_implemented(), True)
def test_is_implemented_2_samp_det_bisect_mu(self):
self._constrain('qaz', 'bisect', 'mu')
eq_(self.cm.is_current_mode_implemented(), True)
def test_is_implemented_2_samp_det_bisect_eta(self):
self._constrain('qaz', 'bisect', 'eta')
eq_(self.cm.is_current_mode_implemented(), True)
def test_is_implemented_2_samp_det_bisect_omega(self):
self._constrain('qaz', 'bisect', 'omega')
eq_(self.cm.is_current_mode_implemented(), True)
# 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({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({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',
' bisect',
' omega'])
def test_build_initial_display_table_with_fixed_sample(self):
self.cm = YouConstraintManager({'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 bisect',
' omega'])
def test_build_initial_display_table_for_four_circle(self):
self.cm = YouConstraintManager({'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 bisect',
' omega'])
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,97 @@
###
# 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
from test.diffcalc.test_hardware import SimpleHardwareAdapter
from diffcalc.hkl.you.geometry import SixCircle
diffcalc.util.DEBUG = True
hkl = None
def setup_module():
global hkl
settings.hardware=SimpleHardwareAdapter([])
settings.geometry=SixCircle()
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,315 @@
###
# 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 math import asin, sin, cos, atan2
from diffcalc.ub.reflections import _Reflection
from diffcalc.hkl.vlieg.geometry import VliegPosition
from diffcalc.hkl.you.geometry import YouPosition
from diffcalc.hkl.you.calc import sign
from diffcalc.util import TORAD, TODEG
class YouPositionScenario(YouPosition):
"""Convert six-circle Vlieg diffractometer angles into 4S+2D You geometry"""
def __init__(self, alpha=None, delta=None, gamma=None, omega=None,
chi=None, phi=None):
self.mu = alpha
self.eta = omega
self.chi = chi
self.phi = phi
self.unit = 'DEG'
asin_delta = asin(sin(delta*TORAD) * cos(gamma*TORAD))*TODEG # Eq.(83)
vals_delta = [asin_delta, 180. - asin_delta]
idx, _ = min([(i, abs(delta - d)) for i, d in enumerate(vals_delta)], key=lambda x: x[1])
self.delta = vals_delta[idx]
sgn = sign(cos(self.delta * TORAD))
self.nu = atan2(sgn*(cos(delta*TORAD)*cos(gamma*TORAD)*sin(alpha*TORAD) + cos(alpha*TORAD)*sin(gamma*TORAD)),
sgn*(cos(delta*TORAD)*cos(gamma*TORAD)*cos(alpha*TORAD) - sin(alpha*TORAD)*sin(gamma*TORAD)))*TODEG # Eq.(84)
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 = []
def sessions(P=VliegPosition):
############################ 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)
############################ SESSION4 ############################
# test crystal
session4 = SessionScenario()
session4.name = "test_orth"
session4.time = datetime.now()
session4.lattice = ((1.41421, 1.41421, 1.00000, 90, 90, 90))
session4.system = 'Orthorhombic'
session4.bmatrix = (((4.44288, 0, 0), (0, 4.44288, 0), (0, 0, 6.28319)))
session4.ref1 = _Reflection(0, 1, 2,
P(0.0000, 122.4938, 0.0000, 80.7181, 90.0000, -45.0000),
15., 'ref1', session4.time)
session4.ref2 = _Reflection(1, 0, 2,
P(0.0000, 122.4938, 0.000, 61.2469, 70.5288, -45.0000),
15, 'ref2', session4.time)
session4.ref3 = _Reflection(1, 0, 1,
P(0.0000, 60.8172, 0.000, 30.4086, 54.7356, -45.0000),
15, 'ref3', session4.time)
session4.ref4 = _Reflection(1, 1, 2,
P(0.0000, 135.0736, 0.000, 67.5368, 63.4349, 0.0000),
15, 'ref4', session4.time)
session4.reflist = (session4.ref1,
session4.ref2,
session4.ref3,
session4.ref4)
session4.umatrix = ((0.70711, 0.70711, 0.00),
(-0.70711, 0.70711, 0.00),
(0.00, 0.00, 1.00))
session4.ref1calchkl = (0, 1, 2) # Must match the guessed value!
session4.ref2calchkl = (1, 0, 2)
############################ SESSION5 ############################
# test crystal
session5 = SessionScenario()
session5.name = "Dalyite"
session5.time = datetime.now()
session5.lattice = ((7.51, 7.73, 7.00, 106.0, 113.5, 99.5))
session5.system = 'Triclinic'
session5.bmatrix = (((0.96021, 0.27759, 0.49527), (0, 0.84559, 0.25738), (0, 0, 0.89760)))
session5.ref1 = _Reflection(0, 1, 2,
P(0.0000, 23.7405, 0.0000, 11.8703, 46.3100, 43.1304),
12.3984, 'ref1', session5.time)
session5.ref2 = _Reflection(1, 0, 3,
P(0.0000, 34.4282, 0.000, 17.2141, 46.4799, 12.7852),
12.3984, 'ref2', session5.time)
session5.ref3 = _Reflection(2, 2, 6,
P(0.0000, 82.8618, 0.000, 41.4309, 41.5154, 26.9317),
12.3984, 'ref3', session5.time)
session5.ref4 = _Reflection(4, 1, 4,
P(0.0000, 71.2763, 0.000, 35.6382, 29.5042, 14.5490),
12.3984, 'ref4', session5.time)
session5.ref5 = _Reflection(8, 3, 1,
P(0.0000, 97.8850, 0.000, 48.9425, 5.6693, 16.7929),
12.3984, 'ref5', session5.time)
session5.ref6 = _Reflection(6, 4, 5,
P(0.0000, 129.6412, 0.000, 64.8206, 24.1442, 24.6058),
12.3984, 'ref6', session5.time)
session5.ref7 = _Reflection(3, 5, 7,
P(0.0000, 135.9159, 0.000, 67.9579, 34.3696, 35.1816),
12.3984, 'ref7', session5.time)
session5.reflist = (session5.ref1,
session5.ref2,
session5.ref3,
session5.ref4,
session5.ref5,
session5.ref6,
session5.ref7
)
session5.umatrix = (( 0.99982, 0.00073, 0.01903),
( 0.00073, 0.99710, -0.07612),
(-0.01903, 0.07612, 0.99692))
session5.ref1calchkl = (0, 1, 2) # Must match the guessed value!
session5.ref2calchkl = (1, 0, 3)
############################ SESSION6 ############################
# test crystal
session6 = SessionScenario()
session6.name = "Acanthite"
session6.time = datetime.now()
session6.lattice = ((4.229, 6.931, 7.862, 90, 99.61, 90))
session6.system = 'Monoclinic'
session6.bmatrix = ((1.50688, 0.00000, 0.13532),
(0.00000, 0.90653, 0.00000),
(0.00000, 0.00000, 0.79918))
session6.ref1 = _Reflection(0, 1, 2,
P(0.0000, 21.1188, 0.0000, 10.5594, 59.6447, 61.8432),
10., 'ref1', session6.time)
session6.ref2 = _Reflection(1, 0, 3,
P(0.0000, 35.2291, 0.000, 62.4207, 87.1516, -90.0452),
10., 'ref2', session6.time)
session6.ref3 = _Reflection(1, 1, 6,
P(0.0000, 64.4264, 0.000, 63.9009, 97.7940, -88.8808),
10., 'ref3', session6.time)
session6.ref4 = _Reflection(1, 2, 2,
P(0.0000, 34.4369, 0.000, 72.4159, 60.1129, -29.0329),
10., 'ref4', session6.time)
session6.ref5 = _Reflection(2, 2, 1,
P(0.0000, 43.0718, 0.000, 21.5359, 8.3873, 29.0230),
10., 'ref5', session6.time)
session6.reflist = (session6.ref1,
session6.ref2,
session6.ref3,
session6.ref4,
session6.ref5,
)
session6.umatrix = (( 0.99411, 0.00079, 0.10835),
( 0.00460, 0.99876, -0.04949),
(-0.10825, 0.04969, 0.99288))
session6.ref1calchkl = (0, 1, 2) # Must match the guessed value!
session6.ref2calchkl = (1, 0, 3)
########################################################################
return (session1, session2, session3, session4, session5, session6)

View File

@@ -0,0 +1,271 @@
###
# 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.minigda.scannable import ScannableGroup
from diffcalc.gdasupport.scannable.diffractometer import \
DiffractometerScannableGroup
from diffcalc.util import DiffcalcException
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 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 = DummyHardwareAdapter(['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 testLowerLimitSetAndGet(self):
self.hardware.set_lower_limit('alpha', -1)
self.hardware.set_lower_limit('delta', -2)
self.hardware.set_lower_limit('gamma', -3)
with pytest.raises(ValueError):
self.hardware.set_lower_limit('not an angle', 1)
self.hardware.set_lower_limit('delta', None)
print "Should print WARNING:"
self.hardware.set_lower_limit('delta', None)
assert self.hardware.get_lower_limit('alpha') == -1
assert self.hardware.get_lower_limit('gamma') == -3
def testUpperLimitSetAndGet(self):
self.hardware.set_upper_limit('alpha', 1)
self.hardware.set_upper_limit('delta', 2)
self.hardware.set_upper_limit('gamma', 3)
with pytest.raises(ValueError):
self.hardware.set_upper_limit('not an angle', 1)
self.hardware.set_upper_limit('delta', None)
print "Should print WARNING:"
self.hardware.set_upper_limit('delta', None)
assert self.hardware.get_upper_limit('alpha') == 1
assert self.hardware.get_upper_limit('gamma') == 3
def testis_position_within_limits(self):
self.hardware.set_upper_limit('alpha', 1)
self.hardware.set_upper_limit('delta', 2)
self.hardware.set_lower_limit('alpha', -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('alpha', 1)
self.hardware.set_upper_limit('delta', 2)
self.hardware.set_lower_limit('gamma', -1)
assert self.hardware.is_axis_value_within_limits('alpha', 0)
assert self.hardware.is_axis_value_within_limits('delta', 0)
assert self.hardware.is_axis_value_within_limits('gamma', 999)
assert self.hardware.is_axis_value_within_limits('alpha', 1)
assert self.hardware.is_axis_value_within_limits('delta', 2)
assert self.hardware.is_axis_value_within_limits('gamma', 999)
assert self.hardware.is_axis_value_within_limits('alpha', -1)
assert self.hardware.is_axis_value_within_limits('delta', -999)
assert not self.hardware.is_axis_value_within_limits('alpha', 1.01)
assert not self.hardware.is_axis_value_within_limits('delta', 2.01)
assert not self.hardware.is_axis_value_within_limits('alpha', 1.01)
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
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(DiffcalcException):
self.hardware.set_lower_limit('not an angle', 1)
self.hardware.set_lower_limit('d', None)
print "Should print WARNING:"
self.hardware.set_lower_limit('d', 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(DiffcalcException):
self.hardware.set_upper_limit('not an angle', 1)
self.hardware.set_upper_limit('d', None)
print "Should print WARNING:"
self.hardware.set_upper_limit('d', None)
assert self.hardware.get_upper_limit('a') == 1
assert self.hardware.get_upper_limit('c') == 3

View File

@@ -0,0 +1,221 @@
###
# 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 nose.tools import eq_ # @UnresolvedImport
from diffcalc.hkl.vlieg.geometry import VliegPosition
from diffcalc.util import MockRawInput, \
getInputWithDefault, differ, nearlyEqual, degreesEquivilant,\
CoordinateConverter
import diffcalc.util # @UnusedImport
import pytest
try:
from numpy import matrix
except ImportError:
from numjy import matrix
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
class TestCoordinateConverter(object):
def setup_method(self):
self.conv = CoordinateConverter(transform=matrix('0 0 1; 1 0 0; 0 1 0'))
def testVector(self):
vec100 = matrix('1;0;0')
vec010 = matrix('0;1;0')
vec001 = matrix('0;0;1')
conv100 = self.conv.transform(vec100)
conv010 = self.conv.transform(vec010)
conv001 = self.conv.transform(vec001)
inv100 = self.conv.transform(conv100, True)
inv010 = self.conv.transform(conv010, True)
inv001 = self.conv.transform(conv001, True)
eq_(conv100.tolist(), vec010.tolist())
eq_(conv010.tolist(), vec001.tolist())
eq_(conv001.tolist(), vec100.tolist())
eq_(vec100.tolist(), inv100.tolist())
eq_(vec010.tolist(), inv010.tolist())
eq_(vec001.tolist(), inv001.tolist())
def testVector1m10(self):
vec110 = matrix(' 1; -1; 0')
vec011 = matrix(' 0; 1; -1')
vec101 = matrix('-1; 0; 1')
conv110 = self.conv.transform(vec110)
conv011 = self.conv.transform(vec011)
conv101 = self.conv.transform(vec101)
inv110 = self.conv.transform(conv110, True)
inv011 = self.conv.transform(conv011, True)
inv101 = self.conv.transform(conv101, True)
eq_(conv110.tolist(), vec011.tolist())
eq_(conv011.tolist(), vec101.tolist())
eq_(conv101.tolist(), vec110.tolist())
eq_(vec110.tolist(), inv110.tolist())
eq_(vec011.tolist(), inv011.tolist())
eq_(vec101.tolist(), inv101.tolist())
def testMatrix(self):
m = matrix('0 -1 0; 1 0 0; 0 0 -1')
tm = self.conv.transform(m)
im = self.conv.transform(tm, True)
eq_(m.tolist(), im.tolist())
vec110 = matrix(' 1; -1; 0')
vec011 = matrix(' 0; 1; -1')
vec101 = matrix('-1; 0; 1')
conv110 = self.conv.transform(vec110)
conv011 = self.conv.transform(vec011)
conv101 = self.conv.transform(vec101)
m110 = m * vec110
m011 = m * vec011
m101 = m * vec101
cm110 = tm * conv110
cm011 = tm * conv011
cm101 = tm * conv101
inv110 = self.conv.transform(cm110, True)
inv011 = self.conv.transform(cm011, True)
inv101 = self.conv.transform(cm101, True)
eq_(cm110.tolist(), self.conv.transform(m110).tolist())
eq_(cm011.tolist(), self.conv.transform(m011).tolist())
eq_(cm101.tolist(), self.conv.transform(m101).tolist())
eq_(m110.tolist(), inv110.tolist())
eq_(m011.tolist(), inv011.tolist())
eq_(m101.tolist(), inv101.tolist())
def testVectorFail(self):
failvec = matrix('0;0;1;0')
failmarix = matrix('0 0 1; 0 0 1; 1 0 0; 0 0 1')
with pytest.raises(TypeError):
CoordinateConverter(transform=failmarix)
with pytest.raises(TypeError):
self.conv.transform(failvec)
with pytest.raises(TypeError):
self.conv.transform(failmarix)

View File

@@ -0,0 +1,201 @@
###
# 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 diffcalc.ub.calcstate import UBCalcStateEncoder
from math import pi, sqrt, atan2
from mock import Mock
from nose.tools import eq_
from test.tools import matrixeq_
import tempfile
import datetime
from diffcalc.util import TORAD, x_rotation
from diffcalc import settings
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, unit='DEG')
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
settings.hardware = hardware
settings.geometry = geometry
self.ubcalc = UBCalculation(UBCalculationJSONPersister(self.tmpdir, UBCalcStateEncoder),
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)
def test_calc_hkl_offset(self):
NAME = 'test_calc_hkl_offset'
self.ubcalc.start_new(NAME)
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.set_U_manually(x_rotation(0))
hkloff_110 = self.ubcalc.calc_hkl_offset(0, 0, sqrt(2), 90. * TORAD, -45 * TORAD)
hkloff_m101 = self.ubcalc.calc_hkl_offset(0, 0, sqrt(2), 45. * TORAD, 90 * TORAD)
alpha = atan2(2,1)
hkloff_102 = self.ubcalc.calc_hkl_offset(sqrt(5), 0, 0, alpha, 90 * TORAD)
matrixeq_(matrix('1 1 0'), matrix(hkloff_110))
matrixeq_(matrix('-1 0 1'), matrix(hkloff_m101))
matrixeq_(matrix('1 0 2'), matrix(hkloff_102))
def test_calc_offset_for_hkl(self):
NAME = 'test_calc_offset_for_hkl'
self.ubcalc.start_new(NAME)
self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
self.ubcalc.set_U_manually(x_rotation(0))
for hklref, hkloff, pol_ref, az_ref, sc_ref in [([0, 0, 1], [1, 1, 0], 90 * TORAD, -45 * TORAD, sqrt(2)),
([0, 0, 1], [-1, 0, 1], 45 * TORAD, 90 * TORAD, sqrt(2)),
([1, 0, 0], [1, 0, 2], atan2(2,1), 90 * TORAD, sqrt(5)),]:
pol, az , sc = self.ubcalc.calc_offset_for_hkl(hkloff, hklref)
matrixeq_(matrix([[pol_ref, az_ref, sc_ref]]),
matrix([[pol, az, sc]]))

View File

@@ -0,0 +1,384 @@
###
# 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
from diffcalc import settings
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.energyScannableMultiplierToGetKeV = 1
mock_hardware.get_axes_names.return_value = ('a', 'd', 'g', 'o', 'c', 'p')
settings.hardware = mock_hardware
settings.geometry = self.geometry
self.ubcalc = UBCalculation(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"
mock_hardware = Mock()
mock_hardware.energyScannableMultiplierToGetKeV = 1
mock_hardware.get_axes_names.return_value = \
('a', 'd', 'g', 'o', 'c', 'p')
settings.hardware = mock_hardware
settings.geometry = SixCircleGammaOnArmGeometry()
self.ubcalc = UBCalculation(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,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/>.
###
from math import pi
from mock import Mock
from diffcalc import settings
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, unit='DEG')
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
settings.hardware = hardware
settings.geometry = geometry
self.ubcalc = UBCalculation(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,75 @@
###
# Copyright 2008-2019 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.orientations import OrientationList
from diffcalc.util import DiffcalcException
import pytest
class TestOrientationList(object):
def setup_method(self):
self.orientlist = OrientationList()
self.time = datetime.now()
self.orientlist.add_orientation(1, 2, 3, 0.1, 0.2, 0.3, "orient1", self.time)
self.orientlist.add_orientation(1.1, 2.2, 3.3, 0.11, 0.12, 0.13, "orient2", self.time)
def test_add_orientation(self):
assert len(self.orientlist) == 2
self.orientlist.add_orientation(10, 20, 30, 0.1, 0.2, 0.3, "orient1", self.time)
def testGetOrientation(self):
answered = self.orientlist.getOrientation(1)
desired = ([1, 2, 3], [0.1, 0.2, 0.3], "orient1", self.time)
assert answered == desired
answered = self.orientlist.getOrientation("orient1")
assert answered == desired
def testRemoveOrientation(self):
self.orientlist.removeOrientation(1)
answered = self.orientlist.getOrientation(1)
desired = ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], "orient2", self.time)
assert answered == desired
self.orientlist.removeOrientation("orient2")
assert self.orientlist._orientlist == []
def testedit_orientation(self):
self.orientlist.edit_orientation(1, 10, 20, 30, 1, 2, 3, "new1", self.time)
assert (self.orientlist.getOrientation(1)
== ([10, 20, 30], [1, 2, 3], "new1", self.time))
assert (self.orientlist.getOrientation(2)
== ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], "orient2", self.time))
self.orientlist.edit_orientation("orient2", 1.1, 2.2, 3.3, 1.11, 1.12, 1.13, "new2", self.time)
assert (self.orientlist.getOrientation("new2")
== ([1.1, 2.2, 3.3], [1.11, 1.12, 1.13], "new2", self.time))
self.orientlist.edit_orientation("new2", 1.1, 2.2, 3.3, 1.11, 1.12, 1.13, "new1", self.time)
assert (self.orientlist.getOrientation("new1")
== ([10, 20, 30], [1, 2, 3], "new1", self.time))
def testSwapOrientation(self):
self.orientlist.swap_orientations(1, 2)
assert (self.orientlist.getOrientation(1)
== ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], "orient2", self.time))
assert (self.orientlist.getOrientation(2)
== ([1, 2, 3], [0.1, 0.2, 0.3], "orient1", self.time))
self.orientlist.swap_orientations("orient1", "orient2")
assert (self.orientlist.getOrientation(2)
== ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], "orient2", self.time))
assert (self.orientlist.getOrientation(1)
== ([1, 2, 3], [0.1, 0.2, 0.3], "orient1", self.time))

View File

@@ -0,0 +1,104 @@
###
# 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
from diffcalc.ub.calcstate import UBCalcStateEncoder
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, UBCalcStateEncoder)
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(1.)
eq_(self.persister.list(), ['first_written'])
self.persister.save(d, 'second_written')
time.sleep(1.)
eq_(self.persister.list(), ['second_written', 'first_written'])
self.persister.save(d, 'third_written')
time.sleep(1.)
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,111 @@
###
# 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
from diffcalc.util import DiffcalcException
import pytest
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
pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66)
self.reflist.add_reflection(11.1, 12.2, 13.3, pos, 1100, "ref2", self.time)
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
answered = self.reflist.getReflection('ref1')
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
self.reflist.removeReflection("ref2")
assert self.reflist._reflist == []
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))
self.reflist.edit_reflection("ref2", 1.1, 2.2, 3.3, pos, 1100, "new2", self.time)
assert (self.reflist.getReflection("new2")
== ([1.1, 2.2, 3.3], pos, 1100, "new2", self.time))
self.reflist.edit_reflection("new2", 10, 20, 30, pos, 1100, "new1", self.time)
assert (self.reflist.getReflection("new1")
== ([10, 20, 30], ps, 1000, "new1", 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))
self.reflist.swap_reflections("ref1", "ref2")
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))
pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6)
assert (self.reflist.getReflection(1)
== ([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,787 @@
###
# 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
from math import atan, sqrt
from nose import SkipTest
try:
from numpy import matrix
except ImportError:
from numjy import matrix
import diffcalc.util # @UnusedImport
from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry,\
VliegPosition
from diffcalc.hkl.you.geometry import SixCircle
from diffcalc.hardware import DummyHardwareAdapter
from test.tools import assert_iterable_almost_equal, mneq_, arrayeq_
from diffcalc.ub.persistence import UbCalculationNonPersister,\
UBCalculationJSONPersister
from diffcalc.ub.calcstate import UBCalcStateEncoder
from diffcalc.util import DiffcalcException, MockRawInput, xyz_rotation,\
TODEG, TORAD, CoordinateConverter
from diffcalc.hkl.vlieg.calc import VliegUbCalcStrategy, vliegAnglesToHkl
from diffcalc.hkl.you.calc import youAnglesToHkl, YouUbCalcStrategy
from test.diffcalc import scenarios
from test.diffcalc.scenarios import YouPositionScenario
diffcalc.util.DEBUG = True
def prepareRawInput(listOfStrings):
diffcalc.util.raw_input = MockRawInput(listOfStrings)
prepareRawInput([])
from diffcalc import settings
class _UBCommandsBase():
def setup_method(self):
names = 'alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'
self.hardware = DummyHardwareAdapter(names)
settings.hardware = self.hardware
self.conv = CoordinateConverter(transform=self.t_matrix)
self._refineub_matrix = matrix('0.70711 0.70711 0.00000; -0.70711 0.70711 0.00000; 0.00000 0.00000 1.00000')
from diffcalc.ub import ub
reload(ub)
self.ub = ub
#self.ub.ubcalc = ub.ubcalc
prepareRawInput([])
diffcalc.util.RAISE_EXCEPTIONS_FOR_ALL_ERRORS = True
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', '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, 91, 90), 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', '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, implicitly 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 convenience
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 convenience
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 convenience
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(IndexError):
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 testShoworient(self):
with pytest.raises(TypeError):
self.ub.showorient((1))
eq_(self.ub.showorient(), None) # No UBCalculation loaded
# will be tested, for exceptions at least, implicitly below
self.ub.newub('testing_showorient')
eq_(self.ub.showorient(), None) # No UBCalculation loaded"
def testAddorient(self):
with pytest.raises(TypeError):
self.ub.addorient(1)
with pytest.raises(TypeError):
self.ub.addorient(1, 2)
with pytest.raises(TypeError):
self.ub.addorient(1, 2, 'blarghh')
# start new ubcalc
self.ub.newub('testing_addorient')
orientlist = self.ub.ubcalc._state.orientlist # for convenience
hkl1 = [1.1, 1.2, 1.3]
hkl2 = [2.1, 2.2, 2.3]
orient1 = [1.4, 1.5, 1.6]
orient2 = [2.4, 2.5, 2.6]
#
self.ub.addorient(hkl1, orient1)
result = orientlist.getOrientation(1)
trans_orient1 = self.conv.transform(matrix([orient1]).T)
eq_(result[0], hkl1)
mneq_(matrix([result[1]]), trans_orient1.T)
eq_(result[2], None)
self.ub.addorient(hkl2, orient2, 'atag')
result = orientlist.getOrientation(2)
trans_orient2 = self.conv.transform(matrix([orient2]).T)
eq_(result[0], hkl2)
mneq_(matrix([result[1]]), trans_orient2.T)
eq_(result[2], 'atag')
def testAddorientInteractively(self):
prepareRawInput([])
# start new ubcalc
self.ub.newub('testing_addorient')
orientlist = self.ub.ubcalc._state.orientlist # for convenience
hkl1 = [1.1, 1.2, 1.3]
hkl2 = [2.1, 2.2, 2.3]
orient1 = [1.4, 1.5, 1.6]
orient2 = [2.4, 2.5, 2.6]
#
prepareRawInput(['1.1', '1.2', '1.3', '1.4', '1.5', '1.6', ''])
self.ub.addorient()
result = orientlist.getOrientation(1)
trans_orient1 = self.conv.transform(matrix([orient1]).T)
eq_(result[0], hkl1)
mneq_(matrix([result[1]]), trans_orient1.T)
eq_(result[2], None)
prepareRawInput(['2.1', '2.2', '2.3', '2.4', '2.5', '2.6', 'atag'])
self.ub.addorient()
result = orientlist.getOrientation(2)
trans_orient2 = self.conv.transform(matrix([orient2]).T)
eq_(result[0], hkl2)
mneq_(matrix([result[1]]), trans_orient2.T)
eq_(result[2], 'atag')
def testEditOrientInteractively(self):
hkl1 = [1.1, 1.2, 1.3]
hkl2 = [1.1, 1.2, 3.1]
orient1 = [1.4, 1.5, 1.6]
orient2 = [2.4, 1.5, 2.6]
orient2s = ['2.4', '', '2.6']
self.ub.newub('testing_editorient')
self.ub.addorient(hkl1, orient1, 'tag1')
prepareRawInput(['1.1', '', '3.1'] + orient2s + ['newtag',])
self.ub.editorient(1)
orientlist = self.ub.ubcalc._state.orientlist
result = orientlist.getOrientation(1)
trans_orient2 = self.conv.transform(matrix([orient2]).T)
eq_(result[0], hkl2)
mneq_(matrix([result[1]]), trans_orient2.T)
eq_(result[2], 'newtag')
def testSwaporient(self):
with pytest.raises(TypeError):
self.ub.swaporient(1)
with pytest.raises(TypeError):
self.ub.swaporient(1, 2, 3)
with pytest.raises(IndexError):
self.ub.swaporient(1, 1.1)
self.ub.newub('testing_swaporient')
hkl = [1.1, 1.2, 1.3]
orient = [1.4, 1.5, 1.6]
self.ub.addorient(hkl, orient, 'tag1')
self.ub.addorient(hkl, orient, 'tag2')
self.ub.addorient(hkl, orient, 'tag3')
self.ub.swaporient(1, 3)
self.ub.swaporient(1, 3)
self.ub.swaporient(3, 1) # end flipped
orientlist = self.ub.ubcalc._state.orientlist
tag1 = orientlist.getOrientation(1)[2]
tag2 = orientlist.getOrientation(2)[2]
tag3 = orientlist.getOrientation(3)[2]
eq_(tag1, 'tag3')
eq_(tag2, 'tag2')
eq_(tag3, 'tag1')
self.ub.swaporient()
tag1 = orientlist.getOrientation(1)[2]
tag2 = orientlist.getOrientation(2)[2]
eq_(tag1, 'tag2')
eq_(tag2, 'tag3')
def testDelorient(self):
self.ub.newub('testing_delorient')
hkl = [1.1, 1.2, 1.3]
pos = [1.4, 1.5, 1.6]
self.ub.addorient(hkl, pos, 'tag1')
orientlist = self.ub.ubcalc._state.orientlist
orientlist.getOrientation(1)
self.ub.delorient(1)
with pytest.raises(IndexError):
orientlist.getOrientation(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(DiffcalcException):
self.ub.calcub(1) # wrong input
# no ubcalc started:
with pytest.raises(DiffcalcException):
self.ub.calcub()
self.ub.newub('testcalcub')
# not enough reflections:
with pytest.raises(DiffcalcException):
self.ub.calcub()
for s in scenarios.sessions(settings.Pos):
self.ub.setlat(s.name, *s.lattice)
self.ub.clearref()
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(s.ref1.tag, s.ref2.tag)
mneq_(self.ub.ubcalc.UB, matrix(s.umatrix) * matrix(s.bmatrix),
4, note="wrong UB matrix after calculating U")
def testOrientub(self):
with pytest.raises(DiffcalcException):
self.ub.orientub(1) # wrong input
# no ubcalc started:
with pytest.raises(DiffcalcException):
self.ub.orientub()
self.ub.newub('testorientub')
# not enough orientations:
with pytest.raises(DiffcalcException):
self.ub.orientub()
s = scenarios.sessions(settings.Pos)[1]
self.ub.setlat(s.name, *s.lattice)
r1 = s.ref1
orient1 = self.conv.transform(matrix('1; 0; 0'), True)
tag1 = 'or'+r1.tag
self.ub.addorient(
(r1.h, r1.k, r1.l), orient1.T.tolist()[0], tag1)
r2 = s.ref2
orient2 = self.conv.transform(matrix('0; -1; 0'), True)
tag2 = 'or'+r2.tag
self.ub.addorient(
(r2.h, r2.k, r2.l), orient2.T.tolist()[0], tag2)
self.ub.orientub()
mneq_(self.ub.ubcalc.UB, matrix(s.umatrix) * matrix(s.bmatrix),
4, note="wrong UB matrix after calculating U")
self.ub.orientub(tag1, tag2)
mneq_(self.ub.ubcalc.UB, matrix(s.umatrix) * matrix(s.bmatrix),
4, note="wrong UB matrix after calculating U")
self.ub.addref(
[r1.h, r1.k, r1.l], r1.pos.totuple(), r1.energy, r1.tag)
self.ub.orientub(r1.tag, tag2)
mneq_(self.ub.ubcalc.UB, matrix(s.umatrix) * matrix(s.bmatrix),
4, note="wrong UB matrix after calculating U")
self.ub.addref(
[r2.h, r2.k, r2.l], r2.pos.totuple(), r2.energy, r2.tag)
self.ub.orientub(tag1, r2.tag)
mneq_(self.ub.ubcalc.UB, matrix(s.umatrix) * matrix(s.bmatrix),
4, note="wrong UB matrix after calculating U")
def testRefineubInteractively(self):
self.ub.newub('testing_refineubinteractive')
self.ub.setlat('xtal', 1, 1, 1, 90, 90, 90)
self.ub.setmiscut(0)
prepareRawInput(['1', '1', '', 'n', '0', '60', '0', '30', '0', '0', 'y', 'y'])
self.ub.refineub()
getLattice = self.ub.ubcalc._state.crystal.getLattice
eq_(('xtal', sqrt(2.), sqrt(2.), 1, 90, 90, 90), getLattice())
mneq_(self.ub.ubcalc.U, self._refineub_matrix,
4, note="wrong U matrix after refinement")
def testRefineubInteractivelyWithPosition(self):
self.ub.newub('testing_refineubinteractivepos')
self.ub.setlat('xtal', 1, 1, 1, 90, 90, 90)
self.ub.setmiscut(0)
self.hardware.position = [0, 60, 0, 30, 0, 0]
prepareRawInput(['1', '1', '', 'y', 'y', 'y'])
self.ub.refineub()
getLattice = self.ub.ubcalc._state.crystal.getLattice
eq_(('xtal', sqrt(2.), sqrt(2.), 1, 90, 90, 90), getLattice())
mneq_(self.ub.ubcalc.U, self._refineub_matrix,
4, note="wrong U matrix after refinement")
def testRefineubInteractivelyWithHKL(self):
self.ub.newub('testing_refineubinteractivehkl')
self.ub.setlat('xtal', 1, 1, 1, 90, 90, 90)
self.ub.setmiscut(0)
self.hardware.position = [0, 60, 0, 30, 0, 0]
prepareRawInput(['y', 'y', 'y'])
self.ub.refineub([1, 1, 0])
getLattice = self.ub.ubcalc._state.crystal.getLattice
eq_(('xtal', sqrt(2.), sqrt(2.), 1, 90, 90, 90), getLattice())
mneq_(self.ub.ubcalc.U, self._refineub_matrix,
4, note="wrong U matrix after refinement")
def testRefineub(self):
self.ub.newub('testing_refineub')
self.ub.setlat('xtal', 1, 1, 1, 90, 90, 90)
self.ub.setmiscut(0)
prepareRawInput(['y', 'y'])
self.ub.refineub([1, 1, 0], [0, 60, 0, 30, 0, 0])
getLattice = self.ub.ubcalc._state.crystal.getLattice
eq_(('xtal', sqrt(2.), sqrt(2.), 1, 90, 90, 90), getLattice())
mneq_(self.ub.ubcalc.U, self._refineub_matrix,
4, note="wrong U matrix after refinement")
def testFitub(self):
self.ub.newub('testfitub')
for s in scenarios.sessions(settings.Pos)[-3:]:
a, b, c, alpha, beta, gamma = s.lattice
self.ub.clearref()
for r in s.reflist:
self.ub.addref(
[r.h, r.k, r.l], r.pos.totuple(), r.energy, r.tag)
self.ub.setlat(s.name, s.system, *s.lattice)
self.ub.calcub(s.ref1.tag, s.ref2.tag)
init_latt = (1.06 * a, 1.07 * b, 0.94 * c,
1.05 * alpha, 1.06 * beta, 0.95 * gamma)
self.ub.setlat(s.name, s.system, *init_latt)
self.ub.addmiscut(3., [0.2, 0.8, 0.1])
prepareRawInput(['y', 'y'])
self.ub.fitub(*tuple(r.tag for r in s.reflist))
assert self.ub.ubcalc._state.crystal._system == s.system
mneq_(matrix((self.ub.ubcalc._state.crystal.getLattice()[1:])), matrix(s.lattice),
2, note="wrong lattice after fitting UB")
mneq_(self.ub.ubcalc.U, matrix(s.umatrix),
3, note="wrong U matrix after fitting UB")
def testC2th(self):
self.ub.newub('testc2th')
self.ub.setlat('cube', 1, 1, 1, 90, 90, 90)
assert self.ub.c2th((0, 0, 1)) == pytest.approx(60)
def testHKLangle(self):
self.ub.newub('testhklangle')
self.ub.setlat('cube', 1, 1, 1, 90, 90, 90)
assert self.ub.hklangle((0, 0, 1), (0, 0, 2)) == pytest.approx(0)
assert self.ub.hklangle((0, 1, 0), (0, 0, 2)) == pytest.approx(90)
assert self.ub.hklangle((1, 0, 0), (0, 0, 2)) == pytest.approx(90)
assert self.ub.hklangle((1, 1, 0), (0, 0, 2)) == pytest.approx(90)
assert self.ub.hklangle((0, 1, 1), (0, 0, 2)) == pytest.approx(45)
assert self.ub.hklangle((1, 0, 1), (0, 0, 2)) == pytest.approx(45)
assert self.ub.hklangle((1, 1, 1), (0, 0, 2)) == pytest.approx(atan(sqrt(2))*TODEG)
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')
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])
def testMiscut(self):
self.ub.newub('testsetmiscut')
self.ub.setlat('cube', 1, 1, 1, 90, 90, 90)
beam_axis = self.conv.transform(matrix('0; 1; 0'), True).T.tolist()[0]
beam_maxis = self.conv.transform(matrix('0; -1; 0'), True).T.tolist()[0]
self.ub.setmiscut(self.t_hand * 30, beam_axis)
mneq_(self.ub.ubcalc._state.reference.n_hkl, matrix('-0.5000000; 0.00000; 0.8660254'))
self.ub.addmiscut(self.t_hand * 15, beam_axis)
mneq_(self.ub.ubcalc._state.reference.n_hkl, matrix('-0.7071068; 0.00000; 0.7071068'))
self.ub.addmiscut(self.t_hand * 45, beam_maxis)
mneq_(self.ub.ubcalc._state.reference.n_hkl, matrix('0.0; 0.0; 1.0'))
class TestUbCommandsVlieg(_UBCommandsBase):
def setup_method(self):
settings.ubcalc_persister = UbCalculationNonPersister()
settings.geometry = SixCircleGammaOnArmGeometry()
settings.ubcalc_strategy = VliegUbCalcStrategy()
settings.angles_to_hkl_function = vliegAnglesToHkl
settings.Pos = VliegPosition
self.t_matrix = matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
self.t_hand = 1
_UBCommandsBase.setup_method(self)
class TestUBCommandsYou(_UBCommandsBase):
def setup_method(self):
settings.ubcalc_persister = UbCalculationNonPersister()
settings.geometry = SixCircle()
settings.ubcalc_strategy = YouUbCalcStrategy()
settings.angles_to_hkl_function = youAnglesToHkl
settings.Pos = YouPositionScenario
self.t_matrix = matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
self.t_hand = 1
_UBCommandsBase.setup_method(self)
class TestUBCommandsCustomGeom(TestUBCommandsYou):
def setup_method(self):
settings.ubcalc_persister = UbCalculationNonPersister()
inv = matrix([[0, 0, -1], [0, 1, 0], [1, 0, 0]])
self.zrot = xyz_rotation([0, 0 ,1], 30. * TORAD)
self.t_matrix = inv * self.zrot
self.t_hand = 1
settings.geometry = SixCircle(beamline_axes_transform=self.t_matrix)
settings.ubcalc_strategy = YouUbCalcStrategy()
settings.angles_to_hkl_function = youAnglesToHkl
settings.Pos = YouPositionScenario
_UBCommandsBase.setup_method(self)
def testSetu(self):
self.ub.newub('testsetu_custom')
self.ub.setlat('NaCl', 1.1)
zrot = xyz_rotation([0, 0 , 1], 30. * TORAD)
self.ub.setu(zrot.tolist())
mneq_(self.ub.ubcalc.U, self.conv.transform(self.zrot))
def testSetuInteractive(self):
# Interactive functionality already tested
raise SkipTest()
def testSetub(self):
self.ub.newub('testsetub_custom')
self.ub.setlat('NaCl', 1.1)
zrot = xyz_rotation([0, 0 , 1], 30. * TORAD)
self.ub.setu(zrot.tolist())
mneq_(self.ub.ubcalc.UB, self.conv.transform(self.zrot) * self.ub.ubcalc._state.crystal.B)
def testSetUbInteractive(self):
# Interactive functionality already tested
raise SkipTest()
class TestUbCommandsJsonPersistence(TestUBCommandsYou):
def setup_method(self):
settings.ubcalc_persister = self._createPersister()
settings.geometry = SixCircle()
settings.ubcalc_strategy = YouUbCalcStrategy()
settings.angles_to_hkl_function = youAnglesToHkl
settings.Pos = YouPositionScenario
self.t_matrix = matrix([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
self.t_hand = 1
_UBCommandsBase.setup_method(self)
def _createPersister(self):
self.tmpdir = tempfile.mkdtemp()
print self.tmpdir
self.persister = UBCalculationJSONPersister(self.tmpdir, UBCalcStateEncoder)
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])