Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c847140
Added how-to for TIFFStackReader, custom AcquisitionGeometry creation…
M-A-Demir Oct 23, 2024
6b86fd0
Updated comment about geometry visualisation
M-A-Demir Oct 23, 2024
f8b8e50
Updated datapaths
M-A-Demir Oct 24, 2024
2bb7043
Removed unneccessary file and added empty data folder
M-A-Demir Oct 24, 2024
c77a9e8
Merge branch 'how_to_tiff' of github.com:TomographicImaging/CIL-Demos…
M-A-Demir Oct 24, 2024
c8c0d57
Merge remote-tracking branch 'origin/main' into how_to_tiff
M-A-Demir Oct 24, 2024
884b773
Merged upstream changes
M-A-Demir Oct 24, 2024
b24676d
undo deletion of Nikon and Zeiss how-tos
M-A-Demir Oct 24, 2024
4524399
Updated explanations in Normaliser, TiffStackReader & Geometry notebo…
M-A-Demir Nov 1, 2024
89447bd
Unrendered ver of notebooks
M-A-Demir Nov 12, 2024
bfdd978
Update how-to/1_Read_and_visualise/TIFFStackReader.ipynb
M-A-Demir Nov 14, 2024
a5ef169
Update how-to/1_Read_and_visualise/TIFFStackReader.ipynb
M-A-Demir Nov 14, 2024
eae68f1
Update how-to/3_Processors/FlatDarkFieldNormaliser.ipynb
M-A-Demir Nov 14, 2024
93ddad3
Update how-to/3_Processors/FlatDarkFieldNormaliser.ipynb
M-A-Demir Nov 14, 2024
a76a64b
Update how-to/3_Processors/FlatDarkFieldNormaliser.ipynb
M-A-Demir Nov 14, 2024
81e2b4a
Update how-to/1_Read_and_visualise/TIFFStackReader.ipynb
M-A-Demir Nov 19, 2024
43e793d
Update how-to/1_Read_and_visualise/TIFFStackReader.ipynb
M-A-Demir Nov 19, 2024
a73e4c9
added clarification on jupyter %store commands
M-A-Demir Nov 19, 2024
ede55ad
Merge branch 'how_to_tiff' of github.com:TomographicImaging/CIL-Demos…
M-A-Demir Nov 19, 2024
9f8a183
Update how-to/1_Read_and_visualise/TIFFStackReader.ipynb
M-A-Demir Nov 19, 2024
32c1089
Update how-to/1_Read_and_visualise/TIFFStackReader.ipynb
M-A-Demir Nov 19, 2024
9c88a89
Update how-to/2_Geometry/CreateCustomGeometry.ipynb
M-A-Demir Nov 19, 2024
b86935d
Update how-to/2_Geometry/CreateCustomGeometry.ipynb
M-A-Demir Nov 19, 2024
a062628
Update how-to/2_Geometry/CreateCustomGeometry.ipynb
M-A-Demir Nov 19, 2024
b7fa11b
clarity
M-A-Demir Nov 19, 2024
6cdbed9
Update how-to/1_Read_and_visualise/TIFFStackReader.ipynb
M-A-Demir Jan 17, 2025
c6810fd
Applied suggestions from code review
M-A-Demir Jan 17, 2025
e2907aa
Update FlatDarkFieldNormaliser.ipynb
M-A-Demir Jan 17, 2025
7bfe782
Update CreateCustomGeometry.ipynb
M-A-Demir Jan 17, 2025
ee79fb1
Update CreateCustomGeometry.ipynb
M-A-Demir Jan 17, 2025
7c25549
Fixed CreateCustomGeometry.ipynb
M-A-Demir Jan 17, 2025
637b8e6
Update FlatDarkFieldNormaliser.ipynb
M-A-Demir Jan 17, 2025
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
299 changes: 299 additions & 0 deletions how-to/1_Read_and_visualise/TIFFStackReader.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,299 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# -*- coding: utf-8 -*-\n",
"# Copyright 2021 - 2024 United Kingdom Research and Innovation\n",
"# Copyright 2021 - 2024 The University of Manchester\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# http://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License.\n",
"#\n",
"# Authored by: Mariam Demir (UKRI-STFC)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Load and Visualise Data Using TIFFStackReader\n",
"This example shows how to use the `TIFFStackReader` to load data from .tiff files and quickly visualise the data and geometry."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from cil.io import TIFFStackReader\n",
"from cil.framework import AcquisitionGeometry, AcquisitionData\n",
"from cil.utilities import dataexample\n",
"from cil.utilities.display import show_geometry\n",
"from cil.utilities.display import show2D\n",
"import numpy as np\n",
"import os"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get the example dataset `dataexample.SANDSTONE` using `download_data()`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"dataexample.SANDSTONE.download_data(data_dir='../data', prompt=False)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can load the .tif file from the dataset using the `TIFFStackReader`. The reader can take a directory or a list of .tiff or .tif files as an argument. \n",
"Here, we create a list of the .tif files, excluding the dark- and flat-field files (See the how-to `3_Processors/FlatDarkFieldNormaliser` notebook for more information on flat and dark fields and how to normalise the data). \n",
"\n",
"We specify the files to load using `file_name = tiff_files`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"data_dir = '../data/sandstone/proj'\n",
"tiff_files = [os.path.join(data_dir, file) for file in os.listdir(data_dir) if \".tif\" in file \\\n",
" and (file not in [\"BBii_0001.tif\", \"BBii_0002.tif\", \"BBii_0031.tif\", \\\n",
" \"BBii_0032.tif\", \"BBii_1632.tif\", \"BBii_1633.tif\"])]\n",
"\n",
"data_reader = TIFFStackReader(file_name=tiff_files)\n",
"data = data_reader.read()\n",
"\n",
"print(data.shape)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can see the data contains 8 projections, with a panel of size 2160 by 2560 pixels. For this dataset, the 8 projections are taken at uniform intervals over 0-180 degrees and there are 2160 pixels in the vertical direction, 2560 in the horizontal direction. \n",
"\n",
"To use CIL's visualisation and reconstruction tools, we need to store this array in an `AcquisitionData` object. This object holds both the pixel data, and the `AcquisitionGeometry`.\n",
"\n",
"First, we will manually create the `AcquisitionGeometry` object based on information about the experimental setup. This dataset has parallel-beam geometry, so we create a Parallel3D `AcquisitionGeometry` object:\n",
"* We know the first axis is angle, the second is vertical, and the third is horizontal, so we set `dimension_labels` to `('angle', 'vertical', 'horizontal')` . \n",
"\n",
"* We set the `num_pixels` to a tuple containing the number of vertical and horizontal pixels, `(data.shape[2], data.shape[1])`. \n",
"\n",
"* The `angles` are set to an array of the projection angles."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"parallel_geom = AcquisitionGeometry.create_Parallel3D() \\\n",
" .set_labels(['angle', 'vertical', 'horizontal']) \\\n",
" .set_panel(num_pixels=(data.shape[2], data.shape[1])) \\\n",
" .set_angles(angles=np.linspace(0,180,8,endpoint=False))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Check the geometry shape, and source/detector positions look reasonable using `show_geometry()`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"show_geometry(parallel_geom)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we use the loaded data and `AcquisitionGeometry` to create the `AcquisitionData` object:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"sandstone = AcquisitionData(array=data, geometry=parallel_geom)\n",
"print(sandstone)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now the data has been loaded, and we are able to use CIL's visualisation and reconstruction tools on the dataset. \n",
"We can view a central projection of the data with `show2D()`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"show2D(sandstone)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Uncomment the cell below to delete the dataset and its folder"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# import shutil\n",
"# shutil.rmtree('../data/sandstone')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To save the sandstone `AcquisitionData` object to the kernel, uncomment and run the cell below. This means that `sandstone` can be called in other notebooks such as `3_Processors/FlatDarkFieldNormaliser.ipynb`, by running `%store -r sandstone`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# %store sandstone"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Using TIFFStackReader's Additional Arguments:"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use the `roi` argument when reading the file to load a subset of the data. The `roi` argument should be passed as a dictionary e.g. `{'axis_1': (start, end, step), 'axis_2': (start, end, step)}` with axis labels `'axis_0'` (angle), `'axis_1'` (vertical), or `'axis_2'` (horizontal)\n",
"\n",
"To load a cropped subset of the data, change the start and end values. Note that setting 'axis_label': -1 is a shortcut to load all elements along the axis."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"roi = {'axis_1':(100, 800, 1), 'axis_2':(-1)}\n",
"data_reader = TIFFStackReader(file_name=tiff_files, roi=roi)\n",
"data = data_reader.read()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Update the `AcquisitionGeometry` to the new panel size and create the updated `AcquisitionData`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"parallel_geom.set_panel(num_pixels=(data.shape[2], data.shape[1]))\n",
"sandstone = AcquisitionData(array=data, geometry=parallel_geom)\n",
"\n",
"print(sandstone)\n",
"show2D(sandstone)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To load a binned subset of the data, change the step value. \n",
"Here we use different binning for the vertical (`axis_1`) and horizontal (`axis_2`) dimensions, which results in a different aspect ratio:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"roi = {'axis_1':(None, None, 2), 'axis_2':(None, None, 4)}\n",
"data_reader = TIFFStackReader(file_name=tiff_files, roi=roi)\n",
"data = data_reader.read()\n",
"\n",
"parallel_geom.set_panel(num_pixels=(data.shape[2], data.shape[1]))\n",
"sandstone = AcquisitionData(array=data, geometry=parallel_geom)\n",
"\n",
"print(sandstone)\n",
"show2D(sandstone)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "cil",
"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.15"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading