Skip to content
Merged
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
220 changes: 220 additions & 0 deletions misc/flux_normaliser.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook shows how the FluxNormaliser processor and preview configuration tool works on different dataset types"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"from cil.utilities import dataexample\n",
"from cil.processors import FluxNormaliser\n",
"from cil.utilities.display import show2D\n",
"from cil.framework import AcquisitionGeometry"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Create some different data types"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The flux can be used to normalise with a scalar value. Each projection is divided by the flux then multiplied by the target"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data = dataexample.SIMULATED_CONE_BEAM_DATA.get()\n",
"processor = FluxNormaliser(flux=1, target=10)\n",
"processor.set_input(data)\n",
"data_norm = processor.get_output()\n",
"show2D([data, data_norm])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Or use a range of flux values the same length as the number of projections. Plot the sinogram to show the effect of normalising by a different value for each angle. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"processor = FluxNormaliser(flux=np.arange(1,2,(2-1)/(data.get_dimension_size('angle'))))\n",
"processor.set_input(data)\n",
"data_norm = processor.get_output()\n",
"show2D([data, data_norm], slice_list=('vertical',80))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If not specified, the default target is 'mean' - the mean value of the input flux or flux across all rois. Here we gave a flux array range between 1 and 2, so the target was 1.5 and the colorbar in the normalised plot shows a maximum value close to 1.5. If we specify `target='first'`, the first value in the flux array will be used as the target. Here it's 1, so in the plot of the normalised data below the colorbar shows a maximum value close to 1."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"processor = FluxNormaliser(flux=np.arange(1,2,(2-1)/(data.get_dimension_size('angle'))), target='first')\n",
"processor.set_input(data)\n",
"data_norm = processor.get_output()\n",
"show2D([data, data_norm], slice_list=('vertical',80))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Alternatively we can get the flux from a region of interest in the data. \n",
"Choose an roi and check how it looks using `preview_configuration()`. The top plots show the roi on the projections with the minimum and maximum intensity in the roi. The bottom plot shows how the mean, minimum and maximum intensity in the roi varies with angle."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data = dataexample.SYNCHROTRON_PARALLEL_BEAM_DATA.get()\n",
"roi = {'horizontal':(60,65),'vertical':(20,70)}\n",
"\n",
"processor = FluxNormaliser(roi=roi)\n",
"processor.set_input(data)\n",
"fig = processor.preview_configuration()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The plot shows the selected roi contains some of the data at certain angles so we see there is a big variation in the maximum intensity measured in the roi. We also get a warning that the selected roi contains more than 10% of the data range\n",
"\n",
"Try adjusting the roi to only select the background"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"roi = {'horizontal':(10,30),'vertical':(10,120)}\n",
"\n",
"processor = FluxNormaliser(roi=roi)\n",
"processor.set_input(data)\n",
"processor.preview_configuration()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data_norm = processor.get_output()\n",
"show2D([data, data_norm])\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"show2D([data, data_norm], slice_list=('vertical',80))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This should also work on a single slice of the data"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data_slice = data.get_slice(vertical=100)\n",
"roi = {'horizontal':(10,30)}\n",
"\n",
"processor = FluxNormaliser(roi=roi)\n",
"processor.set_input(data_slice)\n",
"processor.preview_configuration()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For multichannel data you can select the channel to display in `preview_configuration` to check how the roi looks for each channel, by default the central channel is shown"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ag = AcquisitionGeometry.create_Parallel3D()\\\n",
" .set_angles(np.linspace(0,360,360,endpoint=False))\\\n",
" .set_panel([128,128],0.1)\\\n",
" .set_channels(4)\n",
"data = ag.allocate('random')\n",
"\n",
"roi = {'horizontal':(10,30),'vertical':(10,120)}\n",
"\n",
"processor = FluxNormaliser(roi=roi)\n",
"processor.set_input(data)\n",
"processor.preview_configuration(channel=3)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "cil_dev",
"language": "python",
"name": "python3"
},
"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.10.14"
}
},
"nbformat": 4,
"nbformat_minor": 2
}