Visualizing CHESS temperature dependent data#

Import functions#

import matplotlib.pyplot as plt
from nxs_analysis_tools import TempDependence

The TempDependence class#

It is assumed that the file structure of the temperature dependent scan is as follows:

folder
└── subfolder
   ├── 15
   ├── 100
   └── 300

Here we create a TempDependence objecct called sample whose temperature folders are found in the path 'example_data/sample_name'.

sample = TempDependence()

Loading data#

Use the load_datasets() method to load the “.nxs” files. By default, all files ending with “hkli.nxs” are imported, but this can be changed using the file_ending parameter.

sample.load_datasets(folder='example_data/sample_name', file_ending="hkli.nxs")
Found temperature folders:
[0] 15
[1] 100
[2] 300
-----------------------------------------------
Loading 15 K indexed .nxs files...
Found example_data/sample_name/15/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)
-----------------------------------------------
Loading 100 K indexed .nxs files...
Found example_data/sample_name/100/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)
-----------------------------------------------
Loading 300 K indexed .nxs files...
Found example_data/sample_name/300/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)

A subset of temperatures can be imported using the temperatures_list parameter. Temperatures can be listed here as numeric values ([15,300]) or as strings (['15','300']).

sample.load_datasets(folder='example_data/sample_name', temperatures_list=[15,300])
Found temperature folders:
[0] 15
[1] 100
[2] 300
-----------------------------------------------
Loading 15 K indexed .nxs files...
Found example_data/sample_name/15/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)
-----------------------------------------------
Loading 300 K indexed .nxs files...
Found example_data/sample_name/300/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)

Accessing the data#

sample.load_datasets(folder='example_data/sample_name')
Found temperature folders:
[0] 15
[1] 100
[2] 300
-----------------------------------------------
Loading 15 K indexed .nxs files...
Found example_data/sample_name/15/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)
-----------------------------------------------
Loading 100 K indexed .nxs files...
Found example_data/sample_name/100/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)
-----------------------------------------------
Loading 300 K indexed .nxs files...
Found example_data/sample_name/300/example_hkli.nxs
data:NXdata
  @axes = ['H', 'K', 'L']
  @signal = 'counts'
  H = float64(100)
  K = float64(150)
  L = float64(200)
  counts = float64(100x150x200)

The datasets are stored under the .datasets attribute of the TempDependence object.

sample.datasets
{'15': NXdata('data'), '100': NXdata('data'), '300': NXdata('data')}

Use square brackets to index the individual datasets in the NXentry. Each dataset is a NXdata object and possesses the corresponding attributes and methods.

sample.datasets['15']
NXdata('data')

A list of temperatures is stored in the .temperatures attribute of the TempDependence object.

sample.temperatures
['15', '100', '300']

Visualizing the data#

For example, each NXdata object has a .plot() method. Here we plot the L=0.0 plane.

sample.datasets['15'][:,:,0.0].plot()
../_images/4a5907234cd81631bd099d0716ba4f9c26dadc1bd0bf4f771686d25a3cd6eb4a.png

Temperature dependent linecuts#

Linecuts are performed using the Scissors class. An instance of the Scissors class is created for each temperature and stored in a dict attribute called scissors.

See documentation on the Scissors class for more information.

sample.scissors
{'15': <nxs_analysis_tools.datareduction.Scissors at 0x7fd01ad7fc40>,
 '100': <nxs_analysis_tools.datareduction.Scissors at 0x7fcfe40a8c70>,
 '300': <nxs_analysis_tools.datareduction.Scissors at 0x7fd01bee2200>}

The individual Scissors objects can be indexed using square brackets and the temperature.

sample.scissors['15']
<nxs_analysis_tools.datareduction.Scissors at 0x7fd01ad7fc40>

Batch linecuts are peformed using a method of the TempDependence class called .cut_data(), which internally calls the .cut_data() method on each of the Scissors objects at each temperature.

sample.cut_data(center=(0,0,0), window=(0.1,1,0.1))
-------------------------------
Cutting T = 15 K data...
Linecut axis: K
Integrated axes: ['H', 'L']
-------------------------------
Cutting T = 100 K data...
Linecut axis: K
Integrated axes: ['H', 'L']
-------------------------------
Cutting T = 300 K data...
Linecut axis: K
Integrated axes: ['H', 'L']
{'15': NXdata('data'), '100': NXdata('data'), '300': NXdata('data')}

Similarly, batch plotting of the linecuts can be achieved using the .plot_linecuts() method of the TempDependence object, which internally calls the .plot_linecut() method of the Scissors objects at each temperature.

sample.plot_linecuts()
(<Figure size 640x480 with 1 Axes>,
 <Axes: xlabel='0.0 K 0.0', ylabel='counts'>)
../_images/3f0ddcd0e35411071cb2d045ffa20709747e4cafcc204ac62df28ef5606fb32d.png

Any keyword arguments are passed to a matplotlib function ax.plot() within .plot_linecuts(), so the usual matplotlib parameters can be used to change the formatting.

sample.plot_linecuts(linestyle='-', marker='.')
(<Figure size 640x480 with 1 Axes>,
 <Axes: xlabel='0.0 K 0.0', ylabel='counts'>)
../_images/aa634b8cb919b313679b15b089e1293624a9ab92707e281c64acb2da82553877.png

You can also introduce a vertical offset using the vertical_offset parameter.

sample.plot_linecuts(vertical_offset=500)
(<Figure size 640x480 with 1 Axes>,
 <Axes: xlabel='0.0 K 0.0', ylabel='counts'>)
../_images/3393e702257a17eba1076aa05d1c22f96133da9a305130fe9b86d6ecdca4775e.png

Visualizing the integration window#

To visualize where the integration was performed, use the .highlight_integration_window() method of the Scissors class.

sample.scissors['15'].highlight_integration_window()
../_images/1fe3fc58d9c96266ab4f6399b893dd25fcdd118bbcc5ad6218ca269be9018d0c.png
(<matplotlib.collections.QuadMesh at 0x7fcfe01f6800>,
 <matplotlib.collections.QuadMesh at 0x7fcfe0265660>,
 <matplotlib.collections.QuadMesh at 0x7fcfe029fa60>)

Similarly, to plot a heatmap of the integrated volume itself, use the .plot_integration_window() method of the Scissors class.

sample.scissors['15'].plot_integration_window()
../_images/e9c3662130f17c2fdb1fa5aace4b905e8b9837069b9e8748e938488621245517.png
(<matplotlib.collections.QuadMesh at 0x7fcfe03299c0>,
 <matplotlib.collections.QuadMesh at 0x7fcfdbd80130>,
 <matplotlib.collections.QuadMesh at 0x7fcfdbf038e0>)