Commit f4e71e86 authored by payno's avatar payno
Browse files

Merge branch 'add_alignment_proj_property' into 'master'

add alignment_projections property

See merge request !26
parents 90a88847 38b734da
Pipeline #33245 passed with stages
in 4 minutes
......@@ -166,7 +166,7 @@
],
"source": [
"from silx.io.utils import get_data\n",
"frame_28_data = get_data(scan.projections[28])\n",
"frame_18_data = get_data(scan.projections[18])\n",
"# imshow(frame_28_data)"
]
},
......
%% Cell type:markdown id: tags:
# Read data from an EDF acquisition
To create a 'Scan' object from EDF you have to use the :class:`EDFTomoScan` class and provide the path to the acquisition
WARNING: Browsing EDF files is based on several convention at ESRF.
The most important one is that the acquisition 'identification' - which is the folder name is repeated in the file names.
For example if we have an acquisition names 'acq_0005' we expect edf file prefix to be 'acq_0005' too.
WARNING: The :class:`EDFTomoScan` has been tested on EDF single frame files. It wouldn't be surprising if it fails on EDF multiple frames files.
%% Cell type:code id: tags:
``` python
# %pylab # to use imshow uncomment
```
%%%% Output: stream
Using matplotlib backend: Qt5Agg
Populating the interactive namespace from numpy and matplotlib
%% Cell type:markdown id: tags:
## Get a simple dataset for test (this dataset is a pure noise)
%% Cell type:code id: tags:
``` python
from tomoscan.test.utils import UtilsTest
import os
data_dir = UtilsTest.getDataset('test10')
```
%% Cell type:markdown id: tags:
## create an instance of `EDFTomoScan`
`EDFTomoScan` implements the TomoScanBase interface.
This allow you to have a common API for accessing data from EDF or HDF5 regardless of the type of acquisition.
%% Cell type:code id: tags:
``` python
from tomoscan.esrf.edfscan import EDFTomoScan
scan = EDFTomoScan(scan=data_dir)
```
%% Cell type:markdown id: tags:
Then from it you can access several information
%% Cell type:markdown id: tags:
### projections
%% Cell type:code id: tags:
``` python
scan.projections
```
%%%% Output: execute_result
{3: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100003.edf', data_path=None, data_slice=[0]),
27: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100027.edf', data_path=None, data_slice=[0]),
0: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100000.edf', data_path=None, data_slice=[0]),
31: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100031.edf', data_path=None, data_slice=[0]),
20: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100020.edf', data_path=None, data_slice=[0]),
25: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100025.edf', data_path=None, data_slice=[0]),
7: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100007.edf', data_path=None, data_slice=[0]),
19: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100019.edf', data_path=None, data_slice=[0]),
8: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100008.edf', data_path=None, data_slice=[0]),
5: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100005.edf', data_path=None, data_slice=[0]),
4: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100004.edf', data_path=None, data_slice=[0]),
22: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100022.edf', data_path=None, data_slice=[0]),
26: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100026.edf', data_path=None, data_slice=[0]),
32: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100032.edf', data_path=None, data_slice=[0]),
14: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100014.edf', data_path=None, data_slice=[0]),
18: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100018.edf', data_path=None, data_slice=[0]),
30: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100030.edf', data_path=None, data_slice=[0]),
2: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100002.edf', data_path=None, data_slice=[0]),
16: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100016.edf', data_path=None, data_slice=[0]),
15: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100015.edf', data_path=None, data_slice=[0]),
23: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100023.edf', data_path=None, data_slice=[0]),
11: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100011.edf', data_path=None, data_slice=[0]),
13: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100013.edf', data_path=None, data_slice=[0]),
1: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100001.edf', data_path=None, data_slice=[0]),
17: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100017.edf', data_path=None, data_slice=[0]),
24: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100024.edf', data_path=None, data_slice=[0]),
12: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100012.edf', data_path=None, data_slice=[0]),
9: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100009.edf', data_path=None, data_slice=[0]),
29: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100029.edf', data_path=None, data_slice=[0]),
21: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100021.edf', data_path=None, data_slice=[0]),
28: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100028.edf', data_path=None, data_slice=[0]),
10: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100010.edf', data_path=None, data_slice=[0]),
6: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/test100006.edf', data_path=None, data_slice=[0])}
%% Cell type:markdown id: tags:
This return a dictionnary of projection index and DataUrl.
You can access the data using `silx.io.utils.get_data function`
%% Cell type:code id: tags:
``` python
from silx.io.utils import get_data
frame_28_data = get_data(scan.projections[28])
frame_18_data = get_data(scan.projections[18])
# imshow(frame_28_data)
```
%%%% Output: execute_result
<matplotlib.image.AxesImage at 0x7f5ce5bbcc88>
%% Cell type:markdown id: tags:
### darks
%% Cell type:code id: tags:
``` python
scan.darks
```
%%%% Output: execute_result
{}
%% Cell type:markdown id: tags:
### flats
%% Cell type:code id: tags:
``` python
scan.flats
```
%%%% Output: execute_result
{20: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/refHST0020.edf', data_path=None, data_slice=[0]),
10: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/refHST0010.edf', data_path=None, data_slice=[0]),
0: DataUrl(valid=True, scheme='fabio', file_path='/home/payno/dev/tomo/tomoscan/tomoscan/test/test10/refHST0000.edf', data_path=None, data_slice=[0])}
%% Cell type:markdown id: tags:
### energy (in keV)
%% Cell type:code id: tags:
``` python
scan.energy
```
%%%% Output: execute_result
19.0
%% Cell type:markdown id: tags:
### pixel size (in )
%% Cell type:code id: tags:
``` python
scan.get_pixel_size(unit='cm')
```
%%%% Output: execute_result
0.00030199999999999997
%% Cell type:markdown id: tags:
There is more information that you can access, to get them all please have a look on the [TomwerScanBase API](https://tomotools.gitlab-pages.esrf.fr/tomoscan/modules/scanbase.html#tomoscan.scanbase.TomoScanBase) and [EDFTomoScan API](https://tomotools.gitlab-pages.esrf.fr/tomoscan/modules/esrf.html#tomoscan.esrf.edfscan.EDFTomoScan).
......
......@@ -77,7 +77,6 @@ class EDFTomoScan(TomoScanBase):
# data caches
self._darks = None
self._flats = None
self._projections = None
self.__tomo_n = None
self.__ref_n = None
self.__dark_n = None
......@@ -243,9 +242,27 @@ class EDFTomoScan(TomoScanBase):
@docstring(TomoScanBase.update)
def update(self):
if self.path is not None:
self.projections = EDFTomoScan.get_proj_urls(
all_projections = EDFTomoScan.get_proj_urls(
self.path, n_frames=self._edf_n_frames
)
def select_proj(ddict, from_, to_):
indexes = sorted(set(ddict.keys()))
sel_indexes = indexes[from_:to_]
res = {}
for index in sel_indexes:
res[index] = ddict[index]
return res
if self.tomo_n is not None and len(all_projections) > self.tomo_n:
self._projections = select_proj(all_projections, 0, self.tomo_n)
self._alignment_projections = select_proj(
all_projections, self.tomo_n, None
)
else:
self._projections = all_projections
self._alignment_projections = {}
self._darks = EDFTomoScan.get_darks_url(self.path)
self._flats = EDFTomoScan.get_refs_url(self.path)
......
......@@ -145,7 +145,6 @@ class HDF5TomoScan(TomoScanBase):
# for now the default entry is 1_tomo but should change with time
# data caches
self._projections = None
self._projections_compacted = None
self._flats = None
self._darks = None
......@@ -327,7 +326,6 @@ class HDF5TomoScan(TomoScanBase):
@property
@docstring(TomoScanBase.projections)
def projections(self) -> typing.Union[dict, None]:
"""projections / radio, does not include the return projections"""
if self._projections is None:
if self.frames:
proj_frames = tuple(
......@@ -346,6 +344,23 @@ class HDF5TomoScan(TomoScanBase):
def projections(self, projections: dict):
self._projections = projections
@property
@docstring(TomoScanBase.alignment_projections)
def alignment_projections(self) -> typing.Union[dict, None]:
if self._alignment_projections is None:
if self.frames:
proj_frames = tuple(
filter(
lambda x: x.image_key == ImageKey.PROJECTION
and x.is_control == True,
self.frames,
)
)
self._alignment_projections = {}
for proj_frame in proj_frames:
self._alignment_projections[proj_frame.index] = proj_frame.url
return self._alignment_projections
@property
@docstring(TomoScanBase.darks)
def darks(self) -> typing.Union[dict, None]:
......@@ -833,3 +848,17 @@ class Frame:
@is_control.setter
def is_control(self, is_return: bool):
self._is_control_frame = is_return
def __str__(self):
return (
"Frame {index},: image_key: {image_key},"
"is_control: {is_control},"
"rotation_angle: {rotation_angle},"
"url: {url}".format(
index=self.index,
image_key=self.image_key,
is_control=self.is_control,
rotation_angle=self.rotation_angle,
url=self.url.path(),
)
)
......@@ -302,7 +302,8 @@ class TestProjections(unittest.TestCase):
)
mock.end_acquisition()
scan = EDFTomoScan(scan=self.folder)
self.assertEqual(len(scan.projections), 11 + 2)
self.assertEqual(len(scan.projections), 11)
self.assertEqual(len(scan.alignment_projections), 2)
proj_angle_dict = scan.get_proj_angle_url()
self.assertEqual(len(proj_angle_dict), 11 + 2)
self.assertTrue(90 in proj_angle_dict)
......
......@@ -153,6 +153,10 @@ class TestHDF5Scan(HDF5TestBaseClass):
url_0 = projections[list(projections.keys())[0]]
self.assertEqual(url_0.file_path(), os.path.join(self.scan.master_file))
self.assertEqual(url_0.data_slice(), 22)
# should be 4 but angles are truely missleading: 179.88, 180.0, 90, 0.
# in this case we are not using any information from image_key_control
# and we wait deduce 'return mode' from angles.
self.assertEqual(len(self.scan.alignment_projections), 3)
def testDark(self):
"""Make sure darks are valid"""
......
......@@ -174,13 +174,26 @@ class TomoScanBase:
@property
def projections(self) -> Union[None, dict]:
"""list of projections files"""
"""if found dict of projections urls with index during acquisition as
key"""
return self._projections
@projections.setter
def projections(self, projections: dict) -> None:
self._projections = projections
@property
def alignment_projections(self) -> Union[None, dict]:
"""
dict of projections made for alignment with acquisition index as key
None if not found
"""
return self._alignment_projections
@alignment_projections.setter
def alignment_projections(self, alignment_projs):
self._alignment_projections = alignment_projs
@property
def dark_n(self) -> Union[None, int]:
raise NotImplementedError("Base class")
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment