Commit 679e51d2 authored by payno's avatar payno
Browse files

rework get_proj_angle_url and add unit test on projection and get_proj_angle_url for edf

parent 1d107543
Pipeline #15490 failed with stages
in 49 seconds
......@@ -35,7 +35,6 @@ from lxml import etree
import json
import io
from typing import Union
from silx.io.url import DataUrl
from ..scanbase import TomoScanBase
from .utils import get_parameters_frm_par_or_info, extract_urls_from_edf
from ..unitsystem import metricsystem
......@@ -79,6 +78,7 @@ class EDFTomoScan(TomoScanBase):
self.__pixel_size = None
self.__ref_on = None
self.__scan_range = None
self.update()
@docstring(TomoScanBase.tomo_n)
@property
......@@ -205,35 +205,14 @@ class EDFTomoScan(TomoScanBase):
' the projections')
return {}
n_projection = self.tomo_n
radios = EDFTomoScan.get_proj_paths(self.path)
sorted_keys = list(radios.keys())
sorted_keys.sort()
data_urls = []
# create one DataUrl per projection
for key in sorted_keys:
radio = radios[key]
edf_reader = fabio.open(radio)
if edf_reader.nframes is 1:
data_urls.append(DataUrl(file_path=radio, scheme='fabio'))
else:
data_urls.extend(extract_urls_from_edf(file_=radio))
if n_projection is None:
raise ValueError('unable to get n projection')
if len(data_urls) < n_projection:
mes = 'incoherence between the number of projection found (%s)' \
'and the number of theoretical projection (%s). Maybe the ' \
'acquisition is not complete ?' % (len(data_urls), n_projection)
_logger.warning(mes)
data_urls = EDFTomoScan.get_proj_urls(self.path)
return TomoScanBase.map_urls_on_scan_range(urls=data_urls,
n_projection=n_projection,
scan_range=self.scan_range)
@docstring(TomoScanBase.update)
def update(self):
self.projections = EDFTomoScan.get_proj_angle_url(self.path)
self.projections = EDFTomoScan.get_proj_urls(self.path)
self._darks = EDFTomoScan.get_darks_url(self.path)
self._flats = EDFTomoScan.get_refs_url(self.path)
......@@ -251,7 +230,7 @@ class EDFTomoScan(TomoScanBase):
return self
@staticmethod
def get_proj_paths(scan: str) -> dict:
def get_proj_urls(scan: str) -> dict:
"""
Return the dict of radios / projection for the given scan.
Keys of the dictionary is the slice number
......@@ -263,19 +242,19 @@ class EDFTomoScan(TomoScanBase):
:return: dict of radios files with radio index as key and file as value
:rtype: dict
"""
files = dict({})
urls = dict({})
if(scan is None) or not(os.path.isdir(scan)):
return files
return urls
if os.path.isdir(scan):
for f in os.listdir(scan):
if EDFTomoScan.is_a_proj_path(f, scan):
if EDFTomoScan.is_a_proj_path(fileName=f, scanID=scan):
gfile = os.path.join(scan, f)
index = EDFTomoScan.guess_index_frm_file_name(gfile)
files.update(extract_urls_from_edf(start_index=index,
urls.update(extract_urls_from_edf(start_index=index,
file_=gfile))
return files
return urls
@staticmethod
def is_a_proj_path(fileName: str, scanID: str) -> bool:
......
......@@ -85,7 +85,7 @@ class _ScanMock:
for i_radio in range(n_ini_radio):
self.add_radio(i_radio)
for i_extra_radio in range(n_extra_radio):
self.add_radio(i_extra_radio)
self.add_radio(n_radio+i_extra_radio)
for i_recons in range(n_recons):
self.add_reconstruction(i_recons)
for i_recons in range(n_pag_recons):
......@@ -240,14 +240,14 @@ class MockEDF(_ScanMock):
self._last_radio_index += 1
index_ = self._last_radio_index
file_name = os.path.basename(self.scan_path) + '_{0:04d}'.format(index_) + ".edf"
f = os.path.join(self.scan_path, file_name)
if not os.path.exists(f):
data = self._get_radio_data(index=index_)
assert data.shape == (self.det_width, self.det_height)
edf_writer = fabio.edfimage.EdfImage(data=data,
header={"tata": "toto"})
edf_writer.write(f)
file_name = os.path.basename(self.scan_path) + '_{0:04d}'.format(index_) + ".edf"
f = os.path.join(self.scan_path, file_name)
if not os.path.exists(f):
data = self._get_radio_data(index=index_)
assert data.shape == (self.det_width, self.det_height)
edf_writer = fabio.edfimage.EdfImage(data=data,
header={"tata": "toto"})
edf_writer.write(f)
@staticmethod
def mockReconstruction(folder, nRecons=5, nPagRecons=0, volFile=False):
......
......@@ -167,12 +167,21 @@ class TestProjections(unittest.TestCase):
self.assertEqual(len(scan.projections), 3)
scan.update()
self.assertEqual(len(scan.projections), 4)
self.assertTrue(isinstance(scan.projections[0], silx.io.url.DataUrl))
def testProjectionWithExtraRadio(self):
mock = MockEDF(scan_path=self.folder, n_radio=10, n_extra_radio=3)
mock = MockEDF(scan_path=self.folder, n_radio=11, n_extra_radio=2,
scan_range=180)
mock.end_acquisition()
scan = EDFTomoScan(scan=self.folder)
self.assertEqual(len(scan.projections), 10)
self.assertEqual(len(scan.projections), 11+2)
proj_angle_dict = scan.get_proj_angle_url()
self.assertEqual(len(proj_angle_dict), 11+2)
self.assertTrue(90 in proj_angle_dict)
self.assertTrue(180 in proj_angle_dict)
self.assertTrue('90(1)' in proj_angle_dict)
self.assertTrue('0(1)' in proj_angle_dict)
self.assertTrue(360 not in proj_angle_dict)
class TestScanValidatorFindFiles(unittest.TestCase):
......@@ -205,7 +214,7 @@ class TestScanValidatorFindFiles(unittest.TestCase):
shutil.rmtree(self.path)
def testGetRadioPaths(self):
nFound = len(EDFTomoScan.get_proj_paths(self.path))
nFound = len(EDFTomoScan.get_proj_urls(self.path))
self.assertTrue(nFound == self.N_RADIO)
......
......@@ -31,6 +31,7 @@ __date__ = "09/10/2019"
import os
import logging
from typing import Union
from collections import OrderedDict
logger = logging.getLogger(__name__)
......@@ -235,10 +236,14 @@ class TomoScanBase:
:type: float
:return: angle in degree as key and url as value
:rtype: dict
:raises: ValueError if the number of extra images found and scan_range
are incoherent
"""
assert n_projection is not None
res = {}
ordered_url = OrderedDict(sorted(urls.items(), key= lambda x: x))
res = {}
# deal with the 'standard' acquisitions
for proj_i in range(n_projection):
angle = proj_i * scan_range / (n_projection -1)
......@@ -250,7 +255,7 @@ class TomoScanBase:
if len(urls) > n_projection:
# deal with extra images (used to check if the sampled as moved for
# example)
extraImgs = urls[n_projection:]
extraImgs = list(ordered_url.keys())[n_projection:]
if len(extraImgs) in (4, 5):
if scan_range < 360:
logger.warning('incoherent data information to retrieve'
......@@ -278,8 +283,6 @@ class TomoScanBase:
res['90(1)'] = extraImgs[0]
res['0(1)'] = extraImgs[1]
else:
logger.warning('incoherent data information to retrieve scan'
'extra images angle')
for i_extra, extra in enumerate(extraImgs):
res['? (' + str(i_extra) + ')'] = extra
raise ValueError('incoherent data information to retrieve scan'
'extra images angle')
return res
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