This commit is contained in:
2019-03-20 13:52:00 +01:00
parent 3084fe0510
commit 5db0f78aee
910 changed files with 191152 additions and 322 deletions

View File

@@ -0,0 +1,7 @@
********
Thanks
********
.. Do not add the names of contributors here. Instead, add them to the common list, so that they can be included in separate documents.
.. include:: ../../ACKS_diffcalc.rst

View File

@@ -0,0 +1,26 @@
########################
Diffcalc Developer Guide
########################
:Author: Rob Walton
:Contact: rob.walton (at) diamond (dot) ac (dot) uk
:Website: http://www.opengda.org/
.. rubric:: Diffcalc: A diffraction condition calculator for diffractometer control
.. toctree::
:maxdepth: 2
:numbered:
intro
package
quickstart_api
development
ACKS
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@@ -0,0 +1,24 @@
Development
===========
The files are kept here_ on github_. See bootcamp for an introduction to
using github. To contribute please fork the project. Otherwise you can make
a read-only clone or export.
Code format should follow pep8 guidelines. PyDev has a good pep8 checker.
To run the tests install nose_, change directory into the test folder and run::
$ nosetests
.......... ...
----------------------------------------------------------------------
Ran 3914 tests in 9.584s
OK (SKIP=15)
.. _here: https://github.com/DiamondLightSource/diffcalc
.. _github: https://github.com
.. _nose: http://nose.readthedocs.org/en/latest/
.. _pep8: http://www.python.org/dev/peps/pep-0008/

View File

@@ -0,0 +1,55 @@
Introduction
============
Diffcalc is a diffraction condition calculator used for controlling
diffractometers within reciprocal lattice space. It performs the same
task as the ``fourc``, ``sixc``, ``twoc``, ``kappa``, ``psic`` and
``surf`` macros from SPEC_.
Diffcalc's standard calculation engine is an implementation of
[You1999]_ . The first versions of Diffcalc were based on
[Vlieg1993]_ and [Vlieg1998]_ and a 'Vlieg' engine is still
available. The 'You' engine is more generic and the plan is to remove
the old 'Vlieg' engine once beamlines have been migrated. New users
should use the 'You' engine.
The foundations for this type of calculation were laid by by Busing &
Levi in their classic paper [Busing1967]_. Diffcalc's orientation
algorithm is taken from this paper. Busing & Levi also provided the
original definition of the coordinate frames and of the U and B
matrices used to describe a crystal's orientation and to convert between
Cartesian and reciprical lattice space.
Geometry plugins are used to adapt the six circle model used
internally by Diffcalc to apply to other diffractometers. These
contain a dictionary of the 'missing' angles which Diffcalc uses to
constrain these angles internally, and a methods to map from external
angles to Diffcalc angles and visa versa.
Options to use Diffcalc:
- **The User manual next to this developer manual or README file on github.**
- The :ref:`quickstart-api` section describes how to run up only
the core in Python_. This provides a base option for system integration.
Diffcalc will work with Python 2.7 or higher with numpy_, or with
Jython 2.7 of higher with Jama_.
.. [*] The very small 'Willmott' engine currently handles the case for
surface diffraction where the surface normal is held vertical
[Willmott2011]_. The 'You' engine handles this case fine, but
currently spins nu into an unhelpful quadrant. We hope to
remove the need for this engine soon.
.. _SPEC: http://www.certif.com/
.. _Python: http://python.org
.. _IPython: http://http://ipython.org/
.. _Jython: http://jython.org
.. _OpenGDA: http://opengda.org
.. _numpy: http://numpy.scipy.org/
.. _Jama: http://math.nist.gov/javanumerics/jama/
.. include:: ../../references

View File

@@ -0,0 +1,30 @@
Project Files & Directories
===========================
diffcalc
The main source package.
test
Diffcalcs unit-test package (use Nose_ to run them).
diffcmd
A spec-like openGDA emulator.
numjy
A *very* minimal implentation of numpy for jython. It supports only what
Diffcalc needs.
doc
The documentation is written in reStructuredText and can be compiled into
html and pdf using Python's `Sphinx <http://sphinx.pocoo.org>`_. With Sphinx
installed use ``make clean all`` from within the user and developer guide
folders to build the documentation.
startup
Starup scripts called by diffcmd or openGDA to startup diffcalc
model
Vrml models of diffractometers and a hokey script for animating then and
controlling them from diffcalc.
.. _Nose: http://readthedocs.org/docs/nose/en/latest/

View File

