Commit 5657b708 authored by payno's avatar payno Committed by payno
Browse files

add get_sinogram

parent 1c3370dd
......@@ -42,6 +42,10 @@ from ..scanbase import TomoScanBase
from .utils import get_parameters_frm_par_or_info, extract_urls_from_edf
from ..unitsystem.metricsystem import MetricSystem
from ..utils import docstring
import silx.io.utils
import numpy
from math import ceil
from ..progress import Progress
import logging
_logger = logging.getLogger(__name__)
......@@ -93,6 +97,7 @@ class EDFTomoScan(TomoScanBase):
@docstring(TomoScanBase.clear_caches)
def clear_caches(self):
super().clear_caches()
self._darks = None
self._flats = None
self._projections = None
......@@ -719,3 +724,46 @@ class EDFTomoScan(TomoScanBase):
return self.get_scan_range(self.path)
else:
return None
@docstring(TomoScanBase.get_sinogram)
def get_sinogram(self, line, subsampling=1):
"""
extract the sinogram from projections
:param line: which sinogram we want
:type: int
:param subsampling: subsampling to apply if any. Allows to skip some io
:type: int
:return: sinogram from the radio lines
:rtype: numpy.array
"""
_logger.info(
"compute sinogram for line {} of {} (subsampling: {})".format(
line, self.path, subsampling
)
)
assert isinstance(line, int)
if self.tomo_n is not None and self.dim_2 is not None and line > self.dim_2:
raise ValueError("requested line %s is not in the scan")
else:
y_dim = ceil(self.tomo_n / subsampling)
sinogram = numpy.empty((y_dim, self.dim_1))
proj_urls = self.get_proj_angle_url()
assert len(proj_urls) >= self.tomo_n
proj_sort = list(proj_urls.keys())
proj_sort = list(filter(lambda x: not isinstance(x, str), proj_sort))
proj_sort.sort()
advancement = Progress(
name="compute sinogram for %s, line=%s,"
"sampling=%s" % (os.path.basename(self.path), line, subsampling)
)
advancement.setMaxAdvancement(len(proj_sort))
for i_proj, proj in enumerate(proj_sort):
if i_proj % subsampling == 0:
url = proj_urls[proj]
radio = silx.io.utils.get_data(url)
radio = self.flat_field_correction(radio, proj_indexes=i_proj)
sinogram[i_proj // subsampling] = radio[line]
advancement.increaseAdvancement(1)
return sinogram
......@@ -43,8 +43,11 @@ from tomoscan.io import HDF5File
from silx.io.utils import get_data
from ..unitsystem import metricsystem
from .utils import get_compacted_dataslices
import logging
import typing
import silx.io.utils
from math import ceil
from ..progress import Progress
import logging
_logger = logging.getLogger(__name__)
......@@ -188,6 +191,7 @@ class HDF5TomoScan(TomoScanBase):
@docstring(TomoScanBase.clear_caches)
def clear_caches(self) -> None:
super().clear_caches()
self._projections = None
self._projections_compacted = None
self._flats = None
......@@ -762,6 +766,54 @@ class HDF5TomoScan(TomoScanBase):
"file %s" % (self._entry, self.master_file)
)
@docstring(TomoScanBase.get_sinogram)
def get_sinogram(self, line, subsampling=1):
"""
extract the sinogram from projections
:param line: which sinogram we want
:type: int
:param subsampling: subsampling to apply if any. Allows to skip some io
:type: int
:return: sinogram from the radio lines
:rtype: numpy.array
"""
if (
self.tomo_n is not None and self.dim_2 is not None and line > self.dim_2
) or line < 0:
raise ValueError("requested line {} is not in the scan".format(line))
if self.projections is not None:
dim1, dim2 = self.dim_1, self.dim_2
y_dim = ceil(self.tomo_n / subsampling)
sinogram = numpy.empty((y_dim, dim1))
_logger.info(
"compute sinogram for line {} of {} (subsampling: {})".format(
line, self.path, subsampling
)
)
advancement = Progress(
name="compute sinogram for {}, line={},"
"sampling={}".format(os.path.basename(self.path), line, subsampling)
)
advancement.setMaxAdvancement(self.tomo_n)
projections = self.projections
o_keys = list(projections.keys())
o_keys.sort()
for i_proj, proj_key in enumerate(o_keys):
if i_proj % subsampling == 0:
proj_url = projections[proj_key]
proj = silx.io.utils.get_data(proj_url)
proj = self.flat_field_correction(
projs=[proj], proj_indexes=[i_proj]
)[0]
sinogram[i_proj // subsampling] = proj[line]
advancement.increaseAdvancement(1)
return sinogram
else:
return None
class Frame:
"""class to store all metadata information of a frame"""
......
......@@ -390,6 +390,18 @@ class TomoScanBase:
)
return res
def get_sinogram(self, line, subsampling=1):
"""
extract the sinogram from projections
:param int line: which sinogram we want
:param int subsampling: subsampling to apply. Allows to skip some io
:return: computed sinogram from projections
:rtype: numpy.array
"""
raise NotImplementedError("Base class")
def _flat_field_correction(
self,
data: typing.Union[numpy.ndarray, DataUrl],
......
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