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

Add xarray #51

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
243 changes: 243 additions & 0 deletions example_notebooks/data_arrays.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pandas as pd\n",
"import xarray as xr\n",
"import matplotlib.pyplot as plt\n",
"from databroker import DataBroker as db\n",
"from sixtools.rixs_wrapper import make_scan, centroids_to_spectrum, make_dataset\n",
"from sixtools.tests.test_sixtools import make_test_dataset\n",
"from IPython.display import clear_output, display\n",
"\n",
"%matplotlib widget"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [],
"source": [
"%%capture\n",
"fig0, ax0 = plt.subplots(num=0, clear=True)\n",
"fig1, ax1 = plt.subplots(num=1, clear=True)\n",
"fig2, ax2 = plt.subplots(num=2, clear=True)\n",
"fig3, ax3 = plt.subplots(num=3, clear=True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define and execute processing"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"scan_id = 51402\n",
"process_dicts_high_2theta = {'light_ROI': [800, 1230, 175, 1500],\n",
" 'curvature': np.array([0., 0., 0.]),\n",
" 'bins': 0.5,\n",
" 'background': None}\n",
"\n",
"ds = make_dataset(db[scan_id], **process_dicts_high_2theta)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot it"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "0f12a51c3bf44a9ab6ae85719d4c64be",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"FigureCanvasNbAgg()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig0, ax0 = plt.subplots(num=0, clear=True)\n",
"\n",
"colors = iter(plt.cm.viridis(np.linspace(0, 1, ds['intensity'].sum('y').size)))\n",
"for event_val, event in ds.groupby(ds.attrs['event_name']):\n",
" for frame_val, frame in event.groupby('frame'):\n",
" ax0.errorbar(frame['pixel'].values, frame['intensity'].values, frame['error'].values, color=next(colors),\n",
" fmt='.-',\n",
" label=\"{}={} #{}\".format(ds.attrs['event_name'], event_val, frame_val))\n",
"\n",
"ax0.set_xlabel('pixel')\n",
"ax0.set_ylabel('I')\n",
"display(fig0.canvas)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Make fake spectrum"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "3346e754f8254d80853fe889fbb4672c",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"FigureCanvasNbAgg()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ds_fake = make_test_dataset()\n",
"\n",
"fig1, ax1 = plt.subplots(num=1, clear=True)\n",
"\n",
"colors = iter(plt.cm.viridis(np.linspace(0, 1, ds_fake['intensity'].sum('y').size)))\n",
"for event_val, event in ds_fake.groupby(ds_fake.attrs['event_name']):\n",
" for frame_val, frame in event.groupby('frame'):\n",
" ax1.errorbar(frame['pixel'].values, frame['intensity'].values, frame['error'].values, color=next(colors),\n",
" fmt='.-',\n",
" label=\"{}={} #{}\".format(ds_fake.attrs['event_name'], event_val, frame_val))\n",
"\n",
"ax1.set_xlabel('pixel')\n",
"ax1.set_ylabel('I')\n",
"display(fig1.canvas)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Offset values based on known curvature"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "2006b1957b7c46429a94b71f17fa8807",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"FigureCanvasNbAgg()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ds_fake = make_test_dataset()\n",
"center_offsets = xr.DataArray(ds_fake.attrs['centers']-500, dims='centers')\n",
"\n",
"ds_fake_offset = ds_fake.copy(deep=True)\n",
"ds_fake_offset['pixel'] = ds_fake['pixel'] - center_offsets\n",
"\n",
"fig2, ax2 = plt.subplots(num=2, clear=True)\n",
"\n",
"colors = iter(plt.cm.viridis(np.linspace(0, 1, ds_fake_offset['intensity'].sum('y').size)))\n",
"for event_val, event in ds_fake_offset.groupby(ds_fake_offset.attrs['event_name']):\n",
" for frame_val, frame in event.groupby('frame'):\n",
" ax2.errorbar(frame['pixel'].values, frame['intensity'].values, frame['error'].values, color=next(colors),\n",
" fmt='.-',\n",
" label=\"{}={} #{}\".format(ds_fake.attrs['event_name'], event_val, frame_val))\n",
"\n",
"ax2.set_xlabel('pixel')\n",
"ax2.set_ylabel('I')\n",
"display(fig2.canvas)"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "6a8f73e617da4341be3531acbddcccb6",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"FigureCanvasNbAgg()"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"bins = ds_fake_offset.attrs['bins']\n",
"y = ds_fake_offset.attrs['y']\n",
"I, _ = np.histogram(ds_fake_offset['pixel'].values, bins=bins, weights=ds_fake_offset['intensity'])\n",
"\n",
"fig3, ax3 = plt.subplots(num=3, clear=True)\n",
"ax3.plot(y, I)\n",
"\n",
"display(fig3.canvas)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "MPMD_SIX_from_2018-3.2",
"language": "python",
"name": "myenv"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
99 changes: 97 additions & 2 deletions sixtools/rixs_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import numpy as np
import pandas as pd
import xarray as xr
from scipy.interpolate import interp1d
from pims import pipeline
from rixs.process2d import apply_curvature, image_to_photon_events
Expand Down Expand Up @@ -255,6 +255,100 @@ def get_rixs(header, light_ROI=[0, np.inf, 0, np.inf],
background=background)


def make_dataset(headers, light_ROI=[0, np.inf, 0, np.inf],
curvature=np.array([0., 0., 0.]), bins=1,
ADU_per_photon=None, detector='rixscam_centroids',
min_threshold=-np.inf, max_threshold=np.inf,
background=None):
"""
Make 4D xarray dataset of RIXS spectra with structure
event, image_index, y, I

Parameters
----------
headers : databroker header object or iterable of same
iterable that returns databroker objects
light_ROI : [minx, maxx, miny, maxy]
Define the region of the sensor to use.
Events are chosen with minx <= x < maxx and miny <= y < maxy
curvature : array
The polynominal coeffcients describing the image curvature.
These are in decreasing order e.g.
.. code-block:: python

curvature[0]*x**2 + curvature[1]*x**1 + curvature[2]*x**0
The order of polynominal used is set by len(curvature) - 1
bins : float or array like
Binning in the y direction.
If `bins` is a sequence, it defines the bin edges,
including the rightmost edge.
If `bins' is a single number this defines the step
in the bins sequence, which is created using the min/max
of the input data. Half a bin may be discarded in order
to avoid errors at the edge. (Default 1.)
detector : string
name of the detector passed on header.data
At SIX
'rixscam_centroids' is the centroided data, which is the default
'rixscam_image' is the image data
min_threshold : float
fliter events below this threshold
defaults to -infinity to include all events
max_threshold : float
fliter events above this threshold
defaults to +infinity to include all events
background : array
2D array for background subtraction
Only used for image data.

Returns
-------
scan : array
4D array of RIXS spectra with structure
event, image_index, y, I
"""
if hasattr(headers, 'data') is True:
headers = [headers]

rixs_generators = [get_rixs(h, light_ROI=light_ROI, curvature=curvature,
bins=bins, detector=detector,
ADU_per_photon=ADU_per_photon,
min_threshold=min_threshold,
max_threshold=max_threshold,
background=background)
for h in headers]

scan = np.concatenate([np.array([s for s in rg])
for rg in rixs_generators])

I = scan[:, :, :, 1]
pixel = scan[:, :, :, 0]

try:
iter(bins)
except TypeError:
bins = step_to_bins(pixel.min(), pixel.max(), bins)

try:
event_name = headers[0].start['motors'][0]
events = db.get_table(headers, fields=[event_name])[event_name]
except (AttributeError, KeyError):
event_name = 'event'
events = np.arange(I.shape[0])

ds = xr.Dataset({'intensity': ([event_name, 'frame', 'y'], I),
'error': ([event_name, 'frame', 'y'], np.sqrt(I))},
coords={event_name : events,
'frame': np.arange(I.shape[1]),
'pixel': ([event_name, 'frame', 'y'], pixel)},
attrs=dict(scan_ids = [h.start['scan_id'] for h in headers],
event_name=event_name,
uids=[h.start['uid'] for h in headers],
bins=bins,
y=(bins[:-1] + bins[1:])/2))
return ds


def make_scan(headers, light_ROI=[0, np.inf, 0, np.inf],
curvature=np.array([0., 0., 0.]), bins=1,
ADU_per_photon=1, detector='rixscam_centroids',
Expand Down Expand Up @@ -323,9 +417,10 @@ def make_scan(headers, light_ROI=[0, np.inf, 0, np.inf],

scan = np.concatenate([np.array([s for s in rg])
for rg in rixs_generators])
E = scan[0, 0, :, 0]

return scan


def calibrate(scan, elastics=None, energy_per_pixel=1, I0s=None):
"""Apply energy per pixel, I0 and energy zero calibration.

Expand Down
31 changes: 31 additions & 0 deletions sixtools/tests/test_sixtools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import numpy as np
import xarray as xr
from rixs.process2d import gauss


def make_test_dataset():
"""Make a fake xarray dataset for testing purposes.

Returns
-------
ds : xarray dataset
dataset that with spectra occuring at different pixels
"""
centers = np.linspace(500, 530, 20)
bins = np.arange(300-0.25/2, 700, 0.25)
y = (bins[:-1] + bins[1:])/2
I = np.vstack([gauss(y, 10, center, 5, 0) for center in centers])
I = I[:,np.newaxis,:]
pixel = np.vstack([y for _ in centers])
pixel = pixel[:,np.newaxis,:]

ds = xr.Dataset({'intensity': (['centers', 'frame', 'y'], I),
'error': (['centers', 'frame', 'y'], np.sqrt(I))},
coords={'centers': centers,
'frame': np.array([0]),
'pixel': (['centers', 'frame', 'y'], pixel)},
attrs=dict(event_name='centers',
centers=centers,
bins=bins,
y=y))
return ds