Skip to content
Snippets Groups Projects
Commit e5c2fbeb authored by payno's avatar payno
Browse files

[refactoring] try to get rid of the 'ref' (frame) references and replace them...

[refactoring] try to get rid of the 'ref' (frame) references and replace them by flat in order to be not on the esrf reference.

/close #2
parent 0fd2bf21
No related branches found
No related tags found
1 merge request!60repalce some `ref` (related to frame) to `flat` in order to be more generic
Pipeline #57648 passed
......@@ -44,6 +44,7 @@ from .utils import get_parameters_frm_par_or_info, extract_urls_from_edf
from ..unitsystem.metricsystem import MetricSystem
from ..utils import docstring
import logging
from silx.utils.deprecation import deprecated
_logger = logging.getLogger(__name__)
......@@ -86,12 +87,12 @@ class EDFTomoScan(TomoScanBase):
self._darks = None
self._flats = None
self.__tomo_n = None
self.__ref_n = None
self.__flat_n = None
self.__dark_n = None
self.__dim1 = None
self.__dim2 = None
self.__pixel_size = None
self.__ref_on = None
self.__flat_on = None
self.__scan_range = None
self._edf_n_frames = n_frames
self.__distance = None
......@@ -107,12 +108,12 @@ class EDFTomoScan(TomoScanBase):
self._flats = None
self._projections = None
self.__tomo_n = None
self.__ref_n = None
self.__flat_n = None
self.__dark_n = None
self.__dim1 = None
self.__dim2 = None
self.__pixel_size = None
self.__ref_on = None
self.__flat_on = None
self.__scan_range = None
@docstring(TomoScanBase.tomo_n)
......@@ -130,11 +131,11 @@ class EDFTomoScan(TomoScanBase):
return self.__dark_n
@property
@docstring(TomoScanBase.ref_n)
@docstring(TomoScanBase.flat_n)
def flat_n(self) -> Union[None, int]:
if self.__ref_n is None:
self.__ref_n = EDFTomoScan.get_ref_n(scan=self.path)
return self.__ref_n
if self.__flat_n is None:
self.__flat_n = EDFTomoScan.get_ref_n(scan=self.path)
return self.__flat_n
@property
@docstring(TomoScanBase.pixel_size)
......@@ -190,9 +191,9 @@ class EDFTomoScan(TomoScanBase):
@property
@docstring(TomoScanBase.ff_interval)
def ff_interval(self) -> Union[None, int]:
if self.__ref_on is None and self.path is not None:
self.__ref_on = EDFTomoScan.get_ff_interval(scan=self.path)
return self.__ref_on
if self.__flat_on is None and self.path is not None:
self.__flat_on = EDFTomoScan.get_ff_interval(scan=self.path)
return self.__flat_on
@property
@docstring(TomoScanBase.scan_range)
......@@ -560,11 +561,11 @@ class EDFTomoScan(TomoScanBase):
:param scan_path:
:type scan_path: str
:param prefix: ref / flat field file prefix
:param prefix: flat file prefix
:type prefix: str
:param file_ext: ref / flat field file extension
:param file_ext: flat file extension
:type file_ext: str
:return: list of refs as silx's `DataUrl`
:return: list of flat frames as silx's `DataUrl`
"""
res = {}
if os.path.isdir(scan_path) is False:
......@@ -591,16 +592,25 @@ class EDFTomoScan(TomoScanBase):
return res
@staticmethod
@deprecated(replacement="get_flats_url", since_version="0.7.0")
def get_refs_url(
scan_path: str, prefix: str = "refHST", file_ext: str = ".edf", ignore=None
) -> dict:
return EDFTomoScan.get_flats_url(
scan_path=scan_path, prefix=prefix, file_ext=file_ext, ignore=ignore
)
@staticmethod
def get_flats_url(
scan_path: str, prefix: str = "refHST", file_ext: str = ".edf", ignore=None
) -> dict:
"""
:param scan_path:
:type scan_path: str
:param prefix: ref / flat field file prefix
:param prefix: flat frame file prefix
:type prefix: str
:param file_ext: ref / flat field file extension
:param file_ext: flat frame file extension
:type file_ext: str
:return: list of refs as silx's `DataUrl`
"""
......@@ -691,7 +701,7 @@ class EDFTomoScan(TomoScanBase):
:param scan: root folder of an acquisition. Must be an absolute path
:param ref_file: the refXXXX_YYYY which should contain information
about the scan.
about the scan. Ref in esrf reference is a flat.
:param key: the key (information) we are looking for
:type key: str
:param type_: requestde out type if the information is found
......
......@@ -242,7 +242,7 @@ class HDF5TomoScan(TomoScanBase):
# number of projections / radios
self._dark_n = None
# number of dark image made during acquisition
self._ref_n = None
self._flat_n = None
# number of flat field made during acquisition
self._scan_range = None
# scan range, in degree
......@@ -298,7 +298,7 @@ class HDF5TomoScan(TomoScanBase):
self._darks = None
self._tomo_n = None
self._dark_n = None
self._ref_n = None
self._flat_n = None
self._scan_range = None
self._dim_1, self._dim_2 = None, None
self._x_pixel_size = None
......@@ -729,7 +729,7 @@ class HDF5TomoScan(TomoScanBase):
else:
return None
@docstring(TomoScanBase.ref_n)
@docstring(TomoScanBase.flat_n)
@property
def flat_n(self) -> typing.Union[None, int]:
if self.flats is not None:
......
......@@ -37,10 +37,13 @@ import fabio
import fabio.edfimage
from .hdf5scan import ImageKey, HDF5TomoScan
from silx.io.utils import h5py_read_dataset
import logging
_logger = logging.getLogger(__name__)
class _ScanMock:
"""Base class to mock as scan (radios, darks, refs, reconstructions...)"""
"""Base class to mock as scan (radios, darks, flats, reconstructions...)"""
PIXEL_SIZE = 0.457
......@@ -56,6 +59,7 @@ class _ScanMock:
recons_vol=False,
dim=200,
ref_n=0,
flat_n=0,
dark_n=0,
scene="noise",
):
......@@ -70,7 +74,8 @@ class _ScanMock:
:param n_pag_recons:
:param recons_vol:
:param dim:
:param ref_n:
:param ref_n: repalced by flat_n
:param flat_n:
:param dark_n:
:param str scene: scene type.
* 'noise': generate radios from numpy.random
......@@ -89,8 +94,17 @@ class _ScanMock:
if not os.path.exists(scan_path):
os.mkdir(scan_path)
if ref_n != 0:
# TODO: add a deprecation warning
_logger.warning("ref_n is deprecated. Please use flat_n instead")
if flat_n != 0:
raise ValueError(
"You provide ref_n and flat_n. Please only provide flat_n"
)
flat_n = ref_n
self.write_metadata(
n_radio=n_radio, scan_range=scan_range, ref_n=ref_n, dark_n=dark_n
n_radio=n_radio, scan_range=scan_range, flat_n=flat_n, dark_n=dark_n
)
def add_radio(self, index=None):
......@@ -105,7 +119,7 @@ class _ScanMock:
def add_recons_vol(self):
raise NotImplementedError("Base class")
def write_metadata(self, n_radio, scan_range, ref_n, dark_n):
def write_metadata(self, n_radio, scan_range, flat_n, dark_n):
raise NotImplementedError("Base class")
def end_acquisition(self):
......@@ -148,7 +162,7 @@ class MockHDF5(_ScanMock):
"""
Mock an acquisition in a hdf5 file.
note: for now the Mock class only manage one initial ref and one final
note: for now the Mock class only manage one initial flat and one final
"""
_PROJ_COUNT = 1
......@@ -167,7 +181,10 @@ class MockHDF5(_ScanMock):
create_ini_dark=True,
create_ini_ref=True,
create_final_ref=False,
create_ini_flat=True,
create_final_flat=False,
n_refs=10,
n_flats=10,
scene="noise",
intensity_monitor=False,
distance=None,
......@@ -185,14 +202,25 @@ class MockHDF5(_ScanMock):
:param recons_vol:
:param dim: frame dim - only manage square fame for now
:param create_ini_dark: create one initial dark frame on construction
:param create_ini_ref: create the initial serie of ref (n_ref) on
:param create_ini_flat: create the initial serie of ref (n_ref) on
construction (after creation of the dark)
:param create_final_ref: create the final serie of ref (n_ref) on
:param create_final_flat: create the final serie of ref (n_ref) on
construction (after creation of the dark)
:param n_refs: number of refs per serie
:param distance: if not None then will save energy on the dataset
:param energy: if not None then will save the distance on the dataset
"""
if create_ini_ref is False:
_logger.warning("create_ini_ref is deprecated. Please use create_init_flat")
create_ini_flat = create_ini_ref
if create_final_ref is True:
_logger.warning(
"create_final_ref is deprecated. Please use create_init_flat"
)
create_final_flat = create_final_ref
if n_refs != 10:
_logger.warning("n_refs is deprecated, please use n_flats")
n_flats = n_refs
self.rotation_angle = numpy.linspace(start=0, stop=scan_range, num=n_proj + 1)
self.rotation_angle_return = numpy.linspace(
start=scan_range, stop=0, num=n_alignement_proj
......@@ -201,7 +229,7 @@ class MockHDF5(_ScanMock):
scan_path, os.path.basename((scan_path)) + ".h5"
)
self._intensity_monitor = intensity_monitor
self._n_refs = n_refs
self._n_flats = n_flats
self.scan_entry = "entry"
super(MockHDF5, self).__init__(
......@@ -218,13 +246,13 @@ class MockHDF5(_ScanMock):
)
if create_ini_dark:
self.add_initial_dark()
if create_ini_ref:
self.add_initial_ref()
if create_ini_flat:
self.add_initial_flat()
if n_ini_proj is not None:
for i_radio in range(n_ini_proj):
self.add_radio(index=i_radio)
if create_final_ref:
self.add_final_ref()
if create_final_flat:
self.add_final_flat()
if energy is not None:
self.add_energy(energy)
if distance is not None:
......@@ -254,8 +282,8 @@ class MockHDF5(_ScanMock):
diode_data=diode_data,
)
def add_initial_ref(self):
for i in range(self._n_refs):
def add_initial_flat(self):
for i in range(self._n_flats):
flat = (
numpy.random.random((self.det_height * self.det_width))
.reshape((1, self.det_width, self.det_height))
......@@ -273,8 +301,8 @@ class MockHDF5(_ScanMock):
diode_data=diode_data,
)
def add_final_ref(self):
for i in range(self._n_refs):
def add_final_flat(self):
for i in range(self._n_flats):
flat = (
numpy.random.random((self.det_height * self.det_width))
.reshape((1, self.det_width, self.det_height))
......@@ -424,7 +452,7 @@ class MockHDF5(_ScanMock):
diode_grp.attrs["NX_class"] = "NXdetector"
diode_grp["data"] = new_diode
def write_metadata(self, n_radio, scan_range, ref_n, dark_n):
def write_metadata(self, n_radio, scan_range, flat_n, dark_n):
with h5py.File(self.scan_master_file, "a") as h5_file:
entry_one = h5_file.require_group(self.scan_entry)
instrument_grp = entry_one.require_group("instrument")
......@@ -488,6 +516,7 @@ class MockEDF(_ScanMock):
scene="noise",
dark_n=0,
ref_n=0,
flat_n=0,
):
self._last_radio_index = -1
super(MockEDF, self).__init__(
......@@ -503,6 +532,7 @@ class MockEDF(_ScanMock):
scene=scene,
dark_n=dark_n,
ref_n=ref_n,
flat_n=flat_n,
)
if n_ini_radio:
for i_radio in range(n_ini_radio):
......@@ -512,8 +542,8 @@ class MockEDF(_ScanMock):
for i_dark in range(dark_n):
self.add_dark(i_dark)
for i_ref in range(ref_n):
self.add_ref(i_ref)
for i_flat in range(flat_n):
self.add_flat(i_flat)
for i_recons in range(n_recons):
self.add_reconstruction(i_recons)
for i_recons in range(n_pag_recons):
......@@ -535,14 +565,14 @@ class MockEDF(_ScanMock):
tree = cElementTree.ElementTree(root)
tree.write(xml_file)
def write_metadata(self, n_radio, scan_range, ref_n, dark_n):
def write_metadata(self, n_radio, scan_range, flat_n, dark_n):
info_file = self.get_info_file()
if not os.path.exists(info_file):
# write the info file
with open(self.get_info_file(), "w") as info_file:
info_file.write("TOMO_N= " + str(n_radio) + "\n")
info_file.write("ScanRange= " + str(scan_range) + "\n")
info_file.write("REF_N= " + str(ref_n) + "\n")
info_file.write("REF_N= " + str(flat_n) + "\n")
info_file.write("REF_ON= " + str(n_radio) + "\n")
info_file.write("DARK_N= " + str(dark_n) + "\n")
info_file.write("Dim_1= " + str(self.det_width) + "\n")
......@@ -595,7 +625,7 @@ class MockEDF(_ScanMock):
)
edf_writer.write(file_path)
def add_ref(self, index):
def add_flat(self, index):
file_name = "refHST{0:04d}.edf".format(index)
file_path = os.path.join(self.scan_path, file_name)
if not os.path.exists(file_path):
......
......@@ -230,22 +230,22 @@ class TestOriDarksFlats(unittest.TestCase):
self.scan = EDFTomoScan(self.folder)
# create a .info for mocking the acquisition
self.write_metadata(n_radio=0, scan_range=360, ref_n=20, dark_n=1)
self.write_metadata(n_radio=0, scan_range=360, flat_n=20, dark_n=1)
assert self.scan.dark_n == 1
assert self.scan.ref_n == 20
assert self.scan.flat_n == 20
assert numpy.isclose(self.scan.pixel_size * 10e5, self.pixel_size)
def get_info_file(self):
return os.path.join(self.scan.path, os.path.basename(self.scan.path) + ".info")
def write_metadata(self, n_radio, scan_range, ref_n, dark_n):
def write_metadata(self, n_radio, scan_range, flat_n, dark_n):
info_file = self.get_info_file()
if not os.path.exists(info_file):
# write the info file
with open(self.get_info_file(), "w") as info_file:
info_file.write("TOMO_N= " + str(n_radio) + "\n")
info_file.write("ScanRange= " + str(scan_range) + "\n")
info_file.write("REF_N= " + str(ref_n) + "\n")
info_file.write("REF_N= " + str(flat_n) + "\n")
info_file.write("REF_ON= " + str(n_radio) + "\n")
info_file.write("DARK_N= " + str(dark_n) + "\n")
info_file.write("Dim_1= " + str(self.det_width) + "\n")
......@@ -261,20 +261,20 @@ class TestOriDarksFlats(unittest.TestCase):
unittest.TestCase.tearDown(self)
def testFlatsOri(self):
ref_urls = self.scan.get_refs_url(prefix="ref", scan_path=self.scan.path)
self.assertEqual(len(ref_urls), 42)
flat_urls = self.scan.get_refs_url(prefix="ref", scan_path=self.scan.path)
self.assertEqual(len(flat_urls), 42)
# checks some random files
file_paths = [url.file_path() for url in ref_urls.values()]
file_paths = [url.file_path() for url in flat_urls.values()]
for ref_file in ("ref_0000_1500.edf", "ref_0004_0000.edf", "ref_0019_1500.edf"):
ref_full_path = os.path.join(self.scan.path, ref_file)
self.assertTrue(ref_full_path in file_paths)
ref_urls = self.scan.get_refs_url(prefix="refHST", scan_path=self.scan.path)
self.assertEqual(len(ref_urls), 2)
flat_urls = self.scan.get_refs_url(prefix="refHST", scan_path=self.scan.path)
self.assertEqual(len(flat_urls), 2)
ref_urls = self.scan.get_refs_url(
flat_urls = self.scan.get_refs_url(
prefix="ref", scan_path=self.scan.path, ignore=("HST",)
)
self.assertEqual(len(ref_urls), 40)
self.assertEqual(len(flat_urls), 40)
def testDarksOri(self):
darks = self.scan.get_darks_url(prefix="darkend", scan_path=self.scan.path)
......
......@@ -143,16 +143,16 @@ class TestHDF5Scan(HDF5TestBaseClass):
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_control)
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 flats
flat_1 = frames[2]
self.assertEqual(flat_1.index, 2)
numpy.isclose(flat_1.rotation_angle, 0.0)
self.assertFalse(flat_1.is_control)
self.assertEqual(flat_1.url.file_path(), self.scan.master_file)
self.assertEqual(flat_1.url.data_path(), "entry0000/instrument/detector/data")
self.assertEqual(flat_1.url.data_slice(), 2)
self.assertEqual(flat_1.image_key, ImageKey.FLAT_FIELD)
self.assertEqual(get_data(flat_1.url).shape, (20, 20))
# check some return projections
r_proj_0 = frames[1543]
......@@ -191,7 +191,7 @@ class TestHDF5Scan(HDF5TestBaseClass):
n_flats = 42
flats = self.scan.flats
self.assertEqual(len(flats), n_flats)
self.assertEqual(self.scan.ref_n, n_flats)
self.assertEqual(self.scan.flat_n, n_flats)
with self.assertRaises(NotImplementedError):
self.scan.ff_interval
......
......@@ -151,7 +151,7 @@ def test_TomoScanBase_API():
for prop in (
"dark_n",
"tomo_n",
"ref_n",
"flat_n",
"pixel_size",
"instrument_name",
"dim_1",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment