├── .cache
└── v
│ └── cache
│ └── lastfailed
├── .github
└── workflows
│ └── main.yml
├── .gitignore
├── .project
├── .settings
├── com.wdev91.eclipse.copyright.xml
├── org.eclipse.core.resources.prefs
└── org.eclipse.core.runtime.prefs
├── COPYING
├── Makefile
├── README.rst
├── README_template.rst
├── buckminster.cspec
├── component.def
├── diffcalc.py
├── diffcalc
├── __init__.py
├── dc
│ ├── __init__.py
│ ├── common.py
│ ├── dcvlieg.py
│ ├── dcwillmot.py
│ ├── dcyou.py
│ └── help.py
├── gdasupport
│ ├── __init__.py
│ ├── minigda
│ │ ├── __init__.py
│ │ ├── command.py
│ │ └── scannable.py
│ ├── scannable
│ │ ├── __init__.py
│ │ ├── base.py
│ │ ├── diffractometer.py
│ │ ├── hkl.py
│ │ ├── hkloffset.py
│ │ ├── mock.py
│ │ ├── parameter.py
│ │ ├── parametrised_hkl.py
│ │ ├── qtrans.py
│ │ ├── setref2.py
│ │ ├── sim.py
│ │ ├── simulation.py
│ │ ├── slave_driver.py
│ │ ├── sr2.py
│ │ ├── vrmlanimator.py
│ │ └── wavelength.py
│ └── you.py
├── hardware.py
├── hkl
│ ├── __init__.py
│ ├── calcbase.py
│ ├── common.py
│ ├── vlieg
│ │ ├── __init__.py
│ │ ├── calc.py
│ │ ├── constraints.py
│ │ ├── geometry.py
│ │ ├── hkl.py
│ │ └── transform.py
│ ├── willmott
│ │ ├── __init__.py
│ │ ├── calc.py
│ │ ├── commands.py
│ │ └── constraints.py
│ └── you
│ │ ├── __init__.py
│ │ ├── calc.py
│ │ ├── constraints.py
│ │ ├── geometry.py
│ │ ├── hkl.py
│ │ └── persistence.py
├── log.py
├── settings.py
├── tests
│ ├── __init__.py
│ ├── dc
│ │ ├── __init__.py
│ │ ├── test_dcvlieg.py
│ │ └── you
│ │ │ ├── __init__.py
│ │ │ ├── test_fourcircle.py
│ │ │ └── test_sixcircle.py
│ ├── gdasupport
│ │ ├── __init__.py
│ │ ├── minigda
│ │ │ ├── __init__.py
│ │ │ ├── test_command.py
│ │ │ └── test_scannable.py
│ │ ├── scannable
│ │ │ ├── __init__.py
│ │ │ ├── mockdiffcalc.py
│ │ │ ├── test_diffractometer.py
│ │ │ ├── test_hkl.py
│ │ │ ├── test_parameter.py
│ │ │ ├── test_simulation.py
│ │ │ └── test_wavelength.py
│ │ └── test_you.py
│ ├── hkl
│ │ ├── __init__.py
│ │ ├── vlieg
│ │ │ ├── __init__.py
│ │ │ ├── test_calc.py
│ │ │ ├── test_constraints.py
│ │ │ ├── test_geometry.py
│ │ │ ├── test_hkl.py
│ │ │ └── test_transform.py
│ │ ├── willmot
│ │ │ ├── __init__.py
│ │ │ └── test_calcwill.py
│ │ └── you
│ │ │ ├── __init__.py
│ │ │ ├── test_calc.py
│ │ │ ├── test_calc_methods.py
│ │ │ ├── test_calc_surface.py
│ │ │ ├── test_constraints.py
│ │ │ └── test_hkl.py
│ ├── ref
│ │ ├── b16_dif_270608_printout_for_SixCircleGammaOnArmTestAgainstDif.txt
│ │ ├── i16_reference_results.txt
│ │ └── output_from_spec.txt
│ ├── scenarios.py
│ ├── test_hardware.py
│ ├── test_numjy.py
│ ├── test_tools.py
│ ├── test_utils.py
│ ├── tools.py
│ └── ub
│ │ ├── __init__.py
│ │ ├── test_calculation.py
│ │ ├── test_calculation_vlieg.py
│ │ ├── test_calculation_you.py
│ │ ├── test_crystal.py
│ │ ├── test_orientations.py
│ │ ├── test_persistence.py
│ │ ├── test_reference.py
│ │ ├── test_reflections.py
│ │ └── test_ub.py
├── ub
│ ├── __init__.py
│ ├── calc.py
│ ├── calcstate.py
│ ├── crystal.py
│ ├── fitting.py
│ ├── orientations.py
│ ├── persistence.py
│ ├── reference.py
│ ├── reflections.py
│ └── ub.py
└── util.py
├── diffcmd
├── __init__.py
├── diffcalc_launcher.py
├── diffcmd_utils.py
├── ipython.py
├── ipythonmagic.py
├── make_manual.py
├── start.py
└── tests
│ ├── __init__.py
│ └── test_ipython.py
├── doc
├── Makefile
├── docs-build-diffcalc_doc-linux.launch
├── references
├── source
│ ├── ACKS.rst
│ ├── conf.py
│ ├── developer
│ │ ├── contents.rst
│ │ ├── development.rst
│ │ ├── intro.rst
│ │ ├── package.rst
│ │ ├── quickstart_api.rst
│ │ └── quickstart_setup_environment
│ ├── diffcalc_pdf.png
│ ├── diffcalc_web.png
│ ├── index.rst
│ ├── vliegmanual
│ │ ├── contents.rst
│ │ ├── images
│ │ │ ├── fix.png
│ │ │ ├── sixcircle_gamma_on_arm.pdf
│ │ │ ├── sixcircle_gamma_on_arm.png
│ │ │ ├── sixcircle_gamma_on_arm.ppt
│ │ │ ├── unit_cell.pdf
│ │ │ └── unit_cell.png
│ │ └── vliegmanual.rst
│ ├── youmanual.rst
│ ├── youmanual_images
│ │ └── 4s_2d_diffractometer.png
│ └── youmanual_template.rst
└── tmp
│ ├── constraints.txt
│ ├── extensions_to_yous_paper.wxm
│ └── i16_non_diffcalc_manual.txt
├── install-jython-environment.sh
├── integration_checks.py
├── model
├── README.txt
├── fivec.fxw
├── fivec.wcfg
├── fivec.wrl
├── sixc.fxw
├── sixc.wcfg
├── sixc.wrl
├── sixc_horizontal.fxw
├── sixc_horizontal.wrl
└── vrml_animator.py
├── numjy
├── __init__.py
├── jama_matrix_wrapper.py
└── linalg.py
├── setup.py
├── simplejson
├── __init__.py
├── _speedups.c
├── decoder.py
├── encoder.py
├── ordered_dict.py
├── scanner.py
└── tool.py
├── startup
├── __init__.py
├── _common_imports.py
├── _demo.py
├── _make_sixcircle_manual.py
├── api
│ ├── __init__.py
│ └── sixcircle.py
├── b16.py
├── beamlinespecific
│ ├── __init__.py
│ ├── azihkl.py
│ ├── conic_scannables.py
│ └── i21.py
├── fivecircle.py
├── fourcircle.py
├── i06.py
├── i07EH1h.py
├── i07EH1v.py
├── i07EH2v.py
├── i10.py
├── i13.py
├── i16.py
├── i16robot.py
├── i21.py
└── sixcircle.py
├── todo.txt
└── tox.ini
/.cache/v/cache/lastfailed:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Diffcalc build
2 |
3 | on:
4 | push:
5 | pull_request:
6 |
7 | jobs:
8 | test:
9 | runs-on: ubuntu-latest
10 | strategy:
11 | matrix:
12 | flavour: ['python', 'jython']
13 | python-version: [2.7]
14 |
15 | steps:
16 | - uses: actions/checkout@v2
17 | - name: Set up Python ${{ matrix.python-version }}
18 | uses: actions/setup-python@v2
19 | with:
20 | python-version: ${{ matrix.python-version }}
21 | if: matrix.flavour == 'python'
22 |
23 | - name: Install Python packages
24 | run: |
25 | pip install pytest==3.10.1; pip install pytest-xdist==1.26.1; pip install scipy==1.2.1; pip install nose==1.3.7; pip install mock==3.0.5
26 | echo "PYTEST=pytest -W ignore::PendingDeprecationWarning" >> $GITHUB_ENV
27 | if: matrix.flavour == 'python'
28 |
29 | - name: Install Jython
30 | run: |
31 | source install-jython-environment.sh
32 | echo "PYTEST=$HOME/jython/bin/jython -m pytest" >> $GITHUB_ENV
33 | echo "CLASSPATH=$PWD/jama-1.0.3.jar:$PWD/commons-math3-3.6.1.jar" >> $GITHUB_ENV
34 | if: matrix.flavour == 'jython'
35 |
36 | - name: Tests
37 | run: |
38 | echo Running $PYTEST
39 | $PYTEST
40 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | *~
3 | *.pyc
4 | doc/build/
5 | .pydevproject
6 | .project
7 | .tox
8 | .DS_Store
9 | .idea
10 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | diffcalc
4 |
5 |
6 |
7 |
8 |
9 | org.python.pydev.PyDevBuilder
10 |
11 |
12 |
13 |
14 |
15 | org.python.pydev.pythonNature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.settings/com.wdev91.eclipse.copyright.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Diamond Light Source Ltd.
4 | .]]>
19 |
24 |
29 |
30 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | encoding//doc/source/conf.py=utf-8
3 | encoding/=UTF-8
4 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.runtime.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | line.separator=\n
3 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | test-all: test-python test-jython test-integration test-launcher
3 |
4 | test-python:
5 | py.test
6 |
7 | test-jython:
8 | export CLASSPATH=$(HOME)/lib/Jama-1.0.3.jar:$(CLASSPATH); echo $$CLASSPATH; $(HOME)/jython/bin/py.test
9 |
10 | test-integration:
11 | py.test --boxed integration_checks.py
12 |
13 | test-launcher:
14 | ./diffcalc.py --help
15 | ./diffcalc.py --modules
16 | ./diffcalc.py --non-interactive --python sixcircle
17 |
18 | install-jython:
19 | ./install-jython-environment.sh
20 |
21 | doc-source:
22 | ./diffcalc.py --non-interactive --make-manuals-source
23 |
24 | doc-html:
25 | cd doc; make html
26 |
27 | doc-pdf:
28 | cd doc; make pdf
29 |
30 | doc-all:
31 | cd doc; make all
32 |
33 | doc-clean:
34 | cd doc; make clean
35 |
36 | help:
37 | @echo
38 | @echo "Please use \`make ' where is one of"
39 | @echo
40 | @echo " test-all"
41 | @echo " test-python"
42 | @echo " test-jython"
43 | @echo " test-integration"
44 | @echo " test-launcher"
45 | @echo " install-jython"
46 | @echo
47 | @echo " doc-source : to expand *_template.rst to *.rst"
48 | @echo " doc-html"
49 | @echo " doc-pdf"
50 | @echo " doc-all"
51 | @echo " doc-clean"
52 | @echo
53 |
--------------------------------------------------------------------------------
/buckminster.cspec:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/component.def:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
--------------------------------------------------------------------------------
/diffcalc.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | import sys
4 |
5 | from diffcmd.diffcalc_launcher import main
6 |
7 |
8 | if __name__ == '__main__':
9 | sys.exit(main())
--------------------------------------------------------------------------------
/diffcalc/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/__init__.py
--------------------------------------------------------------------------------
/diffcalc/dc/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/dc/__init__.py
--------------------------------------------------------------------------------
/diffcalc/dc/common.py:
--------------------------------------------------------------------------------
1 | from diffcalc.util import allnum, command, DiffcalcException
2 |
3 |
4 | def sim(scn, hkl):
5 | """sim hkl scn -- simulates moving scannable (not all)
6 | """
7 | if not isinstance(hkl, (tuple, list)):
8 | raise TypeError()
9 |
10 | if not allnum(hkl):
11 | raise TypeError()
12 |
13 | try:
14 | print scn.simulateMoveTo(hkl)
15 | except AttributeError:
16 | raise TypeError(
17 | "The first argument does not support simulated moves")
18 |
19 | def energy_to_wavelength(energy):
20 | try:
21 | return 12.39842 / energy
22 | except ZeroDivisionError:
23 | raise DiffcalcException(
24 | "Cannot calculate hkl position as Energy is set to 0")
--------------------------------------------------------------------------------
/diffcalc/dc/dcvlieg.py:
--------------------------------------------------------------------------------
1 | from diffcalc.dc.common import energy_to_wavelength
2 |
3 | from diffcalc import settings
4 | from diffcalc.hkl.vlieg.transform import VliegTransformSelector,\
5 | TransformCommands, VliegPositionTransformer
6 | from diffcalc.dc.help import compile_extra_motion_commands_for_help
7 | import diffcalc.hkl.vlieg.calc
8 |
9 |
10 | # reload to aid testing only
11 | import diffcalc.ub.ub as _ub
12 | reload(_ub)
13 | from diffcalc import hardware as _hardware
14 | #reload(_hardware)
15 | import diffcalc.hkl.vlieg.hkl as _hkl
16 | reload(_hkl)
17 |
18 | from diffcalc.ub.ub import * # @UnusedWildImport
19 | from diffcalc.hardware import * # @UnusedWildImport
20 | from diffcalc.hkl.vlieg.hkl import * # @UnusedWildImport
21 | from diffcalc.gdasupport.scannable.sim import sim
22 |
23 | _transform_selector = VliegTransformSelector()
24 | _transform_commands = TransformCommands(_transform_selector)
25 | _transformer = VliegPositionTransformer(settings.geometry, settings.hardware,
26 | _transform_selector)
27 |
28 | transform = _transform_commands.transform
29 | transforma = _transform_commands.transforma
30 | transformb = _transform_commands.transformb
31 | transformc = _transform_commands.transformc
32 |
33 |
34 | on = 'on'
35 | off = 'off'
36 | auto = 'auto'
37 | manual = 'manual'
38 |
39 | def hkl_to_angles(h, k, l, energy=None):
40 | """Convert a given hkl vector to a set of diffractometer angles"""
41 | if energy is None:
42 | energy = settings.hardware.get_energy() # @UndefinedVariable
43 |
44 | position, params = hklcalc.hklToAngles(h, k, l, energy_to_wavelength(energy))
45 | position = _transformer.transform(position)
46 | angle_tuple = settings.geometry.internal_position_to_physical_angles(position) # @UndefinedVariable
47 | angle_tuple = settings.hardware.cut_angles(angle_tuple) # @UndefinedVariable
48 |
49 | return angle_tuple, params
50 |
51 |
52 | def angles_to_hkl(angleTuple, energy=None):
53 | """Converts a set of diffractometer angles to an hkl position
54 | ((h, k, l), paramDict)=angles_to_hkl(self, (a1, a2,aN), energy=None)"""
55 | if energy is None:
56 | energy = settings.hardware.get_energy() # @UndefinedVariable
57 |
58 | i_pos = settings.geometry.physical_angles_to_internal_position(angleTuple) # @UndefinedVariable
59 | return hklcalc.anglesToHkl(i_pos, energy_to_wavelength(energy))
60 |
61 |
62 | settings.ubcalc_strategy = diffcalc.hkl.vlieg.calc.VliegUbCalcStrategy()
63 | settings.angles_to_hkl_function = diffcalc.hkl.vlieg.calc.vliegAnglesToHkl
64 | settings.include_sigtau = True
65 |
66 | ub_commands_for_help = _ub.commands_for_help
67 |
68 | hkl_commands_for_help = (_hkl.commands_for_help +
69 | _hardware.commands_for_help +
70 | ['Transform',
71 | transform,
72 | transforma,
73 | transformb,
74 | transformc] +
75 | compile_extra_motion_commands_for_help())
76 |
77 |
--------------------------------------------------------------------------------
/diffcalc/dc/dcwillmot.py:
--------------------------------------------------------------------------------
1 | # This file differs from dcyou in only two places
2 |
3 | from diffcalc import settings
4 | from diffcalc.dc.common import energy_to_wavelength
5 | from diffcalc.dc.help import compile_extra_motion_commands_for_help
6 | import diffcalc.hkl.willmott.calc
7 |
8 |
9 | # reload to aid testing only
10 | from diffcalc.ub import ub as _ub
11 | reload(_ub)
12 | from diffcalc import hardware as _hardware
13 | #reload(_hardware)
14 | from diffcalc.hkl.you import hkl as _hkl
15 | reload(_hkl)
16 |
17 | from diffcalc.ub.ub import * # @UnusedWildImport
18 | from diffcalc.hardware import * # @UnusedWildImport
19 | from diffcalc.hkl.willmot.hkl import * # @UnusedWildImport
20 | from diffcalc.gdasupport.scannable.sim import sim
21 |
22 | def hkl_to_angles(h, k, l, energy=None):
23 | """Convert a given hkl vector to a set of diffractometer angles"""
24 | if energy is None:
25 | energy = settings.hardware.get_energy() # @UndefinedVariable
26 |
27 | (pos, params) = hklcalc.hklToAngles(h, k, l, energy_to_wavelength(energy))
28 | angle_tuple = settings.geometry.internal_position_to_physical_angles(pos) # @UndefinedVariable
29 | angle_tuple = settings.hardware.cut_angles(angle_tuple) # @UndefinedVariable
30 |
31 | return angle_tuple, params
32 |
33 | def angles_to_hkl(angleTuple, energy=None):
34 | """Converts a set of diffractometer angles to an hkl position
35 | ((h, k, l), paramDict)=angles_to_hkl(self, (a1, a2,aN), energy=None)"""
36 | if energy is None:
37 | energy = settings.hardware.get_energy() # @UndefinedVariable
38 | i_pos = settings.geometry.physical_angles_to_internal_position(angleTuple) # @UndefinedVariable
39 | return hklcalc.anglesToHkl(i_pos, energy_to_wavelength(energy))
40 |
41 | settings.ubcalc_strategy = diffcalc.hkl.willmott.calc.WillmottHorizontalUbCalcStrategy()
42 | settings.angles_to_hkl_function = diffcalc.hkl.willmott.calc.angles_to_hkl
43 |
44 |
45 | ub_commands_for_help = _ub.commands_for_help
46 |
47 | hkl_commands_for_help = _hkl.commands_for_help + _hardware.commands_for_help + compile_extra_motion_commands_for_help()
48 |
--------------------------------------------------------------------------------
/diffcalc/dc/dcyou.py:
--------------------------------------------------------------------------------
1 | from diffcalc import settings
2 | from diffcalc.dc.common import energy_to_wavelength
3 | from diffcalc.dc.help import compile_extra_motion_commands_for_help
4 |
5 | import diffcalc.hkl.you.calc
6 | settings.ubcalc_strategy = diffcalc.hkl.you.calc.YouUbCalcStrategy()
7 | settings.angles_to_hkl_function = diffcalc.hkl.you.calc.youAnglesToHkl
8 |
9 | # reload to aid testing only
10 | from diffcalc.ub import ub as _ub
11 |
12 | reload(_ub)
13 | from diffcalc import hardware as _hardware
14 | #reload(_hardware)
15 | from diffcalc.hkl.you import hkl as _hkl
16 | reload(_hkl)
17 |
18 | from diffcalc.ub.ub import * # @UnusedWildImport
19 | from diffcalc.hardware import * # @UnusedWildImport
20 | from diffcalc.hkl.you.hkl import * # @UnusedWildImport
21 |
22 |
23 | class DiffractometerYouCalculator(object):
24 |
25 | def __init__(self, diffractometerObject, diffcalcObject):
26 | self.diffhw = diffractometerObject
27 | self.geometry = diffcalcObject
28 |
29 |
30 | def hkl_to_angles(self, h, k, l, energy=None):
31 | """Convert a given hkl vector to a set of diffractometer angles
32 |
33 | return angle tuple and params dictionary
34 |
35 | """
36 | if energy is None:
37 | energy = self.diffhw.get_energy() # @UndefinedVariable
38 |
39 | (pos, params) = hklcalc.hklToAngles(h, k, l, energy_to_wavelength(energy))
40 | angle_tuple = self.geometry.internal_position_to_physical_angles(pos) # @UndefinedVariable
41 | angle_tuple = self.diffhw.cut_angles(angle_tuple) # @UndefinedVariable
42 |
43 | return angle_tuple, params
44 |
45 |
46 | def hkl_list_to_angles(self, hkl_list, energy=None):
47 | """Convert a given hkl vector to a set of diffractometer angles
48 |
49 | return angle tuple and params dictionary
50 |
51 | """
52 | if energy is None:
53 | energy = self.diffhw.get_energy() # @UndefinedVariable
54 |
55 | (pos, params) = hklcalc.hklListToAngles(hkl_list, energy_to_wavelength(energy))
56 | angle_tuple = self.geometry.internal_position_to_physical_angles(pos) # @UndefinedVariable
57 | angle_tuple = self.diffhw.cut_angles(angle_tuple) # @UndefinedVariable
58 |
59 | return angle_tuple, params
60 |
61 |
62 | def angles_to_hkl(self, angleTuple, energy=None):
63 | """Converts a set of diffractometer angles to an hkl position
64 |
65 | Return hkl tuple and params dictionary
66 |
67 | """
68 | if energy is None:
69 | energy = self.diffhw.get_energy() # @UndefinedVariable
70 | i_pos = self.geometry.physical_angles_to_internal_position(angleTuple) # @UndefinedVariable
71 | return hklcalc.anglesToHkl(i_pos, energy_to_wavelength(energy))
72 |
73 |
74 | def hkl_to_angles(h, k, l, energy=None):
75 | _dcyou = DiffractometerYouCalculator(settings.hardware, settings.geometry)
76 | return _dcyou.hkl_to_angles(h, k, l, energy)
77 |
78 | def hkl_list_to_angles(hkl, energy=None):
79 | _dcyou = DiffractometerYouCalculator(settings.hardware, settings.geometry)
80 | return _dcyou.hkl_list_to_angles(hkl, energy)
81 |
82 | def angles_to_hkl(angleTuple, energy=None):
83 | _dcyou = DiffractometerYouCalculator(settings.hardware, settings.geometry)
84 | return _dcyou.angles_to_hkl(angleTuple, energy)
85 |
86 |
87 |
88 | ub_commands_for_help = _ub.commands_for_help
89 | hkl_commands_for_help = _hkl.commands_for_help + _hardware.commands_for_help + compile_extra_motion_commands_for_help()
90 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/gdasupport/__init__.py
--------------------------------------------------------------------------------
/diffcalc/gdasupport/minigda/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/gdasupport/minigda/__init__.py
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/gdasupport/scannable/__init__.py
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/base.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | try:
20 | from gda.device.scannable import ScannableMotionBase \
21 | as PseudoDevice
22 | except ImportError:
23 | from diffcalc.gdasupport.minigda.scannable import \
24 | ScannableBase as PseudoDevice
25 |
26 |
27 | class ScannableGroup(PseudoDevice):
28 |
29 | def __init__(self, name, motorList):
30 |
31 | self.setName(name)
32 | # Set input format
33 | motorNames = []
34 | for scn in motorList:
35 | motorNames.append(scn.getName())
36 | self.setInputNames(motorNames)
37 | # Set output format
38 | format = []
39 | for motor in motorList:
40 | format.append(motor.getOutputFormat()[0])
41 | self.setOutputFormat(format)
42 | self.__motors = motorList
43 |
44 | def asynchronousMoveTo(self, position):
45 | # if input has any Nones, then replace these with the current positions
46 | if None in position:
47 | position = list(position)
48 | current = self.getPosition()
49 | for idx, val in enumerate(position):
50 | if val is None:
51 | position[idx] = current[idx]
52 |
53 | for scn, pos in zip(self.__motors, position):
54 | scn.asynchronousMoveTo(pos)
55 |
56 | def getPosition(self):
57 | return [scn.getPosition() for scn in self.__motors]
58 |
59 | def isBusy(self):
60 | for scn in self.__motors:
61 | if scn.isBusy():
62 | return True
63 | return False
64 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/mock.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | try:
20 | from gda.device.scannable import ScannableMotionBase
21 | except ImportError:
22 | from diffcalc.gdasupport.minigda.scannable import \
23 | ScannableBase as ScannableMotionBase
24 |
25 |
26 | class MockMotor(ScannableMotionBase):
27 |
28 | def __init__(self, name='mock'):
29 | self.pos = 0.0
30 | self._busy = False
31 | self.name = name
32 |
33 | def asynchronousMoveTo(self, pos):
34 | self._busy = True
35 | self.pos = float(pos)
36 |
37 | def getPosition(self):
38 | return self.pos
39 |
40 | def isBusy(self):
41 | return self._busy
42 |
43 | def makeNotBusy(self):
44 | self._busy = False
45 |
46 | def getOutputFormat(self):
47 | return ['%f']
48 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/parameter.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 | from diffcalc import settings
19 |
20 | try:
21 | from gda.device.scannable import ScannableMotionBase
22 | except ImportError:
23 | from diffcalc.gdasupport.minigda.scannable import \
24 | ScannableBase as ScannableMotionBase
25 |
26 |
27 | class DiffractionCalculatorParameter(ScannableMotionBase):
28 |
29 | def __init__(self, name, parameterName, parameter_manager):
30 |
31 | self.parameter_manager = parameter_manager
32 | self.parameterName = parameterName
33 | self._ext_name = settings.geometry.map_to_external_name(parameterName)
34 |
35 | self.setName(name)
36 | self.setInputNames([parameterName,])
37 | self.setOutputFormat(['%5.5f',])
38 | self.setLevel(3)
39 |
40 | def asynchronousMoveTo(self, value):
41 | _, cons_value = settings.geometry.map_to_internal_position(self._ext_name, value)
42 | self.parameter_manager.set_constraint(self.parameterName, cons_value)
43 |
44 | def getPosition(self):
45 | value = self.parameter_manager.get_constraint(self.parameterName)
46 | _, cons_value = settings.geometry.map_to_internal_position(self.parameterName, value)
47 | return [cons_value,]
48 |
49 | def isBusy(self):
50 | return False
51 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/parametrised_hkl.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2019 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 | from diffcalc.gdasupport.scannable.hkl import Hkl
19 | from diffcalc import settings
20 | from diffcalc.util import getMessageFromException
21 | from pprint import pformat
22 |
23 |
24 | class ParametrisedHKLScannable(Hkl):
25 |
26 | def __init__(self, name, inputNames, num_cached_params=0, idx_cached_pos=[], tol=1e-4):
27 |
28 | from diffcalc.dc import dcyou as _dc
29 | Hkl.__init__(self, name, settings.axes_scannable_group, _dc, None)
30 |
31 | self.setName(name)
32 | self.setInputNames(inputNames)
33 | self.setOutputFormat(['%7.5f'] * len(inputNames))
34 |
35 | self.parameter_to_hkl = self._diffcalc.angles_to_hkl
36 | self.hkl_to_parameter = self._diffcalc.hkl_to_angles
37 | self.num_cached_params = num_cached_params
38 | self.cached_params = None
39 | self.idx_cached_pos = idx_cached_pos
40 | self.tol = tol
41 |
42 | self.completeInstantiation()
43 | self.setAutoCompletePartialMoveToTargets(True)
44 | self.dynamic_class_doc = 'Parametrised HKL Scannable'
45 |
46 |
47 | def rawAsynchronousMoveTo(self, params):
48 | self.cached_params = params[-self.num_cached_params:]
49 | tmp_pos = self.diffhw.getPosition() # a tuple
50 | cached_pos = {idx: tmp_pos[idx] for idx in self.idx_cached_pos}
51 | hkl = self.parameter_to_hkl(params)
52 | if isinstance(hkl[0], (int, float)):
53 | (calc_pos, _) = self._diffcalc.hkl_to_angles(*hkl)
54 | elif isinstance(hkl[0], (tuple, list)):
55 | (calc_pos, _) = self._diffcalc.hkl_list_to_angles(hkl)
56 | final_pos = tuple(cached_pos[idx] if idx in cached_pos else val for idx, val in enumerate(calc_pos))
57 | calc_hkl, _ = self._diffcalc.angles_to_hkl(calc_pos)
58 | final_hkl, _ = self._diffcalc.angles_to_hkl(final_pos)
59 | if max([abs(i - j) for i,j in zip(calc_hkl, final_hkl)]) > self.tol:
60 | print("Warning: Final hkl position %s exceeds tolerance %f compared to calculated hkl %s"
61 | % (pformat(final_hkl), self.tol, pformat(calc_hkl)))
62 | self.diffhw.asynchronousMoveTo(final_pos)
63 |
64 |
65 | def rawGetPosition(self):
66 | pos = self.diffhw.getPosition() # a tuple
67 | hkl, _ = self._diffcalc.angles_to_hkl(pos)
68 | pos = self.hkl_to_parameter(list(hkl))
69 | return pos
70 |
71 |
72 | def simulateMoveTo(self, pos):
73 | lines = ['%s:' % self.name]
74 | hkl = self.parameter_to_hkl(pos)
75 | if isinstance(hkl[0], (tuple, list)):
76 | (angles, _) = self._diffcalc.hkl_list_to_angles(hkl)
77 | hkl, _ = self._diffcalc.angles_to_hkl(angles)
78 | #fmt_scn_params = ' '.join([' : %9.4f'] + ['%.4f'] * (len(pos) - 1))
79 | #lines.append(' ' + self.name + fmt_scn_params % tuple(pos))
80 | width = max(len(k) for k in self.inputNames)
81 | fmt = ' %' + str(width) + 's : % 9.4f'
82 | for idx, k in enumerate(self.inputNames):
83 | lines.append(fmt % (k, pos[idx]))
84 | lines.append('\n ' + 'hkl'.rjust(width) + ' : %9.4f %.4f %.4f' % (hkl[0], hkl[1], hkl[2]))
85 | res = Hkl.simulateMoveTo(self, hkl)
86 | lines.append(res)
87 | return '\n'.join(lines)
88 |
89 |
90 | def __repr__(self):
91 | lines = ['%s:' % self.name]
92 | pos = self.diffhw.getPosition()
93 | try:
94 | (hkl, params) = self._diffcalc.angles_to_hkl(pos)
95 | scn_params = self.hkl_to_parameter(list(hkl))
96 | except Exception, e:
97 | return "<%s: %s>" % (self.name, getMessageFromException(e))
98 |
99 | width = max(len(k) for k in params)
100 | fmt_scn_params = ' '.join([' : %9.4f'] + ['%.4f'] * (len(scn_params) - 1))
101 | lines.append(' ' + self.name.rjust(width) + fmt_scn_params % scn_params)
102 | lines.append(' ' + 'hkl'.rjust(width) + ' : %9.4f %.4f %.4f' % (hkl[0], hkl[1], hkl[2]))
103 | lines[-1] = lines[-1] + '\n'
104 | fmt = ' %' + str(width) + 's : % 9.4f'
105 | for k in sorted(params):
106 | lines.append(fmt % (k, params[k]))
107 | return '\n'.join(lines)
108 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/setref2.py:
--------------------------------------------------------------------------------
1 | '''
2 | Created on 1 Nov 2018
3 |
4 | @author: voo82357
5 | '''
6 | from diffcalc.util import allnum, DiffcalcException, TODEG
7 | from diffcalc.gdasupport.scannable.sim import sim
8 | from diffcalc.util import getInputWithDefault
9 |
10 | def setref2(scn, hkl):
11 | """setref2 scn [h k l] -- setup hkloffset scannable to scan for second reflection [hkl]"""
12 |
13 | if not isinstance(hkl, (tuple, list)):
14 | raise DiffcalcException("Please specify hkl values for a second reference reflection to search.")
15 |
16 | if not allnum(hkl):
17 | raise DiffcalcException("Please specify numeric values for hkl.")
18 |
19 | try:
20 | hkl_ref = scn._diffcalc._ub.ubcalc.get_reflection(0)[0]
21 | except IndexError:
22 | raise DiffcalcException("Please add one reference reflection into the reflection list.")
23 | pol, az, sc = scn._diffcalc._ub.ubcalc.calc_offset_for_hkl(hkl, hkl_ref)
24 | hkl_rot = [sc * val for val in hkl_ref]
25 | hkl_sc = hkl_rot[:]
26 | hkl_rot.extend([pol * TODEG, az * TODEG])
27 | hkl_sc.extend([0, 0])
28 |
29 | print ('\nRescaled hkl reference for second reflection : %9.4f %.4f %.4f' % (hkl_sc[0], hkl_sc[1], hkl_sc[2]))
30 | print (' polar and azimuthal rotation angles : %9.4f %.4f\n' % (pol * TODEG, az * TODEG))
31 |
32 | sim(scn, hkl_sc)
33 | print ('IMPORTANT: Applying subsequent polar and azimuthal rotations might fail. In this case, please manually\n'
34 | ' find accessible azimuthal rotation range to scan for second reference reflection.')
35 | reply = getInputWithDefault('Move to rescaled hkl position', 'y')
36 | if reply in ('y', 'Y', 'yes'):
37 | scn.asynchronousMoveTo(hkl_sc)
38 | else:
39 | print 'Aborting'
40 | return
41 |
42 | sim(scn, hkl_rot)
43 | reply = getInputWithDefault('Apply polar and azimuthal rotations', 'y')
44 | if reply in ('y', 'Y', 'yes'):
45 | scn.asynchronousMoveTo(hkl_rot)
46 | else:
47 | print 'Aborting'
48 | return
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/sim.py:
--------------------------------------------------------------------------------
1 | '''
2 | Created on 7 May 2016
3 |
4 | @author: walton
5 | '''
6 |
7 | def sim(scn, hkl):
8 | """sim hkl scn -- simulates moving scannable (not all)
9 | """
10 | try:
11 | print scn.simulateMoveTo(hkl)
12 | except AttributeError:
13 | raise TypeError(
14 | "The first argument does not support simulated moves")
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/simulation.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import time
20 | from math import sqrt, pi, exp
21 |
22 | try:
23 | from gda.device.scannable import ScannableMotionBase \
24 | as PseudoDevice
25 | except ImportError:
26 | from diffcalc.gdasupport.minigda.scannable import \
27 | ScannableBase as PseudoDevice
28 |
29 | from diffcalc.ub.crystal import CrystalUnderTest
30 | from diffcalc.hkl.you.calc import youAnglesToHkl
31 | from diffcalc.hkl.vlieg.calc import vliegAnglesToHkl
32 | from diffcalc.hkl.you.geometry import calcCHI, calcPHI
33 |
34 | TORAD = pi / 180
35 | TODEG = 180 / pi
36 |
37 |
38 | class Equation(object):
39 |
40 | def __call__(self, dh, dk, dl):
41 | raise Exception('Abstract')
42 |
43 | def __str__(self):
44 | "Abstract equation"
45 |
46 |
47 | class Gaussian(Equation):
48 |
49 | def __init__(self, variance):
50 | self.variance = float(variance)
51 |
52 | def __call__(self, dh, dk, dl):
53 | dr_squared = dh * dh + dk * dk + dl * dl
54 | return (1 / sqrt(2 * pi * self.variance) *
55 | exp(-dr_squared / (2 * self.variance)))
56 |
57 |
58 | class SimulatedCrystalCounter(PseudoDevice):
59 |
60 | def __init__(self, name, diffractometerScannable, geometryPlugin,
61 | wavelengthScannable, equation=Gaussian(.01), engine='you'):
62 | self.setName(name)
63 | self.setInputNames([name + '_count'])
64 | self.setOutputFormat(['%7.5f'])
65 | self.exposureTime = 1
66 | self.pause = True
67 | self.diffractometerScannable = diffractometerScannable
68 | self.geometry = geometryPlugin
69 | self.wavelengthScannable = wavelengthScannable
70 | self.equation = equation
71 | self.engine = engine
72 |
73 | self.cut = None
74 | self.UB = None
75 | self.chiMissmount = 0.
76 | self.phiMissmount = 0.
77 | self.setCrystal('cubic', 1, 1, 1, 90, 90, 90)
78 |
79 | def setCrystal(self, name, a, b, c, alpha, beta, gamma):
80 | self.cut = CrystalUnderTest(name, a, b, c, alpha, beta, gamma)
81 | self.calcUB()
82 |
83 | def setChiMissmount(self, chi):
84 | self.chiMissmount = chi
85 | self.calcUB()
86 |
87 | def setPhiMissmount(self, phi):
88 | self.phiMissmount = phi
89 | self.calcUB()
90 |
91 | def calcUB(self):
92 | CHI = calcCHI(self.chiMissmount * TORAD)
93 | PHI = calcPHI(self.phiMissmount * TORAD)
94 | self.UB = CHI * PHI * self.cut.B
95 |
96 | def asynchronousMoveTo(self, exposureTime):
97 | self.exposureTime = exposureTime
98 | if self.pause:
99 | time.sleep(exposureTime) # Should not technically block!
100 |
101 | def getPosition(self):
102 | h, k, l = self.getHkl()
103 | dh, dk, dl = h - round(h), k - round(k), l - round(l)
104 | count = self.equation(dh, dk, dl)
105 | #return self.exposureTime, count*self.exposureTime
106 | return count * self.exposureTime
107 |
108 | def getHkl(self):
109 | pos = self.geometry.physical_angles_to_internal_position(
110 | self.diffractometerScannable.getPosition())
111 | pos.changeToRadians()
112 | wavelength = self.wavelengthScannable.getPosition()
113 | if self.engine.lower() == 'vlieg':
114 | return vliegAnglesToHkl(pos, wavelength, self.UB)
115 | elif self.engine.lower() == 'you':
116 | return youAnglesToHkl(pos, wavelength, self.UB)
117 | else:
118 | raise ValueError(self.engine)
119 |
120 | def isBusy(self):
121 | return False
122 |
123 | def __str__(self):
124 | return self.__repr__()
125 |
126 | def __repr__(self):
127 | s = 'simulated crystal detector: %s\n' % self.getName()
128 | h, k, l = self.getHkl()
129 | s += ' h : %f\n' % h
130 | s += ' k : %f\n' % k
131 | s += ' l : %f\n' % l
132 | s += self.cut.__str__() + '\n'
133 | s += "chi orientation: %s\n" % self.chiMissmount
134 | s += "phi orientation: %s\n" % self.phiMissmount
135 | ub = self.UB.tolist()
136 | s += "UB:\n"
137 | s += " % 18.13f% 18.13f% 18.12f\n" % (ub[0][0], ub[0][1], ub[0][2])
138 | s += " % 18.13f% 18.13f% 18.12f\n" % (ub[1][0], ub[1][1], ub[1][2])
139 | s += " % 18.13f% 18.13f% 18.12f\n" % (ub[2][0], ub[2][1], ub[2][2])
140 | return s
141 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/slave_driver.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from math import pi, tan, sin, atan, cos, atan2
20 |
21 | TORAD = pi / 180
22 | TODEG = 180 / pi
23 |
24 |
25 | class SlaveScannableDriver(object):
26 |
27 | def __init__(self, scannables):
28 | self.scannables = scannables
29 |
30 | def isBusy(self):
31 | for scn in self.scannables:
32 | if scn.isBusy():
33 | return True
34 | return False
35 |
36 | def waitWhileBusy(self):
37 | for scn in self.scannables:
38 | scn.waitWhileBusy()
39 |
40 | def triggerAsynchronousMove(self, triggerPos):
41 | nu = self.slaveFromTriggerPos(triggerPos)
42 | for scn in self.scannables:
43 | scn.asynchronousMoveTo(nu)
44 |
45 | def getPosition(self):
46 | return self.scannables[0].getPosition()
47 |
48 | def slaveFromTriggerPos(self, triggerPos):
49 | raise Exception("Abstract")
50 |
51 | def getScannableNames(self):
52 | return [scn.name for scn in self.scannables]
53 |
54 | def getScannable(self, name):
55 | for scn in self.scannables:
56 | if scn.getName() == name:
57 | return scn
58 | return None
59 |
60 | def getOutputFormat(self):
61 | return [list(scn.outputFormat)[0] for scn in self.scannables]
62 |
63 | def getPositions(self):
64 | return [float(scn.getPosition()) for scn in self.scannables]
65 |
66 |
67 | """
68 | Based on: Elias Vlieg, "A (2+3)-Type Surface Diffractometer: Mergence of the
69 | z-axis and (2+2)-Type Geometries", J. Appl. Cryst. (1998). 31. 198-203
70 | """
71 |
72 |
73 | class NuDriverForSixCirclePlugin(SlaveScannableDriver):
74 |
75 | def slaveFromTriggerPos(self, triggerPos):
76 |
77 | alpha, delta, gamma, _, _, _ = triggerPos
78 | alpha = alpha * TORAD
79 | delta = delta * TORAD
80 | gamma = gamma * TORAD
81 |
82 | ### Equation16 RHS ###
83 | rhs = -1 * tan(gamma - alpha) * sin(delta)
84 | nu = atan(rhs) # -pi/2 <= nu <= pi/2
85 | return nu * TODEG
86 |
87 |
88 | class NuDriverForWillmottHorizontalGeometry(SlaveScannableDriver):
89 |
90 | """
91 | Based on: Phillip Willmott, "Angle calculations for a (2+3)-type
92 | diffractometer: focus on area detectors", J. Appl. Cryst. (2011). 44.
93 | 73-83
94 | """
95 |
96 | def __init__(self, scannables, area_detector=False):
97 | SlaveScannableDriver.__init__(self, scannables)
98 | self.area_detector = area_detector
99 |
100 | def slaveFromTriggerPos(self, triggerPos):
101 |
102 | delta, gamma, omegah, _ = triggerPos
103 | delta *= TORAD
104 | gamma *= TORAD
105 | omegah *= TORAD
106 | if self.area_detector:
107 | nu = atan2(sin(delta - omegah), tan(gamma)) # (66)
108 | else:
109 | top = -sin(gamma) * sin(omegah)
110 | bot = (sin(omegah) * cos(gamma) * sin(delta) +
111 | cos(omegah) * cos(delta))
112 | nu = atan2(top, bot) # (61)
113 |
114 | print 'nu:', nu * TODEG
115 | return nu * TODEG
116 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/scannable/wavelength.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | try:
20 | from gdascripts.pd.dummy_pds import DummyPD
21 | except ImportError:
22 | from diffcalc.gdasupport.minigda.scannable import DummyPD
23 |
24 |
25 | class Wavelength(DummyPD):
26 |
27 | def __init__(self, name, energyScannable,
28 | energyScannableMultiplierToGetKeV=1):
29 | self.energyScannable = energyScannable
30 | self.energyScannableMultiplierToGetKeV = \
31 | energyScannableMultiplierToGetKeV
32 |
33 | DummyPD.__init__(self, name)
34 |
35 | def asynchronousMoveTo(self, pos):
36 | self.energyScannable.asynchronousMoveTo(
37 | (12.39842 / pos) / self.energyScannableMultiplierToGetKeV)
38 |
39 | def getPosition(self):
40 | energy = self.energyScannable.getPosition()
41 | if energy == 0:
42 | raise Exception(
43 | "The energy is 0, so no wavelength could be calculated.run_All()")
44 | return 12.39842 / (energy * self.energyScannableMultiplierToGetKeV)
45 |
46 | def isBusy(self):
47 | return self.energyScannable.isBusy()
48 |
49 | def waitWhileBusy(self):
50 | return self.energyScannable.waitWhileBusy()
51 |
--------------------------------------------------------------------------------
/diffcalc/gdasupport/you.py:
--------------------------------------------------------------------------------
1 | from diffcalc.gdasupport.scannable.diffractometer import DiffractometerScannableGroup
2 | from diffcalc.gdasupport.scannable.hkl import Hkl
3 | from diffcalc.gdasupport.scannable.hkloffset import HklOffset
4 | from diffcalc.gdasupport.scannable.simulation import SimulatedCrystalCounter
5 | from diffcalc.gdasupport.scannable.wavelength import Wavelength
6 | from diffcalc.gdasupport.scannable.parameter import DiffractionCalculatorParameter
7 |
8 |
9 | from diffcalc.dc import dcyou as _dc
10 | from diffcalc.dc.help import format_command_help
11 | from diffcalc.gdasupport.scannable.sr2 import Sr2
12 | from diffcalc.gdasupport.scannable.qtrans import Qtrans
13 | reload(_dc)
14 | from diffcalc.dc.dcyou import * # @UnusedWildImport
15 | from diffcalc import settings
16 |
17 | try:
18 | import gda # @UnusedImport @UnresolvedImport
19 | GDA = True
20 | except:
21 | GDA = False
22 |
23 | if not GDA:
24 | from diffcalc.gdasupport.minigda import command
25 | _pos = command.Pos()
26 | _scan = command.Scan(command.ScanDataPrinter())
27 |
28 | def pos(*args):
29 | """
30 | pos show position of all Scannables
31 | pos scn show position of scn
32 | pos scn targetmove scn to target (a number)
33 | """
34 | return _pos(*args)
35 |
36 | def scan(*args):
37 | """
38 | scan scn start stop step {scn {target}} {det t}
39 | """
40 | return _scan(*args)
41 |
42 |
43 | from diffcalc.gdasupport.scannable.sim import sim # @UnusedImport
44 |
45 | _scn_group = settings.axes_scannable_group
46 | _diff_scn_name = settings.geometry.name # @UndefinedVariable
47 | _energy_scannable = settings.energy_scannable
48 |
49 |
50 | # Create diffractometer scannable
51 | _diff_scn = DiffractometerScannableGroup(_diff_scn_name, _dc, _scn_group)
52 | globals()[_diff_scn_name] = _diff_scn
53 |
54 | # Create hkl scannables
55 | hkl = Hkl('hkl', _scn_group, _dc)
56 | h = hkl.h
57 | k = hkl.k
58 | l = hkl.l
59 |
60 | hkloffset = HklOffset('hkloffset', _scn_group, _dc)
61 | h_offset = hkloffset.h
62 | k_offset = hkloffset.k
63 | l_offset = hkloffset.l
64 | pol_offset = hkloffset.polar
65 | az_offset = hkloffset.azimuthal
66 |
67 | sr2 = Sr2('sr2', _scn_group, _dc)
68 |
69 | qtrans = Qtrans('qtrans', _scn_group, _dc)
70 |
71 | Hkl.dynamic_docstring = format_command_help(hkl_commands_for_help) # must be on the class
72 | ub.__doc__ = format_command_help(ub_commands_for_help)
73 |
74 | if settings.include_reference:
75 | _virtual_angles = ('theta', 'ttheta', 'qaz', 'alpha', 'naz', 'tau', 'psi', 'beta', 'betain', 'betaout')
76 | else:
77 | _virtual_angles = ('theta', 'ttheta', 'qaz', 'betain', 'betaout')
78 | hklverbose = Hkl('hklverbose', _scn_group, _dc, _virtual_angles)
79 |
80 |
81 | # Create wavelength scannable
82 | wl = Wavelength(
83 | 'wl', _energy_scannable, settings.energy_scannable_multiplier_to_get_KeV)
84 | if not GDA:
85 | wl.asynchronousMoveTo(1) # Angstrom
86 | _energy_scannable.level = 3
87 | wl.level = 3
88 |
89 |
90 | # Create simulated counter timer
91 | ct = SimulatedCrystalCounter('ct', _scn_group, settings.geometry, wl)
92 | ct.level = 10
93 |
94 |
95 | # Create constraint scannables
96 | def _create_constraint_scannable(con_name, scn_name=None):
97 | if not scn_name:
98 | scn_name = con_name
99 | return DiffractionCalculatorParameter(
100 | scn_name, con_name, _dc.constraint_manager)
101 |
102 | # Detector constraints
103 | def isconstrainable(name):
104 | return not constraint_manager.is_constraint_fixed(name)
105 |
106 | if isconstrainable('delta'): delta_con = _create_constraint_scannable('delta', 'delta_con')
107 | if isconstrainable('gam'): gam_con = _create_constraint_scannable('gam', 'gam_con')
108 | if isconstrainable('qaz'): qaz = _create_constraint_scannable('qaz')
109 | if isconstrainable('naz'): naz = _create_constraint_scannable('naz')
110 |
111 | # Reference constraints
112 | if settings.include_reference:
113 | alpha = _create_constraint_scannable('alpha')
114 | beta = _create_constraint_scannable('beta')
115 | psi = _create_constraint_scannable('psi')
116 | a_eq_b = 'a_eq_b'
117 | betain = _create_constraint_scannable('betain')
118 | betaout = _create_constraint_scannable('betaout')
119 | bin_eq_bout = 'bin_eq_bout'
120 |
121 | # Sample constraints
122 | if isconstrainable('mu'): mu_con = _create_constraint_scannable('mu', 'mu_con')
123 | if isconstrainable('eta'): eta_con = _create_constraint_scannable('eta', 'eta_con')
124 | if isconstrainable('chi'): chi_con = _create_constraint_scannable('chi', 'chi_con')
125 | if isconstrainable('phi'): phi_con = _create_constraint_scannable('phi', 'phi_con')
126 | if isconstrainable('mu') and isconstrainable('gam'): mu_is_gam = 'mu_is_gam'
127 | omega = _create_constraint_scannable('omega')
128 | bisect = 'bisect'
129 |
130 |
131 | # Cleanup other cruft
132 | del format_command_help
133 |
--------------------------------------------------------------------------------
/diffcalc/hkl/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/hkl/__init__.py
--------------------------------------------------------------------------------
/diffcalc/hkl/common.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 | from diffcalc.util import allnum
19 |
20 | def getNameFromScannableOrString(o):
21 | try: # it may be a scannable
22 | return o.getName()
23 | except AttributeError:
24 | return str(o)
25 | raise TypeError()
26 |
27 |
28 | class DummyParameterManager(object):
29 |
30 | def getParameterDict(self):
31 | return {}
32 |
33 | def _setParameter(self, name, value):
34 | raise KeyError(name)
35 |
36 | def _getParameter(self, name):
37 | raise KeyError(name)
38 |
39 | def update_tracked(self):
40 | pass
41 |
42 |
43 | def sim(self, scn, hkl):
44 | """sim hkl scn -- simulates moving scannable (not all)
45 | """
46 | if not isinstance(hkl, (tuple, list)):
47 | raise TypeError
48 |
49 | if not allnum(hkl):
50 | raise TypeError()
51 |
52 | try:
53 | print scn.simulateMoveTo(hkl)
54 | except AttributeError:
55 | raise TypeError("The first argument does not support simulated moves")
56 |
--------------------------------------------------------------------------------
/diffcalc/hkl/vlieg/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/hkl/vlieg/__init__.py
--------------------------------------------------------------------------------
/diffcalc/hkl/vlieg/hkl.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from diffcalc.hkl.common import getNameFromScannableOrString
20 | from diffcalc.util import command
21 | from diffcalc import settings
22 |
23 |
24 | from diffcalc.ub import ub
25 | from diffcalc.hkl.vlieg.calc import VliegHklCalculator
26 |
27 |
28 | __all__ = ['hklmode', 'setpar', 'trackalpha', 'trackgamma', 'trackphi',
29 | 'parameter_manager', 'hklcalc']
30 |
31 |
32 | hklcalc = VliegHklCalculator(ub.ubcalc)
33 |
34 | parameter_manager = hklcalc.parameter_manager
35 |
36 | def __str__(self):
37 | return hklcalc.__str__()
38 |
39 | @command
40 | def hklmode(num=None):
41 | """hklmode {num} -- changes mode or shows current and available modes and all settings""" #@IgnorePep8
42 |
43 | if num is None:
44 | print hklcalc.__str__()
45 | else:
46 | hklcalc.mode_selector.setModeByIndex(int(num))
47 | pm = hklcalc.parameter_manager
48 | print (hklcalc.mode_selector.reportCurrentMode() + "\n" +
49 | pm.reportParametersUsedInCurrentMode())
50 |
51 | def _setParameter(name, value):
52 | hklcalc.parameter_manager.set_constraint(name, value)
53 |
54 | def _getParameter(name):
55 | return hklcalc.parameter_manager.get_constraint(name)
56 |
57 | @command
58 | def setpar(scannable_or_string=None, val=None):
59 | """setpar {parameter_scannable {{val}} -- sets or shows a parameter'
60 | setpar {parameter_name {val}} -- sets or shows a parameter'
61 | """
62 |
63 | if scannable_or_string is None:
64 | #show all
65 | parameterDict = hklcalc.parameter_manager.getParameterDict()
66 | names = parameterDict.keys()
67 | names.sort()
68 | for name in names:
69 | print _representParameter(name)
70 | else:
71 | name = getNameFromScannableOrString(scannable_or_string)
72 | if val is None:
73 | _representParameter(name)
74 | else:
75 | oldval = _getParameter(name)
76 | _setParameter(name, float(val))
77 | print _representParameter(name, oldval, float(val))
78 |
79 | def _representParameter(name, oldval=None, newval=None):
80 | flags = ''
81 | if hklcalc.parameter_manager.isParameterTracked(name):
82 | flags += '(tracking hardware) '
83 | if settings.geometry.parameter_fixed(name): # @UndefinedVariable
84 | flags += '(fixed by geometry) '
85 | pm = hklcalc.parameter_manager
86 | if not pm.isParameterUsedInSelectedMode(name):
87 | flags += '(not relevant in this mode) '
88 | if oldval is None:
89 | val = _getParameter(name)
90 | if val is None:
91 | val = "---"
92 | else:
93 | val = str(val)
94 | return "%s: %s %s" % (name, val, flags)
95 | else:
96 | return "%s: %s --> %f %s" % (name, oldval, newval, flags)
97 |
98 | def _checkInputAndSetOrShowParameterTracking(name, b=None):
99 | """
100 | for track-parameter commands: If no args displays parameter settings,
101 | otherwise sets the tracking switch for the given parameter and displays
102 | settings.
103 | """
104 | # set if arg given
105 | if b is not None:
106 | hklcalc.parameter_manager.setTrackParameter(name, b)
107 | # Display:
108 | lastValue = _getParameter(name)
109 | if lastValue is None:
110 | lastValue = "---"
111 | else:
112 | lastValue = str(lastValue)
113 | flags = ''
114 | if hklcalc.parameter_manager.isParameterTracked(name):
115 | flags += '(tracking hardware)'
116 | print "%s: %s %s" % (name, lastValue, flags)
117 |
118 | @command
119 | def trackalpha(b=None):
120 | """trackalpha {boolean} -- determines wether alpha parameter will track alpha axis""" #@IgnorePep8
121 | _checkInputAndSetOrShowParameterTracking('alpha', b)
122 |
123 | @command
124 | def trackgamma(b=None):
125 | """trackgamma {boolean} -- determines wether gamma parameter will track alpha axis""" #@IgnorePep8
126 | _checkInputAndSetOrShowParameterTracking('gamma', b)
127 |
128 | @command
129 | def trackphi(b=None):
130 | """trackphi {boolean} -- determines wether phi parameter will track phi axis""" #@IgnorePep8
131 | _checkInputAndSetOrShowParameterTracking('phi', b)
132 |
133 |
134 | commands_for_help = ['Mode',
135 | hklmode,
136 | setpar,
137 | trackalpha,
138 | trackgamma,
139 | trackphi]
140 |
--------------------------------------------------------------------------------
/diffcalc/hkl/willmott/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/hkl/willmott/__init__.py
--------------------------------------------------------------------------------
/diffcalc/hkl/willmott/commands.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from diffcalc.hkl.common import getNameFromScannableOrString
20 | from diffcalc.util import command
21 |
22 |
23 | class WillmottHklCommands(object):
24 |
25 | def __init__(self, hklcalc):
26 | self._hklcalc = hklcalc
27 | self.commands = [self.con,
28 | self.uncon,
29 | self.cons]
30 |
31 | def __str__(self):
32 | return self._hklcalc.__str__()
33 |
34 | @command
35 | def con(self, scn_or_string):
36 | """con -- constrains constraint
37 | """
38 | name = getNameFromScannableOrString(scn_or_string)
39 | self._hklcalc.constraints.constrain(name)
40 | print self._report_constraints()
41 |
42 | @command
43 | def uncon(self, scn_or_string):
44 | """uncon -- unconstrains constraint
45 | """
46 | name = getNameFromScannableOrString(scn_or_string)
47 | self._hklcalc.constraints.unconstrain(name)
48 | print self._report_constraints()
49 |
50 | @command
51 | def cons(self):
52 | """cons -- list available constraints and values
53 | """
54 | print self._report_constraints()
55 |
56 | def _report_constraints(self):
57 | return (self._hklcalc.constraints.build_display_table_lines() + '\n\n' +
58 | self._hklcalc.constraints._report_constraints())
59 |
--------------------------------------------------------------------------------
/diffcalc/hkl/you/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/hkl/you/__init__.py
--------------------------------------------------------------------------------
/diffcalc/hkl/you/persistence.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2018 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 | from diffcalc.ub.calcstate import UBCalcStateEncoder, UBCalcState
19 | from diffcalc.util import DiffcalcException, TODEG
20 |
21 |
22 | class YouStateEncoder(UBCalcStateEncoder):
23 |
24 | def default(self, obj):
25 |
26 | if isinstance(obj, UBCalcState):
27 | d = UBCalcStateEncoder.default(self, obj)
28 |
29 | from diffcalc.hkl.you.hkl import constraint_manager
30 | d['constraints'] = constraint_manager.all
31 | return d
32 |
33 | return UBCalcStateEncoder.default(self, obj)
34 |
35 | @staticmethod
36 | def decode_ubcalcstate(state, geometry, diffractometer_axes_names, multiplier):
37 |
38 | # Backwards compatibility code
39 | try:
40 | cons_dict = state['constraints']
41 | from diffcalc.hkl.you.hkl import constraint_manager
42 | for cons_name, val in cons_dict.iteritems():
43 | try:
44 | constraint_manager.constrain(cons_name)
45 | if val is not None:
46 | constraint_manager.set_constraint(cons_name, val * TODEG)
47 | except DiffcalcException:
48 | print 'WARNING: Ignoring constraint %s' % cons_name
49 | except KeyError:
50 | pass
51 |
52 | return UBCalcStateEncoder.decode_ubcalcstate(state, geometry, diffractometer_axes_names, multiplier)
53 |
--------------------------------------------------------------------------------
/diffcalc/log.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from __future__ import absolute_import
20 |
21 | import logging
22 |
23 | try:
24 | import gda
25 | GDA = True
26 | except ImportError:
27 | GDA = False
28 |
29 | if not GDA:
30 | import getpass
31 | logging.basicConfig(format="%(asctime)s %(levelname)s:%(name)s:%(message)s",
32 | datefmt='%m/%d/%Y %I:%M:%S',
33 | filename='/tmp/diffcalc_%s.log' % getpass.getuser(),
34 | level=logging.DEBUG)
35 |
--------------------------------------------------------------------------------
/diffcalc/settings.py:
--------------------------------------------------------------------------------
1 | '''
2 | Created on Aug 5, 2013
3 |
4 | @author: walton
5 | '''
6 | from diffcalc.ub.persistence import UbCalculationNonPersister
7 |
8 | try:
9 | from numpy import matrix
10 | except ImportError:
11 | from numjy import matrix
12 |
13 | # These should be by the user *before* importing other modules
14 | geometry = None
15 | hardware = None
16 | ubcalc_persister = UbCalculationNonPersister()
17 |
18 | axes_scannable_group = None
19 | energy_scannable = None
20 | energy_scannable_multiplier_to_get_KeV=1
21 |
22 |
23 | # These will be set by dcyou, dcvlieg or dcwillmot
24 | ubcalc_strategy = None
25 | angles_to_hkl_function = None # Used by checkub to avoid coupling it to an hkl module
26 | include_sigtau=False
27 | include_reference=True
28 |
29 | reference_vector = matrix('1; 0; 0')
30 | surface_vector = matrix('0; 0; 1')
31 |
32 | NUNAME = 'gam'
33 |
--------------------------------------------------------------------------------
/diffcalc/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/dc/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/dc/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/dc/you/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/dc/you/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/dc/you/test_fourcircle.py:
--------------------------------------------------------------------------------
1 | from math import pi
2 |
3 | try:
4 | from numpy import matrix
5 | except ImportError:
6 | from numjy import matrix
7 | from diffcalc.tests.tools import mneq_, aneq_, assert_dict_almost_equal
8 |
9 | import diffcalc.util # @UnusedImport
10 | from diffcalc.hardware import DummyHardwareAdapter
11 | from diffcalc.hkl.you.geometry import FourCircle
12 | from diffcalc.ub.persistence import UbCalculationNonPersister
13 | from diffcalc import settings
14 |
15 |
16 | diffcalc.util.DEBUG = True
17 | wl = 1
18 | en = 12.39842 / wl
19 |
20 | angles = [60, 30, 0, 0]
21 | param = {'tau': 90, 'psi': 90, 'beta': 0, 'alpha': 0, 'naz': 0, 'qaz': 90, 'theta': 30, 'ttheta': 60, 'betain': 0, 'betaout': 0}
22 |
23 |
24 | dc = None
25 | def setup_module():
26 | global dc
27 | axes = 'delta', 'eta', 'chi', 'phi'
28 | settings.hardware = DummyHardwareAdapter(axes)
29 | settings.geometry = FourCircle()
30 | settings.ubcalc_persister = UbCalculationNonPersister()
31 | settings.reference_vector = matrix('0; 0; 1')
32 |
33 | from diffcalc.dc import dcyou as dc
34 | reload(dc)
35 | dc.newub('test')
36 | dc.setlat('cubic', 1, 1, 1, 90, 90, 90)
37 | dc.addref([1, 0, 0], [60, 30, 0, 0], en, 'ref1')
38 | dc.addref([0, 1, 0], [60, 30, 0, 90], en, 'ref2')
39 |
40 | def test_orientation_phase():
41 | # assumes reflections added were ideal (with no mis-mount)
42 | dc.ub()
43 | dc.checkub()
44 | dc.showref()
45 |
46 | U = matrix('1 0 0; 0 1 0; 0 0 1')
47 | UB = U * 2 * pi
48 | mneq_(dc._ub.ubcalc.U, U)
49 | mneq_(dc._ub.ubcalc.UB, UB)
50 |
51 | def test_angles_to_hkl_bypassing_hardware_plugin():
52 | hkl_calc, param_calc = dc.angles_to_hkl(angles, en)
53 | aneq_(hkl_calc, [1, 0, 0])
54 | assert_dict_almost_equal(param_calc, param)
55 |
56 | def test_hkl_to_angles_bypassing_hardware_plugin():
57 | dc.con('a_eq_b')
58 | h, k, l = [1, 0, 0]
59 | angles_calc, param_calc = dc.hkl_to_angles(h, k, l, en)
60 | aneq_(angles_calc, angles)
61 | assert_dict_almost_equal(param_calc, param)
62 |
63 | def test_angles_to_hkl():
64 | hkl_calc, param_calc = dc.angles_to_hkl(angles, en)
65 | aneq_(hkl_calc, [1, 0, 0])
66 | assert_dict_almost_equal(param_calc, param)
67 |
68 | def test_hkl_to_angles():
69 | dc.con('a_eq_b')
70 | h, k, l = [1, 0, 0]
71 | angles_calc, param_calc = dc.hkl_to_angles(h, k, l, en)
72 | aneq_(angles_calc, angles)
73 | assert_dict_almost_equal(param_calc, param)
--------------------------------------------------------------------------------
/diffcalc/tests/dc/you/test_sixcircle.py:
--------------------------------------------------------------------------------
1 |
2 | from math import pi
3 |
4 | try:
5 | from numpy import matrix
6 | except ImportError:
7 | from numjy import matrix
8 | from diffcalc.tests.tools import mneq_, aneq_, dneq_
9 |
10 | import diffcalc.util # @UnusedImport
11 | from diffcalc.hardware import DummyHardwareAdapter
12 | from diffcalc.hkl.you.geometry import SixCircle
13 | from diffcalc.ub.persistence import UbCalculationNonPersister
14 | from diffcalc.settings import NUNAME
15 | from diffcalc import settings
16 |
17 |
18 | diffcalc.util.DEBUG = True
19 | wl = 1
20 | en = 12.39842 / wl
21 |
22 | angles = [0, 60, 0, 30, 0, 0]
23 | param = {'tau': 90, 'psi': 90, 'beta': 0, 'alpha': 0, 'naz': 0, 'qaz': 90, 'theta': 30, 'ttheta': 60, 'betain': 0, 'betaout': 0}
24 |
25 |
26 | dc=None
27 | def setup_module():
28 | global dc
29 | axes = 'mu', 'delta', NUNAME, 'eta', 'chi', 'phi'
30 | settings.hardware = DummyHardwareAdapter(axes)
31 | settings.geometry = SixCircle()
32 | settings.ubcalc_persister = UbCalculationNonPersister()
33 |
34 | from diffcalc.dc import dcyou as dc
35 | reload(dc)
36 |
37 | dc.newub('test')
38 | dc.setlat('cubic', 1, 1, 1, 90, 90, 90)
39 | dc.addref([1, 0, 0], [0, 60, 0, 30, 0, 0], en, 'ref1')
40 | dc.addref([0, 1, 0], [0, 60, 0, 30, 0, 90], en, 'ref2')
41 |
42 | def test_orientation_phase():
43 | # assumes reflections added were ideal (with no mis-mount)
44 | dc.ub()
45 | dc.checkub()
46 | dc.showref()
47 |
48 | U = matrix('1 0 0; 0 1 0; 0 0 1')
49 | UB = U * 2 * pi
50 | mneq_(dc._ub.ubcalc.U, U)
51 | mneq_(dc._ub.ubcalc.UB, UB)
52 |
53 | def test_angles_to_hkl_bypassing_hardware_plugin():
54 | hkl_calc, param_calc = dc.angles_to_hkl(angles, en)
55 | aneq_(hkl_calc, [1, 0, 0])
56 | dneq_(param_calc, param)
57 |
58 | def test_hkl_to_angles_bypassing_hardware_plugin():
59 | dc.con('a_eq_b')
60 | dc.con('mu', 0)
61 | dc.con(NUNAME, 0)
62 |
63 | h, k, l = [1, 0, 0]
64 | angles_calc, param_calc = dc.hkl_to_angles(h, k, l, en)
65 | aneq_(angles_calc, angles)
66 | dneq_(param_calc, param)
67 |
68 | def test_angles_to_hkl():
69 | hkl_calc, param_calc = dc.angles_to_hkl(angles)
70 | aneq_(hkl_calc, [1, 0, 0])
71 | dneq_(param_calc, param)
72 |
73 | def test_hkl_to_angles():
74 | dc.con('a_eq_b')
75 | dc.con('mu', 0)
76 | dc.con(NUNAME, 0)
77 |
78 | h, k, l = [1, 0, 0]
79 | angles_calc, param_calc = dc.hkl_to_angles(h, k, l)
80 | aneq_(angles_calc, angles)
81 | dneq_(param_calc, param)
82 |
83 | def test_allhkl():
84 | diffcalc.util.DEBUG = True
85 | dc.con('eta', 0, 'chi', 0, 'phi', 0)
86 | dc.allhkl([.1, 0, .01], 1)
87 |
88 |
89 | # def test_ub_help_visually(self):
90 | # print "-" * 80 + "\nub:"
91 | # print format_command_help(self.dc.ub.commands)
92 | #
93 | # def test_hkl_help_visually(self):
94 | # print "-" * 80 + "\nhkl:"
95 | # print format_command_help(self.dc.hkl.commands)
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/gdasupport/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/minigda/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/gdasupport/minigda/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/minigda/test_scannable.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import unittest
20 |
21 | try:
22 | from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
23 | except ImportError:
24 | from diffcalc.gdasupport.minigda.scannable import DummyPD
25 |
26 | from diffcalc.gdasupport.scannable.mock import MockMotor
27 | from diffcalc.gdasupport.minigda.scannable import \
28 | SingleFieldDummyScannable
29 | from diffcalc.gdasupport.minigda.scannable import Scannable
30 | from diffcalc.gdasupport.minigda.scannable import ScannableGroup
31 |
32 |
33 | class TestScannable(object):
34 |
35 | def setup_method(self):
36 | self.scannable = Scannable()
37 |
38 | def testSomethingUnrelated(self):
39 | a = SingleFieldDummyScannable('a')
40 | print isinstance(a, Scannable)
41 |
42 |
43 | def createDummyAxes(names):
44 | result = []
45 | for name in names:
46 | result.append(DummyPD(name))
47 | return result
48 |
49 |
50 | class TestScannableGroup(object):
51 |
52 | def setup_method(self):
53 | self.a = MockMotor('a')
54 | self.b = MockMotor('bbb')
55 | self.c = MockMotor('c')
56 | self.sg = ScannableGroup('abc', (self.a, self.b, self.c))
57 |
58 | def testInit(self):
59 | assert list(self.sg.getInputNames()) == ['a', 'bbb', 'c']
60 | assert self.sg.getPosition() == [0.0, 0.0, 0.0]
61 |
62 | def testAsynchronousMoveTo(self):
63 | self.sg.asynchronousMoveTo([1, 2.0, 3])
64 | assert self.sg.getPosition() == [1.0, 2.0, 3.0]
65 |
66 | def testAsynchronousMoveToWithNones(self):
67 | self.sg.asynchronousMoveTo([1.0, 2.0, 3.0])
68 | self.sg.asynchronousMoveTo([None, None, 3.2])
69 | assert self.sg.getPosition() == [1.0, 2.0, 3.2]
70 |
71 | def testGetPosition(self):
72 | # implicitely tested above
73 | pass
74 |
75 | def testIsBusy(self):
76 | assert not self.sg.isBusy()
77 | self.sg.asynchronousMoveTo([1.0, 2.0, 3.0])
78 | assert self.sg.isBusy()
79 | self.b.makeNotBusy()
80 | assert self.sg.isBusy()
81 | self.a.makeNotBusy()
82 | self.c.makeNotBusy()
83 | assert not self.sg.isBusy()
84 |
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/scannable/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/gdasupport/scannable/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/scannable/mockdiffcalc.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | class MockParameterManager:
20 |
21 | def __init__(self):
22 | self.params = {}
23 |
24 | def set_constraint(self, name, value):
25 | self.params[name] = value
26 |
27 | def get_constraint(self, name):
28 | return self.params[name]
29 |
30 |
31 | class MockDiffcalc:
32 |
33 | def __init__(self, numberAngles):
34 | self.numberAngles = numberAngles
35 | self.parameter_manager = MockParameterManager()
36 |
37 | def hkl_to_angles(self, h, k, l):
38 | params = {}
39 | params['theta'] = 1.
40 | params['2theta'] = 12.
41 | params['Bin'] = 123.
42 | params['Bout'] = 1234.
43 | params['azimuth'] = 12345.
44 | return ([h] * self.numberAngles, params)
45 |
46 | def angles_to_hkl(self, pos):
47 | if len(pos) != self.numberAngles: raise ValueError
48 | params = {}
49 | params['theta'] = 1.
50 | params['2theta'] = 12.
51 | params['Bin'] = 123.
52 | params['Bout'] = 1234.
53 | params['azimuth'] = 12345.
54 | return ([pos[0]] * 3, params)
55 |
56 |
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/scannable/test_parameter.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import unittest
20 |
21 | from diffcalc.gdasupport.scannable.parameter import \
22 | DiffractionCalculatorParameter
23 | from diffcalc.tests.gdasupport.scannable.mockdiffcalc import \
24 | MockParameterManager
25 |
26 |
27 | class TestDiffractionCalculatorParameter(object):
28 |
29 | def setup_method(self):
30 | self.dcp = DiffractionCalculatorParameter('dcp', 'betain',
31 | MockParameterManager())
32 |
33 | def testAsynchronousMoveToAndGetPosition(self):
34 | self.dcp.asynchronousMoveTo(12.3)
35 | assert self.dcp.getPosition() == [12.3,]
36 |
37 | def testIsBusy(self):
38 | assert not self.dcp.isBusy()
39 |
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/scannable/test_simulation.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from math import pi
20 | import unittest
21 | from pytest import approx
22 |
23 | try:
24 | from numpy import matrix
25 | except ImportError:
26 | from numjy import matrix
27 |
28 | from diffcalc.gdasupport.scannable.simulation import SimulatedCrystalCounter, \
29 | Gaussian
30 | from diffcalc.hkl.vlieg.geometry import Fourc
31 | from diffcalc.util import nearlyEqual
32 | from diffcalc.tests.tools import mneq_
33 |
34 |
35 | class MockScannable(object):
36 | def __init__(self):
37 | self.pos = None
38 |
39 | def getPosition(self):
40 | return self.pos
41 |
42 |
43 | class MockEquation(object):
44 |
45 | def __call__(self, dh, dk, dl):
46 | self.dHkl = dh, dk, dl
47 | return 1
48 |
49 |
50 | class TestSimulatedCrystalCounter(object):
51 |
52 | def setup_method(self):
53 | self.diff = MockScannable()
54 | self.wl = MockScannable()
55 | self.wl.pos = 1.
56 | self.eq = MockEquation()
57 | self.scc = SimulatedCrystalCounter('det', self.diff, Fourc(), self.wl,
58 | self.eq)
59 |
60 | def testInit(self):
61 | assert list(self.scc.getInputNames()) == ['det_count']
62 | assert list(self.scc.getExtraNames()) == []
63 | assert self.scc.chiMissmount == 0.
64 | assert self.scc.phiMissmount == 0.
65 |
66 | def testCalcUB(self):
67 | UB = matrix([[2 * pi, 0, 0], [0, 2 * pi, 0], [0, 0, 2 * pi]])
68 | mneq_(self.scc.UB, UB)
69 |
70 | def testGetHkl(self):
71 | self.diff.pos = [60, 30, 0, 0]
72 | hkl = self.scc.getHkl()
73 | assert hkl == approx((1, 0, 0))
74 |
75 | self.diff.pos = [60, 31, 0, 0]
76 | hkl = self.scc.getHkl()
77 | assert hkl == approx((0.999847695156391, 0.017452406437283574, 0))
78 |
79 | def testGetPosition(self):
80 | self.diff.pos = [60, 30, 0, 0]
81 | self.scc.asynchronousMoveTo(2)
82 | count = self.scc.getPosition()
83 | assert self.eq.dHkl == approx((0, 0, 0))
84 | assert count == 2
85 |
86 | self.diff.pos = [60, 31, 0, 0]
87 | count = self.scc.getPosition()
88 | dHkl = (0.999847695156391 - 1, .017452406437283574, 0)
89 | assert self.eq.dHkl == approx(dHkl)
90 | assert count == 2
91 |
92 | def test__repr__(self):
93 | self.diff.pos = [60, 30, 0, 0]
94 | print self.scc.__repr__()
95 |
96 |
97 | class TestGaussianEquation(object):
98 | def setup_method(self):
99 | self.eq = Gaussian(1.)
100 |
101 | def test__call__(self):
102 | assert self.eq(0, 0, 0) == 0.3989422804014327
103 |
--------------------------------------------------------------------------------
/diffcalc/tests/gdasupport/scannable/test_wavelength.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import unittest
20 |
21 | from diffcalc.gdasupport.scannable.wavelength import Wavelength
22 | try:
23 | from gdascripts.pd.dummy_pds import DummyPD
24 | except ImportError:
25 | from diffcalc.gdasupport.minigda.scannable import DummyPD
26 |
27 |
28 | class TestWavelength(object):
29 |
30 | def setup_method(self):
31 | self.en = DummyPD('en')
32 | self.wl = Wavelength('wl', self.en)
33 |
34 | def testIt(self):
35 | self.en.asynchronousMoveTo(12.39842)
36 | assert self.wl.getPosition() == 1
37 |
38 | self.wl.asynchronousMoveTo(1.)
39 | assert self.wl.getPosition() == 1.
40 | assert self.en.getPosition() == 12.39842
41 |
--------------------------------------------------------------------------------
/diffcalc/tests/hkl/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/hkl/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/hkl/vlieg/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/hkl/vlieg/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/hkl/vlieg/test_constraints.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import unittest
20 |
21 | from diffcalc.hkl.vlieg.constraints import ModeSelector, VliegParameterManager
22 | from diffcalc.util import DiffcalcException
23 | from diffcalc.tests.hkl.vlieg.test_calc import \
24 | createMockHardwareMonitor, createMockDiffractometerGeometry
25 | import pytest
26 |
27 |
28 | class TestModeSelector(object):
29 |
30 | def setup_method(self):
31 |
32 | self.ms = ModeSelector(createMockDiffractometerGeometry(),
33 | parameterManager=None)
34 | self.pm = VliegParameterManager(createMockDiffractometerGeometry(),
35 | None, self.ms)
36 | self.ms.setParameterManager(self.pm)
37 |
38 | def testSetModeByIndex(self):
39 | self.ms.setModeByIndex(0)
40 | assert self.ms.getMode().name == '4cFixedw'
41 | self.ms.setModeByIndex(1)
42 | assert self.ms.getMode().name == '4cBeq'
43 |
44 | def testGetMode(self):
45 | # tested implicetely by testSetmode
46 | pass
47 |
48 | def testShowAvailableModes(self):
49 | print self.ms.reportAvailableModes()
50 |
51 |
52 | class TestParameterManager(object):
53 |
54 | def setup_method(self):
55 | self.hw = createMockHardwareMonitor()
56 | self.ms = ModeSelector(createMockDiffractometerGeometry())
57 | self.pm = VliegParameterManager(createMockDiffractometerGeometry(),
58 | self.hw, self.ms)
59 |
60 | def testDefaultParameterValues(self):
61 | assert self.pm.get_constraint('alpha') == 0
62 | assert self.pm.get_constraint('gamma') == 0
63 | with pytest.raises(DiffcalcException):
64 | self.pm.get_constraint('not-a-parameter-name')
65 |
66 | def testSetParameter(self):
67 | self.pm.set_constraint('alpha', 10.1)
68 | assert self.pm.get_constraint('alpha') == 10.1
69 |
70 | def testSetTrackParameter_isParameterChecked(self):
71 | assert not self.pm.isParameterTracked('alpha')
72 | self.pm.set_constraint('alpha', 9)
73 |
74 | self.pm.setTrackParameter('alpha', True)
75 | assert self.pm.isParameterTracked('alpha') == True
76 | with pytest.raises(DiffcalcException):
77 | self.pm.set_constraint('alpha', 10)
78 | self.hw.get_position.return_value = 888, 11, 999
79 | assert self.pm.get_constraint('alpha') == 11
80 |
81 | print self.pm.reportAllParameters()
82 | print "**"
83 | print self.ms.reportCurrentMode()
84 | print self.pm.reportParametersUsedInCurrentMode()
85 |
86 | self.pm.setTrackParameter('alpha', False)
87 | assert not self.pm.isParameterTracked('alpha')
88 | assert self.pm.get_constraint('alpha') == 11
89 | self.hw.get_position.return_value = 888, 12, 999
90 | assert self.pm.get_constraint('alpha') == 11
91 | self.pm.set_constraint('alpha', 13)
92 | assert self.pm.get_constraint('alpha') == 13
93 |
--------------------------------------------------------------------------------
/diffcalc/tests/hkl/vlieg/test_hkl.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import unittest
20 |
21 | from mock import Mock
22 |
23 | import diffcalc.util # @UnusedImport to overide raw_input
24 | from diffcalc.hkl.vlieg.geometry import SixCircleGammaOnArmGeometry
25 | from diffcalc.hardware import DummyHardwareAdapter
26 | from diffcalc.util import MockRawInput
27 | from diffcalc.hkl.vlieg.calc import VliegHklCalculator
28 | from diffcalc.ub.calc import UBCalculation
29 | from diffcalc.ub.persistence import UbCalculationNonPersister
30 | import pytest
31 |
32 | try:
33 | from gdascripts.pd.dummy_pds import DummyPD # @UnusedImport
34 | except ImportError:
35 | from diffcalc.gdasupport.minigda.scannable import DummyPD
36 |
37 |
38 | def prepareRawInput(listOfStrings):
39 | diffcalc.util.raw_input = MockRawInput(listOfStrings)
40 |
41 | prepareRawInput([])
42 |
43 |
44 | class TestHklCommands(object):
45 |
46 | def setup_method(self):
47 | from diffcalc import settings
48 | settings.geometry = SixCircleGammaOnArmGeometry()
49 | dummy = 'alpha', 'delta', 'gamma', 'omega', 'chi', 'phi'
50 | settings.hardware = DummyHardwareAdapter(dummy)
51 | self.mock_ubcalc = Mock(spec=UBCalculation)
52 | self.hklcalc = VliegHklCalculator(self.mock_ubcalc, True)
53 | settings.ubcalc_persister = UbCalculationNonPersister()
54 |
55 | from diffcalc.hkl.vlieg import hkl
56 | reload(hkl)
57 | hkl.hklcalc = self.hklcalc
58 | self.hkl = hkl
59 | prepareRawInput([])
60 |
61 | def testHklmode(self):
62 | with pytest.raises(TypeError):
63 | self.hkl.hklmode(1, 2)
64 | with pytest.raises(ValueError):
65 | self.hkl.hklmode('unwanted_string')
66 | print self.hkl.hklmode()
67 | print self.hkl.hklmode(1)
68 |
69 | def testSetWithString(self):
70 | self.hkl.setpar()
71 | self.hkl.setpar('alpha')
72 | self.hkl.setpar('alpha', 1)
73 | self.hkl.setpar('alpha', 1.1)
74 | pm = self.hkl.hklcalc.parameter_manager
75 | assert pm.get_constraint('alpha') == 1.1
76 |
77 | def testSetWithScannable(self):
78 | alpha = DummyPD('alpha')
79 | self.hkl.setpar(alpha, 1.1)
80 | pm = self.hkl.hklcalc.parameter_manager
81 | assert pm.get_constraint('alpha') == 1.1
82 |
--------------------------------------------------------------------------------
/diffcalc/tests/hkl/willmot/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/hkl/willmot/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/hkl/you/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/hkl/you/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/hkl/you/test_hkl.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 |
20 | from mock import Mock, call
21 | from diffcalc import settings
22 |
23 | import diffcalc
24 | from diffcalc.tests.test_hardware import SimpleHardwareAdapter
25 | from diffcalc.hkl.you.geometry import SixCircle
26 | diffcalc.util.DEBUG = True
27 |
28 |
29 | hkl = None
30 | def setup_module():
31 | global hkl
32 | settings.hardware=SimpleHardwareAdapter([])
33 | settings.geometry=SixCircle()
34 | settings.angles_to_hkl_function=Mock()
35 | settings.ubcalc_strategy=Mock()
36 | settings.geometry.fixed_constraints = {}
37 |
38 | from diffcalc.hkl.you import hkl
39 | reload(hkl)
40 |
41 | hkl.hklcalc = Mock()
42 | hkl.hklcalc.constraints.report_constraints_lines.return_value = ['report1', 'report2']
43 |
44 |
45 | def test_con_with_1_constraint():
46 | hkl.con('cona')
47 | hkl.hklcalc.constraints.constrain.assert_called_with('cona')
48 |
49 | def test_con_with_1_constraint_with_value():
50 | hkl.con('cona', 123)
51 | hkl.hklcalc.constraints.constrain.assert_called_with('cona')
52 | hkl.hklcalc.constraints.set_constraint.assert_called_with('cona', 123)
53 |
54 | def test_con_with_3_constraints():
55 | hkl.con('cona', 'conb', 'conc')
56 | hkl.hklcalc.constraints.clear_constraints.assert_called()
57 | calls = [call('cona'), call('conb'), call('conc')]
58 | hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
59 |
60 | def test_con_with_3_constraints_first_val():
61 | hkl.con('cona', 1, 'conb', 'conc')
62 | hkl.hklcalc.constraints.clear_constraints.assert_called()
63 | calls = [call('cona'), call('conb'), call('conc')]
64 | hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
65 | hkl.hklcalc.constraints.set_constraint.assert_called_with('cona', 1)
66 |
67 | def test_con_with_3_constraints_second_val():
68 | hkl.con('cona', 'conb', 2, 'conc')
69 | hkl.hklcalc.constraints.clear_constraints.assert_called()
70 | calls = [call('cona'), call('conb'), call('conc')]
71 | hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
72 | hkl.hklcalc.constraints.set_constraint.assert_called_with('conb', 2)
73 |
74 | def test_con_with_3_constraints_third_val():
75 | hkl.con('cona', 'conb', 'conc', 3)
76 | hkl.hklcalc.constraints.clear_constraints.assert_called()
77 | calls = [call('cona'), call('conb'), call('conc')]
78 | hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
79 | hkl.hklcalc.constraints.set_constraint.assert_called_with('conc', 3)
80 |
81 | def test_con_with_3_constraints_all_vals():
82 | hkl.con('cona', 1, 'conb', 2, 'conc', 3)
83 | hkl.hklcalc.constraints.clear_constraints.assert_called()
84 | calls = [call('cona'), call('conb'), call('conc')]
85 | hkl.hklcalc.constraints.constrain.assert_has_calls(calls)
86 | calls = [call('cona', 1), call('conb', 2), call('conc', 3)]
87 | hkl.hklcalc.constraints.set_constraint.assert_has_calls(calls)
88 |
89 | def test_con_messages_and_help_visually():
90 | hkl.con()
91 | print "**"
92 | print hkl.con.__doc__
93 |
94 | def test_con_message_display_whenn_selecting_an_unimplmented_mode():
95 | hkl.hklcalc.constraints.is_fully_constrained.return_value = True
96 | hkl.hklcalc.constraints.is_current_mode_implemented.return_value = False
97 | hkl.con('phi', 'chi', 'eta')
98 |
--------------------------------------------------------------------------------
/diffcalc/tests/ub/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/tests/ub/__init__.py
--------------------------------------------------------------------------------
/diffcalc/tests/ub/test_calculation_you.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from math import pi
20 | from mock import Mock
21 | from diffcalc import settings
22 |
23 | try:
24 | from numpy import matrix
25 | except ImportError:
26 | from numjy import matrix
27 |
28 | from diffcalc.hkl.you.geometry import SixCircle
29 | from diffcalc.hkl.you.geometry import YouPosition
30 | from diffcalc.hkl.you.calc import YouUbCalcStrategy
31 | from diffcalc.tests.tools import matrixeq_
32 | from diffcalc.ub.calc import UBCalculation
33 | from diffcalc.ub.persistence import UbCalculationNonPersister
34 |
35 | #newub 'cubic' <--> reffile('cubic)
36 | #setlat 'cubic' 1 1 1 90 90 90 <--> latt([1,1,1,90,90,90])
37 | #pos wl 1 <--> BLi.setWavelength(1)
38 | # <--> c2th([0,0,1]) --> 60
39 | #pos sixc [0 60 0 30 1 1] <--> pos euler [1 1 30 0 60 0]
40 | #addref 1 0 0 <--> saveref('100',[1, 0, 0])
41 | #pos chi 91 <-->
42 | #addref 0 0 1 <--> saveref('100',[1, 0, 0]) ; showref()
43 | # ubm('100','001')
44 | # ubm() ->
45 | #array('d', [0.9996954135095477, -0.01745240643728364, -0.017449748351250637,
46 | #0.01744974835125045, 0.9998476951563913, -0.0003045864904520898,
47 | #0.017452406437283505, -1.1135499981271473e-16, 0.9998476951563912])
48 |
49 |
50 | def posFromI16sEuler(phi, chi, eta, mu, delta, gamma):
51 | return YouPosition(mu, delta, gamma, eta, chi, phi, unit='DEG')
52 |
53 | UB1 = matrix(
54 | ((0.9996954135095477, -0.01745240643728364, -0.017449748351250637),
55 | (0.01744974835125045, 0.9998476951563913, -0.0003045864904520898),
56 | (0.017452406437283505, -1.1135499981271473e-16, 0.9998476951563912))
57 | ) * (2 * pi)
58 |
59 | EN1 = 12.39842
60 | REF1a = posFromI16sEuler(1, 1, 30, 0, 60, 0)
61 | REF1b = posFromI16sEuler(1, 91, 30, 0, 60, 0)
62 |
63 |
64 | class TestUBCalculationWithYouStrategy():
65 | """Testing the math only here.
66 | """
67 |
68 | def setup_method(self):
69 | geometry = SixCircle() # pass through
70 | hardware = Mock()
71 | names = 'm', 'd', 'n', 'e', 'c', 'p'
72 | hardware.get_axes_names.return_value = names
73 | settings.hardware = hardware
74 | settings.geometry = geometry
75 | self.ubcalc = UBCalculation(UbCalculationNonPersister(),
76 | YouUbCalcStrategy())
77 |
78 | def testAgainstI16Results(self):
79 | self.ubcalc.start_new('cubcalc')
80 | self.ubcalc.set_lattice('latt', 1, 1, 1, 90, 90, 90)
81 | self.ubcalc.add_reflection(1, 0, 0, REF1a, EN1, '100', None)
82 | self.ubcalc.add_reflection(0, 0, 1, REF1b, EN1, '001', None)
83 | self.ubcalc.calculate_UB()
84 | matrixeq_(self.ubcalc.UB, UB1)
85 |
--------------------------------------------------------------------------------
/diffcalc/tests/ub/test_crystal.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import unittest
20 |
21 | try:
22 | from numpy import matrix
23 | except ImportError:
24 | from numjy import matrix
25 |
26 | from diffcalc.tests.tools import assert_dict_almost_equal, mneq_
27 | from diffcalc.ub.crystal import CrystalUnderTest
28 | from diffcalc.tests import scenarios
29 |
30 |
31 | class TestCrystalUnderTest(object):
32 |
33 | def setup_method(self):
34 | self.tclatt = []
35 | self.tcbmat = []
36 |
37 | # From the dif_init.mat next to dif_dos.exe on Vlieg's cd
38 | #self.tclatt.append([4.0004, 4.0004, 2.270000, 90, 90, 90])
39 | #self.tcbmat.append([[1.570639, 0, 0] ,[0.0, 1.570639, 0] ,
40 | # [0.0, 0.0, 2.767923]])
41 |
42 | # From b16 on 27June2008 (From Chris Nicklin)
43 | # self.tclatt.append([3.8401, 3.8401, 5.43072, 90, 90, 90])
44 | # self.tcbmat.append([[1.636204, 0, 0],[0, 1.636204, 0],
45 | # [0, 0, 1.156971]])
46 |
47 | def testGetBMatrix(self):
48 | # Check the calculated B Matrix
49 | for sess in scenarios.sessions():
50 | if sess.bmatrix is None:
51 | continue
52 | cut = CrystalUnderTest('tc', *sess.lattice)
53 | desired = matrix(sess.bmatrix)
54 | print desired.tolist()
55 | answer = cut.B
56 | print answer.tolist()
57 | note = "Incorrect B matrix calculation for scenario " + sess.name
58 | mneq_(answer, desired, 4, note=note)
59 |
60 | def test__str__(self):
61 | cut = CrystalUnderTest("HCl", 1, 2, 3, 4, 5, 6)
62 | print cut.__str__()
--------------------------------------------------------------------------------
/diffcalc/tests/ub/test_orientations.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2019 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from datetime import datetime
20 | from diffcalc.ub.orientations import OrientationList
21 | from diffcalc.hkl.you.geometry import YouPosition as Pos, SixCircle
22 | from diffcalc.util import DiffcalcException
23 | import pytest
24 |
25 |
26 | class TestOrientationList(object):
27 |
28 | def setup_method(self):
29 | self._geometry = SixCircle()
30 | self.orientlist = OrientationList(self._geometry,
31 | ['a', 'd', 'g', 'o', 'c', 'p'])
32 | self.time = datetime.now()
33 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
34 | self.orientlist.add_orientation(1, 2, 3, 0.1, 0.2, 0.3, pos, "orient1", self.time)
35 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
36 | self.orientlist.add_orientation(1.1, 2.2, 3.3, 0.11, 0.12, 0.13, pos, "orient2", self.time)
37 |
38 | def test_add_orientation(self):
39 | assert len(self.orientlist) == 2
40 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
41 | self.orientlist.add_orientation(10, 20, 30, 0.1, 0.2, 0.3, pos, "orient1", self.time)
42 |
43 | def testGetOrientation(self):
44 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
45 | answered = self.orientlist.getOrientation(1)
46 | desired = ([1, 2, 3], [0.1, 0.2, 0.3], pos, "orient1", self.time)
47 | assert answered == desired
48 | answered = self.orientlist.getOrientation("orient1")
49 | assert answered == desired
50 |
51 | def testRemoveOrientation(self):
52 | self.orientlist.removeOrientation(1)
53 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
54 | answered = self.orientlist.getOrientation(1)
55 | desired = ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], pos, "orient2", self.time)
56 | assert answered == desired
57 | self.orientlist.removeOrientation("orient2")
58 | assert self.orientlist._orientlist == []
59 |
60 | def testedit_orientation(self):
61 | ps = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
62 | self.orientlist.edit_orientation(1, 10, 20, 30, 1, 2, 3, ps, "new1", self.time)
63 | assert (self.orientlist.getOrientation(1)
64 | == ([10, 20, 30], [1, 2, 3], ps, "new1", self.time))
65 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
66 | assert (self.orientlist.getOrientation(2)
67 | == ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], pos, "orient2", self.time))
68 | self.orientlist.edit_orientation("orient2", 1.1, 2.2, 3.3, 1.11, 1.12, 1.13, pos, "new2", self.time)
69 | assert (self.orientlist.getOrientation("new2")
70 | == ([1.1, 2.2, 3.3], [1.11, 1.12, 1.13], pos, "new2", self.time))
71 | self.orientlist.edit_orientation("new2", 1.1, 2.2, 3.3, 1.11, 1.12, 1.13, pos, "new1", self.time)
72 | assert (self.orientlist.getOrientation("new1")
73 | == ([10, 20, 30], [1, 2, 3], ps, "new1", self.time))
74 |
75 | def testSwapOrientation(self):
76 | self.orientlist.swap_orientations(1, 2)
77 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
78 | assert (self.orientlist.getOrientation(1)
79 | == ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], pos, "orient2", self.time))
80 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
81 | assert (self.orientlist.getOrientation(2)
82 | == ([1, 2, 3], [0.1, 0.2, 0.3], pos, "orient1", self.time))
83 | self.orientlist.swap_orientations("orient1", "orient2")
84 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
85 | assert (self.orientlist.getOrientation(2)
86 | == ([1.1, 2.2, 3.3], [0.11, 0.12, 0.13], pos, "orient2", self.time))
87 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
88 | assert (self.orientlist.getOrientation(1)
89 | == ([1, 2, 3], [0.1, 0.2, 0.3], pos, "orient1", self.time))
90 |
--------------------------------------------------------------------------------
/diffcalc/tests/ub/test_persistence.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import os
20 | import shutil
21 | import unittest
22 | import tempfile
23 | import time
24 | from nose.tools import eq_ # @UnresolvedImport
25 |
26 | try:
27 | from gda.configuration.properties import LocalProperties
28 | except ImportError:
29 | print "Could not import LocalProperties to configure database locations."
30 |
31 | from diffcalc.ub.persistence import UbCalculationNonPersister, UBCalculationJSONPersister
32 | from diffcalc.ub.calcstate import UBCalcStateEncoder
33 |
34 |
35 | def prepareEmptyGdaVarFolder():
36 | vartest_dir = os.path.join(os.getcwd(), 'var_test')
37 | LocalProperties.set('gda.var', vartest_dir)
38 | if os.path.exists(vartest_dir):
39 | print "Removing existing gda.var: ", vartest_dir
40 | shutil.rmtree(vartest_dir)
41 | print "Creating gda.var: ", vartest_dir
42 | os.mkdir(vartest_dir)
43 |
44 |
45 | class TestUBCalculationNonPersister(object):
46 |
47 | def setup_method(self):
48 | self.persister = UbCalculationNonPersister()
49 |
50 | def testSaveAndLoad(self):
51 | self.persister.save('string1', 'ub1')
52 |
53 |
54 | class TestUBCalculationJSONPersister(object):
55 |
56 | def setup_method(self):
57 | self.tmpdir = tempfile.mkdtemp()
58 | print self.tmpdir
59 | self.persister = UBCalculationJSONPersister(self.tmpdir, UBCalcStateEncoder)
60 | f = open(os.path.join(self.tmpdir, 'unexpected_file'), 'w')
61 | f.close()
62 |
63 | def test_list_with_empty_dir(self):
64 | eq_(self.persister.list(), [])
65 |
66 | def test_save_load(self):
67 | d = {'a' : 1, 'b': 2}
68 | self.persister.save(d, 'first')
69 | eq_(self.persister.load('first'), d)
70 |
71 | def test_save_overwites(self):
72 | d1 = {'a' : 1, 'b': 2}
73 | self.persister.save(d1, 'first')
74 | eq_(self.persister.load('first'), d1)
75 |
76 | d2 = {'a' : 3, 'b': 4, 'c' : 5}
77 | self.persister.save(d2, 'first')
78 | eq_(self.persister.load('first'), d2)
79 |
80 | def test_list(self):
81 | d = {'a' : 1, 'b': 2}
82 | self.persister.save(d, 'first')
83 | eq_(self.persister.list(), ['first'])
84 |
85 | def test_multiple_list(self):
86 | d = {'a' : 1, 'b': 2}
87 | self.persister.save(d, 'first_written')
88 | time.sleep(1.)
89 | eq_(self.persister.list(), ['first_written'])
90 | self.persister.save(d, 'second_written')
91 | time.sleep(1.)
92 | eq_(self.persister.list(), ['second_written', 'first_written'])
93 | self.persister.save(d, 'third_written')
94 | time.sleep(1.)
95 | eq_(self.persister.list(), ['third_written', 'second_written', 'first_written'])
96 |
97 | def test_remove_list(self):
98 | d = {'a' : 1, 'b': 2}
99 | self.persister.save(d, 'first')
100 | self.persister.remove('first')
101 | eq_(self.persister.list(), [])
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/diffcalc/tests/ub/test_reference.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from mock import Mock
20 | from diffcalc.ub.reference import YouReference
21 | from diffcalc.tests.tools import assert_array_almost_equal, assert_2darray_almost_equal
22 |
23 | try:
24 | from numpy import matrix, hstack
25 | from numpy.linalg import norm
26 | except ImportError:
27 | from numjy import matrix, hstack
28 | from numjy.linalg import norm
29 |
30 |
31 | class TestYouReference():
32 |
33 | def setup_method(self):
34 | self.get_UB = Mock()
35 | self.reference = YouReference(self.get_UB)
36 | self.reference._set_n_phi_configured(matrix('0; 0; 1'))
37 | self.get_UB.return_value = matrix('1 0 0; 0 1 0; 0 0 1')
38 |
39 | def test_default_n_phi(self):
40 | assert_2darray_almost_equal(self.reference.n_phi.tolist(), matrix('0; 0; 1').tolist())
41 |
42 | def test__str__with_phi_configured(self):
43 | print self.reference
44 |
45 | def test__str__with_hkl_configured(self):
46 | self.reference.n_hkl_configured = matrix('0; 1; 1')
47 | print self.reference
48 |
49 | def test_n_phi_from_hkl_with_unity_matrix_001(self):
50 | self.get_UB.return_value = matrix('1 0 0; 0 1 0; 0 0 1')
51 | self.reference.n_hkl_configured = matrix('0; 0; 1')
52 | assert_2darray_almost_equal(self.reference.n_phi.tolist(), matrix('0; 0; 1').tolist())
53 |
54 | def test_n_phi_from_hkl_with_unity_matrix_010(self):
55 | self.get_UB.return_value = matrix('1 0 0; 0 1 0; 0 0 1')
56 | self.reference.n_hkl_configured = matrix('0; 1; 0')
57 | assert_2darray_almost_equal(self.reference.n_phi.tolist(), matrix('0; 1; 0').tolist())
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/diffcalc/tests/ub/test_reflections.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | from datetime import datetime
20 | from diffcalc.ub.reflections import ReflectionList
21 | from diffcalc.hkl.you.geometry import YouPosition as Pos, SixCircle
22 | from diffcalc.util import DiffcalcException
23 | import pytest
24 |
25 |
26 | class TestReflectionList(object):
27 |
28 | def setup_method(self):
29 | self._geometry = SixCircle()
30 | self.reflist = ReflectionList(self._geometry,
31 | ['a', 'd', 'g', 'o', 'c', 'p'])
32 | self.time = datetime.now()
33 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
34 | self.reflist.add_reflection(1, 2, 3, pos, 1000, "ref1", self.time)
35 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
36 | self.reflist.add_reflection(1.1, 2.2, 3.3, pos, 1100, "ref2", self.time)
37 |
38 | def test_add_reflection(self):
39 | assert len(self.reflist) == 2
40 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
41 | self.reflist.add_reflection(11.1, 12.2, 13.3, pos, 1100, "ref2", self.time)
42 |
43 | def testGetReflection(self):
44 | answered = self.reflist.getReflection(1)
45 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
46 | desired = ([1, 2, 3], pos, 1000, "ref1", self.time)
47 | assert answered == desired
48 | answered = self.reflist.getReflection('ref1')
49 | assert answered == desired
50 |
51 | def testRemoveReflection(self):
52 | self.reflist.removeReflection(1)
53 | answered = self.reflist.getReflection(1)
54 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
55 | desired = ([1.1, 2.2, 3.3], pos, 1100, "ref2", self.time)
56 | assert answered == desired
57 | self.reflist.removeReflection("ref2")
58 | assert self.reflist._reflist == []
59 |
60 | def testedit_reflection(self):
61 | ps = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
62 | self.reflist.edit_reflection(1, 10, 20, 30, ps, 1000, "new1", self.time)
63 | assert (self.reflist.getReflection(1)
64 | == ([10, 20, 30], ps, 1000, "new1", self.time))
65 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
66 | assert (self.reflist.getReflection(2)
67 | == ([1.1, 2.2, 3.3], pos, 1100, "ref2", self.time))
68 | self.reflist.edit_reflection("ref2", 1.1, 2.2, 3.3, pos, 1100, "new2", self.time)
69 | assert (self.reflist.getReflection("new2")
70 | == ([1.1, 2.2, 3.3], pos, 1100, "new2", self.time))
71 | self.reflist.edit_reflection("new2", 10, 20, 30, pos, 1100, "new1", self.time)
72 | assert (self.reflist.getReflection("new1")
73 | == ([10, 20, 30], ps, 1000, "new1", self.time))
74 |
75 | def testSwapReflection(self):
76 | self.reflist.swap_reflections(1, 2)
77 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
78 | assert (self.reflist.getReflection(1)
79 | == ([1.1, 2.2, 3.3], pos, 1100, "ref2", self.time))
80 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
81 | assert (self.reflist.getReflection(2)
82 | == ([1, 2, 3], pos, 1000, "ref1", self.time))
83 | self.reflist.swap_reflections("ref1", "ref2")
84 | pos = Pos(0.11, 0.22, 0.33, 0.44, 0.55, 0.66, 'DEG')
85 | assert (self.reflist.getReflection(2)
86 | == ([1.1, 2.2, 3.3], pos, 1100, "ref2", self.time))
87 | pos = Pos(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'DEG')
88 | assert (self.reflist.getReflection(1)
89 | == ([1, 2, 3], pos, 1000, "ref1", self.time))
90 |
91 | def createRefStateDicts(self):
92 | ref_0 = {
93 | 'h': 1,
94 | 'k': 2,
95 | 'l': 3,
96 | 'position': (0.1, 0.2, 0.3, 0.4, 0.5, 0.6),
97 | 'energy': 1000,
98 | 'tag': "ref1",
99 | 'time': repr(self.time)
100 | }
101 | ref_1 = {
102 | 'h': 1.1,
103 | 'k': 2.2,
104 | 'l': 3.3,
105 | 'position': (0.11, 0.22, 0.33, 0.44, 0.55, 0.66),
106 | 'energy': 1100,
107 | 'tag': "ref2",
108 | 'time': repr(self.time)
109 | }
110 | return ref_0, ref_1
--------------------------------------------------------------------------------
/diffcalc/ub/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcalc/ub/__init__.py
--------------------------------------------------------------------------------
/diffcalc/ub/reference.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2019 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | try:
20 | from numpy.linalg import norm
21 | except ImportError:
22 | from numjy.linalg import norm
23 |
24 |
25 | class YouReference(object):
26 |
27 | def __init__(self, get_UB):
28 | self.get_UB = get_UB # callable
29 | self._n_phi_configured = None
30 | self._n_hkl_configured = None
31 |
32 | def _set_n_phi_configured(self, n_phi):
33 | self._n_phi_configured = n_phi
34 | self._n_hkl_configured = None
35 |
36 | def _get_n_phi_configured(self):
37 | return self._n_phi_configured
38 |
39 | n_phi_configured = property(_get_n_phi_configured, _set_n_phi_configured)
40 |
41 | def _set_n_hkl_configured(self, n_hkl):
42 | self._n_phi_configured = None
43 | self._n_hkl_configured = n_hkl
44 |
45 | def _get_n_hkl_configured(self):
46 | return self._n_hkl_configured
47 |
48 | n_hkl_configured = property(_get_n_hkl_configured, _set_n_hkl_configured)
49 |
50 | @property
51 | def n_phi(self):
52 | if self._n_phi_configured is None:
53 | n_phi = self.get_UB() * self._n_hkl_configured
54 | n_phi = n_phi / norm(n_phi)
55 | else:
56 | n_phi = self._n_phi_configured
57 | return n_phi
58 |
59 | @property
60 | def n_hkl(self):
61 | if self._n_hkl_configured is None:
62 | n_hkl = self.get_UB().I * self._n_phi_configured
63 | n_hkl = n_hkl / norm(n_hkl)
64 | else:
65 | n_hkl = self._n_hkl_configured
66 | return n_hkl
67 |
68 | def _pretty_vector(self, m):
69 | return ' '.join([('% 9.5f' % e).rjust(9) for e in m.T.tolist()[0]])
70 |
71 | def repr_lines(self, ub_calculated, WIDTH, conv):
72 | SET_LABEL = ' <- set'
73 | lines = []
74 | if self._n_phi_configured is not None:
75 | nphi_label = SET_LABEL
76 | nhkl_label = ''
77 | elif self._n_hkl_configured is not None:
78 | nphi_label = ''
79 | nhkl_label = SET_LABEL
80 | else:
81 | raise AssertionError("Neither a manual n_phi nor n_hkl is configured")
82 |
83 | if ub_calculated:
84 | lines.append(" n_phi:".ljust(WIDTH) + self._pretty_vector(conv.transform(self.n_phi, True)) + nphi_label)
85 | lines.append(" n_hkl:".ljust(WIDTH) + self._pretty_vector(self.n_hkl) + nhkl_label)
86 | else: # no ub calculated
87 | if self._n_phi_configured is not None:
88 | lines.append(" n_phi:".ljust(WIDTH) + self._pretty_vector(conv.transform(self._n_phi_configured, True)) + SET_LABEL)
89 | elif self._n_hkl_configured is not None:
90 | lines.append(" n_hkl:".ljust(WIDTH) + self._pretty_vector(self._n_hkl_configured) + SET_LABEL)
91 |
92 | return lines
93 |
--------------------------------------------------------------------------------
/diffcmd/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcmd/__init__.py
--------------------------------------------------------------------------------
/diffcmd/diffcalc_launcher.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 |
3 | import argparse
4 | import subprocess
5 | import os
6 | import getpass
7 |
8 | DIFFCALC_BIN = os.path.split(os.path.realpath(__file__))[0]
9 | DIFFCALC_ROOT = os.path.abspath(os.path.join(DIFFCALC_BIN, os.pardir))
10 |
11 | MODULE_FOR_MANUALS = '_make_sixcircle_manual'
12 |
13 | def main():
14 | parser = argparse.ArgumentParser(description='Diffcalc: A diffraction condition calculator of x-ray and neutron crystalography')
15 | parser.add_argument('--modules', dest='show_modules', action='store_true',
16 | help='list available modules')
17 | parser.add_argument('--python', dest='use_python', action='store_true',
18 | help='run within python rather than ipython')
19 | parser.add_argument('--debug', dest='debug', action='store_true',
20 | help='run in debug mode')
21 | parser.add_argument('--make-manuals-source', dest='make_manuals', action='store_true',
22 | help='make .rst manual files by running template through sixcircle')
23 | parser.add_argument('--non-interactive', dest='non_interactive', action='store_true',
24 | help='do not enter interactive mode after startup')
25 | parser.add_argument('module', type=str, nargs='?',
26 | help='the module to startup with')
27 | args = parser.parse_args()
28 |
29 | # Create list of available modules
30 | module_names = []
31 | for module_path in os.listdir(os.path.join(DIFFCALC_ROOT, 'startup')):
32 | if not module_path.startswith('_') and module_path.endswith('.py'):
33 | module_names.append(module_path.split('.')[0])
34 | module_names.sort()
35 |
36 | if args.show_modules:
37 | print_available_modules(module_names)
38 | exit(0)
39 |
40 | if not args.make_manuals and not args.module:
41 | print "A module name should be provided. Choose one of:"
42 | print_available_modules(module_names)
43 | exit(0)
44 |
45 | if args.make_manuals:
46 | if args.module:
47 | print "When building the manuals no module should be given"
48 | exit(1)
49 | args.module = MODULE_FOR_MANUALS
50 |
51 | if not args.make_manuals and args.module not in module_names:
52 | print "The provided argument '%s' is not one of:" % args.module
53 | print_available_modules(module_names)
54 | exit(1)
55 |
56 | env = os.environ.copy()
57 |
58 | if 'PYTHONPATH' not in env:
59 | env['PYTHONPATH'] = ''
60 | env['PYTHONPATH'] = DIFFCALC_ROOT + ':' + env['PYTHONPATH']
61 |
62 | diffcmd_start_path = os.path.join(DIFFCALC_ROOT, 'diffcmd', 'start.py')
63 |
64 | if args.use_python:
65 | cmd = 'python'
66 | else: # ipython
67 | cmd = 'ipython --no-banner --HistoryManager.hist_file=/tmp/ipython_hist_%s.sqlite' % getpass.getuser()
68 |
69 | iflag = '' if args.non_interactive else '-i'
70 | cmd = cmd + ' ' + ' '.join([iflag, diffcmd_start_path, args.module, str(args.debug)])
71 |
72 | print 'Running: ' + cmd
73 | rc = subprocess.call(cmd, env=env, shell=True)
74 | exit(rc)
75 |
76 |
77 | def print_available_modules(module_names):
78 | lines = []
79 | for m in sorted(module_names):
80 | lines.append(' ' + m)
81 | print '\n'.join(lines)
82 |
83 |
84 | if __name__ == '__main__':
85 | main()
86 | #
87 |
--------------------------------------------------------------------------------
/diffcmd/diffcmd_utils.py:
--------------------------------------------------------------------------------
1 | #
2 | # General utility functions to handle Diffcalc commands
3 | #
4 |
5 | from gda.jython.commands.GeneralCommands import alias
6 |
7 | try:
8 | import gda
9 | GDA = True
10 | except ImportError:
11 | GDA = False
12 |
13 |
14 |
15 | def alias_commands(global_namespace_dict):
16 | """Alias commands left in global_namespace_dict by previous import from
17 | diffcalc.
18 |
19 | This is the equivalent of diffcmd/ipython/magic_commands() for use
20 | when IPython is not available
21 | """
22 | gnd = global_namespace_dict
23 | global GLOBAL_NAMESPACE_DICT
24 | GLOBAL_NAMESPACE_DICT = gnd
25 | print "Aliasing commands"
26 |
27 | ### Alias commands in namespace ###
28 | commands = gnd['hkl_commands_for_help']
29 | commands += gnd['ub_commands_for_help']
30 | if not GDA: # TODO: encapsulation issue: this should be done outside this function!
31 | commands.append(gnd['pos'])
32 | commands.append(gnd['scan'])
33 | aliased_names = []
34 |
35 | for f in commands:
36 | # Skip section headers like 'Motion'
37 | if not hasattr(f, '__call__'):
38 | continue
39 |
40 | alias(f.__name__)
41 | aliased_names.append(f.__name__)
42 |
43 | print "Aliased commands: " + ' '.join(aliased_names)
44 |
--------------------------------------------------------------------------------
/diffcmd/ipythonmagic.py:
--------------------------------------------------------------------------------
1 |
2 | import diffcmd.ipython
3 | from IPython.core.magic import register_line_magic
4 | from diffcmd.ipython import parse_line
5 |
6 | command_map = {}
7 |
8 | _DEFAULT_HELP = """
9 | For help with diffcalc's orientation phase try:
10 |
11 | >>> help ub
12 |
13 | For help with moving in reciprocal lattice space try:
14 |
15 | >>> help hkl
16 |
17 | For more detailed help try for example:
18 |
19 | >>> help newub
20 |
21 | For help with driving axes or scanning:
22 |
23 | >>> help pos
24 | >>> help scan
25 |
26 | For help with regular python try for example:
27 |
28 | >>> help list
29 |
30 | For more detailed help with diffcalc go to:
31 |
32 | https://diffcalc.readthedocs.io
33 |
34 | """
35 |
36 | # This function should be called with parameter globals()
37 | def define_commands(dictionary):
38 | print "Ipython detected - magicing commands"
39 | magiced_names = []
40 | commands = hkl_commands_for_help + ub_commands_for_help # @UndefinedVariable
41 | commands += [pos, scan] # @UndefinedVariable
42 | ipython.GLOBAL_NAMESPACE_DICT = dictionary
43 | for f in commands:
44 | # Skip section headers like 'Motion'
45 | if not hasattr(f, '__call__'):
46 | continue
47 |
48 | # magic the function and remove from namespace (otherwise it would
49 | # shadow the magiced command)
50 | register_line_magic(parse_line(f))
51 | del dictionary[f.__name__]
52 | command_map[f.__name__] = f
53 | magiced_names.append(f.__name__)
54 |
55 | print "Magiced commands: " + ' '.join(magiced_names)
56 |
57 | # because the functions have gone from namespace we need to override
58 | pythons_help = __builtins__.help
59 | del __builtins__.help
60 |
61 | register_line_magic(help)
62 | del help
63 |
64 | def help(s):
65 | """Diffcalc help for iPython
66 | """
67 | if s == '':
68 | print _DEFAULT_HELP
69 | elif s == 'hkl':
70 | # Use help injected into hkl object
71 | print hkl.__doc__
72 | elif s == 'ub':
73 | # Use help injected into ub command
74 | print command_map['ub'].__doc__
75 | elif s in command_map:
76 | print "%s (diffcalc command):" %s
77 | print command_map[s].__doc__
78 | else:
79 | exec('pythons_help(%s)' %s)
80 |
--------------------------------------------------------------------------------
/diffcmd/make_manual.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from StringIO import StringIO
4 | from IPython import get_ipython
5 | import sys
6 | from diffcalc.dc.help import format_commands_for_rst_table
7 |
8 |
9 | TEST_INPUT="""
10 | Diffcalc's Scannables
11 | =====================
12 |
13 | Please see :ref:`moving-in-hkl-space` and :ref:`scanning-in-hkl-space` for some relevant examples.
14 |
15 | To list and show the current positions of your beamline's scannables
16 | use ``pos`` with no arguments::
17 |
18 | >>> pos wl
19 |
20 | should do nought, but this should be replaced::
21 |
22 | ==> pos wl 2
23 |
24 | should do the thing
25 |
26 | ==> abcd
27 | """
28 |
29 |
30 |
31 | def echorun(magic_cmd):
32 | print "\n>>> " + str(magic_cmd)
33 |
34 |
35 |
36 | def make_manual(input_file_path,
37 | output_file_path,
38 | ub_commands_for_help,
39 | hkl_commands_for_help):
40 |
41 | # Read input file (should be .rst file)
42 | with open(input_file_path, 'r') as f:
43 | input_string = f.read()
44 |
45 | # Parse input string
46 | output_lines = []
47 | for lineno, line in enumerate(input_string.split('\n')):
48 | process = '==>' in line
49 |
50 | if process and 'STOP' in line:
51 | print "'==> STOP' found on line. STOPPING", lineno + 1
52 | return
53 |
54 | elif process and 'UB_HELP_TABLE' in line:
55 | print 'Creating UB help table'
56 | output_lines_from_line = format_commands_for_rst_table(
57 | '', ub_commands_for_help)
58 |
59 | elif process and 'HKL_HELP_TABLE' in line:
60 | print 'Creating HKL help table'
61 | output_lines_from_line = format_commands_for_rst_table(
62 | '', hkl_commands_for_help)
63 |
64 | else:
65 | output_lines_from_line = parse_line(
66 | line, lineno + 1, input_file_path)
67 |
68 | # print '\n'.join(output_lines_from_line)
69 | output_lines.extend(output_lines_from_line)
70 |
71 | # Write output file
72 | if output_file_path:
73 | with open(output_file_path, 'w') as f:
74 | f.write('\n'.join(output_lines))
75 | print "Wrote file:", output_file_path
76 | # try:
77 | # if output_file_path:
78 | # orig_stdout = sys.stdout
79 | # f = file(output_file_path, 'w')
80 | # sys.stdout = f
81 | #
82 | #
83 | #
84 | # finally:
85 | # if output_file_path:
86 | # sys.stdout = orig_stdout
87 | # f.close()
88 |
89 |
90 | def parse_line(linein, lineno, filepath):
91 | output_lines = []
92 | if '==>' in linein:
93 | pre, cmd = linein.split('==>')
94 | _check_spaces_only(pre, lineno, filepath)
95 | cmd = cmd.strip() # strip whitespace
96 | output_lines.append(pre + ">>> " + cmd)
97 | result_lines = _capture_magic_command_output(cmd, lineno, filepath)
98 |
99 |
100 | # append to output
101 | for line in result_lines:
102 | output_lines.append(pre + line)
103 | else:
104 | output_lines.append(linein)
105 | return output_lines
106 |
107 |
108 | def _check_spaces_only(s, lineno, filepath):
109 | for c in s:
110 | if c != ' ':
111 | raise Exception('Error on line %i of %s :\n text proceeding --> must be '
112 | 'spaces only' % (lineno, filepath))
113 |
114 | def _capture_magic_command_output(magic_cmd, lineno, filepath):
115 | orig_stdout = sys.stdout
116 | result = StringIO()
117 | sys.stdout = result
118 |
119 | def log_error():
120 | msg = "Error on line %i of %s evaluating '%s'" % (lineno, filepath, magic_cmd)
121 | sys.stderr.write('\n' + '=' * 79 + '\n' + msg + '\n' +'v' * 79 + '\n')
122 | return msg
123 |
124 | try:
125 | line_magics = get_ipython().magics_manager.magics['line']
126 | magic = magic_cmd.split(' ')[0]
127 | if magic not in line_magics:
128 | msg = log_error()
129 | raise Exception(msg + " ('%s' is not a magic command)" % magic)
130 | get_ipython().magic(magic_cmd)
131 | except:
132 | log_error()
133 | raise
134 | finally:
135 | sys.stdout = orig_stdout
136 |
137 | result_lines = result.getvalue().split('\n')
138 |
139 | # trim trailing lines which are whitespace only
140 | while result_lines and (result_lines[-1].isspace() or not result_lines[-1]):
141 | result_lines.pop()
142 |
143 | return result_lines
144 |
145 |
146 |
--------------------------------------------------------------------------------
/diffcmd/start.py:
--------------------------------------------------------------------------------
1 | """
2 | start the diffcmd environemt using a script from startup.
3 | This should normally be run by the main diffcalc.py program.
4 |
5 | with diffcalc on PYTHONPATH
6 | $ ipython -i -m diffcm.diffcmd module_name_string debug_bool
7 | """
8 | from __future__ import absolute_import
9 |
10 | import diffcalc
11 | import diffcalc.settings
12 | import os
13 | import sys
14 | from diffcalc.ub.persistence import UBCalculationJSONPersister
15 | from diffcalc.ub.calcstate import UBCalcStateEncoder
16 | from diffcalc.util import bold
17 | import diffcalc.util
18 | import diffcalc.gdasupport.minigda.command
19 | DIFFCALC_ROOT = os.path.realpath(diffcalc.__file__).split('diffcalc/__init__.py')[0]
20 |
21 | try:
22 | __IPYTHON__ # @UndefinedVariable
23 | IPYTHON = True
24 | except NameError:
25 | IPYTHON = False
26 |
27 |
28 | module_name = sys.argv[1] #3 if IPYTHON else 1]
29 | debug = sys.argv[2] == 'True' #4 if IPYTHON else 2])
30 |
31 | print
32 | print bold('-' * 34 + ' DIFFCALC ' + '-' * 35)
33 |
34 | # configure persisentence
35 | DIFFCALC_VAR = os.path.join(os.path.expanduser('~'), '.diffcalc', module_name)
36 | if not os.path.exists(DIFFCALC_VAR):
37 | print "Making diffcalc var folder:'%s'" % DIFFCALC_VAR
38 | os.makedirs(DIFFCALC_VAR)
39 | diffcalc.settings.ubcalc_persister = UBCalculationJSONPersister(DIFFCALC_VAR, UBCalcStateEncoder)
40 |
41 | # configure debug
42 | diffcalc.util.DEBUG = debug
43 | if debug:
44 | print "WARNING: debug mode on; help for command syntax errors disabled."
45 |
46 | # import script
47 | script = os.path.join(DIFFCALC_ROOT, 'startup', module_name) + '.py'
48 |
49 | print "Startup script: '%s'" % script
50 | namespace = {}
51 | execfile(script, namespace)
52 | globals().update(namespace)
53 | diffcalc.gdasupport.minigda.command.ROOT_NAMESPACE_DICT = dict(namespace)
54 | print bold('-' * 36 + ' Help ' + '-' * 37)
55 | print HELP_STRING # @UndefinedVariable
56 | if 'LOCAL_MANUAL' in locals():
57 | print "Local: " + LOCAL_MANUAL # @UndefinedVariable
58 | print bold('-' * 79)
59 | print
60 |
61 |
62 | # magic commands if IPython
63 | if IPYTHON:
64 | from diffcmd.ipython import magic_commands
65 | magic_commands(globals())
66 |
67 |
68 | if 'MANUALS_TO_MAKE' in locals():
69 | summary_lines = ['Made manuals:']
70 | from diffcmd.make_manual import make_manual
71 | for source_path in MANUALS_TO_MAKE: # @UndefinedVariable
72 | import diffcalc.ub.ub
73 | try:
74 | diffcalc.ub.ub.rmub('example')
75 | except KeyError:
76 | pass
77 | target_path = source_path.replace('_template', '')
78 | print '@' * 79
79 | print "Making manual"
80 | print " Source:", source_path
81 | print " Target:", target_path
82 |
83 | make_manual(source_path, target_path,
84 | ub_commands_for_help, # @UndefinedVariable
85 | hkl_commands_for_help) # @UndefinedVariable
86 | summary_lines.append(' - ' + source_path + ' -- > ' + target_path)
87 | print '\n'.join(summary_lines)
88 |
--------------------------------------------------------------------------------
/diffcmd/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/diffcmd/tests/__init__.py
--------------------------------------------------------------------------------
/doc/docs-build-diffcalc_doc-linux.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/doc/references:
--------------------------------------------------------------------------------
1 |
2 | .. [You1999] H. You. *Angle calculations for a '4S+2D' six-circle diffractometer.*
3 | J. Appl. Cryst. (1999). **32**, 614-623. `(pdf link)
4 | `__.
5 |
6 | .. [Busing1967] W. R. Busing and H. A. Levy. *Angle calculations for 3- and 4-circle X-ray
7 | and neutron diffractometers.* Acta Cryst. (1967). **22**, 457-464. `(pdf link)
8 | `__.
9 |
10 | .. [Vlieg1993] Martin Lohmeier and Elias Vlieg. *Angle calculations for a six-circle
11 | surface x-ray diffractometer.* J. Appl. Cryst. (1993). **26**, 706-716. `(pdf link)
12 | `__.
13 |
14 | .. [Vlieg1998] Elias Vlieg. *A (2+3)-type surface diffractometer: mergence of the z-axis and
15 | (2+2)-type geometries.* J. Appl. Cryst. (1998). **31**, 198-203. `(pdf link)
16 | `__.
17 |
18 | .. [Willmott2011] C. M. Schlepütz, S. O. Mariager, S. A. Pauli, R. Feidenhans'l and
19 | P. R. Willmott. *Angle calculations for a (2+3)-type diffractometer: focus
20 | on area detectors.* J. Appl. Cryst. (2011). **44**, 73-83. `(pdf link)
21 | `__.
22 |
23 |
--------------------------------------------------------------------------------
/doc/source/ACKS.rst:
--------------------------------------------------------------------------------
1 | ################
2 | Acknowledgements
3 | ################
4 |
5 | .. toctree::
6 | :maxdepth: 2
7 | :numbered:
8 |
9 | We would like to acknowledge the people who have made a direct impact on the
10 | Diffcalc project, knowingly or not, in terms of encouragement, suggestions,
11 | criticism, bug reports, code contributions, and related projects.
12 |
13 | Names are ordered alphabetically by surname.
14 |
15 | .. If you add new entries, keep the list sorted by surname!
16 |
17 | .. acks::
18 |
19 | * Allesandro Bombardi
20 | * Mark Booth
21 | * W. R. Busing
22 | * Steve Collins
23 | * Mirian Garcia-Fernandez
24 | * H. A. Levy
25 | * Martin Lohmier
26 | * Chris Nicklin
27 | * Elias Vlieg --- writer of DIF software used as a model for Diffcalc
28 | * Robert Walton
29 | * H. You
30 | * Fajin Yuan
31 |
32 | Thank you!
33 |
34 | Rob Walton & Irakli Sikharulidze
--------------------------------------------------------------------------------
/doc/source/developer/contents.rst:
--------------------------------------------------------------------------------
1 | ########################
2 | Diffcalc Developer Guide
3 | ########################
4 |
5 | :Author: Rob Walton
6 | :Contact: rob.walton (at) diamond (dot) ac (dot) uk
7 | :Website: http://www.opengda.org/
8 |
9 | .. rubric:: Diffcalc: A diffraction condition calculator for diffractometer control
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 | :numbered:
14 |
15 | intro
16 | package
17 | quickstart_api
18 | development
19 |
20 | Indices and tables
21 | ==================
22 |
23 | * :ref:`genindex`
24 | * :ref:`modindex`
25 | * :ref:`search`
--------------------------------------------------------------------------------
/doc/source/developer/development.rst:
--------------------------------------------------------------------------------
1 | Development
2 | ===========
3 |
4 | The files are kept here_ on github_. See bootcamp for an introduction to
5 | using github. To contribute please fork the project. Otherwise you can make
6 | a read-only clone or export.
7 |
8 | Code format should follow pep8 guidelines. PyDev has a good pep8 checker.
9 |
10 | To run the tests install nose_, change directory into the test folder and run::
11 |
12 | $ nosetests
13 | .......... ...
14 | ----------------------------------------------------------------------
15 | Ran 3914 tests in 9.584s
16 |
17 | OK (SKIP=15)
18 |
19 |
20 |
21 | .. _here: https://github.com/DiamondLightSource/diffcalc
22 | .. _github: https://github.com
23 | .. _nose: http://nose.readthedocs.org/en/latest/
24 | .. _pep8: http://www.python.org/dev/peps/pep-0008/
25 |
--------------------------------------------------------------------------------
/doc/source/developer/intro.rst:
--------------------------------------------------------------------------------
1 | Introduction
2 | ============
3 |
4 | Diffcalc is a diffraction condition calculator used for controlling
5 | diffractometers within reciprocal lattice space. It performs the same
6 | task as the ``fourc``, ``sixc``, ``twoc``, ``kappa``, ``psic`` and
7 | ``surf`` macros from SPEC_.
8 |
9 | Diffcalc's standard calculation engine is an implementation of
10 | [You1999]_ . The first versions of Diffcalc were based on
11 | [Vlieg1993]_ and [Vlieg1998]_ and a 'Vlieg' engine is still
12 | available. The 'You' engine is more generic and the plan is to remove
13 | the old 'Vlieg' engine once beamlines have been migrated. New users
14 | should use the 'You' engine.
15 |
16 | The foundations for this type of calculation were laid by by Busing &
17 | Levi in their classic paper [Busing1967]_. Diffcalc's orientation
18 | algorithm is taken from this paper. Busing & Levi also provided the
19 | original definition of the coordinate frames and of the U and B
20 | matrices used to describe a crystal's orientation and to convert between
21 | Cartesian and reciprical lattice space.
22 |
23 | Geometry plugins are used to adapt the six circle model used
24 | internally by Diffcalc to apply to other diffractometers. These
25 | contain a dictionary of the 'missing' angles which Diffcalc uses to
26 | constrain these angles internally, and a methods to map from external
27 | angles to Diffcalc angles and visa versa.
28 |
29 | Options to use Diffcalc:
30 |
31 | - **The User manual next to this developer manual or README file on github.**
32 | - The :ref:`quickstart-api` section describes how to run up only
33 | the core in Python_. This provides a base option for system integration.
34 |
35 | Diffcalc will work with Python 2.7 or higher with numpy_, or with
36 | Jython 2.7 of higher with Jama_.
37 |
38 |
39 | .. [*] The very small 'Willmott' engine currently handles the case for
40 | surface diffraction where the surface normal is held vertical
41 | [Willmott2011]_. The 'You' engine handles this case fine, but
42 | currently spins nu into an unhelpful quadrant. We hope to
43 | remove the need for this engine soon.
44 |
45 |
46 | .. _SPEC: http://www.certif.com/
47 | .. _Python: http://python.org
48 | .. _IPython: http://http://ipython.org/
49 | .. _Jython: http://jython.org
50 | .. _OpenGDA: http://opengda.org
51 | .. _numpy: http://numpy.scipy.org/
52 | .. _Jama: http://math.nist.gov/javanumerics/jama/
53 |
54 |
55 | .. include:: ../../references
56 |
--------------------------------------------------------------------------------
/doc/source/developer/package.rst:
--------------------------------------------------------------------------------
1 | Project Files & Directories
2 | ===========================
3 |
4 | diffcalc
5 | The main source package.
6 |
7 | test
8 | Diffcalcs unit-test package (use Nose_ to run them).
9 |
10 | diffcmd
11 | A spec-like openGDA emulator.
12 |
13 | numjy
14 | A *very* minimal implentation of numpy for jython. It supports only what
15 | Diffcalc needs.
16 |
17 | doc
18 | The documentation is written in reStructuredText and can be compiled into
19 | html and pdf using Python's `Sphinx `_. With Sphinx
20 | installed use ``make clean all`` from within the user and developer guide
21 | folders to build the documentation.
22 |
23 | startup
24 | Starup scripts called by diffcmd or openGDA to startup diffcalc
25 |
26 | model
27 | Vrml models of diffractometers and a hokey script for animating then and
28 | controlling them from diffcalc.
29 |
30 | .. _Nose: http://readthedocs.org/docs/nose/en/latest/
--------------------------------------------------------------------------------
/doc/source/developer/quickstart_setup_environment:
--------------------------------------------------------------------------------
1 |
2 | Change directory to the diffcalc project (python adds the current
3 | working directory to the path)::
4 |
5 | $ cd diffcalc
6 | $ ls
7 | COPYING diffcalc doc example mock.py mock.pyc model numjy test
8 |
9 | If using Python make sure numpy and diffcalc can be imported::
10 |
11 | $ python
12 | Python 2.7.2+ (default, Oct 4 2011, 20:06:09)
13 | [GCC 4.6.1] on linux2
14 | Type "help", "copyright", "credits" or "license" for more information.
15 | >>> import numpy
16 | >>> import diffcalc
17 |
18 | If using Jython make sure Jama and diffcalc can be imported::
19 |
20 | $ jython -Dpython.path=:/Jama-1.0.1.jar
21 |
22 | Jython 2.2.1 on java1.5.0_11
23 | Type "copyright", "credits" or "license" for more information.
24 | >>> import Jama
25 | >>> import diffcalc
26 |
--------------------------------------------------------------------------------
/doc/source/diffcalc_pdf.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/diffcalc_pdf.png
--------------------------------------------------------------------------------
/doc/source/diffcalc_web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/diffcalc_web.png
--------------------------------------------------------------------------------
/doc/source/index.rst:
--------------------------------------------------------------------------------
1 | ###################################
2 | Diffcalc User and Developer Guide
3 | ###################################
4 |
5 | :Author: Rob Walton
6 | :Contact: rob.walton (at) diamond.ac.uk
7 | :Web site: https://github.com/DiamondLightSource/diffcalc
8 |
9 | .. rubric:: Diffcalc: A Diffraction Condition Calculator for Diffractometer Control
10 |
11 | See also the `quickstart guide at github `_.
12 |
13 | .. toctree::
14 | :maxdepth: 2
15 |
16 | youmanual
17 | vliegmanual/contents
18 | developer/contents
19 | ACKS
20 |
21 | Indices and tables
22 | ==================
23 |
24 | * :ref:`genindex`
25 | * :ref:`modindex`
26 | * :ref:`search`
27 |
--------------------------------------------------------------------------------
/doc/source/vliegmanual/contents.rst:
--------------------------------------------------------------------------------
1 | #############################################
2 | Diffcalc User Guide (Deprecated Vlieg Engine)
3 | #############################################
4 |
5 | :Author: Rob Walton
6 | :Contact: rob.walton (at) diamond (dot) ac (dot) uk
7 | :Website: http://www.opengda.org/
8 |
9 | .. rubric:: Diffcalc: A diffraction condition calculator for diffractometer control
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 | :numbered:
14 |
15 | vliegmanual
16 |
17 | Indices and tables
18 | ==================
19 |
20 | * :ref:`genindex`
21 | * :ref:`modindex`
22 | * :ref:`search`
--------------------------------------------------------------------------------
/doc/source/vliegmanual/images/fix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/vliegmanual/images/fix.png
--------------------------------------------------------------------------------
/doc/source/vliegmanual/images/sixcircle_gamma_on_arm.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/vliegmanual/images/sixcircle_gamma_on_arm.pdf
--------------------------------------------------------------------------------
/doc/source/vliegmanual/images/sixcircle_gamma_on_arm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/vliegmanual/images/sixcircle_gamma_on_arm.png
--------------------------------------------------------------------------------
/doc/source/vliegmanual/images/sixcircle_gamma_on_arm.ppt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/vliegmanual/images/sixcircle_gamma_on_arm.ppt
--------------------------------------------------------------------------------
/doc/source/vliegmanual/images/unit_cell.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/vliegmanual/images/unit_cell.pdf
--------------------------------------------------------------------------------
/doc/source/vliegmanual/images/unit_cell.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/vliegmanual/images/unit_cell.png
--------------------------------------------------------------------------------
/doc/source/youmanual_images/4s_2d_diffractometer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/doc/source/youmanual_images/4s_2d_diffractometer.png
--------------------------------------------------------------------------------
/doc/tmp/constraints.txt:
--------------------------------------------------------------------------------
1 | Take a six circle diffractometer with angles:
2 |
3 | delta, nu, mu, eta, chi, phi
4 |
5 | and virtual angles:
6 |
7 | qaz, naz, psi, alpha, beta.
8 |
9 | Many combinations of these can be constrained:
10 |
11 |
12 | constrain
13 | >>> con nu
14 | >>> con psi
15 | >>> con mu
16 | >>> con nu mu a_eq_b
17 |
18 | real angles are always constrained to there last set position. If they are too far from here
19 | an error will result.
20 |
21 | >>> pos nu 0 (moves, parameter tracks last set value (actually checks it when hkl moved))
22 | >>> pos psi 90 (does not move, sets parameter in diffcalc)
23 | >>> pos mu 0 (moves)
24 | >>> pos hkl [1 0 0] (moves based on last set nu, psi, mu)
25 | >>> pos betain --> Exception, not constrained
26 |
27 | moving a virtual angle simply sets it to efftec the next hkl move
28 |
29 | Here we need onlu con, uncon and pos.
30 |
31 | ......
32 |
33 | However it would be nice to be able to pos betain for example and have it change
34 | betain while staying on the same reflection. This might be enabled by locking the
35 | the current hkl position. It would be trick to make this work with the physical angles though.
36 |
37 | >>> lock hkl
38 | >>> pos psi 90 (moves immediately)
39 | >>> scan psi 0 90 1 (scans, moving immediately)
40 | >>> pos mu 0 (does not move immediately) (could work by listening to target positions, and triggering move when complete)
41 | >>> pos c(mu) moves
42 | >>> pos mu_c moves
43 |
44 | Only one thing would be varyable at a time unless they are put in a CoordinatedMotionGroup,
45 | which would be hard for the real motors)
46 |
47 |
48 |
--------------------------------------------------------------------------------
/doc/tmp/i16_non_diffcalc_manual.txt:
--------------------------------------------------------------------------------
1 | Creating a UB Matrix
2 | There are three euler modes:
3 |
4 | =bisecting: eta and delta are fixed, phi and chi are not fixed.
5 | =fixed phi: phi and 2theta are fixed, eta and chi are not fixed.
6 | =fixed psi: Not used for creating a UB matrix .
7 | First creat a reflection file to store the reflections data using:
8 |
9 | reffile('name')
10 |
11 | Set the crystal lattice:
12 |
13 | latt([a]) assumes cubic
14 | latt([a,b]) assumes tetragonal
15 | latt([a,b,c]) assumes orthorhombic
16 | latt([a,b,c,gam]) assumes monclinic/hexagonal gam different from 90.
17 | latt([a,b,c,alp,bet,gam])
18 |
19 | Use:
20 |
21 | c2th([h k l])
22 |
23 | to calculate the 2 theta position for the hkl for example:
24 |
25 | c2th([0 0 2])
26 |
27 | Then use the following to move the diffractometer to the correct positions:
28 |
29 | pos delta c2th([0 0 2]) eta c2th([0 0 2])/2
30 |
31 | You can now scan eta, chi, and delta to optomise the peak intensity using the following scans for example:
32 |
33 | scancn eta 0.01 40 w 0.2 t 1
34 |
35 | scancn chi 0.01 40 w 0.2 t 1
36 |
37 | scancn delta 0.01 40 w 0.2 t 1
38 |
39 | A few iterations may be required.
40 |
41 | Now that you have the first reflection it can be stored using the following command:
42 |
43 | saveref('reflable',[h k l])
44 |
45 | saveref('Ti1',[0 0 2]) for the above example.
46 |
47 | Then create a dummy UB matrix using a dummy non-parallel hkl plane eg:
48 |
49 | ubm('Ti1',[2 0 0])
50 |
51 | Useing the following command to calculate the direction of the second reflection:
52 |
53 | hkl_calc([0 2 2])
54 |
55 | If the calculated positions can be safely achieved then type:
56 |
57 | pos hkl [0 2 2]
58 |
59 | Find the second reflection by scanning phi, once the reflection is found save the second reflection using:
60 |
61 | saveref('Ti2',[0 2 2]) for example.
62 |
63 | Now create a real UB-Matrix using:
64 |
65 | ubm('Ti1','Ti2')
66 |
67 | You can now drive in recriprocal space.
68 |
69 | To change the lattice parameters according the found Bragg peaks
70 |
71 | latt([latt()[0]*2/l()]) (cubic only)
--------------------------------------------------------------------------------
/install-jython-environment.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | JYTHON_URL='https://repo1.maven.org/maven2/org/python/jython-installer/2.7.1/jython-installer-2.7.1.jar'
4 | JAMA_JAR_URL='https://repo1.maven.org/maven2/gov/nist/math/jama/1.0.3/jama-1.0.3.jar'
5 | COMMONS_MATH_URL='https://repo1.maven.org/maven2/org/apache/commons/commons-math3/3.6.1/commons-math3-3.6.1.jar'
6 |
7 | # Install jars
8 | wget $JAMA_JAR_URL
9 | wget $COMMONS_MATH_URL
10 | export CLASSPATH=$PWD/jama-1.0.3.jar:$PWD/commons-math3-3.6.1.jar:$CLASSPATH
11 |
12 | # Install Jython
13 | wget $JYTHON_URL -O jython_installer.jar
14 | java -jar jython_installer.jar -s -d $HOME/jython
15 |
16 | # Install nose for Jython
17 | # TODO: move to a setup.py
18 | #$HOME/jython/bin/pip install nose==1.3.7
19 | #$HOME/jython/bin/pip install pytest==3.10.1
20 | #$HOME/jython/bin/pip install pytest-xdist==1.26.1
21 |
22 |
23 | # Download dependencies directly from Pypi
24 | # as pip is currently broken (https://github.com/jython/jython/issues/97)
25 |
26 |
27 | wget https://files.pythonhosted.org/packages/02/ee/b6e02dc6529e82b75bb06823ff7d005b141037cb1416b10c6f00fc419dca/Pygments-2.2.0-py2.py3-none-any.whl
28 | wget https://files.pythonhosted.org/packages/a1/4e/c42167ba5c3192bed633726d39d7896cc55d4fa3ec4a1fb60cd3a53fc4c7/decorator-4.1.2-py2.py3-none-any.whl
29 | wget https://files.pythonhosted.org/packages/70/c7/e8cb4a537ee4fc497ac80a606a667fd1832f28ad3ddbfa25bf30473eae13/pytest-4.6.11-py2.py3-none-any.whl
30 | wget https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl
31 | wget https://files.pythonhosted.org/packages/2c/a0/da5f49008ec6e9a658dbf5d7310a4debd397bce0b4db03cf8a410066bb87/atomicwrites-1.4.0-py2.py3-none-any.whl
32 | wget https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl
33 | wget https://files.pythonhosted.org/packages/be/be/7abce643bfdf8ca01c48afa2ddf8308c2308b0c3b239a44e57d020afa0ef/attrs-21.4.0-py2.py3-none-any.whl
34 | wget https://files.pythonhosted.org/packages/a0/28/85c7aa31b80d150b772fbe4a229487bc6644da9ccb7e427dd8cc60cb8a62/pluggy-0.13.1-py2.py3-none-any.whl
35 | wget https://files.pythonhosted.org/packages/c1/f9/9058661f6b4bb017dfe17ef84b461e4b11130c7bbee1b35cc0883ec8533b/importlib_metadata-2.1.2-py2.py3-none-any.whl
36 | wget https://files.pythonhosted.org/packages/96/0a/67556e9b7782df7118c1f49bdc494da5e5e429c93aa77965f33e81287c8c/zipp-1.2.0-py2.py3-none-any.whl
37 | wget https://files.pythonhosted.org/packages/cf/e5/989798d38831a8505d62687c94b0f2954ff0a40782e25f9add8ed675dc1f/contextlib2-0.6.0-py2.py3-none-any.whl
38 | wget https://files.pythonhosted.org/packages/7a/2a/95ed0501cf5d8709490b1d3a3f9b5cf340da6c433f896bbe9ce08dbe6785/configparser-4.0.2-py2.py3-none-any.whl
39 | wget https://files.pythonhosted.org/packages/76/67/dc02c72177ec79f0176e5bf9921e9c1745a381ed556afb3b3ecc2bb8ba2e/pathlib2-2.3.6-py2.py3-none-any.whl
40 | wget https://files.pythonhosted.org/packages/f9/d0/6b7b38eaf9964510f5c32aa5aaf9f419864d2e0ebe34274e6cba5689a0c5/scandir-1.10.0-cp27-cp27m-win_amd64.whl
41 | wget https://files.pythonhosted.org/packages/3e/89/7ea760b4daa42653ece2380531c90f64788d979110a2ab51049d92f408af/packaging-20.9-py2.py3-none-any.whl
42 | wget https://files.pythonhosted.org/packages/69/cb/f5be453359271714c01b9bd06126eaf2e368f1fddfff30818754b5ac2328/funcsigs-1.0.2-py2.py3-none-any.whl
43 | wget https://files.pythonhosted.org/packages/a4/a6/42f17d065bda1fac255db13afc94c93dbfb64393eae37c749b4cb0752fc7/more_itertools-5.0.0-py3-none-any.whl
44 | wget https://files.pythonhosted.org/packages/99/4f/13fb671119e65c4dce97c60e67d3fd9e6f7f809f2b307e2611f4701205cb/nose-1.3.7-py2-none-any.whl
45 | wget https://files.pythonhosted.org/packages/59/83/8fcdcf4babcc55290e50cbd54fcc9fcdd81c2e62eff27c1e6a2f23d79381/mock-3.0.0-py2.py3-none-any.whl
46 |
47 | unzip -d $HOME/jython/Lib/site-packages Pygments-2.2.0-py2.py3-none-any.whl
48 | unzip -d $HOME/jython/Lib/site-packages decorator-4.1.2-py2.py3-none-any.whl
49 | unzip -d $HOME/jython/Lib/site-packages pytest-4.6.11-py2.py3-none-any.whl
50 | unzip -d $HOME/jython/Lib/site-packages six-1.16.0-py2.py3-none-any.whl
51 | unzip -d $HOME/jython/Lib/site-packages atomicwrites-1.4.0-py2.py3-none-any.whl
52 | unzip -d $HOME/jython/Lib/site-packages py-1.11.0-py2.py3-none-any.whl
53 | unzip -d $HOME/jython/Lib/site-packages attrs-21.4.0-py2.py3-none-any.whl
54 | unzip -d $HOME/jython/Lib/site-packages pluggy-0.13.1-py2.py3-none-any.whl
55 | unzip -d $HOME/jython/Lib/site-packages importlib_metadata-2.1.2-py2.py3-none-any.whl
56 | unzip -d $HOME/jython/Lib/site-packages zipp-1.2.0-py2.py3-none-any.whl
57 | unzip -d $HOME/jython/Lib/site-packages contextlib2-0.6.0-py2.py3-none-any.whl
58 | unzip -d $HOME/jython/Lib/site-packages configparser-4.0.2-py2.py3-none-any.whl
59 | unzip -d $HOME/jython/Lib/site-packages pathlib2-2.3.6-py2.py3-none-any.whl
60 | unzip -d $HOME/jython/Lib/site-packages scandir-1.10.0-cp27-cp27m-win_amd64.whl
61 | unzip -d $HOME/jython/Lib/site-packages packaging-20.9-py2.py3-none-any.whl
62 | unzip -d $HOME/jython/Lib/site-packages funcsigs-1.0.2-py2.py3-none-any.whl
63 | unzip -d $HOME/jython/Lib/site-packages more_itertools-5.0.0-py3-none-any.whl
64 | unzip -d $HOME/jython/Lib/site-packages nose-1.3.7-py2-none-any.whl
65 | unzip -d $HOME/jython/Lib/site-packages mock-3.0.0-py2.py3-none-any.whl
66 |
67 |
--------------------------------------------------------------------------------
/integration_checks.py:
--------------------------------------------------------------------------------
1 | '''
2 | Created on 9 Mar 2017
3 |
4 | @author: zrb13439
5 |
6 | '''
7 |
8 | '''
9 | Integration tests for startup scripts (named so that nosetests will *not* pick
10 | up by default.
11 |
12 | This is because these must be run with:
13 |
14 | $ nosetests --with-process-isolation integration_checks.py
15 |
16 | This is not a standard nose option. Install it with:
17 |
18 | $ pip install nosepipe
19 |
20 | nosepipe is described at https://github.com/dmccombs/nosepipe/
21 | '''
22 |
23 | from nose import SkipTest
24 |
25 |
26 | def test_sixcircle_startup():
27 | import startup.sixcircle
28 | startup.sixcircle.ct.pause = False
29 | startup.sixcircle.demo.all()
30 |
31 |
32 | def test_fivecircle_startup():
33 | import startup.fivecircle
34 | startup.fivecircle.ct.pause = False
35 | startup.fivecircle.demo.all()
36 |
37 |
38 | def test_fourcircle_startup():
39 | import startup.fourcircle
40 | startup.fourcircle.ct.pause = False
41 | startup.fourcircle.demo.all()
42 |
43 |
44 | def test_i13_startup():
45 | raise SkipTest('Still need to work out to use i13s very tight limits')
46 | import startup.i13
47 | startup.i13.ct.pause = False
48 | startup.i13.demo.all()
49 |
50 |
51 | def test_i16_startup():
52 | import startup.i16
53 | startup.i16.ct.pause = False
54 | startup.i16.demo.all()
55 |
56 |
57 | def test_i21_startup_standard():
58 | import startup.i21
59 | startup.i21.ct.pause = False
60 | startup.i21.demo.all()
61 |
62 |
63 | def test_i21_startup_bespoke():
64 | import startup.i21
65 | startup.i21.ct.pause = False
66 | startup.i21.demo.i21()
67 |
68 |
69 | def test_sixcirle_api():
70 | import startup.api.sixcircle
71 | startup.api.sixcircle.demo_all()
72 |
73 |
--------------------------------------------------------------------------------
/model/README.txt:
--------------------------------------------------------------------------------
1 | Setting up the sixc vrml model to work via Epics pv's from b16's simulation running on the office network.
2 |
3 |
4 | 1. Synoptic
5 | $ launcher --port 6064
6 |
7 | 2. Shell
8 | export EPICS_CA_REPEATER_PORT=6065
9 | export EPICS_CA_SERVER_PORT=6064
10 |
11 | 3. Vrml viewer
12 | export EPICS_CA_SERVER_PORT=6064
13 | dls-vrml-epics-viewer.py fivec.wrl fivec.wcfg
14 |
--------------------------------------------------------------------------------
/model/fivec.fxw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/model/fivec.fxw
--------------------------------------------------------------------------------
/model/fivec.wcfg:
--------------------------------------------------------------------------------
1 | dad_alpha_frame rotation pv["DIFFSIM:FIVEC:ALPHA.RBV"]
2 | dad_delta_frame rotation pv["DIFFSIM:FIVEC:DELTA.RBV"]
3 | dad_omega_frame rotation pv["DIFFSIM:FIVEC:OMEGA.RBV"]
4 | dad_chi_frame rotation pv["DIFFSIM:FIVEC:CHI.RBV"]
5 | dad_phi_frame rotation pv["DIFFSIM:FIVEC:PHI.RBV"]
--------------------------------------------------------------------------------
/model/sixc.fxw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/model/sixc.fxw
--------------------------------------------------------------------------------
/model/sixc.wcfg:
--------------------------------------------------------------------------------
1 | dad_alpha_frame rotation pv["DIFFSIM:SIXC:ALPHA.RBV"]
2 | dad_delta_frame rotation pv["DIFFSIM:SIXC:DELTA.RBV"]
3 | dad_gamma_frame rotation pv["DIFFSIM:SIXC:GAMMA.RBV"]
4 | dad_omega_frame rotation pv["DIFFSIM:SIXC:OMEGA.RBV"]
5 | dad_chi_frame rotation pv["DIFFSIM:SIXC:CHI.RBV"]
6 | dad_phi_frame rotation pv["DIFFSIM:SIXC:PHI.RBV"]
7 |
--------------------------------------------------------------------------------
/model/sixc_horizontal.fxw:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/model/sixc_horizontal.fxw
--------------------------------------------------------------------------------
/model/vrml_animator.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import sys
20 | import time
21 | import threading
22 | from math import pi
23 | import socket
24 |
25 | from pivy.coin import *
26 | from pivy.sogui import *
27 |
28 |
29 | PORT = 4567
30 | TORAD = pi / 180
31 |
32 |
33 | def connect_to_socket(host, port):
34 | print "Connecting to %s on port %d" % (host, port)
35 | connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
36 | print "Connected"
37 | connection.connect((host, port))
38 | socketfile = connection.makefile('rw', 0)
39 | return socketfile
40 |
41 |
42 | def serve_socket_connection(port):
43 | print ("Serving connection on all interfaces on %s port %d" %
44 | (socket.gethostname(), port))
45 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
46 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
47 | sock.bind((socket.gethostname(), port))
48 | sock.listen(1)
49 | time.sleep(1)
50 | (connection, addr) = sock.accept()
51 | print 'Connected from ', addr, ' accepted'
52 | socket_file = connection.makefile('rw', 0) # no buffering
53 | return socket_file
54 |
55 |
56 | def node_name(anglename):
57 | return 'dad_' + anglename + '_frame'
58 |
59 |
60 | class SceneUpdatingThread(threading.Thread):
61 |
62 | def __init__(self, scene, axisnames):
63 | threading.Thread.__init__(self)
64 | self.scene = scene
65 |
66 | # Infer rotation axes based on initial orientation
67 | self.rotation_axes = {}
68 | self.axies_nodes = {}
69 | for axisname in axisnames:
70 | node = self.scene.getByName(node_name(axisname))
71 | self.axies_nodes[axisname] = node
72 | value = node.rotation.getValue()
73 | self.rotation_axes[axisname] = value.getAxisAngle()[0]
74 |
75 | def run(self):
76 | socket_file = serve_socket_connection(PORT)
77 |
78 | while True:
79 | msg = socket_file.readline()
80 | if msg == '':
81 | print '***Socket closed'
82 | socket_file = serve_socket_connection(PORT)
83 | continue
84 | print msg.strip()
85 | d = eval(msg.strip()) # msg should be a dictionary representation
86 | for axisname in d:
87 | self.set_axis_rotation(axisname, d[axisname])
88 |
89 | def set_axis_rotation(self, anglename, degrees):
90 | nodename = node_name(anglename)
91 | angle = degrees * TORAD
92 | while angle < 0:
93 | angle = 2 * pi + angle
94 | node = self.scene.getByName(nodename)
95 | getattr(node, 'rotation').setValue(
96 | self.rotation_axes[anglename], angle)
97 |
98 |
99 | class Animator(object):
100 |
101 | def __init__(self, filename, axisnames):
102 | print "filename : " + filename
103 | print " axes : " + ' '.join(axisnames)
104 | # Create viewer
105 | self.myWindow = SoGui.init(sys.argv[0]) # @UndefinedVariable
106 | if self.myWindow is None: sys.exit(1)
107 | viewer = SoGuiExaminerViewer(self.myWindow) # @UndefinedVariable
108 | # load file into scene
109 | so_input = SoInput() # @UndefinedVariable
110 | so_input.openFile(filename)
111 | self.scene = SoDB.readAll(so_input) # @UndefinedVariable
112 | # Add scene to viewer
113 | viewer.setSceneGraph(self.scene)
114 | viewer.setTitle(' '.join(axisnames))
115 | viewer.show()
116 |
117 | self.start_update_scene_thread(axisnames)
118 |
119 | def start_update_scene_thread(self, axisnames):
120 | t = SceneUpdatingThread(self.scene, axisnames)
121 | t.setDaemon(True)
122 | t.start()
123 |
124 | def show(self):
125 | SoGui.show(self.myWindow) # @UndefinedVariable
126 | SoGui.mainLoop() # @UndefinedVariable
127 |
128 | def main():
129 | animator = Animator(sys.argv[1], sys.argv[2:])
130 | animator.show()
131 |
132 | if __name__ == "__main__":
133 | main()
134 |
135 |
--------------------------------------------------------------------------------
/numjy/__init__.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | try:
20 | import Jama
21 | from numjy import linalg
22 | from numjy.jama_matrix_wrapper import matrix
23 | JAMA = True
24 | except ImportError:
25 | JAMA = False
26 |
27 |
28 | def hstack(list_of_column_matrices):
29 | if not Jama:
30 | raise Exception('Jama not available, use numpy directly')
31 | ncol = len(list_of_column_matrices)
32 | nrow = list_of_column_matrices[0].shape[0]
33 | m = Jama.Matrix(nrow, ncol)
34 | for c, column_matrix in enumerate(list_of_column_matrices):
35 | m.setMatrix(0, nrow - 1, c, c, column_matrix.m)
36 | return matrix(m)
37 |
--------------------------------------------------------------------------------
/numjy/jama_matrix_wrapper.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import Jama
20 |
21 |
22 | class matrix(object):
23 |
24 | def __init__(self, a):
25 | if isinstance(a, Jama.Matrix):
26 | self.m = a
27 | elif isinstance(a, basestring):
28 | l = []
29 | for row in a.strip().split(';'):
30 | l.append([float(element)
31 | for element in row.replace(',', ' ').split()])
32 | self.m = Jama.Matrix(l)
33 | elif isinstance(a, matrix):
34 | self.m = Jama.Matrix(a.tolist())
35 | elif isinstance(a, (list, tuple)):
36 | if isinstance(a[0], (list, tuple)):
37 | # a is a list of lists (not rigorous test!)
38 | self.m = Jama.Matrix(a)
39 | else:
40 | # a is a row vector
41 | self.m = Jama.Matrix([a])
42 | else:
43 | # give it a go
44 | self.m = Jama.Matrix(a)
45 |
46 | def __eq__(self, other):
47 | nrow, ncol = self.shape
48 | b = matrix(Jama.Matrix(nrow, ncol))
49 | for i in range(nrow):
50 | for j in range(ncol):
51 | b[i, j] = self[i, j] == other[i, j]
52 | return b
53 |
54 | @property
55 | def shape(self):
56 | return self.m.getRowDimension(), self.m.getColumnDimension()
57 |
58 | def __len__(self):
59 | return self.m.getRowDimension()
60 |
61 | def all(self): # @ReservedAssignment
62 | for row in self.m.array:
63 | if not all(row):
64 | return False
65 | return True
66 |
67 | def tolist(self):
68 | l = []
69 | nrow, ncol = self.shape
70 | for i in range(nrow):
71 | row = []
72 | for j in range(ncol):
73 | row.append(self[i, j])
74 | l.append(row)
75 | return l
76 |
77 | def sum(self): # @ReservedAssignment
78 | return sum(sum(row) for row in self.m.array)
79 |
80 | @property
81 | def I(self):
82 | return matrix(self.m.inverse())
83 |
84 | @property
85 | def T(self):
86 | return matrix(self.m.transpose())
87 |
88 | def _scaler(self, scaler):
89 | return Jama.Matrix(self.shape[0], self.shape[1], scaler)
90 |
91 | def __add__(self, other):
92 | v = other.m if isinstance(other, matrix) else self._scaler(other)
93 | return matrix(self.m.plus(v))
94 |
95 | def __sub__(self, other):
96 | v = other.m if isinstance(other, matrix) else self._scaler(other)
97 | return matrix(self.m.minus(v))
98 |
99 | def __mul__(self, other):
100 | return matrix(self.m.times(other.m if isinstance(other, matrix) else
101 | other))
102 |
103 | def __div__(self, other):
104 | # dividend = other.I if isinstance(other, matrix) else 1. /float(other)
105 | return self.__mul__(1. / float(other))
106 |
107 | def __getitem__(self, key):
108 | i, j = key
109 | return self.m.get(i, j)
110 |
111 | def __setitem__(self, key, value):
112 | i, j = key
113 | self.m.set(i, j, value)
114 |
115 | def __str__(self):
116 | insides = [' '.join([str(el) for el in row]) for row in self.tolist()]
117 | return '[[' + ']\n ['.join(insides) + ']]'
118 |
119 | def __repr__(self):
120 | return 'matrix(' + '\n '.join(self.__str__().split('\n')) + ')'
121 |
--------------------------------------------------------------------------------
/numjy/linalg.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | def norm(mat):
20 | return mat.m.normF()
21 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup, find_packages
2 |
3 | setup(
4 | name='diffcalc',
5 | version='2.1',
6 |
7 | description='A diffraction condition calculator for X-ray or neutron diffractometer control.',
8 | long_description=open('README.rst').read(),
9 | url='https://github.com/DiamondLightSource/diffcalc',
10 |
11 | author='Rob Walton',
12 | author_email='rob.walton@diamond.ac.uk',
13 |
14 | license='GNU',
15 |
16 | packages=find_packages(exclude=['docs']),
17 |
18 | install_requires=[
19 | 'numpy',
20 | 'ipython',
21 | 'pytest==3.10.1',
22 | 'pytest-xdist',
23 | 'nose',
24 | 'mock'
25 | ],
26 |
27 | entry_points={
28 | 'console_scripts': [
29 | 'diffcalc=diffcmd.diffcalc_launcher:main',
30 | ],
31 | },
32 | )
--------------------------------------------------------------------------------
/simplejson/ordered_dict.py:
--------------------------------------------------------------------------------
1 | """Drop-in replacement for collections.OrderedDict by Raymond Hettinger
2 |
3 | http://code.activestate.com/recipes/576693/
4 |
5 | """
6 | from UserDict import DictMixin
7 |
8 | # Modified from original to support Python 2.4, see
9 | # http://code.google.com/p/simplejson/issues/detail?id=53
10 | try:
11 | all
12 | except NameError:
13 | def all(seq):
14 | for elem in seq:
15 | if not elem:
16 | return False
17 | return True
18 |
19 | class OrderedDict(dict, DictMixin):
20 |
21 | def __init__(self, *args, **kwds):
22 | if len(args) > 1:
23 | raise TypeError('expected at most 1 arguments, got %d' % len(args))
24 | try:
25 | self.__end
26 | except AttributeError:
27 | self.clear()
28 | self.update(*args, **kwds)
29 |
30 | def clear(self):
31 | self.__end = end = []
32 | end += [None, end, end] # sentinel node for doubly linked list
33 | self.__map = {} # key --> [key, prev, next]
34 | dict.clear(self)
35 |
36 | def __setitem__(self, key, value):
37 | if key not in self:
38 | end = self.__end
39 | curr = end[1]
40 | curr[2] = end[1] = self.__map[key] = [key, curr, end]
41 | dict.__setitem__(self, key, value)
42 |
43 | def __delitem__(self, key):
44 | dict.__delitem__(self, key)
45 | key, prev, next = self.__map.pop(key)
46 | prev[2] = next
47 | next[1] = prev
48 |
49 | def __iter__(self):
50 | end = self.__end
51 | curr = end[2]
52 | while curr is not end:
53 | yield curr[0]
54 | curr = curr[2]
55 |
56 | def __reversed__(self):
57 | end = self.__end
58 | curr = end[1]
59 | while curr is not end:
60 | yield curr[0]
61 | curr = curr[1]
62 |
63 | def popitem(self, last=True):
64 | if not self:
65 | raise KeyError('dictionary is empty')
66 | # Modified from original to support Python 2.4, see
67 | # http://code.google.com/p/simplejson/issues/detail?id=53
68 | if last:
69 | key = reversed(self).next()
70 | else:
71 | key = iter(self).next()
72 | value = self.pop(key)
73 | return key, value
74 |
75 | def __reduce__(self):
76 | items = [[k, self[k]] for k in self]
77 | tmp = self.__map, self.__end
78 | del self.__map, self.__end
79 | inst_dict = vars(self).copy()
80 | self.__map, self.__end = tmp
81 | if inst_dict:
82 | return (self.__class__, (items,), inst_dict)
83 | return self.__class__, (items,)
84 |
85 | def keys(self):
86 | return list(self)
87 |
88 | setdefault = DictMixin.setdefault
89 | update = DictMixin.update
90 | pop = DictMixin.pop
91 | values = DictMixin.values
92 | items = DictMixin.items
93 | iterkeys = DictMixin.iterkeys
94 | itervalues = DictMixin.itervalues
95 | iteritems = DictMixin.iteritems
96 |
97 | def __repr__(self):
98 | if not self:
99 | return '%s()' % (self.__class__.__name__,)
100 | return '%s(%r)' % (self.__class__.__name__, self.items())
101 |
102 | def copy(self):
103 | return self.__class__(self)
104 |
105 | @classmethod
106 | def fromkeys(cls, iterable, value=None):
107 | d = cls()
108 | for key in iterable:
109 | d[key] = value
110 | return d
111 |
112 | def __eq__(self, other):
113 | if isinstance(other, OrderedDict):
114 | return len(self)==len(other) and \
115 | all(p==q for p, q in zip(self.items(), other.items()))
116 | return dict.__eq__(self, other)
117 |
118 | def __ne__(self, other):
119 | return not self == other
120 |
--------------------------------------------------------------------------------
/simplejson/scanner.py:
--------------------------------------------------------------------------------
1 | """JSON token scanner
2 | """
3 | import re
4 | def _import_c_make_scanner():
5 | try:
6 | from simplejson._speedups import make_scanner
7 | return make_scanner
8 | except ImportError:
9 | return None
10 | c_make_scanner = _import_c_make_scanner()
11 |
12 | __all__ = ['make_scanner']
13 |
14 | NUMBER_RE = re.compile(
15 | r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?',
16 | (re.VERBOSE | re.MULTILINE | re.DOTALL))
17 |
18 | def py_make_scanner(context):
19 | parse_object = context.parse_object
20 | parse_array = context.parse_array
21 | parse_string = context.parse_string
22 | match_number = NUMBER_RE.match
23 | encoding = context.encoding
24 | strict = context.strict
25 | parse_float = context.parse_float
26 | parse_int = context.parse_int
27 | parse_constant = context.parse_constant
28 | object_hook = context.object_hook
29 | object_pairs_hook = context.object_pairs_hook
30 | memo = context.memo
31 |
32 | def _scan_once(string, idx):
33 | try:
34 | nextchar = string[idx]
35 | except IndexError:
36 | raise StopIteration
37 |
38 | if nextchar == '"':
39 | return parse_string(string, idx + 1, encoding, strict)
40 | elif nextchar == '{':
41 | return parse_object((string, idx + 1), encoding, strict,
42 | _scan_once, object_hook, object_pairs_hook, memo)
43 | elif nextchar == '[':
44 | return parse_array((string, idx + 1), _scan_once)
45 | elif nextchar == 'n' and string[idx:idx + 4] == 'null':
46 | return None, idx + 4
47 | elif nextchar == 't' and string[idx:idx + 4] == 'true':
48 | return True, idx + 4
49 | elif nextchar == 'f' and string[idx:idx + 5] == 'false':
50 | return False, idx + 5
51 |
52 | m = match_number(string, idx)
53 | if m is not None:
54 | integer, frac, exp = m.groups()
55 | if frac or exp:
56 | res = parse_float(integer + (frac or '') + (exp or ''))
57 | else:
58 | res = parse_int(integer)
59 | return res, m.end()
60 | elif nextchar == 'N' and string[idx:idx + 3] == 'NaN':
61 | return parse_constant('NaN'), idx + 3
62 | elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity':
63 | return parse_constant('Infinity'), idx + 8
64 | elif nextchar == '-' and string[idx:idx + 9] == '-Infinity':
65 | return parse_constant('-Infinity'), idx + 9
66 | else:
67 | raise StopIteration
68 |
69 | def scan_once(string, idx):
70 | try:
71 | return _scan_once(string, idx)
72 | finally:
73 | memo.clear()
74 |
75 | return scan_once
76 |
77 | make_scanner = c_make_scanner or py_make_scanner
78 |
--------------------------------------------------------------------------------
/simplejson/tool.py:
--------------------------------------------------------------------------------
1 | r"""Command-line tool to validate and pretty-print JSON
2 |
3 | Usage::
4 |
5 | $ echo '{"json":"obj"}' | python -m simplejson.tool
6 | {
7 | "json": "obj"
8 | }
9 | $ echo '{ 1.2:3.4}' | python -m simplejson.tool
10 | Expecting property name: line 1 column 2 (char 2)
11 |
12 | """
13 | import sys
14 | import simplejson as json
15 |
16 | def main():
17 | if len(sys.argv) == 1:
18 | infile = sys.stdin
19 | outfile = sys.stdout
20 | elif len(sys.argv) == 2:
21 | infile = open(sys.argv[1], 'rb')
22 | outfile = sys.stdout
23 | elif len(sys.argv) == 3:
24 | infile = open(sys.argv[1], 'rb')
25 | outfile = open(sys.argv[2], 'wb')
26 | else:
27 | raise SystemExit(sys.argv[0] + " [infile [outfile]]")
28 | try:
29 | obj = json.load(infile,
30 | object_pairs_hook=json.OrderedDict,
31 | use_decimal=True)
32 | except ValueError, e:
33 | raise SystemExit(e)
34 | json.dump(obj, outfile, sort_keys=True, indent=' ', use_decimal=True)
35 | outfile.write('\n')
36 |
37 |
38 | if __name__ == '__main__':
39 | main()
40 |
--------------------------------------------------------------------------------
/startup/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/startup/__init__.py
--------------------------------------------------------------------------------
/startup/_common_imports.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2011 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 |
20 | from __future__ import absolute_import
21 |
22 | import os, sys
23 |
24 | from diffcalc.hardware import ScannableHardwareAdapter
25 | import diffcalc.hkl.you.geometry
26 | from diffcalc.ub.persistence import UBCalculationJSONPersister
27 | from diffcalc.hkl.you.persistence import YouStateEncoder
28 | from diffcalc import settings
29 | import diffcalc.util
30 |
31 | try:
32 | __IPYTHON__ # @UndefinedVariable
33 | IPYTHON = True
34 | except NameError:
35 | IPYTHON = False
36 |
37 | try:
38 | from gda.device.scannable.scannablegroup import ScannableGroup
39 | from gdascripts.scannable.dummy import SingleInputDummy as Dummy
40 | from diffcmd.diffcmd_utils import alias_commands
41 | GDA = True
42 | except ImportError:
43 | # Not running in gda environment so fall back to minigda emulation
44 | from diffcalc.gdasupport.minigda.scannable import ScannableGroup
45 | from diffcalc.gdasupport.minigda.scannable import SingleFieldDummyScannable as Dummy
46 | GDA = False
47 |
48 |
49 | HELP_STRING = \
50 | """Quick: https://github.com/DiamondLightSource/diffcalc/blob/master/README.rst
51 | Manual: http://diffcalc.readthedocs.io/en/latest/youmanual.html
52 | Type: > help ub
53 | > help hkl"""
54 |
55 |
56 | if GDA:
57 | from gda.configuration.properties import LocalProperties # @UnresolvedImport
58 | var_folder = LocalProperties.get("gda.var")
59 | diffcalc_persistance_path = os.path.join(var_folder, 'diffcalc')
60 | if not os.path.exists(diffcalc_persistance_path):
61 | print "Making diffcalc var folder:'%s'" % diffcalc_persistance_path
62 | os.makedirs(diffcalc_persistance_path)
63 | settings.ubcalc_persister = UBCalculationJSONPersister(diffcalc_persistance_path, YouStateEncoder)
64 | # else: should have been set if outside GDA
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/startup/_make_sixcircle_manual.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import *
2 |
3 |
4 | diffcalc.util.COLOURISE_TERMINAL_OUTPUT = False
5 |
6 | ### Create dummy scannables ###
7 | print "Dummy scannables: sixc(mu, delta, gam, eta, chi, phi) and en"
8 | mu = Dummy('mu')
9 | delta = Dummy('delta')
10 | gam = Dummy('gam')
11 | eta = Dummy('eta')
12 | chi = Dummy('chi')
13 | phi = Dummy('phi')
14 | _sixc = ScannableGroup('sixc', (mu, delta, gam, eta, chi, phi))
15 | en = Dummy('en')
16 | en.level = 3
17 |
18 |
19 | ### Configure and import diffcalc objects ###
20 | ESMTGKeV = 1
21 | settings.hardware = ScannableHardwareAdapter(_sixc, en, ESMTGKeV)
22 | settings.geometry = diffcalc.hkl.you.geometry.SixCircle() # @UndefinedVariable
23 | settings.energy_scannable = en
24 | settings.axes_scannable_group= _sixc
25 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
26 |
27 |
28 | # For manual!
29 | from diffcalc.ub.persistence import UbCalculationNonPersister
30 | settings.ubcalc_persister = UbCalculationNonPersister()
31 |
32 | from diffcalc.gdasupport.you import * # @UnusedWildImport
33 |
34 |
35 | DIFFCALC_ROOT = os.sep.join(
36 | os.path.realpath(diffcalc.__file__).split(os.sep)[:-2])
37 |
38 | MANUALS_TO_MAKE = [
39 | os.path.join(
40 | DIFFCALC_ROOT, 'doc', 'source', 'youmanual_template.rst'),
41 | os.path.join(
42 | DIFFCALC_ROOT, 'README_template.rst')]
43 |
44 | print 'MANUALS_TO_MAKE: ', MANUALS_TO_MAKE
45 |
--------------------------------------------------------------------------------
/startup/api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/startup/api/__init__.py
--------------------------------------------------------------------------------
/startup/api/sixcircle.py:
--------------------------------------------------------------------------------
1 |
2 | from __future__ import absolute_import
3 |
4 |
5 | from diffcalc import settings
6 | from diffcalc.hkl.you.geometry import SixCircle
7 | from diffcalc.hardware import DummyHardwareAdapter
8 | import diffcalc.util # @UnusedImport
9 |
10 |
11 | # Disable error handling designed for interactive use
12 | diffcalc.util.DEBUG = True
13 |
14 |
15 | # Configure and import diffcalc objects
16 | settings.hardware = DummyHardwareAdapter(('mu', 'delta', 'gam', 'eta', 'chi', 'phi'))
17 | settings.geometry = SixCircle() # @UndefinedVariable
18 |
19 |
20 | # These must be imported AFTER the settings have been configured
21 | from diffcalc.dc import dcyou as dc
22 | from diffcalc.ub import ub
23 | from diffcalc import hardware
24 | from diffcalc.hkl.you import hkl
25 |
26 | # Set some limits
27 | hardware.setmin('gam', -179)
28 | hardware.setmax('gam', 179)
29 |
30 | # These demos reproduce the outline in the developer guide
31 | def demo_all():
32 | demo_orient()
33 | demo_motion()
34 |
35 |
36 | def demo_orient():
37 |
38 | ub.listub()
39 |
40 | # Create a new ub calculation and set lattice parameters
41 | ub.newub('test')
42 | ub.setlat('cubic', 1, 1, 1, 90, 90, 90)
43 |
44 | # Add 1st reflection (demonstrating the hardware adapter)
45 | settings.hardware.wavelength = 1
46 | ub.c2th([1, 0, 0]) # energy from hardware
47 | settings.hardware.position = 0, 60, 0, 30, 0, 0
48 | ub.addref([1, 0, 0])# energy and position from hardware
49 |
50 | # Add 2nd reflection (this time without the harware adapter)
51 | ub.c2th([0, 1, 0], 12.39842)
52 | ub.addref([0, 1, 0], [0, 60, 0, 30, 0, 90], 12.39842)
53 |
54 | # check the state
55 | ub.ub()
56 | ub.checkub()
57 |
58 |
59 | def demo_motion():
60 | dc.angles_to_hkl((0., 60., 0., 30., 0., 0.))
61 | hkl.con('qaz', 90)
62 | hkl.con('a_eq_b')
63 | hkl.con('mu', 0)
64 |
65 | hardware.setmin('delta', 0)
66 | dc.hkl_to_angles(1, 0, 0)
67 |
68 |
69 | demo_all()
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/startup/b16.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import *
2 | from diffcalc.hkl.you.geometry import YouPosition
3 | import diffcalc.hkl.you.geometry
4 |
5 | if GDA:
6 | from __main__ import delta, theta, chi, phi
7 |
8 | from diffcalc.hkl.you.geometry import YouRemappedGeometry
9 |
10 | class FourCircleB16(YouRemappedGeometry):
11 | """For a diffractometer with angles:
12 | delta, theta, chi, phi
13 | """
14 | def __init__(self, beamline_axes_transform=None):
15 | YouRemappedGeometry.__init__(self, 'fourc', {"gam": 0, "mu": 0}, beamline_axes_transform)
16 |
17 | # Order should match scannable order in _fourc group for mapping to work correctly
18 | self._scn_mapping_to_int = (('delta', lambda x: x),
19 | ('eta', lambda x: x),
20 | ('chi', lambda x: x + 90.0),
21 | ('phi', lambda x: x))
22 | self._scn_mapping_to_ext = (('delta', lambda x: x),
23 | ('eta', lambda x: x),
24 | ('chi', lambda x: x - 90.0),
25 | ('phi', lambda x: x))
26 |
27 | if GDA:
28 | from scannable.extraNameHider import ExtraNameHider
29 | dummy_energy = Dummy('dummy_energy')
30 | simple_energy = ExtraNameHider('energy', dummy_energy) # @UndefinedVariable
31 |
32 | else: # Assume running in dummy mode outside GDA
33 | delta = Dummy('delta')
34 | theta = Dummy('theta')
35 | chi = Dummy('chi')
36 | phi = Dummy('phi')
37 | energy = simple_energy = Dummy('energy')
38 | energy.level = 3
39 |
40 | ### Configure and import diffcalc objects ###
41 |
42 | ESMTGKeV = 0.001
43 | euler = ScannableGroup('euler', (delta, theta, chi, phi))
44 |
45 | settings.hardware = ScannableHardwareAdapter(euler, simple_energy, ESMTGKeV)
46 | settings.geometry = FourCircleB16()
47 | settings.energy_scannable = simple_energy
48 | settings.axes_scannable_group= euler
49 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
50 |
51 | from diffcalc.gdasupport.you import * # @UnusedWildImport
52 |
53 | hkl.setLevel(6)
54 |
55 | if GDA:
56 | print "Running in GDA --- aliasing commands"
57 | alias_commands(globals())
58 |
59 | #lastub() # Load the last ub calculation used
60 |
61 | from startup.beamlinespecific.azihkl import AzihklClass
62 | azihkl=AzihklClass('aziref')
63 | azihkl()
64 |
65 | # iPython removes the actual command from namespace
66 | if not GDA:
67 | diffcalc.hardware.setrange(chi, -96.4, 259.4)
68 | diffcalc.hardware.setrange(phi, -147, 150)
69 | diffcalc.hardware.setrange(theta, -100, 235)
70 | diffcalc.hardware.setrange(delta, -10.4, 101.9)
71 | setcut(phi, -180)
72 |
--------------------------------------------------------------------------------
/startup/beamlinespecific/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DiamondLightSource/diffcalc/e72db71307a65fbd2c30c1ab37422297a6cfaa25/startup/beamlinespecific/__init__.py
--------------------------------------------------------------------------------
/startup/beamlinespecific/azihkl.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2018 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | import platform
20 | from diffcalc.util import DiffcalcException
21 |
22 | DEBUG = False
23 |
24 | try:
25 | from gda.device.scannable import ScannableBase
26 | except ImportError:
27 | from diffcalc.gdasupport.minigda.scannable import ScannableBase
28 |
29 | from diffcalc.ub.ub import ubcalc, _to_column_vector_triple
30 |
31 |
32 | class _DynamicDocstringMetaclass(type):
33 |
34 | def _get_doc(self):
35 | return AzihklClass.dynamic_docstring
36 |
37 | __doc__ = property(_get_doc) # @ReservedAssignment
38 |
39 |
40 | class AzihklClass(ScannableBase):
41 | 'Azimuthal reference reciprocal lattice vector'
42 |
43 | if platform.system() != 'Java':
44 | __metaclass__ = _DynamicDocstringMetaclass # TODO: Removed to fix Jython
45 |
46 | dynamic_docstring = 'Azimuthal reference reciprocal lattice vector'
47 |
48 | def _get_doc(self):
49 | return AzihklClass.dynamic_docstring
50 |
51 | __doc__ = property(_get_doc) # @ReservedAssignment
52 |
53 | def __init__(self,name):
54 | self.setName(name)
55 | self.setLevel(3)
56 | self.setInputNames(['azih','azik','azil'])
57 | self.setOutputFormat(['%4.4f', '%4.4f','%4.4f'])
58 |
59 | def asynchronousMoveTo(self,new_position):
60 | ref_matrix = _to_column_vector_triple(new_position)
61 | ubcalc.set_n_hkl_configured(ref_matrix)
62 |
63 | def isBusy(self):
64 | return 0
65 |
66 | def getPosition(self):
67 | try:
68 | ref_matrix = ubcalc.n_hkl
69 | return ref_matrix.T.tolist()[0]
70 | except DiffcalcException, e:
71 | print e
72 |
--------------------------------------------------------------------------------
/startup/beamlinespecific/i21.py:
--------------------------------------------------------------------------------
1 | ###
2 | # Copyright 2008-2019 Diamond Light Source Ltd.
3 | # This file is part of Diffcalc.
4 | #
5 | # Diffcalc is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Diffcalc is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Diffcalc. If not, see .
17 | ###
18 |
19 | try:
20 | from gda.device.scannable.scannablegroup import ScannableGroup
21 | except ImportError:
22 | from diffcalc.gdasupport.minigda.scannable import ScannableGroup
23 |
24 | from diffcalc.gdasupport.scannable.diffractometer import DiffractometerScannableGroup
25 | from diffcalc.settings import NUNAME
26 | from diffcalc.hkl.you.geometry import YouRemappedGeometry
27 |
28 |
29 | TP_TOLL = 1e-4
30 |
31 | class FourCircleI21(YouRemappedGeometry):
32 | """For a diffractometer with angles:
33 | delta, eta, chi, phi
34 | """
35 | def __init__(self, beamline_axes_transform=None, delta_offset=0):
36 | self._delta_offset = delta_offset
37 | YouRemappedGeometry.__init__(self, 'fourc', {'eta': 0, 'delta': 0}, beamline_axes_transform)
38 |
39 | # Order should match scannable order in _fourc group for mapping to work correctly
40 | self._scn_mapping_to_int = ((NUNAME, lambda x: x + self._delta_offset),
41 | ('mu', lambda x: x),
42 | ('chi', lambda x: x),
43 | ('phi', lambda x: -x))
44 | self._scn_mapping_to_ext = ((NUNAME, lambda x: x - self._delta_offset),
45 | ('mu', lambda x: x),
46 | ('chi', lambda x: x),
47 | ('phi', lambda x: -x))
48 |
49 | class TPScannableGroup(ScannableGroup):
50 |
51 | def asynchronousMoveTo(self, position):
52 | # if input has any Nones, then replace these with the current positions
53 | current = self.getPosition()
54 | if None in position:
55 | position = list(position)
56 | for idx, val in enumerate(position):
57 | if val is None:
58 | position[idx] = current[idx]
59 |
60 | for scn, pos, cur in zip(self.getGroupMembers(), position, current):
61 | if abs(pos - cur) < TP_TOLL:
62 | continue
63 | scn.asynchronousMoveTo(pos)
64 | scn.waitWhileBusy()
65 |
66 | class DiffractometerTPScannableGroup(DiffractometerScannableGroup):
67 |
68 | def asynchronousMoveTo(self, position):
69 | # if input has any Nones, then replace these with the current positions
70 | current = self.getPosition()
71 | if None in position:
72 | position = list(position)
73 | for idx, val in enumerate(position):
74 | if val is None:
75 | position[idx] = current[idx]
76 |
77 | for scn, pos, cur in zip(self.__motors, position, current):
78 | if abs(pos - cur) < TP_TOLL:
79 | continue
80 | scn.asynchronousMoveTo(pos)
81 | scn.waitWhileBusy()
82 |
83 |
84 |
--------------------------------------------------------------------------------
/startup/fivecircle.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import *
2 | import startup._demo
3 |
4 | ### Create dummy scannables ###
5 | print "Diffcalc creating dummy Scannables as _fivec and en were not found"
6 | delta = Dummy('delta')
7 | gam = Dummy('gam')
8 | eta = Dummy('eta')
9 | chi = Dummy('chi')
10 | phi = Dummy('phi')
11 | _fivec = ScannableGroup('_fivec', (delta, gam, eta, chi, phi))
12 | en = Dummy('en')
13 | en.level = 3
14 |
15 |
16 | ### Configure and import diffcalc objects ###
17 | ESMTGKeV = 1
18 | settings.hardware = ScannableHardwareAdapter(_fivec, en, ESMTGKeV)
19 | settings.geometry = diffcalc.hkl.you.geometry.FiveCircle() # @UndefinedVariable
20 | settings.energy_scannable = en
21 | settings.axes_scannable_group = _fivec
22 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
23 |
24 | from diffcalc.gdasupport.you import * # @UnusedWildImport
25 |
26 | if GDA:
27 | print "Running in GDA --- aliasing commands"
28 | alias_commands(globals())
29 |
30 | lastub() # Load the last ub calculation used
31 |
32 | # Set some limits
33 | setmin('gam', -179)
34 | setmax('gam', 179)
35 |
36 | demo = startup._demo.Demo(globals(), 'fivec')
--------------------------------------------------------------------------------
/startup/fourcircle.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import *
2 | import startup._demo
3 |
4 | ### Create dummy scannables ###
5 | delta = Dummy('delta')
6 | eta = Dummy('eta')
7 | chi = Dummy('chi')
8 | phi = Dummy('phi')
9 | _fourc = ScannableGroup('_fourc', (delta, eta, chi, phi))
10 | en = Dummy('en')
11 | en.level = 3
12 |
13 |
14 | ### Configure and import diffcalc objects ###
15 | ESMTGKeV = 1
16 | settings.hardware = ScannableHardwareAdapter(_fourc, en, ESMTGKeV)
17 | settings.geometry = diffcalc.hkl.you.geometry.FourCircle() # @UndefinedVariable
18 | settings.energy_scannable = en
19 | settings.axes_scannable_group= _fourc
20 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
21 |
22 | from diffcalc.gdasupport.you import * # @UnusedWildImport
23 |
24 | if GDA:
25 | print "Running in GDA --- aliasing commands"
26 | alias_commands(globals())
27 |
28 | # Load the last ub calculation used
29 | lastub()
30 |
31 | demo = startup._demo.Demo(globals(), 'fourc')
--------------------------------------------------------------------------------
/startup/i06.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import * # @UnusedWildImport
2 | from diffcalc.gdasupport.minigda.scannable import ScannableMotionWithScannableFieldsBase # @UnusedImport
3 |
4 | from diffcalc.hkl.you.geometry import YouGeometry, YouPosition
5 | from diffcalc.settings import NUNAME
6 | from diffcalc.hardware import setrange
7 | from diffcalc.hkl.you.calc import SMALL
8 | if not GDA:
9 | import startup._demo
10 | else:
11 | # import __main__ # @UnresolvedImport
12 | from __main__ import dd2th,ddth,dummychi,energy # @UnresolvedImport
13 | LOCAL_MANUAL = "http://confluence.diamond.ac.uk/pages/viewpage.action?pageId=31853413"
14 | # Diffcalc i06-1
15 | # ======== ===
16 | # delta dd2th
17 | # eta ddth
18 | # chi dummy
19 | # phi 0
20 |
21 | class ThreeCircleI06(YouGeometry):
22 | """For a diffractometer with theta two-theta geometry:
23 | delta, eta
24 | """
25 | def __init__(self, beamline_axes_transform=None):
26 | YouGeometry.__init__(self, 'threec', {'mu': 0, NUNAME: 0, 'phi': 0}, beamline_axes_transform)
27 |
28 | def physical_angles_to_internal_position(self, physical_angle_tuple):
29 | # mu, delta, nu, eta, chi, phi
30 | delta_phys, eta_phys, chi_phys = physical_angle_tuple
31 | return YouPosition(0, delta_phys, 0, eta_phys, chi_phys, 0, 'DEG')
32 |
33 | def internal_position_to_physical_angles(self, internal_position):
34 | clone_position = internal_position.clone()
35 | clone_position.changeToDegrees()
36 | _, delta_phys, _, eta_phys, chi_phys, _ = clone_position.totuple()
37 | return delta_phys, eta_phys, chi_phys
38 |
39 |
40 | ### Create dummy scannables ###
41 | if GDA:
42 | print "!!! Starting LIVE diffcalc with delta(dd2th), eta(ddth), chi(dummy) and denergy."
43 | _threec = ScannableGroup('_threec', (dd2th, ddth, dummychi))
44 | delta = _threec.dd2th
45 | eta = _threec.ddth
46 | en=energy
47 | # if float(en.getPosition()) == 0: # no energy value - dummy mode
48 | # en(800)
49 |
50 | else:
51 | delta = Dummy('delta')
52 | eta = Dummy('eta')
53 | chi = Dummy('chi')
54 | _threec = ScannableGroup('_threec', (delta, eta, chi))
55 | en = Dummy('en')
56 | en(800)
57 |
58 | en.level = 3
59 |
60 | ### Configure and import diffcalc objects ###
61 | ESMTGKeV = 0.001
62 | settings.hardware = ScannableHardwareAdapter(_threec, en, ESMTGKeV)
63 | settings.geometry = ThreeCircleI06() # @UndefinedVariable
64 | settings.energy_scannable = en
65 | settings.axes_scannable_group= _threec
66 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
67 |
68 | if not GDA:
69 | setrange('chi', 90 - SMALL, 90 + SMALL)
70 |
71 | from diffcalc.gdasupport.you import * # @UnusedWildImport
72 |
73 | if GDA:
74 | print "Running in GDA --- aliasing commands"
75 | alias_commands(globals())
76 |
77 | # Load the last ub calculation used
78 | lastub()
79 |
--------------------------------------------------------------------------------
/startup/i07EH1h.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import * # @UnusedWildImport
2 | from diffcalc.settings import NUNAME
3 |
4 | if GDA:
5 | from __main__ import diff1delta, diff1chi, diff1gamma, diff1theta, dcm1energy # @UnresolvedImport
6 |
7 | from diffcalc.hkl.you.geometry import YouRemappedGeometry
8 |
9 | try:
10 | from numpy import matrix
11 | except ImportError:
12 | from numjy import matrix
13 |
14 |
15 | class FourCircleI07EH1h(YouRemappedGeometry):
16 | """For a diffractometer with angles:
17 | delta, gam, eta, phi
18 | """
19 | def __init__(self, beamline_axes_transform=None):
20 | YouRemappedGeometry.__init__(self, 'fourc', {'mu': 0, 'chi': 90}, beamline_axes_transform)
21 |
22 | # Order should match scannable order in _fourc group for mapping to work correctly
23 | omega_to_phi = lambda x: 180. - x
24 | self._scn_mapping_to_int = (('delta', lambda x: x),
25 | ('gam', lambda x: x),
26 | ('eta', lambda x: x),
27 | ('phi', omega_to_phi))
28 | phi_to_omega = lambda x: ((180. - x) + 180.) % 360 - 180
29 | self._scn_mapping_to_ext = (('delta', lambda x: x),
30 | ('gam', lambda x: x),
31 | ('eta', lambda x: x),
32 | ('phi', phi_to_omega))
33 |
34 | ### Create dummy scannables ###
35 | if GDA:
36 | ###map GDA scannable to diffcalc axis name###
37 | _fourc = ScannableGroup('_fourc', (diff1delta, diff1gamma, diff1chi, diff1theta))
38 | delta=_fourc.diff1delta
39 | gamma=_fourc.diff1gamma
40 | chi=_fourc.diff1chi
41 | theta=_fourc.diff1theta
42 | omega = diff1omega
43 | en=dcm1energy
44 | if float(en.getPosition()) == 0: # no energy value - dummy mode
45 | en(800)
46 | else:
47 | #Create dummy axes to run outside GDA in IPython#
48 | delta = Dummy('delta')
49 | gamma = Dummy('gamma')
50 | chi = Dummy('chi')
51 | theta = Dummy('theta')
52 | _fourc = ScannableGroup('_fourc', (delta, gamma, chi, theta))
53 | en = Dummy('en')
54 | en(800)
55 |
56 | en.level = 3
57 |
58 | ### Configure and import diffcalc objects ###
59 | ESMTGKeV = 1
60 | settings.hardware = ScannableHardwareAdapter(_fourc, en, ESMTGKeV)
61 | settings.geometry = FourCircleI07EH1h() # @UndefinedVariable
62 | settings.energy_scannable = en
63 | settings.axes_scannable_group= _fourc
64 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
65 | settings.include_reference = False
66 |
67 | from diffcalc.gdasupport.you import * # @UnusedWildImport
68 |
69 | if GDA:
70 | omega = diff1omega
71 | print "Running in GDA --- aliasing commands"
72 | alias_commands(globals())
73 |
74 | # Load the last ub calculation used
75 | lastub()
76 | # Set reference vector direction returning betain and betaout angles as theta and beta
77 | if ubcalc.name:
78 | surfnphi('0; 0; 1')
79 |
80 | ### Set i07 specific limits
81 | def setLimitsAndCuts():
82 | ''' set motor limits for diffcalc, these are within the actual motor limits
83 | '''
84 | setmin(delta, -11.275)
85 | setmax(delta, 100.0)
86 | setmin(gamma, -11.0)
87 | setmax(gamma, 49.934)
88 | setmin(chi, -5.096)
89 | setmax(chi, 5.115)
90 | setcut(omega, -180.0)
91 | print "Current hardware limits set to:"
92 | hardware()
93 |
94 | if not GDA:
95 | setLimitsAndCuts()
96 |
97 | # TODO: make demo code for (2+2) diffractometer geometry
98 | #if not GDA:
99 | # demo = startup._demo.Demo(globals(), 'fourc')
100 |
--------------------------------------------------------------------------------
/startup/i07EH1v.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import * # @UnusedWildImport
2 | from diffcalc.settings import NUNAME
3 |
4 | if GDA:
5 | from __main__ import diff1delta, diff1theta, diff1gamma, diff1omega, dcm1energy # @UnresolvedImport
6 |
7 | from diffcalc.hkl.you.geometry import YouGeometry, YouPosition
8 |
9 |
10 | class FourCircleI07EH1v(YouGeometry):
11 | """For a diffractometer with angles:
12 | delta, gam, mu, phi
13 | """
14 | def __init__(self, beamline_axes_transform=None):
15 | YouGeometry.__init__(self, 'fourc', {'eta': 0, 'chi': 0}, beamline_axes_transform)
16 |
17 | def physical_angles_to_internal_position(self, physical_angle_tuple):
18 | delta_phys, gam_phys, mu_phys, phi_phys = physical_angle_tuple
19 | return YouPosition(mu_phys, delta_phys, gam_phys, 0, 0, phi_phys, 'DEG')
20 |
21 | def internal_position_to_physical_angles(self, internal_position):
22 | clone_position = internal_position.clone()
23 | clone_position.changeToDegrees()
24 | mu_phys, delta_phys, gam_phys, _, _, phi_phys = clone_position.totuple()
25 | return delta_phys, gam_phys, mu_phys, phi_phys
26 |
27 |
28 | ### Create dummy scannables ###
29 | if GDA:
30 | ###map GDA scannable to diffcalc axis name###
31 | _fourc = ScannableGroup('_fourc', (diff1delta, diff1gamma, diff1theta, diff1omega))
32 | delta=_fourc.diff1delta
33 | gamma = _fourc.diff1gamma
34 | omega = _fourc.diff1omega
35 | chi = diff1chi
36 | theta = diff1theta
37 | en=dcm1energy
38 | else:
39 | #Create dummy axes to run outside GDA in IPython#
40 | delta = Dummy('delta')
41 | gamma = Dummy('gamma')
42 | theta = Dummy('theta')
43 | omega = Dummy('omega')
44 | _fourc = ScannableGroup('_fourc', (delta, gamma, theta, omega))
45 | en = Dummy('en')
46 |
47 | en.level = 3
48 |
49 | ### Configure and import diffcalc objects ###
50 | ESMTGKeV = 1
51 | settings.hardware = ScannableHardwareAdapter(_fourc, en, ESMTGKeV)
52 | settings.geometry = FourCircleI07EH1v() # @UndefinedVariable
53 | settings.energy_scannable = en
54 | settings.axes_scannable_group= _fourc
55 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
56 | settings.include_reference = False
57 |
58 | from diffcalc.gdasupport.you import * # @UnusedWildImport
59 |
60 | if GDA:
61 | omega = _fourc.diff1omega
62 | print "Running in GDA --- aliasing commands"
63 | alias_commands(globals())
64 |
65 | # Load the last ub calculation used
66 | lastub()
67 | # Set reference vector direction returning betain and betaout angles as theta and beta
68 | if ubcalc.name:
69 | surfnphi('0; 0; 1')
70 |
71 | ### Set i07 specific limits
72 | def setLimitsAndCuts():
73 | ''' set motor limits for diffcalc, these are within the actual motor limits
74 | '''
75 | setmin(delta, -11.275)
76 | setmax(delta, 100.0)
77 | setmin(gamma, -11.0)
78 | setmax(gamma, 49.934)
79 | setmin(theta, -6.561)
80 | setmax(theta, 29.163)
81 | setcut(omega, -180.0)
82 | print "Current hardware limits set to:"
83 | hardware()
84 |
85 | if not GDA:
86 | setLimitsAndCuts()
87 |
88 | # TODO: make demo code for (2+2) diffractometer geometry
89 | #if not GDA:
90 | # demo = startup._demo.Demo(globals(), 'fourc')
91 |
--------------------------------------------------------------------------------
/startup/i07EH2v.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import * # @UnusedWildImport
2 | from diffcalc.settings import NUNAME
3 |
4 | if GDA:
5 | from __main__ import diff2delta, diff2alpha, diff2gamma, diff2omega, dcm1energy # @UnresolvedImport
6 |
7 | from diffcalc.hkl.you.geometry import YouGeometry, YouPosition
8 |
9 |
10 | class FourCircleI07EH2v(YouGeometry):
11 | """For a diffractometer with angles:
12 | delta, gam, mu, phi
13 | """
14 | def __init__(self, beamline_axes_transform=None):
15 | YouGeometry.__init__(self, 'fourc', {'eta': 0, 'chi': 0}, beamline_axes_transform)
16 |
17 | def physical_angles_to_internal_position(self, physical_angle_tuple):
18 | delta_phys, gam_phys, mu_phys, phi_phys = physical_angle_tuple
19 | return YouPosition(mu_phys, delta_phys, gam_phys, 0, 0, phi_phys, 'DEG')
20 |
21 | def internal_position_to_physical_angles(self, internal_position):
22 | clone_position = internal_position.clone()
23 | clone_position.changeToDegrees()
24 | mu_phys, delta_phys, gam_phys, _, _, phi_phys = clone_position.totuple()
25 | return delta_phys, gam_phys, mu_phys, phi_phys
26 |
27 |
28 | ### Create dummy scannables ###
29 | if GDA:
30 | ###map GDA scannable to diffcalc axis name###
31 | _fourc = ScannableGroup('_fourc', (diff2delta, diff2gamma, diff2alpha, diff2omega))
32 | delta=_fourc.diff2delta
33 | gamma = _fourc.diff2gamma
34 | alpha = _fourc.diff2alpha
35 | omega = _fourc.diff2omega
36 | en=dcm1energy
37 | else:
38 | #Create dummy axes to run outside GDA in IPython#
39 | delta = Dummy('delta')
40 | gamma = Dummy('gamma')
41 | alpha = Dummy('alpha')
42 | omega = Dummy('omega')
43 | _fourc = ScannableGroup('_fourc', (delta, gamma, alpha, omega))
44 | en = Dummy('en')
45 |
46 | en.level = 3
47 |
48 | ### Configure and import diffcalc objects ###
49 | ESMTGKeV = 1
50 | settings.hardware = ScannableHardwareAdapter(_fourc, en, ESMTGKeV)
51 | settings.geometry = FourCircleI07EH2v() # @UndefinedVariable
52 | settings.energy_scannable = en
53 | settings.axes_scannable_group= _fourc
54 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
55 | settings.include_reference = False
56 |
57 | from diffcalc.gdasupport.you import * # @UnusedWildImport
58 |
59 | if GDA:
60 | omega = _fourc.diff2omega
61 | print "Running in GDA --- aliasing commands"
62 | alias_commands(globals())
63 |
64 | # Load the last ub calculation used
65 | lastub()
66 | # Set reference vector direction returning betain and betaout angles as alpha and beta
67 | if ubcalc.name:
68 | surfnphi('0; 0; 1')
69 |
70 | ### Set i07 specific limits
71 | def setLimitsAndCuts():
72 | ''' set motor limits for diffcalc, these are within the actual motor limits
73 | '''
74 | setmin(delta, -0.60755)
75 | setmax(delta, 120.0)
76 | setmin(gamma, -1.3913)
77 | setmax(gamma, 48.160)
78 | setmin(alpha, -2.5124)
79 | setmax(alpha, 24.107)
80 | setcut(omega, -180.0)
81 | print "Current hardware limits set to:"
82 | hardware()
83 |
84 | if not GDA:
85 | setLimitsAndCuts()
86 |
87 | # TODO: make demo code for (2+2) diffractometer geometry
88 | #if not GDA:
89 | # demo = startup._demo.Demo(globals(), 'fourc')
90 |
--------------------------------------------------------------------------------
/startup/i16robot.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import *
2 | from diffcalc.hkl.you.geometry import YouPosition
3 | import diffcalc.hkl.you.geometry
4 |
5 | if GDA:
6 | from __main__ import delta, gam, rmu, reta, rchi, rphi # @UnresolvedImport
7 |
8 | if not GDA:
9 | import startup._demo
10 |
11 | LOCAL_MANUAL = 'http://confluence.diamond.ac.uk/display/I16/Diffcalc%20(i16)'
12 |
13 | class SixCircleI16(diffcalc.hkl.you.geometry.YouGeometry):
14 | def __init__(self):
15 | diffcalc.hkl.you.geometry.YouGeometry.__init__(self, 'sixc', {})
16 |
17 | def physical_angles_to_internal_position(self, physical_angle_tuple):
18 | # i16: phi, chi, eta, mu, delta, gam
19 | # H. You: mu, delta, nu, eta, chi, phi
20 | phi_phys, chi_phys, eta_phys, mu_phys, delta_phys, gam_phys = physical_angle_tuple
21 | return YouPosition(mu_phys, delta_phys, gam_phys, eta_phys, chi_phys, phi_phys, unit='DEG')
22 |
23 | def internal_position_to_physical_angles(self, internal_position):
24 | clone_position = internal_position.clone()
25 | clone_position.changeToDegrees()
26 | mu_phys, delta_phys, nu_phys, eta_phys, chi_phys, phi_phys = clone_position.totuple()
27 | return phi_phys, chi_phys, eta_phys, mu_phys, delta_phys, nu_phys
28 |
29 |
30 | if GDA:
31 | from scannable.extraNameHider import ExtraNameHider
32 | dummy_energy = Dummy('dummy_energy')
33 | simple_energy = ExtraNameHider('energy', dummy_energy) # @UndefinedVariable
34 | reuler = ScannableGroup('reuler', (rphi, rchi, reta, rmu, delta, gam))
35 | phi = reuler.phi
36 | chi = reluer.chi
37 | eta = reuler.eta
38 | mu = reuler.mu
39 | else: # Assume running in dummy mode outside GDA
40 | mu = Dummy('mu')
41 | delta = Dummy('delta')
42 | gam = Dummy('gam')
43 | eta = Dummy('eta')
44 | chi = Dummy('chi')
45 | phi = Dummy('phi')
46 | euler = ScannableGroup('euler', (phi, chi, eta, mu, delta, gam))
47 | en = simple_energy = Dummy('energy')
48 | en.level = 3
49 |
50 |
51 | ### Configure and import diffcalc objects ###
52 | ESMTGKeV = 1
53 | settings.hardware = ScannableHardwareAdapter(reuler, simple_energy, ESMTGKeV)
54 | settings.geometry = SixCircleI16()
55 | settings.energy_scannable = simple_energy
56 | settings.axes_scannable_group= reuler
57 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
58 |
59 | from diffcalc.gdasupport.you import * # @UnusedWildImport
60 |
61 | hkl.setLevel(6)
62 |
63 | if GDA:
64 | print "Running in GDA --- aliasing commands"
65 | alias_commands(globals())
66 |
67 | lastub() # Load the last ub calculation used
68 |
69 | from startup.beamlinespecific.azihkl import AzihklClass
70 | azihkl=AzihklClass('aziref')
71 | azihkl()
72 |
73 | # iPython removes the actual command from namespace
74 | if not GDA:
75 | diffcalc.hardware.setrange(chi, -2, 100)
76 | diffcalc.hardware.setrange(eta, -2, 92)
77 | diffcalc.hardware.setrange(delta, -2, 145)
78 | diffcalc.hardware.setrange(gam, -2, 145)
79 | setcut(phi, -180)
80 |
81 | demo = startup._demo.Demo(globals(), 'i16')
82 |
--------------------------------------------------------------------------------
/startup/sixcircle.py:
--------------------------------------------------------------------------------
1 | from startup._common_imports import *
2 | import startup._demo
3 |
4 | ### Create dummy scannables ###
5 | mu = Dummy('mu')
6 | delta = Dummy('delta')
7 | gam = Dummy('gam')
8 | eta = Dummy('eta')
9 | chi = Dummy('chi')
10 | phi = Dummy('phi')
11 | _sixc = ScannableGroup('_sixc', (mu, delta, gam, eta, chi, phi))
12 | en = Dummy('en')
13 | en.level = 3
14 |
15 |
16 | ### Configure and import diffcalc objects ###
17 | ESMTGKeV = 1
18 | settings.hardware = ScannableHardwareAdapter(_sixc, en, ESMTGKeV)
19 | settings.geometry = diffcalc.hkl.you.geometry.SixCircle() # @UndefinedVariable
20 | settings.energy_scannable = en
21 | settings.axes_scannable_group= _sixc
22 | settings.energy_scannable_multiplier_to_get_KeV = ESMTGKeV
23 |
24 | from diffcalc.gdasupport.you import * # @UnusedWildImport
25 |
26 | if GDA:
27 | print "Running in GDA --- aliasing commands"
28 | alias_commands(globals())
29 |
30 | # Load the last ub calculation used
31 | lastub()
32 |
33 | # Set some limits
34 | setmin('gam', -179)
35 | setmax('gam', 179)
36 |
37 | demo = startup._demo.Demo(globals(), 'sixc')
--------------------------------------------------------------------------------
/todo.txt:
--------------------------------------------------------------------------------
1 | Complete restructure work:
2 | --------------------------
3 |
4 | Merge current mast in
5 |
6 | Make sure we can start the willmot engine - also dcwillmot differs from dcyou in only two places
7 |
8 | Fix and sure have tests (or delete startup files):
9 |
10 | append_diffcalc_to_gda_jython_path.py
11 | b16fivecircle.py
12 | b16fourcircle_you_engine.py
13 | i10fourcircle.py
14 | sixcircle_api.py
15 | sixcircle_vrmldummy.py
16 | sixcircle.py
17 |
18 | Check for 3 failing math (at least on OSX):
19 | -
20 |
21 | Remove _diffcalc module:
22 | - comment as you go!
23 | - checkub -> add test to test_you.py
24 | - fix the 'help ub' and 'help hkl' commands
25 | - get hkl scannable working without _diffcalc
26 |
27 |
28 | Tidy:
29 | - move sim logic off: DiffractometerScannableGroup
30 | - move example folder up into diffcalc.gdasupport package
31 | - rewite documentaion to call actual code for tests
32 |
33 | Improve:
34 | - you.py should not skip creating any scannables for fixed constraints (or related ones)
35 |
36 | Compare number of tests again branch point
37 | Decision not to dump vlieg mode
38 | why no integration test for willmott
39 |
40 |
41 |
42 |
43 |
44 |
45 | List needs review. Unordered. RobW.
46 | ----------------------------------
47 |
48 | - look at all commands together (showref, listub, cons)
49 |
50 | - overide help command. Perhaps just print __doc__ if it starts with '!' or '@command'
51 |
52 | - error handling in wrapper. check TypeError depth. Give help inside exception string.
53 |
54 | - parameter scannables should return current virtual angle __str__ would also show requestd
55 |
56 | - remove need for axis_par scannables - set value, consider e.g. mu scan, and moved from epics. mu scan requires mu to be same level as hkl to work efficiently
57 |
58 | - implement mu_eq_nu mode
59 |
60 | - add eta_half_delta and mu_half_nu modes
61 |
62 | - provide fivec etc plugins (i13 first)
63 |
64 | - provide arbitrary virtual names (and check arbitray motor names work)
65 |
66 | - provide short cut mode access my number (beamline specific) ? Good idea?
67 |
68 | - handle eV / keV properly (wavelength internally, flag to energy_unit equal 'keV' (default) or 'eV'
69 |
70 | - Fix .__doc__ help on hkl (metaclass syetm fails under Jython with a java base class)
--------------------------------------------------------------------------------
/tox.ini:
--------------------------------------------------------------------------------
1 | # Tox (https://tox.readthedocs.io/) is a tool for running tests
2 | # in multiple virtualenvs. This configuration file will run the
3 | # test suite on all supported python versions. To use it, "pip install tox"
4 | # and then run "tox" from this directory.
5 | #py27
6 |
7 | [tox]
8 | envlist = jython
9 |
10 | [testenv:jython]
11 | basepython=/Users/zrb13439/jython/bin/jython
12 |
13 |
14 | [testenv]
15 | commands =
16 | # pytest
17 | # py.test --boxed integration_checks.py
18 | # diffcalc --help
19 | # ./diffcalc.py --modules
20 | # ./diffcalc.py --non-interactive --python sixcircle
21 | # ./diffcalc.py --non-interactive sixcircle
22 |
23 | deps =
24 |
--------------------------------------------------------------------------------