Commit d195d5c1 authored by payno's avatar payno
Browse files

[hdf5scan] one step for reading 'christian.hdf5'

- add `Frame` and frames to filter projections, darks, flats and return projections
- start updating a few properties
parent 1bb8e06f
......@@ -86,6 +86,20 @@ class EDFTomoScan(TomoScanBase):
self._edf_n_frames = n_frames
self.update()
@docstring(TomoScanBase.clear_caches)
def clear_caches(self):
self._darks = None
self._flats = None
self._projections = None
self.__tomo_n = None
self.__ref_n = None
self.__dark_n = None
self.__dim1 = None
self.__dim2 = None
self.__pixel_size = None
self.__ref_on = None
self.__scan_range = None
@docstring(TomoScanBase.tomo_n)
@property
def tomo_n(self) -> Union[None, int]:
......
This diff is collapsed.
......@@ -33,7 +33,8 @@ import shutil
import os
import tempfile
from tomoscan.test.utils import UtilsTest
from tomoscan.esrf.hdf5scan import HDF5TomoScan
from tomoscan.esrf.hdf5scan import HDF5TomoScan, ImageKey, Frame
from silx.io.utils import get_data
import numpy
......@@ -56,41 +57,112 @@ class TestHDF5Scan(HDF5TestBaseClass):
"""Basic test for the hdf5 scan"""
def setUp(self) -> None:
super(TestHDF5Scan, self).setUp()
self.dataset_file = self.get_dataset('data_test2.h5')
self.scan = HDF5TomoScan(self.dataset_file)
self.dataset_file = self.get_dataset('frm_edftomomill_twoentries.nx')
self.scan = HDF5TomoScan(scan=self.dataset_file)
def testGeneral(self):
"""some general on the HDF5Scan """
self.assertEqual(self.scan.master_file, self.dataset_file)
self.assertEqual(self.scan.path, os.path.dirname(self.dataset_file))
self.assertEqual(self.scan.type, 'hdf5')
self.assertEqual(self.scan.entry, '/entry0000')
self.assertEqual(len(self.scan.flats), 42)
self.assertEqual(len(self.scan.darks), 1)
self.assertEqual(len(self.scan.return_projs), 3)
proj_angles = self.scan.get_proj_angle_url()
self.assertEqual(len(proj_angles), 1500 + 3)
self.assertTrue(90 in proj_angles)
self.assertTrue(24.0 in proj_angles)
self.assertTrue('90.0(1)' in proj_angles)
self.assertTrue('180.0(1)' in proj_angles)
self.assertTrue(179.88 not in proj_angles)
url_1 = proj_angles[0]
self.assertTrue(url_1.is_valid())
self.assertTrue(url_1.is_absolute())
self.assertEquals(url_1.scheme(), 'silx')
# check conversion to dict
_dict = self.scan.to_dict()
scan2 = HDF5TomoScan.from_dict(_dict)
self.assertEqual(scan2.path, self.scan.path)
radios_urls = self.scan.get_proj_angle_url()
self.assertEqual(len(radios_urls), 100)
url_1 = radios_urls[0]
self.assertTrue(url_1.is_valid())
self.assertFalse(url_1.is_absolute())
self.assertEquals(url_1.scheme(), 'silx')
self.assertEqual(scan2.entry, self.scan.entry)
def testFrames(self):
"""Check the `frames` property which is massively used under the
HDF5TomoScan class"""
frames = self.scan.frames
# check some projections
proj_2 = frames[24]
self.assertTrue(isinstance(proj_2, Frame))
self.assertEqual(proj_2.index, 24)
numpy.isclose(proj_2.rotation_angle, 0.24)
self.assertFalse(proj_2.is_return)
self.assertEqual(proj_2.url.file_path(), self.scan.master_file)
self.assertEqual(proj_2.url.data_path(), '/entry0000/instrument/detector/data')
self.assertEqual(proj_2.url.data_slice(), 24)
self.assertEqual(proj_2.image_key, ImageKey.PROJECTION)
self.assertEqual(get_data(proj_2.url).shape, (20, 20))
# check last two non-return projection
for frame_index in (1520, 1542):
with self.subTest(frame_index=frame_index):
frame = frames[frame_index]
self.assertTrue(frame.image_key, ImageKey.PROJECTION)
self.assertFalse(frame.is_return)
# check some darks
dark_0 = frames[0]
self.assertEqual(dark_0.index, 0)
numpy.isclose(dark_0.rotation_angle, 0.0)
self.assertFalse(dark_0.is_return)
self.assertEqual(dark_0.url.file_path(), self.scan.master_file)
self.assertEqual(dark_0.url.data_path(), '/entry0000/instrument/detector/data')
self.assertEqual(dark_0.url.data_slice(), 0)
self.assertEqual(dark_0.image_key, ImageKey.DARK_FIELD)
self.assertEqual(get_data(dark_0.url).shape, (20, 20))
# check some refs
ref_1 = frames[2]
self.assertEqual(ref_1.index, 2)
numpy.isclose(ref_1.rotation_angle, 0.0)
self.assertFalse(ref_1.is_return)
self.assertEqual(ref_1.url.file_path(), self.scan.master_file)
self.assertEqual(ref_1.url.data_path(),
'/entry0000/instrument/detector/data')
self.assertEqual(ref_1.url.data_slice(), 2)
self.assertEqual(ref_1.image_key, ImageKey.FLAT_FIELD)
self.assertEqual(get_data(ref_1.url).shape, (20, 20))
# check some return projections
r_proj_0 = frames[1543]
self.assertTrue(isinstance(r_proj_0, Frame))
self.assertEqual(r_proj_0.index, 1543)
numpy.isclose(r_proj_0.rotation_angle, 180)
self.assertTrue(r_proj_0.is_return)
self.assertEqual(r_proj_0.url.file_path(), self.scan.master_file)
self.assertEqual(r_proj_0.url.data_path(),
'/entry0000/instrument/detector/data')
self.assertEqual(r_proj_0.url.data_slice(), 1543)
self.assertEqual(r_proj_0.image_key, ImageKey.PROJECTION)
self.assertEqual(get_data(r_proj_0.url).shape, (20, 20))
def testProjections(self):
"""Make sure projections are valid"""
projections = self.scan.projections
self.assertEqual(len(projections), 100)
proj_1 = projections[0]
self.assertEqual(proj_1.file_path(),
'../../../../../../users/opid19/W:/clemence/visualtomo/data_test2/tomo0001/tomo_0000.h5')
self.assertEqual(proj_1.data_slice(), ('0',))
self.assertTrue(100 not in projections)
@unittest.skip('no valid hdf5 acquisition defined yet')
self.assertEqual(len(self.scan.projections), 1500)
url_0 = projections[0]
self.assertEqual(url_0.file_path(), os.path.join(self.scan.master_file))
self.assertEqual(url_0.data_slice(), 22)
def testDark(self):
n_dark = 20
"""Make sure darks are valid"""
n_dark = 1
self.assertEqual(self.scan.dark_n, n_dark)
with self.assertRaises(NotImplementedError):
self.scan.darks
darks = self.scan.darks
self.assertEqual(len(darks), 1)
# TODO check accumulation time
def testFlats(self):
"""Make sure flats are valid"""
with self.assertRaises(NotImplementedError):
flats = self.scan.flats
n_ref = 21
......
......@@ -57,6 +57,11 @@ class TomoScanBase:
self.path = scan
self._type = type_
def clear_caches(self):
"""clear caches. Might be call if some data changed after
first read of data or metadata"""
raise NotImplementedError('Base class')
@property
def path(self) -> Union[None, str]:
"""
......@@ -135,6 +140,7 @@ class TomoScanBase:
@property
def tomo_n(self) -> Union[None, int]:
"""number of projection WITHOUT the return projections"""
raise NotImplementedError('Base class')
@property
......@@ -237,9 +243,11 @@ class TomoScanBase:
def get_proj_angle_url(self) -> dict:
"""
Return the 'extra' radios of a scan which are used to see if the scan
moved during the acquisition. If no extra radio are found, return the
dictionary of all radios.
return a dictionary of all the projection. key is the angle of the
projection and value is the url.
Keys are int for 'standard' projections and strings for return
projections.
:return dict: angles as keys, radios as value.
"""
......
......@@ -30,8 +30,10 @@ __date__ = "24/01/2017"
import unittest
from ..esrf.edfscan import EDFTomoScan
from ..esrf.hdf5scan import HDF5TomoScan
from ..scanfactory import ScanFactory
from .utils import UtilsTest
from silx.io.url import DataUrl
import tempfile
......@@ -40,15 +42,71 @@ class TestScanFactory(unittest.TestCase):
valid scan type for a given file / directory
"""
def test_no_scan(self):
"""Make sure an error is raised if we try yo create a scan from an
empty dir"""
scan_dir = tempfile.mkdtemp()
with self.assertRaises(ValueError):
ScanFactory.create_scan_object(scan_dir)
def test_scan_edf(self):
"""can we create a TomoScanBase object from a folder containing a
valid .edf acquisition"""
scan_dir = UtilsTest.getDataset('test10')
scan = ScanFactory.create_scan_object(scan_dir)
self.assertTrue(isinstance(scan, EDFTomoScan))
def test_one_nx(self):
"""Can we create a TomoScanBase from a .nx master file containing
one acquisition"""
scan_dir = UtilsTest.getH5Dataset('frm_edftomomill_oneentry.nx')
scan = ScanFactory.create_scan_object(scan_dir)
self.assertTrue(isinstance(scan, HDF5TomoScan))
self.assertEqual(scan.path, DataUrl(scan_dir, data_path='entry',
scheme='tomoscan'))
# def test_one_two_nx(self):
# """Can we create a TomoScanBase from a .nx master file containing
# two acquisitions"""
# scan_dir = UtilsTest.getH5Dataset('frm_edftomomill_twoentries.nx')
# scan = ScanFactory.create_scan_object(scan_dir)
# self.assertTrue(isinstance(scan, HDF5TomoScan))
# self.assertEqual(scan.path, DataUrl(scan_dir, data_path='entry0000',
# scheme='tomoscan'))
#
# def test_one_frm_two_nx_with_index(self):
# """Can we create a TomoScanBase from a .nx master file containing
# two acquisitions. Pick the one at given index"""
# scan_dir = UtilsTest.getH5Dataset('frm_edftomomill_twoentries.nx')
# scan = ScanFactory.create_scan_object(scan_dir)
# self.assertTrue(isinstance(scan, HDF5TomoScan))
# self.assertEqual(scan.path, DataUrl(scan_dir, data_path='entry0000',
# scheme='tomoscan'))
#
# def test_one_frm_two_nx_with_entry_name(self):
# """Can we create a TomoScanBase from a .nx master file containing
# two acquisitions. Pick the one with the given name"""
# scan_dir = UtilsTest.getH5Dataset('frm_edftomomill_twoentries.nx')
# scan = ScanFactory.create_scan_object(scan_dir)
# self.assertTrue(isinstance(scan, HDF5TomoScan))
# self.assertEqual(scan.path, DataUrl(scan_dir, data_path='entry0000',
# scheme='tomoscan'))
#
# def test_two_nx(self):
# """Can we create two TomoScanBase from a .nx master file containing
# two acquisitions using the ScanFactory"""
# scan_dir = UtilsTest.getH5Dataset('frm_edftomomill_twoentries.nx')
# scans = ScanFactory.create_scan_objects(scan_dir)
# scan_0000, scan_0001 = scans
# self.assertTrue(isinstance(scan_0000, EDFTomoScan))
# self.assertTrue(isinstance(scan_0001, EDFTomoScan))
# self.assertEqual(scan_0000.path, DataUrl(scan_dir,
# data_path='entry0000',
# scheme='tomoscan'))
# self.assertEqual(scan_0001.path, DataUrl(scan_dir,
# data_path='entry0001',
# scheme='tomoscan'))
def suite():
test_suite = unittest.TestSuite()
......
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