Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC: Update documentation for Data and Material #104

Merged
merged 3 commits into from
Feb 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 19 additions & 20 deletions doc/reference/examples/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,43 +13,42 @@ Load from file
^^^^^^^^^^^^^^
First, let's assume that you have a data file, ``'scan.dat'`` from a HFIR instrument (SPICE format):

>>> from neutronpy.io import load_data
>>> from neutronpy.fileio import load_data
>>> data = load_data('scan.dat')

This builds ``data`` automatically and loads the following information from the file:
This builds ``data`` automatically and loads all of the data columns from the file.

* detector counts
* monitor counts
* h, k, l
* energy transfer
* temperature
* time
* ei, ef (future feature)
If you want to load more than one file at a time, simple add the file names as a list or a tuple of file names, *e.g.*

Currently, other data from the files is not included, but some additional support will be added in the future.
>>> data = load_data(('scan1.dat', 'scan2.dat'))

.. note::
Note: The primary problem is there is no standard variable name set between different file formats, and documentation for the file formats are not complete in some cases. Additionally, instruments at the same facility often use different software, so formats are frequently incompatible.

If you want to load more than one file at a time, simple add the file names as separate arguments, *e.g.*

>>> data = load('scan1.dat', 'scan2.dat')

By default, :py:meth:`.load` attempts to determine the format of the input files automatically, but you can specify the ``filetype`` if desired. Valid filetypes are currently:
By default, :py:meth:`.load_data` attempts to determine the format of the input files automatically, but you can specify the ``filetype`` if desired. Valid filetypes are currently:

* ``'auto'`` - Default: attempt to automatically determine the file type
* ``'SPICE'`` - HFIR files
* ``'ICE'`` - NCNR files
* ``'ICP'`` - NCNR files
* ``'iexy'`` - plaintext files from *e.g.* DAVE (future support planned)
* ``'DCS_MSLICE'`` - ASCII files exported from DCS MSLICE in Dave
* ``'MAD'`` - ILL files
* ``'GRASP'`` - ASCII and HDF5 files exported from GRASP

Pass pre-loaded data
^^^^^^^^^^^^^^^^^^^^
Assuming that your data is in a format that is not supported by :py:meth:`.Data.load_file` you will need to load the data yourself and pass it to the :py:class:`.Data` class and build ``Data.Q`` using :py:meth:`.Data.build_Q`. To build ``Data.Q`` you must have defined ``h``, ``k``, ``l``, ``e``, and ``temp``.
If your data is not in a format supported by :py:meth:`.Data.load_data` you will need to load the data yourself and pass it to the :py:class:`.Data` class and build ``Data.Q`` using :py:meth:`.Data.build_Q`. To build ``Data.Q`` you must have defined ``h``, ``k``, ``l``, ``e``, and ``temp``.

>>> data = Data(h=h, k=k, l=l, e=e, temp=temp, detector=detector,
monitor=monitor, time=time)

However, if you do not need to build ``Data.Q``, and want to use some subset of the predefined columns (``h``, ``k``, ``l``, ``e``, ``temp``, ``monitor``, ``detector``, ``time``, the undefined columns will be fill by np.zeros, with the length of the data passed.

>>> data = Data(h=np.arange(0, 1, 0.1))

.. note::
In the future, it may be possible to pass arbitrary data to build a bare ``Data`` object with the ``Data.data`` attribute. It is already technically possible to do this by building an empty Data object, and reassigning the .data attribute.

>>> data = Data()
>>> data.data = dict(angle1=np.arange(47, 49, 0.25))

``Data`` properties
-------------------
Below I outline some of the most common properties that you will want of the :py:class:`.Data` class.
Expand Down
19 changes: 14 additions & 5 deletions doc/reference/examples/material.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ For this example we will use Fe\ :sub:`1.1`\ Te, a high-temperature tetragonal :
{'ion': 'Fe', 'pos': [0.25, 0.25, 0.721], 'occupancy': 0.1},
{'ion': 'Fe', 'pos': [0.75, 0.75, -0.721], 'occupancy': 0.1}],
'debye-waller': False,
'massNorm': True,
'massNorm': False,
'lattice': {'abc': [3.81, 3.81, 6.25],
'abg': [90, 90, 90]},
}