@@ -0,0 +1,266 @@
.. _quickstart-api:
.. warning:: This documentation is out of date. The README and the user doc has been updated recently. For now if you need help with API, please contact me at Diamond. -- Rob Walton
Quick-Start: Python API
=======================
This section describes how to run up only the core in Python or
IPython. This provides an API which could be used to integrate Diffcalc into an
existing data acquisition system; although the interface described in
the README would normally provide a better starting point.
For a full description of what Diffcalc does and how to use it please
see the 'Diffcalc user manual'.
Setup environment
-----------------
.. include:: quickstart_setup_environment
Start
-----
With Python start the sixcircle_api.py example startup script (notice
the -i and -m) and call `demo_all()`::
$ python -i -m startup.api.sixcircle
>>> demo_all()
IPython requires::
$ ipython -i startup/api/sixcircle.py
>>> demo_all()
Alternatively start Python or IPython and cut and paste lines from the rest of
this tutorial.
Configure a diffraction calculator
----------------------------------
By default some exceptions are handled in a way to make user interaction
friendlier. Switch this off with::
>>> import diffcalc.util
>>> diffcalc.util.DEBUG = True
To setup a Diffcalc calculator, first configure `diffcalc.settings` module::
>>> from diffcalc import settings
>>> from diffcalc.hkl.you.geometry import SixCircle
>>> from diffcalc.hardware import DummyHardwareAdapter
>>> settings.hardware = DummyHardwareAdapter(('mu', 'delta', 'gam', 'eta', 'chi', 'phi'))
>>> settings.geometry = SixCircle() # @UndefinedVariable
The hardware adapter is used by Diffcalc to read up the current angle
settings, wavelength and axes limits. It is primarily used to simplify
commands for end users. It could be dropped for this API use, but it
is also used for the important job of checking axes limits while
choosing solutions.
Geometry plugins are used to adapt the six circle model used
internally by Diffcalc to apply to other diffractometers. These
contain a dictionary of the 'missing' angles which Diffcalc internally
uses to constrain these angles, and a methods to map from
external angles to Diffcalc angles and visa versa.
Calling the API
---------------
The ``diffcalc.dc.dcyou`` module (and others) read the ``diffcalc.settings`` module when first
imported. Note that this means that changes to the settings will most likely
have no effect unless ``diffcalc.dc.dcyou`` is reloaded::
>>> import diffcalc.dc.dcyou as dc
This includes the two critical functions::
def hkl_to_angles(h, k, l, energy=None):
"""Convert a given hkl vector to a set of diffractometer angles
return angle tuple and virtual angles dictionary
"""
def angles_to_hkl(angle_tuple, energy=None):
"""Converts a set of diffractometer angles to an hkl position
Return hkl tuple and virtual angles dictionary
"""
``diffcalc.dc.dcyou`` also brings in all the commands from ``diffcalc.ub.ub``,
``diffcalc.hardware`` and ``diffcalc.hkl.you.hkl``. That is it includes all the
commands exposed in the top level namespace when diffcalc is used interactively::
>>> dir(dc)
['__builtins__', '__doc__', '__file__', '__name__', '__package__',
'_hardware','_hkl', '_ub', 'addref', 'allhkl', 'angles_to_hkl', 'c2th',
'calcub', 'checkub', 'clearref', 'con', 'constraint_manager', 'delref',
'diffcalc', 'editref', 'energy_to_wavelength', 'hardware', 'hkl_to_angles',
'hklcalc', 'lastub', 'listub', 'loadub', 'newub', 'rmub', 'saveubas', 'setcut',
'setlat', 'setmax', 'setmin', 'settings', 'setu', 'setub', 'showref',
'swapref', 'trialub', 'ub', 'ub_commands_for_help', 'ubcalc', 'uncon']
This doesn't form the best API to program against though, so it is best to
use the four modules more directly. The example below assumes you have
also imported::
>>> from diffcalc.ub import ub
>>> from diffcalc import hardware
>>> from diffcalc.hkl.you import hkl
Getting help
------------
To get help for the diffcalc angle calculations, the orientation phase, the
angle calculation phase, and the dummy hardware adapter commands::
>>> help(dc)
>>> help(ub)
>>> help(hkl)
>>> help(hardware)
Orientation
-----------
To orient the crystal for example (see the user manual for a fuller
tutorial) first find some reflections::
# Create a new ub calculation and set lattice parameters
ub.newub('test')
ub.setlat('cubic', 1, 1, 1, 90, 90, 90)
# Add 1st reflection (demonstrating the hardware adapter)
hardware.settings.hardware.wavelength = 1
ub.c2th([1, 0, 0]) # energy from hardware
settings.hardware.position = 0, 60, 0, 30, 0, 0 # mu del nu eta chi ph
ub.addref([1, 0, 0]) # energy & pos from hardware
# Add 2nd reflection (this time without the hardware adapter)
ub.c2th([0, 1, 0], 12.39842)
ub.addref([0, 1, 0], [0, 60, 0, 30, 0, 90], 12.39842)
To check the state of the current UB calculation::
>>> ub.ub()
UBCALC
name: test
n_phi: 0.00000 0.00000 1.00000 <- set
n_hkl: -0.00000 0.00000 1.00000
miscut: None
CRYSTAL
name: cubic
a, b, c: 1.00000 1.00000 1.00000
90.00000 90.00000 90.00000
B matrix: 6.28319 0.00000 0.00000
0.00000 6.28319 0.00000
0.00000 0.00000 6.28319
UB MATRIX
U matrix: 1.00000 0.00000 0.00000
0.00000 1.00000 0.00000
0.00000 0.00000 1.00000
U angle: 0
UB matrix: 6.28319 0.00000 0.00000
0.00000 6.28319 0.00000
0.00000 0.00000 6.28319
REFLECTIONS
ENERGY H K L MU DELTA GAM ETA CHI PHI TAG
1 12.398 1.00 0.00 0.00 0.0000 60.0000 0.0000 30.0000 0.0000 0.0000
2 12.398 0.00 1.00 0.00 0.0000 60.0000 0.0000 30.0000 0.0000 90.0000
And finally to check the reflections were specified acurately::
>>> dc.checkub()
ENERGY H K L H_COMP K_COMP L_COMP TAG
1 12.3984 1.00 0.00 0.00 1.0000 0.0000 0.0000
2 12.3984 0.00 1.00 0.00 -0.0000 1.0000 0.0000
Motion
------
Hkl positions and virtual angles can now be read up from angle
settings (the easy direction!)::
>>> dc.angles_to_hkl((0., 60., 0., 30., 0., 0.)) # energy from hardware
((1.0, 5.5511151231257827e-17, 0.0),
{'alpha': -0.0,
'beta': 3.5083546492674376e-15,
'naz': 0.0,
'psi': 90.0,
'qaz': 90.0,
'tau': 90.0,
'theta': 29.999999999999996})
Before calculating the settings to reach an hkl position (the trickier
direction) hardware limits must be set and combination of constraints
chosen. The constraints here result in a four circle like mode with a
vertical scattering plane and incident angle 'alpha' equal to the exit
angle 'beta'::
>>> hkl.con('qaz', 90)
! 2 more constraints required
qaz: 90.0000
>>> hkl.con('a_eq_b')
! 1 more constraint required
qaz: 90.0000
a_eq_b
>>> hkl.con('mu', 0)
qaz: 90.0000
a_eq_b
mu: 0.0000
To check the constraints::
>>> hkl.con()
DET REF SAMP
====== ====== ======
delta --> a_eq_b --> mu
alpha eta
--> qaz beta chi
naz psi phi
mu_is_nu
qaz: 90.0000
a_eq_b
mu: 0.0000
Type 'help con' for instructions
Limits can be set to help Diffcalc choose a solution::
>>> hardware.setmin('delta', 0) # used when choosing solution
Angles and virtual angles are then easily determined for a given hkl reflection::
>>> dc.hkl_to_angles(1, 0, 0) # energy from hardware
((0.0, 60.0, 0.0, 30.0, 0.0, 0.0),
{'alpha': -0.0,
'beta': 0.0,
'naz': 0.0,
'psi': 90.0,
'qaz': 90.0,
'tau': 90.0,
'theta': 30.0}
)

View File

@@ -0,0 +1,25 @@
Change directory to the diffcalc project (python adds the current
working directory to the path)::
$ cd diffcalc
$ ls
COPYING diffcalc doc example mock.py mock.pyc model numjy test
If using Python make sure numpy and diffcalc can be imported::
$ python
Python 2.7.2+ (default, Oct 4 2011, 20:06:09)
[GCC 4.6.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> import diffcalc
If using Jython make sure Jama and diffcalc can be imported::
$ jython -Dpython.path=<diffcalc_root>:<path_to_Jama>/Jama-1.0.1.jar
Jython 2.2.1 on java1.5.0_11
Type "copyright", "credits" or "license" for more information.
>>> import Jama
>>> import diffcalc