...
 
Commits (27)
image: tomogui:latest
test:
stage: test
# TODO: have at least one unit test with the lastest version of freeart to insure compatibility
# do the same for the different silx versions
test:debian.8-python2.7-silx0.8-PySide2-latest_freeartrelease:
type: test
image: docker-registry.esrf.fr/dau/opengl:python2.7-jessie
script:
- echo 'current dir is '
- pwd
- echo '--------------- Unit test under - PySide2 WITHOUT freeart ---------'
- echo 'source /home/gitlab-runner/venvs/tomogui_python2_no_freeart/bin/activate'
- source /home/gitlab-runner/venvs/tomogui_python2_no_freeart/bin/activate
- python info_version.py
- xvfb-run --server-args="-screen 0 1024x768x24" -a ./bootstrap.py run_tests.py -v
- deactivate
- echo '--------------- Unit test under python3 - PyQt5 with freeart ------'
- echo 'source /home/gitlab-runner/venvs/tomogui_python2/bin/activate'
- source /home/gitlab-runner/venvs/tomogui_python3/bin/activate
- python info_version.py
- xvfb-run --server-args="-screen 0 1024x768x24" -a ./bootstrap.py run_tests.py -v
- deactivate
- echo '--------------- Unit test under - PySide2 WITH freeart ------------'
- echo 'source /home/gitlab-runner/venvs/tomogui_python2/bin/activate'
- source /home/gitlab-runner/venvs/tomogui_python2/bin/activate
- python info_version.py
- xvfb-run --server-args="-screen 0 1024x768x24" -a ./bootstrap.py run_tests.py -v
- deactivate
- export http_proxy=http://proxy.esrf.fr:3128/
- export https_proxy=http://proxy.esrf.fr:3128/
- python --version
- python -m pip install pip --upgrade
- python -m pip install setuptools --upgrade
- python -m pip install PySide2
- python -m pip install silx
- python -m pip install matplotlib
- source ./ci/tomogui_install.sh
- install_freeart 'master'
- freeart_version
- python -m pip install .
- xvfb-run --server-args="-screen 0 1024x768x24" -a tomogui test -v
#
#test:debian.8-python3.4-silx0.8-PySide2-freeartmaster:
# type: test
# image: docker-registry.esrf.fr/dau/opengl:python3.4-jessie
# script:
# - export http_proxy=http://proxy.esrf.fr:3128/
# - export https_proxy=http://proxy.esrf.fr:3128/
# - python --version
# - pip install pip --upgrade
# - pip install setuptools --upgrade
# - pip install PyQt5
# - pip install silx
# - pip install matplotlib
# - source ./ci/tomogui_install.sh
# - install_freeart 'master'
# - pip install .
# - xvfb-run --server-args="-screen 0 1024x768x24" -a tomogui test -v
test:debian.9-python3.5-silx0.8-PyQt5-freeartmaster:
type: test
image: docker-registry.esrf.fr/dau/opengl:python3.5-stretch
script:
- export http_proxy=http://proxy.esrf.fr:3128/
- export https_proxy=http://proxy.esrf.fr:3128/
- python --version
- python -m pip install pip --upgrade
- python -m pip install setuptools --upgrade
- python -m pip install PyQt5
- python -m pip install matplotlib
- python -m pip install -r requirements.txt
- source ./ci/tomogui_install.sh
- install_freeart 'master'
- freeart_version
- python -m pip install .
- xvfb-run --server-args="-screen 0 1024x768x24" -a tomogui test -v
# TODO: add this, but require opencl at least installed and configure...
#test:debian.9-python3.5-silx0.8-PyQt5-nofreeart:
# type: test
# image: docker-registry.esrf.fr/dau/opengl:python3.5-stretch
# script:
# - export http_proxy=http://proxy.esrf.fr:3128/
# - export https_proxy=http://proxy.esrf.fr:3128/
# - python --version
# - pip install pip --upgrade
# - pip install setuptools --upgrade
# - pip install PyQt5
# - pip install matplotlib
# - pip install -r requirements.txt
# - pip install .
# - xvfb-run --server-args="-screen 0 1024x768x24" -a tomogui test -v
#!/bin/bash
function install_freeart(){
if [ "$2" = 'latest' ]; then
pip install freeart
else
unset http_proxy
unset https_proxy
mkdir freeart
cd freeart
wget https://gitlab.esrf.fr/freeart/freeart/repository/master/archive.tar
tar -xvf archive.tar
rm archive.tar
cd ./*
python -m pip install -r requirements.txt
python -m pip install .
cd ../../
export http_proxy=http://proxy.esrf.fr:3128/
export https_proxy=http://proxy.esrf.fr:3128/
fi
}
function freeart_version(){
python -c 'import freeart; print(freeart.version)'
}
import silx
print('silx version is ', silx._version.version)
from silx.gui import qt
print('qt version is ', qt.qVersion())
try:
import freeart
except:
pass
else:
print('freeart version is ', freeart._version.version)
import numpy
print('numpy version is ', numpy.version.version)
import fisx
print('fisx version is ', fisx.version())
# List all dependencies of freeart
# Requires pip >= 8.0
silx >= 0.6 # for GUI
silx >= 0.8 # for GUI
fabio # for IO
h5py
......@@ -71,6 +71,9 @@ def main():
launcher.add_command("materials",
module_name="tomogui.app.materials",
description="Allow materials edition from a .h5")
launcher.add_command("test",
module_name="tomogui.app.test_",
description="Launch tomogui unittest")
status = launcher.execute(sys.argv)
return status
......
......@@ -29,6 +29,8 @@ def main(argv):
if options.debug:
logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.WARNING)
global app # QApplication must be global to avoid seg fault on quit
app = qt.QApplication.instance() or qt.QApplication([])
......@@ -42,4 +44,4 @@ def main(argv):
if __name__ == '__main__':
main(sys.argv)
\ No newline at end of file
main(sys.argv)
......@@ -34,6 +34,7 @@ __date__ = "08/08/2017"
from freeart.utils import reconstrutils
import argparse
import sys
import logging
def getinputinfo():
......@@ -55,6 +56,8 @@ def main(argv):
if options.debug:
logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.WARNING)
_input = options.edf_input
_output = options.edf_output
......
......@@ -39,6 +39,8 @@ def main(argv):
if options.debug:
logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.WARNING)
filePath = options.mat_file
file_info_dict = fileInfo.DictInfo(file_path=filePath,
......
......@@ -34,6 +34,7 @@ __date__ = "08/08/2017"
from freeart.utils import reconstrutils
import sys
import argparse
import logging
def getinputinfo():
......@@ -55,6 +56,8 @@ def main(argv):
if options.debug:
logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.WARNING)
if len(argv) is not 3:
err = 'You should give an input .edf files and an output .edf file'
......
......@@ -8,7 +8,7 @@ from tomogui import utils
import argparse
import os
import h5py
import logging
def getinputinfo():
return "tomogui project [projectfile.cfg]"
......@@ -32,6 +32,8 @@ def main(argv):
if options.debug:
logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.WARNING)
newCFGFile = options.project_file
if newCFGFile:
......
......@@ -5,7 +5,7 @@ import os
import sys
import argparse
from silx.gui import qt
from tomogui import utils
from logging
from tomogui.gui.reconstruction import ReconsManager
import tomogui.core
......@@ -36,6 +36,8 @@ def main(argv):
if options.debug:
logging.root.setLevel(logging.DEBUG)
else:
logging.root.setLevel(logging.WARNING)
cfgFile = options.project_file
fn, file_extension = os.path.splitext(cfgFile)
......
# coding: utf-8
# /*##########################################################################
# Copyright (C) 2016-2018 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ############################################################################*/
"""Launch unittests of the library"""
__authors__ = ["V. Valls"]
__license__ = "MIT"
__date__ = "12/01/2018"
import sys
import argparse
import logging
import unittest
class StreamHandlerUnittestReady(logging.StreamHandler):
"""The unittest class TestResult redefine sys.stdout/err to capture
stdout/err from tests and to display them only when a test fail.
This class allow to use unittest stdout-capture by using the last sys.stdout
and not a cached one.
"""
def emit(self, record):
"""
:type record: logging.LogRecord
"""
self.stream = sys.stderr
super(StreamHandlerUnittestReady, self).emit(record)
def flush(self):
pass
def createBasicHandler():
"""Create the handler using the basic configuration"""
hdlr = StreamHandlerUnittestReady()
fs = logging.BASIC_FORMAT
dfs = None
fmt = logging.Formatter(fs, dfs)
hdlr.setFormatter(fmt)
return hdlr
# Use an handler compatible with unittests, else use_buffer is not working
for h in logging.root.handlers:
logging.root.removeHandler(h)
logging.root.addHandler(createBasicHandler())
logging.captureWarnings(True)
_logger = logging.getLogger(__name__)
"""Module logger"""
class TextTestResultWithSkipList(unittest.TextTestResult):
"""Override default TextTestResult to display list of skipped tests at the
end
"""
def printErrors(self):
unittest.TextTestResult.printErrors(self)
# Print skipped tests at the end
self.printErrorList("SKIPPED", self.skipped)
def main(argv):
"""
Main function to launch the unittests as an application
:param argv: Command line arguments
:returns: exit status
"""
from silx.test import utils
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("-v", "--verbose", default=0,
action="count", dest="verbose",
help="Increase verbosity. Option -v prints additional " +
"INFO messages. Use -vv for full verbosity, " +
"including debug messages and test help strings.")
parser.add_argument("--qt-binding", dest="qt_binding", default=None,
help="Force using a Qt binding: 'PyQt5' or 'PySide2'")
utils.test_options.add_parser_argument(parser)
options = parser.parse_args(argv[1:])
test_verbosity = 1
use_buffer = True
if options.verbose == 1:
logging.root.setLevel(logging.INFO)
_logger.info("Set log level: INFO")
test_verbosity = 2
use_buffer = False
elif options.verbose > 1:
logging.root.setLevel(logging.DEBUG)
_logger.info("Set log level: DEBUG")
test_verbosity = 2
use_buffer = False
if options.qt_binding:
binding = options.qt_binding.lower()
if binding == "pyqt4":
_logger.info("Force using PyQt4")
import PyQt4.QtCore # noqa
elif binding == "pyqt5":
_logger.info("Force using PyQt5")
import PyQt5.QtCore # noqa
elif binding == "pyside":
_logger.info("Force using PySide")
import PySide.QtCore # noqa
elif binding == "pyside2":
_logger.info("Force using PySide2")
import PySide2.QtCore # noqa
else:
raise ValueError("Qt binding '%s' is unknown" % options.qt_binding)
# Configure test options
utils.test_options.configure(options)
# Run the tests
runnerArgs = {}
runnerArgs["verbosity"] = test_verbosity
runnerArgs["buffer"] = use_buffer
runner = unittest.TextTestRunner(**runnerArgs)
runner.resultclass = TextTestResultWithSkipList
# Display the result when using CTRL-C
unittest.installHandler()
import tomogui.test
test_suite = unittest.TestSuite()
test_suite.addTest(tomogui.test.suite())
result = runner.run(test_suite)
if result.wasSuccessful():
exit_status = 0
else:
exit_status = 1
return exit_status
......@@ -289,7 +289,7 @@ class _MainTabWidget(qt.QTabWidget):
)
self.materialsWidget.isDisplayed = True
self.setTabToolTip(
self.addTab(self.materialsWidget, "sample comsposition"),
self.addTab(self.materialsWidget, "sample composition"),
self.materialsWidget.getShortToolTip())
if visible is False and self.materialsWidget.isDisplayed is True:
self.removeTab(3)
......@@ -727,6 +727,8 @@ class MainWidget(qt.QWidget):
# bad hack : we are looking for the reconsparam type.
# Silx configparser as the freeart configparser are able to get it
# since it is the same structure used for this option
if config is None:
return
self.setReconstructionType(config.reconsType)
self.getDataSourceWidget().loadConfiguration(config)
self.getNormalizationWidget().loadConfiguration(config)
......
......@@ -81,7 +81,6 @@ class AbsMatCreator(qt.QMainWindow):
def _load(self):
dialog = ImageFileDialog(self)
dialog.setFileType(TomoGUIFileTypeCB(dialog))
dialog.setDirectory(_getDefaultFolder())
result = dialog.exec_()
......
......@@ -77,6 +77,10 @@ class QDataSourceWidget(qt.QWidget, ConfigurationActor):
FREEART_FLUO_DEF: freeartconfig._ReconsConfig.FLUO_ID,
}
DICT_IDS_DEF = {}
for key, value in list(DICT_IDS.items()):
DICT_IDS_DEF[value] = key
sigReconstructionTypeChanged = qt.Signal(object)
@staticmethod
......@@ -306,14 +310,10 @@ class QDataSourceWidget(qt.QWidget, ConfigurationActor):
Value can be freeartconfig.FLUO_ID,
freeartconfig.COMPTON_ID or freeartconfig.TX_ID
"""
if val == tomoguiconfig.FBPConfig.FBP_ID:
self.qcbReconstructionType.setCurrentIndex(0)
elif val == freeartconfig._ReconsConfig.TX_ID:
self.qcbReconstructionType.setCurrentIndex(1)
elif val == freeartconfig._ReconsConfig.COMPTON_ID:
self.qcbReconstructionType.setCurrentIndex(2)
elif val == freeartconfig._ReconsConfig.FLUO_ID:
self.qcbReconstructionType.setCurrentIndex(3)
if val in self.DICT_IDS_DEF:
index = self.qcbReconstructionType.findText(self.DICT_IDS_DEF[val])
assert index >= 0
self.qcbReconstructionType.setCurrentIndex(index)
else:
err = "Given reconsparam type (%s) is not recognize" % val
raise ValueError(err)
......
......@@ -43,6 +43,7 @@ except:
import numpy
from tomogui.third_party.dialog.ImageFileDialog import _ImagePreview, ImageFileDialog
from tomogui.gui.datasource.tomoguiFileTypeCB import TomoGUIFileTypeCB
from silx.gui.plot import Plot2D
from tomogui.gui.datasource.sinograminfo.TxSinogramInfo import TxSinogramInfo
import logging
import os
......@@ -62,6 +63,7 @@ class FluorescenceSinogramInfo(TxSinogramInfo):
Constructor
"""
TxSinogramInfo.__init__(self, sinogram=sinogram, parent=parent)
self._viewWindow = None
widget_EF_Elmt = qt.QWidget(self)
self.layout().setContentsMargins(0, 0, 0, 0)
self.layout().setSpacing(2)
......@@ -108,7 +110,7 @@ class FluorescenceSinogramInfo(TxSinogramInfo):
self._physElmtSel.setEnabled(True)
# set self abs mat
if self.sinogram.selfAbsMat and self.sinogram.selfAbsMat.fileInfo:
txt = self.sinogram.selfAbsMat.fileInfo.getUri()
txt = str(self.sinogram.selfAbsMat.fileInfo)
enable = True
else:
txt = ''
......@@ -170,35 +172,35 @@ class FluorescenceSinogramInfo(TxSinogramInfo):
self._selfAbsMatWid.setVisible(visible)
def _showSelfAbsMat(self):
self.viewWindow = qt.QMainWindow()
widget = _ImagePreview(parent=None)
self.sinogram.selfAbsMat.loadData(None)
widget.setImage(self.sinogram.selfAbsMat.data)
widget.setWindowTitle('Self abs mat view' + self.sinogram.selfAbsMat.fileInfo.getUri())
self.viewWindow.setCentralWidget(widget)
self.viewWindow.show()
plot = self.getPlot()
self.sinogram.selfAbsMat.loadData()
plot.addImage(data=self.sinogram.selfAbsMat.data)
plot.setWindowTitle('Self abs mat view' + self.sinogram.selfAbsMat.fileInfo.path())
plot.show()
def getPlot(self):
if self._viewWindow is None:
self._viewWindow = Plot2D()
return self._viewWindow
def _selectSelfAbsMat(self):
dialog = ImageFileDialog(parent=self)
dialog.setFileType(TomoGUIFileTypeCB(dialog))
dialog.setDirectory(_getDefaultFolder())
result = dialog.exec_()
if result:
s = str(dialog.selectedPath()).split('::')
index = '0'
assert len(s) <= 2
if len(s) == 2:
index = s[1]
fi = freeartconfig.retrieveInfoFile(file=s[0],
index=index)
self.sinogram.selfAbsMat = structs.SelfAbsMatrix(fileInfo=fi)
filePath = dialog.selectedFile()
index = dialog.selectedDataUrl().data_path() or '0'
self.sinogram.selfAbsMat = structs.SelfAbsMatrix(
fileInfo=freeartconfig.retrieveInfoFile(file=filePath,
index=index)
)
try:
self.sinogram.selfAbsMat.loadData()
except:
pass
self._qlSelfAbsMat.setText(str(dialog.selectedPath()))
self._qlSelfAbsMat.setText(str(dialog.selectedDataUrl()))
self._qpbViewSelfAbsMat.setEnabled(True)
def _tryGuessingElementName(self):
......
......@@ -90,22 +90,21 @@ class SampleCompDialog(qt.QDialog):
self.layout().addWidget(self.mainWindow)
self.layout().addWidget(_buttons)
def setMaterials(self, materials):
self.mainWindow.setMaterials(materials)
# expose API
self.setMaterials = self.mainWindow.setMaterials
self.saveTo = self.mainWindow.saveTo
self.getMaterials = self.mainWindow.getMaterials
def load(self):
self.mainWindow.load()
def saveTo(self, outputFile):
self.mainWindow.saveTo(outputFile)
try:
self.mainWindow.load()
except ValueError as e:
_logger.warning('Fail to materials information. Error is', str(e))
def _quit(self):
"""callback of the validate button"""
self.close()
def getMaterials(self, refFile):
return self.mainWindow.getMaterials(refFile)
class QSampleComposition(qt.QWidget, ConfigurationActor):
"""
......@@ -172,13 +171,16 @@ class QSampleComposition(qt.QWidget, ConfigurationActor):
assert (isinstance(config, freeartconfig.FluoConfig))
self.config = config
self.materials = config.materials
self.setMaterials(self.materials)
if self.config.absMat is not None and self.config.absMat.data is not None:
if self.config.isAbsMatASinogram:
self.tryToGuessBackground()
else:
self.addImage(self.config.absMat.data)
elif (self.materials is not None and self.self.materials.matComposition
and self.materials.matComposition.data is not None):
self.addImage(numpy.zeros(self.materials.matComposition.data.shape))
self.setMaterials(self.materials)
def tryToGuessBackground(self):
# try to use the silx FBP to run a background image reconstruction
......@@ -321,6 +323,7 @@ class QSampleComposition(qt.QWidget, ConfigurationActor):
materials.matComposition.data is not None:
self.materials = materials
self.maskToolWidget.loadSampleComposition(materials)
self.setEnabled(True)
def getMaterials(self, h5File):
if self.materials is None:
......@@ -332,13 +335,11 @@ class QSampleComposition(qt.QWidget, ConfigurationActor):
self.materials.materials.data = self.maskToolWidget.materials
if h5File is not None:
if fileInfo.FreeARTFileInfo._equalOrNone(self.materials.matComposition.fileInfo, None):
self.materials.matComposition.fileInfo = fileInfo.MatrixFileInfo(file_path=h5File,
data_path=structs.MatComposition.MAT_COMP_DATASET)
if fileInfo.FreeARTFileInfo._equalOrNone(self.materials.materials.fileInfo, None):
self.materials.materials.fileInfo = fileInfo.DictInfo(file_path=h5File,
data_path=structs.MaterialsDic.MATERIALS_DICT)
assert h5File.endswith(('h5', '.nx', '.nxs', '.hdf', '.hdf5'))
self.materials.matComposition.fileInfo = fileInfo.MatrixFileInfo(file_path=h5File,
data_path=structs.MatComposition.MAT_COMP_DATASET)
self.materials.materials.fileInfo = fileInfo.DictInfo(file_path=h5File,
data_path=structs.MaterialsDic.MATERIALS_DICT)
return self.materials
def addImage(self, data):
......@@ -435,7 +436,7 @@ class QSampleComposition(qt.QWidget, ConfigurationActor):
if refFile is not None:
fn, file_extension = os.path.splitext(refFile)
if file_extension.lower() not in ('.h5', '.hdf5', '.hdf'):
m = self.getMaterials(refFile)
m = self.getMaterials(h5File=None)
needFileToStoreMaterials = m.materials.fileInfo is None or m.matComposition.fileInfo is None
if needFileToStoreMaterials:
outFile = self.askForH5File()
......@@ -443,6 +444,8 @@ class QSampleComposition(qt.QWidget, ConfigurationActor):
_logger.warning('No file specify for materials and sample '
'composition, won\'t be store')
if outFile and outFile.endswith(('.h5', '.nx', '.nxs', '.hdf', '.hdf5'))is False:
outFile = None
config.materials = self.getMaterials(outFile)
config.materials.save()
......@@ -488,9 +491,9 @@ class SampleCompositionTab(qt.QWidget, ConfigurationActor):
# expose API
self.setMaterials = self.mainWindow.setMaterials
self.tryToGuessBackground = self.mainWindow.tryToGuessBackground
def getShortToolTip(self):
return self.mainWindow.getShortToolTip()
self.getShortToolTip = self.mainWindow.getShortToolTip
self.saveConfiguration = self.mainWindow.saveConfiguration
self.clean = self.mainWindow.clean
def loadConfiguration(self, config):
if not isinstance(config, freeartconfig.FluoConfig):
......@@ -499,12 +502,6 @@ class SampleCompositionTab(qt.QWidget, ConfigurationActor):
return
self.mainWindow.loadConfiguration(config)
def saveConfiguration(self, config, refFile):
self.mainWindow.saveConfiguration(config, refFile)
def clean(self):
self.mainWindow.clean()
class MaterialMaskToolWidget(MaskToolsWidget.MaskToolsWidget):
"""
......@@ -618,6 +615,9 @@ class MaterialMaskToolWidget(MaskToolsWidget.MaskToolsWidget):
eq = numpy.isin(materials.matComposition.data, (bytes(materialName.encode('utf-8')),))
mask[eq] = self.nextFreeMaskId - 1
if self.plot.getActiveImage() is None or self.plot.getActiveImage().getData(copy=False).size == 0:
self.plot.addImage(data=numpy.zeros(shape=materials.matComposition.data.shape))
# self.setEnabled(True)
self._mask.reset(shape=mask.shape)
self.setSelectionMask(mask, copy=False)
self.plot.resetZoom()
......
......@@ -34,6 +34,11 @@ import tomogui.utils as utils
import tempfile
import sys
import logging
import os
try:
from freeart.configuration import fileInfo
except ImportError:
from tomogui.third_party.configuration import fileInfo
_logger = logging.getLogger("QFreeARTReconstructionManager")
......@@ -85,6 +90,7 @@ def runReconstruction(config, platformId=None, deviceId=None):
configTx.minAngle = configFluo.minAngle
configTx.maxAngle = configFluo.maxAngle
configTx.center = configFluo.center
print('center is %s' % configTx.center)
configTx.includeLastProjection = configFluo.includeLastProjection
configTx.useAFileForI0 = configFluo.useAFileForI0
configTx.I0 = configFluo.I0
......@@ -142,7 +148,10 @@ def runReconstruction(config, platformId=None, deviceId=None):
reconsAlgos = dialog.mainWindow.freeartInterpreter.getReconstructionAlgorithms()
assert(len(reconsAlgos) is 1)
reconsPh = reconsAlgos[list(reconsAlgos.keys())[0]].getPhantom()
config.absMat.fileInfo = None
outputfile = os.path.join(tempfile.gettempdir(),
'absMatrix.edf')
config.absMat.fileInfo = fileInfo.file_path=outputfile
_logger.info('Save absMatrix into %s' % outputfile)
config.absMat.data = reconsPh
assert(reconsPh is not None)
config.isAbsMatASinogram = False
......
......@@ -50,6 +50,7 @@ import os
import time
import logging
import weakref
import tempfile
_logger = logging.getLogger(__name__)
......@@ -167,12 +168,10 @@ class FreeartReconsManager(ReconsManagerBase):
if not diag.exec_():
return False
else:
refFile = tomogui.core._active_file if tomogui.core._merge is True else None
if refFile:
materialFile = os.path.join(os.path.dirname(refFile), 'tomogui_materials.h5')
config.materials = diag.getMaterials(materialFile)
logger.info('save materials to %s' % materialFile)
config.materials.save()
materialFile = os.path.join(tempfile.gettempdir(), 'freeartmaterialsFile.h5')
config.materials = diag.getMaterials(materialFile)
_logger.warning('save materials to %s' % materialFile)
config.materials.save()
# save(configuration=config, filePath=refFile, overwrite=True,
# merge=False)
......@@ -339,7 +338,10 @@ class FreeartReconsManager(ReconsManagerBase):
"""
callback function when the damping factor changed
"""
newVal = float(newVal)
try:
newVal = float(newVal)
except ValueError:
return
assert(type(newVal) == float)
if self.freeartInterpreter and (newVal > 0 and newVal <= 1.0):
self.freeartInterpreter.setDampingFactor(newVal)
......
......@@ -140,6 +140,8 @@ class QFileSelection(qt.QWidget):
"""
if url is None:
return
if type(url) is str and url == '':
return
_url = url
if isinstance(_url, DataUrl) is False:
_url = DataUrl(path=_url)
......@@ -340,8 +342,8 @@ class QProjectFileDialog(qt.QFileDialog):
self.setWindowTitle("Save project")
self.setModal(1)
self.setOption(qt.QFileDialog.DontUseNativeDialog, True)
# self.setOption(qt.QFileDialog.DontUseNativeDialog, True)
self.setLayout(qt.QGridLayout())
_nameFilters = nameFilters
if _nameFilters is None:
_nameFilters = [CFG_FILTER, H5_FILTER]
......
......@@ -45,6 +45,11 @@ try:
freeart_missing = False
except ImportError:
freeart_missing = True
try:
from silx.opencl.backprojection import Backprojection
has_silx_FBP = True
except ImportError:
has_silx_FBP = False
@unittest.skipIf(freeart_missing, "freeart missing")
......@@ -263,6 +268,7 @@ class FluoProject(ScenarioProject):
))
@unittest.skipIf(has_silx_FBP is False, "silx FBP missing")
class FBPProject(ScenarioProject):
"""Test that the usage of the project window for Tx is correct"""
......