.. note::
The ``'massNorm'`` key should be set to ``False`` to return the structure factor in units of ``barns``. ``'massNorm'`` is used for calculation of the coherent one-phonon inelastic cross-section, which depends on a calculation of nuclear structure factor in which the coherent scattering lengths are normalized by the square-root of the atomic mass *i.e.* :math:`\bar{b}_d/\sqrt{M_d}` (see Eq. 4.88 in "Theory of neutron scattering from condensed matter, Volume 1" by Stephen W. Lovesey.

Initializing the Material class
-------------------------------
Once we have built our material in the above format we can initialize the class.
Expand All @@ -34,7 +37,8 @@ Once we have built our material in the above format we can initialize the class.

Calculating the structure factor
--------------------------------
**Note**: The structure factor calculation method :py:meth:`.calc_nuc_str_fac` returns the full structure factor term :math:`F(q)`, including any imaginary parts, and not :math:`\left|F(q)\right|^2` which is typically used in other calculations.
.. note::
The structure factor calculation method :py:meth:`.calc_nuc_str_fac` returns the full structure factor term :math:`F(q)`, including any imaginary parts, and not :math:`\left|F(q)\right|^2` which is typically used in other calculations.

Now that our material is defined, we can calculate the structural form factor with :py:meth:`.calc_nuc_str_fac`. First, we will calculate it at a single point :math:`q`:

Expand Down Expand Up @@ -63,7 +67,7 @@ The resulting plot of this structure factor would look like the following figure
{'ion': 'Fe', 'pos': [0.25, 0.25, 0.721], 'occupancy': 0.1},
{'ion': 'Fe', 'pos': [0.75, 0.75, -0.721], 'occupancy': 0.1}],
'debye-waller': False,
'massNorm': True,
'massNorm': False,
'lattice': {'abc': [3.81, 3.81, 6.25],
'abg': [90, 90, 90]}}
FeTe = Material(def_FeTe)
Expand All @@ -76,7 +80,8 @@ The resulting plot of this structure factor would look like the following figure
plt.ylabel('k (r.l.u.)')
plt.show()

**Note**: The above picture will only be reproducible if the structure factor is partially symmetrized, *i.e.* in this case the calculation would be:
.. note::
The above picture will only be reproducible if the structure factor is partially symmetrized, *i.e.* in this case the calculation would be:

.. code-block:: python

Expand All @@ -85,6 +90,7 @@ The resulting plot of this structure factor would look like the following figure
np.abs(FeTe.calc_nuc_str_fac((h, -k, 0))) ** 2 +
np.abs(FeTe.calc_nuc_str_fac((-h, -k, 0))) ** 2)


Using space group to properly symmetrize
----------------------------------------
By providing a space group symbol or number in the following way it is possible to automatically symmetrize a crystal structure.
Expand All @@ -109,7 +115,7 @@ Calculating the resulting Material object's structure factor as in the previous
{'ion': 'Fe', 'pos': [0.25, 0.25, 0.721], 'occupancy': 0.1},
{'ion': 'Fe', 'pos': [0.75, 0.75, -0.721], 'occupancy': 0.1}],
'debye-waller': False,
'massNorm': True,
'massNorm': False,
'lattice': {'abc': [3.81, 3.81, 6.25],
'abg': [90, 90, 90]},
'space_group': 'P4/nmm'}
Expand All @@ -119,3 +125,6 @@ Calculating the resulting Material object's structure factor as in the previous
plt.xlabel('h (r.l.u.)')
plt.ylabel('k (r.l.u.)')
plt.show()

.. warning::
This feature is currently broken in the sense the absolute values are incorrect due to a bug in the symmetrization routine.
8 changes: 7 additions & 1 deletion neutronpy/crystal/material.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,13 @@ class Material(Sample, NuclearStructureFactor, MagneticStructureFactor, PlotMate
Include Debye-Waller in calculation with anisotropic U

'massNorm' : bool
Normalize calculations to mass of atoms
Normalize calculations to the square-root of the mass of atoms. This
is useful for the calculation of the coherent one-phonon inelastic
cross-section, which is dependent on a nuclear structure factor in
which the nuclear scattering length is normalized by the square-root
of the mass, *i.e.* :math:`\bar{b}_d/\sqrt{M_d}`, see Eq. 4.88 in
"Theory of neutron scattering from condensed matter, Volume 1" by
Stephen W. Lovesey.

'formulaUnits' : float
Number of formula units to use in the calculation
Expand Down
8 changes: 4 additions & 4 deletions neutronpy/fileio/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ def load_data(files, filetype='auto', tols=1e-4, build_hkl=True, load_instrument

filetype : str, optional
Default: `'auto'`. Specify file type; Currently supported file types
are SPICE (HFIR), ICE and ICP (NIST), MAD (ILL), DAVE exported ascii
formats, GRASP exported ascii and HDF5 formats, and neutronpy exported
formats. By default the function will attempt to determine the
filetype automatically.
are `'SPICE'` (HFIR), `'ICE'` and `'ICP'` (NIST), `'MAD'` (ILL),
`'dcs_mslice'` DAVE exported ascii formats, GRASP exported ascii and
HDF5 formats, and neutronpy exported formats. By default the function
will attempt to determine the filetype automatically.

tols : float or array_like
Default: `1e-4`. A float or array of shape `(5,)` giving tolerances
Expand Down