Source code for freeart.configuration.config

# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2016 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.
#
# ###########################################################################*/
"""
Contains the python representation of the reconstruction parameters
"""

__authors__ = ["H. Payno"]
__license__ = "MIT"
__date__ = "18/10/2017"


from freeart.unitsystem import metricsystem
from silx.io import configdict
import numpy
import time
try:
    from freeart import version
except:
    version = ''
from . import structs, fileInfo
import os


class _ReconsConfig(object):

    TX_ID = "Transmission"
    COMPTON_ID = "Compton"
    FLUO_ID = "Fluorescence"

    RECONS_TYPES = [TX_ID, COMPTON_ID, FLUO_ID]

    PRECISION_TO_TYPE = {
        'simple': numpy.float32,
        'double': numpy.float64
    }

    reconsParams = None
    """
    The reconstruction parameters (oversampling...) to launch once configured
    """

    def __init__(self, reconsType=None, minAngle=None, maxAngle=None,
                 projections=None, defReduction=1, projNumReduction=1,
                 oversampling=1, solidAngleOff=False,
                 includeLastProjection=True, I0=None, beamCalcMethod=0,
                 centerOfRotation=-1, acquiInverted=False, precision='double'):
        """

        :param reconsType:
        :param centerOfRotation: if -1 then will take the middle
        :param precision: calcul precision, can be simple or double.
        """
        if reconsType not in _ReconsConfig.RECONS_TYPES:
            raise ValueError('reconsType not recognized')
        if minAngle is not None and not (0 <= minAngle <= 2.*numpy.pi):
            raise ValueError('min angle not in [0, 2pi]')
        if minAngle is not None and not (0 <= maxAngle <= 2.*numpy.pi):
            raise ValueError('max angle not in [0, 2pi]')
        if (minAngle is not None or maxAngle is not None) and not minAngle <= maxAngle:
            raise ValueError('False condition: minAngle <= maxAngle')

        self.precision = precision
        assert self.precision in self.PRECISION_TO_TYPE
        self.reconsType = reconsType
        self.center = centerOfRotation
        self.projections = projections
        """The projections to be consider for the reconstruction"""
        self.definitionReduction = defReduction
        """
        Should we take a pixel each definition_reduction for the reconstruction
        """
        self.projectionNumberReduction = projNumReduction
        """
        Should we take one projection each projection_number_reduction for the
         reconstruction.
        """
        self.voxelSize = metricsystem.cm
        """voxel size"""
        self.oversampling = oversampling
        """Oversampling value"""
        self.solidAngleOff = solidAngleOff
        """Should we always set the the value of the solid angle to 1"""
        self.minAngle = minAngle
        self.maxAngle = maxAngle
        self.includeLastProjection = includeLastProjection
        self.setI0(I0)
        self.beamCalcMethod = beamCalcMethod
        self.acquiInverted = acquiInverted

    def setI0(self, I0, i0_index=None):
        if type(I0) is str or (hasattr(I0, 'dtype') and numpy.issubdtype(I0.dtype,
                                                                   numpy.character)):
            self._I0 = structs.I0Sinogram()
            fn, file_extension = os.path.splitext(str(I0).split('::')[0])
            if file_extension.lower() == '.edf':
                self._I0.fileInfo = fileInfo.EDFMatrixFileInfo(filePath=str(I0),
                                                               index=int(i0_index or 0))
            else:
                self._I0.fileInfo = fileInfo.H5MatrixFileInfo(
                    filePath=str(I0) + '::'+ str(i0_index or ''))
            self.useAFileForI0 = True
        elif isinstance(I0, structs.I0Sinogram):
            self._I0 = I0
            self.useAFileForI0 = True
        else:
            self._I0 = 1.0 if I0 is None else I0
            self.useAFileForI0 = False

    def getI0(self):
        return self._I0

    I0 = property(getI0, setI0)

    def toDict(self):
        """Convert the configuration to a silx ConfigDict"""
        dic = configdict.ConfigDict()
        dic['general_settings'] = self._getGeneralSettings()
        dic['normalization'] = self._getNormalization()
        dic['reconstruction_properties'] = self._getReconsProp()
        dic['reduction_data'] = self._getReductionDataInfo()
        dic['projection_information'] = self._getProjInfo()
        return dic

    def _getGeneralSettings(self):
        return {
            'reconstruction_type': self.reconsType,
            'date ': str(time.strftime("%d/%m/%Y")),
            'freeart_version': version,
            'precision': self.precision
        }

    def _getNormalization(self):
        if isinstance(self.I0, structs.DataStored):
            if self.I0.fileInfo is None:
                i0_out = ''
                i0_index = ''
            else:
                i0_out = self.I0.fileInfo.filePath
                i0_index = self.I0.fileInfo.location
        else:
            i0_out = self.I0
            i0_index = ''
        return {
            'rotation_center': self.center,
            'normalizationi0fromafile': self.useAFileForI0,
            'i0': i0_out,
            'i0_index': i0_index
        }

    def _getReconsProp(self):
        return {
            'voxel_size': self.voxelSize,
            'oversampling': self.oversampling,
            'bean_calculation_method': self.beamCalcMethod,
            'solid_angle_is_off': self.solidAngleOff,
            'include_last_angle': self.includeLastProjection
        }

    def _getReductionDataInfo(self):
        return {
            'definition_reducted_by': self.definitionReduction,
            'projection_number_reducted_by': self.projectionNumberReduction,
        }

    def _getProjInfo(self):
        return {
            'min_angle': self.minAngle,
            'max_angle': self.maxAngle,
            'projections_sel': self.projections or ':',
            'acqui_inv': self.acquiInverted
        }

    def _fromDict(self, dict):
        """set the configuration fron a silx ConfigDict"""
        self._setGenSettingFrmDict(dict)
        self._setNormalizationFrmDict(dict)
        self._setReconsPropFrmDict(dict)
        self._setReducDataFrmDict(dict)
        self._setProjInfoFrmDict(dict)
        return self

    def _setGenSettingFrmDict(self, dict):
        assert('general_settings' in dict)
        assert('reconstruction_type' in dict['general_settings'])
        self.reconsType = dict['general_settings']['reconstruction_type']
        if type(self.reconsType) is not str:
            self.reconsType = str(self.reconsType.tostring().decode())
        assert('precision' in dict['general_settings'])
        self.precision = dict['general_settings']['precision']
        if type(self.precision) is not str:
            self.precision = str(self.precision.tostring().decode())

    def _setNormalizationFrmDict(self, dict):
        assert('normalization' in dict)
        info = dict['normalization']
        assert('rotation_center' in info)
        assert('i0' in info)
        self.center = info['rotation_center']
        i0 = info['i0']
        if hasattr(i0, 'dtype') and not numpy.issubdtype(i0.dtype, numpy.number):
            i0 = str(i0.tostring().decode())
        i0_index = info['i0_index'] if 'i0_index' in info else None
        if hasattr(i0_index, 'dtype') and not numpy.issubdtype(i0_index.dtype, numpy.number):
            i0_index = str(i0_index.tostring().decode())

        self.setI0(i0, i0_index)

    def _setReconsPropFrmDict(self, dict):
        assert('reconstruction_properties' in dict)
        info = dict['reconstruction_properties']
        assert('voxel_size' in info)
        assert('oversampling' in info)
        assert('bean_calculation_method' in info)
        assert('solid_angle_is_off' in info)
        assert('include_last_angle' in info)
        self.voxelSize = float(info['voxel_size'])
        self.oversampling = int(info['oversampling'])
        self.beamCalcMethod = int(info['bean_calculation_method'])
        self.solidAngleOff = bool(info['solid_angle_is_off'])
        self.includeLastProjection = bool(info['include_last_angle'])

    def _setReducDataFrmDict(self, dict):
        assert('reduction_data' in dict)
        info = dict['reduction_data']
        assert('definition_reducted_by' in info)
        assert('projection_number_reducted_by' in info)
        self.definitionReduction = info['definition_reducted_by']
        self.projectionNumberReduction = info['projection_number_reducted_by']

    def _setProjInfoFrmDict(self, dict):
        assert('projection_information' in dict)
        info = dict['projection_information']
        assert('min_angle' in info)
        assert('max_angle' in info)
        assert('projections_sel' in info)
        assert('acqui_inv' in info)
        self.minAngle = info['min_angle']
        self.maxAngle = info['max_angle']
        self.projections = info['projections_sel']
        if not type(self.projections) is str:
            self.projections = str(self.projections.tostring().decode())
        self.acquiInverted = bool(info['acqui_inv'])

    def __eq__(self, other):
        projectionsAreEqual = self.projections == other.projections or \
            self.projections is None and other.projections == ':' or \
            self.projections == ':' and other.projections is None

        return self.reconsType == other.reconsType and \
               self.maxAngle == other.maxAngle and \
               self.minAngle == other.minAngle and \
               self.I0 == other.I0 and \
               self.center == other.center and \
               self.includeLastProjection == other.includeLastProjection and \
               self.useAFileForI0 == other.useAFileForI0 and \
               self.solidAngleOff == other.solidAngleOff and \
               self.beamCalcMethod == other.beamCalcMethod and \
               self.voxelSize == other.voxelSize and \
               self.definitionReduction == other.definitionReduction and \
               projectionsAreEqual and \
               self.projectionNumberReduction == other.projectionNumberReduction and \
               self.acquiInverted == other.acquiInverted and \
               self.precision == other.precision


    def __str__(self):
        res = 'reconsType is %s \n' % self.reconsType
        res = res + 'oversampling is %s \n' % self.oversampling
        res = res + 'minAngle is %s \n' % self.minAngle
        res = res + 'maxAngle is %s \n' % self.maxAngle
        res = res + 'I0 is %s \n' % self.I0
        res = res + 'center is %s \n' % self.center
        res = res + 'includeLastProjection is %s \n' % self.includeLastProjection
        res = res + 'useAFileForI0 is %s \n' % self.useAFileForI0
        res = res + 'solidAngleOff is %s \n' % self.solidAngleOff
        res = res + 'beamCalcMethod is %s \n' % self.beamCalcMethod
        res = res + 'voxelSize is %s \n' % self.voxelSize
        res = res + 'definitionReduction is %s \n' % self.definitionReduction
        res = res + 'projections is %s \n' % self.projections
        res = res + 'acquiInverted is %s \n' % self.acquiInverted
        res = res + 'projectionNumberReduction is %s \n' % self.projectionNumberReduction
        return res

    def setFileInfoToH5File(self, refFile, save=False):
        """
        Change all the fileInfo to point ot the given h5 file

        :param refFile: the h5 file to store information
        :param save: if true once the file info updated, save the dataset
        """
        assert fileInfo
        fn, file_extension = os.path.splitext(refFile)
        assert file_extension in ('.hdf5', '.hdf', '.h5')
        if self.I0 is not None and self.useAFileForI0 is True:
            self.I0.fileInfo = fileInfo.H5MatrixFileInfo(refFile + structs.I0Sinogram.I0_DATASET)
            if save is True:
                self.I0.save()


class _ItReconsConfig(_ReconsConfig):
    """Define parameters needed for an iterative reconstruction

    :param dampingFactor: if the dampingFactor is None then will be deduced
                          automatically
    """
    def __init__(self, dampingFactor=None, *var, **kw):
        _ReconsConfig.__init__(self, *var, **kw)
        self.dampingFactor = dampingFactor

    def _getReconsProp(self):
        dict = _ReconsConfig._getReconsProp(self)
        dict['relaxation_factor'] = self.dampingFactor
        return dict

    def _setReconsPropFrmDict(self, dict):
        _ReconsConfig._setReconsPropFrmDict(self, dict)
        assert('relaxation_factor' in dict['reconstruction_properties'])
        self.dampingFactor = dict['reconstruction_properties']['relaxation_factor']

    def __eq__(self, other):
        return _ReconsConfig.__eq__(self, other) and self.dampingFactor == other.dampingFactor


class _SimpleSinoConfig(_ItReconsConfig):
    def __init__(self, reconsType, sinograms=None, computeLog=True, *var, **kw):
        _ItReconsConfig.__init__(self, *var, reconsType=reconsType, **kw)
        self.sinograms = []
        """list of sinograms to be reconstructed"""
        if sinograms:
            for sinogram in sinograms:
                assert isinstance(sinogram, self._defaultSinoType())
                self.addSinogram(sinogram)

    def addSinogram(self, sinogram):
        if sinogram is None:
            return
        elif isinstance(sinogram, self._defaultSinoType()):
            _sinogram = sinogram
        # case of h5 file
        elif type(sinogram) is str or (hasattr(sinogram, 'dtype') and
                                           numpy.issubdtype(sinogram.dtype, numpy.character)):
            _sinogram = self._defaultSinoType()()
            # Raw check for hdf5 file
            if '::' in str(sinogram):
                _sinogram.fileInfo = fileInfo.H5MatrixFileInfo(
                    filePath=str(sinogram))
            else:
                _sinogram.fileInfo = fileInfo.EDFMatrixFileInfo(
                    filePath=str(sinogram))
        else:
            _sinogram = self._defaultSinoType()()
            _sinogram.data = sinogram

        assert isinstance(_sinogram, self._defaultSinoType())
        self.sinograms.append(_sinogram)

    def _defaultSinoType(self):
        return structs.Sinogram

    def setFileInfoToH5File(self, refFile, save=False):
        """
        Change all the fileInfo to point ot the given h5 file

        :param refFile: the h5 file to store information
        :param save: if true once the file info updated, save the dataset
        """
        _ItReconsConfig.setFileInfoToH5File(self, refFile, save)
        for _sinogram in self.sinograms:
            _sinogram.fileInfo = fileInfo.H5MatrixFileInfo(refFile + _sinogram.h5defaultPath)
            if save is True:
                _sinogram.save()

    def toDict(self):
        dic = _ItReconsConfig.toDict(self)
        dic[self._getDataSourceHeader()] = self._getDataSourceInfo()
        self._sinogramsToDict(dic)
        return dic

    def _sinogramsToDict(self, dic):
        sinogramsDict = self.getSinogramsFileDict()
        iSinoFile = 0
        for iSinoFile, sinoFile in enumerate(sinogramsDict):
            index = 0
            section = 'sino_file_' + str(iSinoFile)
            dic[section] = {}
            dic[section]['file_path'] = sinoFile
            for sinogram in sinogramsDict[sinoFile]:
                assert isinstance(sinogram, self._defaultSinoType())
                fi = ''
                fp = ''
                if sinogram.fileInfo is not None:
                    fp = sinogram.fileInfo.filePath
                    fi = sinogram.fileInfo.location
                    dic[section]['sino_file_' + str(index)] = fp
                    dic[section]['sino_file_index_' + str(index)] = fi
                    dataNameID = 'data_name_' + str(index)
                    dic[section][dataNameID] = sinogram.name
                    index += 1
        return dic

    def _getDataSourceHeader(self):
        return 'data_source_tx'

    def _getDataSourceInfo(self):
        return {}

    def _fromDict(self, dict):
        _ItReconsConfig._fromDict(self, dict)
        self._sinogramsFromDict(dict)
        return self

    def _sinogramsFromDict(self, dict):
        iFile = 0
        section = 'sino_file_' + str(iFile)
        while section in dict:
            info = dict[section]
            filePath = info['file_path']
            if hasattr(filePath, 'tostring'):
                filePath = str(info['file_path'].tostring().decode())

            index = 0
            info = dict[section]
            while ('sino_file_' + str(index) in info):
                file = info['sino_file_' + str(index)]
                location = info['sino_file_index_' + str(index)]

                if not type(file) is str:
                    file = str(file.tostring().decode())

                if hasattr(location, 'dtype') and \
                        not numpy.issubdtype(location.dtype, numpy.number):
                    location = str(location.tostring().decode())
                fi = retrieveInfoFile(file=file, index=location)

                dataNameID = 'data_name_' + str(index)
                name = info[dataNameID]
                if hasattr(name, 'astype'):
                    name = str(name.astype('U13'))

                self.addSinogram(sinogram=structs.TxSinogram(fileInfo=fi,
                                                             name=name))
                index += 1
            iFile += 1
            section = 'sino_file_' + str(iFile)

    def __eq__(self, other):
        return _ItReconsConfig.__eq__(self, other) and \
               self.getSinogramsFileDict() == other.getSinogramsFileDict()

    def checkSinoType(self, sino):
        assert(isinstance(sino, structs.Sinogram))

    def getSinogramsFileDict(self):
        """
        return the sinograms as a dictionnary with key the file containing the
        sinograms and values the list of sinograms in this file

        :return: dict
        """
        dd = {}
        for sinogram in self.sinograms:
            assert isinstance(sinogram, structs.Sinogram)
            filePath = 'unknow'
            if sinogram.fileInfo and sinogram.fileInfo.getFile():
                filePath = sinogram.fileInfo.getFile()
            if filePath not in dd:
                dd[filePath] = []
            dd[filePath].append(sinogram)
        import collections
        sortedDict = collections.OrderedDict(sorted(dd.items()))
        return sortedDict

    def fillSinogramNames(self):
        # if no name define, define one for each sinogram
        if self.sinograms is not None:
            index = 0
            for sinogram in self.sinograms:
                if sinogram.name is None:
                    sinogram.name = 'sinogram_' + str(index)
                    index += 1


[docs]class TxConfig(_SimpleSinoConfig): """ .. note:: Need to get a differentiation between TxConfig and this class because tomogui has also to deal with the FBP... and won't have the log option and maybe others """ def __init__(self, sinograms=None, computeLog=True, *var, **kw): _SimpleSinoConfig.__init__(self, reconsType=self.TX_ID, sinograms=sinograms, *var, **kw) self.computeLog = computeLog def _setNormalizationFrmDict(self, dict): _SimpleSinoConfig._setNormalizationFrmDict(self, dict) assert('normalization' in dict) info = dict['normalization'] assert('computeminuslog' in info) self.computeLog = info['computeminuslog'] def _getNormalization(self): dic = _SimpleSinoConfig._getNormalization(self) dic['computeminuslog'] = self.computeLog return dic def __eq__(self, other): return _SimpleSinoConfig.__eq__(self, other) and \ self.computeLog == other.computeLog
[docs]class FluoConfig(_SimpleSinoConfig): """ configuration to build fluorescence or compton reconstruction algorithm """ def __init__(self, outBeamCalMethod=0, sinoI0=None, absMat=None, isAbsMatASinogram=False, detector=None, materials=None, sinograms=None, e0=1, *var, **kw): _SimpleSinoConfig.__init__(self, reconsType=self.FLUO_ID, *var, **kw) assert(absMat is None or isinstance(absMat, structs.AbsMatrix)) self.absMat = absMat if self.absMat is None: self.absMat = structs.AbsMatrix() self.sinoI0 = sinoI0 self.isAbsMatASinogram = isAbsMatASinogram assert(materials is None or isinstance(materials, structs.Materials)) self.materials = materials if self.materials is None: self.materials = structs.Materials() self.detector = detector self.outBeamCalMethod = outBeamCalMethod self.E0 = e0 def _defaultSinoType(self): return structs.FluoSino def _getDataSourceHeader(self): return 'data_source_fluo'
[docs] def toDict(self): dic = _SimpleSinoConfig.toDict(self) dic['detector_setup'] = self._getDetector() return dic
def _sinogramsToDict(self, dic): # deal with all fluorescence sinogram sinogramsDict = self.getSinogramsFileDict() for iSinoFile, sinoFile in enumerate(sinogramsDict): section = 'fluo_sino_file_' + str(iSinoFile) dic[section] = {} dic[section]['file_path'] = sinoFile indexSino = 0 for sino in sinogramsDict[sinoFile]: indexID = 'data_set_index_' + str(indexSino) loc = '' if sino.fileInfo: loc = sino.fileInfo.location dic[section][indexID] = loc dataNameID = 'data_name_' + str(indexSino) dic[section][dataNameID] = sino.name dataPhysElmtID = 'data_physical_element_' + str(indexSino) dic[section][dataPhysElmtID] = sino.physElmt EFID = 'ef_' + str(indexSino) dic[section][EFID] = sino.EF selfAbsMatID = 'self_absorption_file_' + str(indexSino) selfAbsMatIndexID = 'self_absorption_index_file_' + str(indexSino) if sino.selfAbsMat is None: dic[section][selfAbsMatID] = '' else: assert(isinstance(sino.selfAbsMat, structs.AbsMatrix)) assert(sino.selfAbsMat.fileInfo is not None) dic[section][selfAbsMatID] = sino.selfAbsMat.fileInfo.getFile() dic[section][selfAbsMatIndexID] = sino.selfAbsMat.fileInfo.location indexSino += 1 return dic def _fromDict(self, dict): _SimpleSinoConfig._fromDict(self, dict) assert('detector_setup' in dict) info = dict['detector_setup'] assert('det_width' in info) assert('det_pos_x' in info) assert('det_pos_y' in info) assert('det_pos_z' in info) self.detector = structs.Detector(x=info['det_pos_x'], y=info['det_pos_y'], z=info['det_pos_z'], width=info['det_width']) # deal with data_source_fluo assert('data_source_fluo' in dict) info = dict['data_source_fluo'] self.isAbsMatASinogram = bool(info['absorption_file_is_a_sinogram']) absMat = info['absorption_file'] if not type(absMat) is str: absMat = str(absMat.tostring().decode()) absMat_index = info['absorption_file_index'] if hasattr(absMat_index, 'dtype') and not numpy.issubdtype(absMat_index.dtype, numpy.number): absMat_index = str(absMat_index.tostring().decode()) info_file_abs_mat = retrieveInfoFile(file=absMat, index=absMat_index) self.absMat = structs.AbsMatrix(fileInfo=info_file_abs_mat) materialCompoFile = info['samp_composition_file'] if not type(materialCompoFile) is str: materialCompoFile = str(info['samp_composition_file'].tostring().decode()) materialCompoIndex = info['samp_composition_file_index'] if hasattr(materialCompoIndex, 'dtype') and not numpy.issubdtype(materialCompoIndex.dtype, numpy.number): materialCompoIndex = str(materialCompoIndex.tostring().decode()) info_file_comp = retrieveInfoFile(file=materialCompoFile, index=materialCompoIndex) materialsFile = info['materials_file'] if not type(materialsFile) is str: materialsFile = str(info['materials_file'].tostring().decode()) materialsIndex = info['materials_file_index'] if hasattr(materialsIndex, 'dtype') and not numpy.issubdtype(materialsIndex.dtype, numpy.number): materialsIndex = str(materialsIndex.tostring().decode()) info_file_mat_dic = retrieveInfoFile(file=materialsFile, index=materialsIndex) self.materials = structs.Materials( materials=structs.MaterialsDic(fileInfo=info_file_mat_dic), matComposition=structs.MatComposition(fileInfo=info_file_comp)) return self def _sinogramsFromDict(self, dict): # deal with all fluorescence sinogram iFile = 0 section = 'fluo_sino_file_' + str(iFile) while section in dict: info = dict[section] filePath = info['file_path'] if hasattr(filePath, 'tostring'): filePath = str(info['file_path'].tostring().decode()) indexSino = 0 indexID = 'data_set_index_' + str(indexSino) sinogramsToAdd = [] while indexID in info: dataNameID = 'data_name_' + str(indexSino) dataPhysElmtID = 'data_physical_element_' + str(indexSino) EFID = 'ef_' + str(indexSino) selfAbsMatID = 'self_absorption_file_' + str(indexSino) selfAbsMatIndexID = 'self_absorption_index_file_' + str(indexSino) index = info[indexID] if hasattr(index, 'dtype') and not numpy.issubdtype( index.dtype, numpy.number): index = str(index.tostring().decode()) # deal with sinogram file_info = retrieveInfoFile(filePath, index) selfAbsMat = structs.SelfAbsMatrix(fileInfo=file_info) # deal with selfAbsMat selfAbsMatFile = info[selfAbsMatID] if selfAbsMatID in info else None if hasattr(selfAbsMatFile, 'tostring'): selfAbsMatFile = str(selfAbsMatFile.tostring().decode()) selfAbsMatIndex = info[selfAbsMatIndexID] if selfAbsMatIndexID in info else None if hasattr(selfAbsMatIndex, 'dtype') and not numpy.issubdtype( selfAbsMatIndex.dtype, numpy.number): selfAbsMatIndex = str(selfAbsMatIndex.tostring().decode()) selfAbsMatFileInfo = None if selfAbsMatFile is None or selfAbsMatFile == '' or ord(selfAbsMatFile[0]) == 0: selfAbsMat = None else: selfAbsMat = structs.SelfAbsMatrix( fileInfo=retrieveInfoFile(file=selfAbsMatFile, index=selfAbsMatIndex)) name = info[dataNameID] if hasattr(name, 'astype'): name = str(name.astype('U13')) physElmt = info[dataPhysElmtID] if hasattr(physElmt, 'astype'): physElmt = str(physElmt.astype('U13')) # create the fluorescence sinogram self.addSinogram(structs.FluoSino(name=name, fileInfo=file_info, physElmt=physElmt, ef=info[EFID], selfAbsMat=selfAbsMat)) indexSino += 1 indexID = 'data_set_index_' + str(indexSino) iFile += 1 section = 'fluo_sino_file_' + str(iFile) def _getDataSourceInfo(self): assert(type(self.isAbsMatASinogram) is bool) compoFile = compoFileIndex = matFile = matFileIndex = None if self.materials is not None: if self.materials.matComposition is not None: if self.materials.matComposition.fileInfo is not None: compoFile = self.materials.matComposition.fileInfo.getFile() assert (isinstance(self.materials.matComposition, structs.MatComposition)) if isinstance(self.materials.matComposition.fileInfo, fileInfo.EDFMatrixFileInfo): compoFileIndex = self.materials.matComposition.fileInfo.getIndex() elif isinstance(self.materials.matComposition.fileInfo, fileInfo.H5MatrixFileInfo): compoFileIndex = self.materials.matComposition.fileInfo.getH5Location() elif self.materials.matComposition.data is not None: compoFile = '' compoFileIndex = self.materials.matComposition.h5defaultPath if self.materials.materials is not None: if self.materials.materials.fileInfo is not None: assert(isinstance(self.materials.materials, structs.MaterialsDic)) assert(isinstance(self.materials.materials.fileInfo, fileInfo.MatrixFileInfo)) matFile = self.materials.materials.fileInfo.getFile() if isinstance(self.materials.materials.fileInfo, fileInfo.EDFMatrixFileInfo): matFileIndex = self.materials.materials.fileInfo.getIndex() elif isinstance(self.materials.materials.fileInfo, fileInfo.H5MatrixFileInfo): matFileIndex = self.materials.materials.fileInfo.getH5Location() elif self.materials.materials.data is not None: matFile = '' matFileIndex = self.materials.materials.h5defaultPath absMatIndex = '' absMatFile = '' if self.absMat is not None and self.absMat.fileInfo is not None and \ self.absMat.fileInfo.filePath is not None: absMatFile = self.absMat.fileInfo.getFile() if isinstance(self.absMat.fileInfo, fileInfo.EDFMatrixFileInfo): absMatIndex = self.absMat.fileInfo.getIndex() elif isinstance(self.absMat.fileInfo, fileInfo.H5MatrixFileInfo): absMatIndex = self.absMat.fileInfo.getH5Location() return { 'absorption_file_is_a_sinogram': self.isAbsMatASinogram, 'absorption_file': absMatFile, 'absorption_file_index': absMatIndex, 'samp_composition_file': compoFile or '', 'samp_composition_file_index': compoFileIndex or '', 'materials_file': matFile or '', 'materials_file_index': matFileIndex or '' } def _getReconsProp(self): dic = _ItReconsConfig._getReconsProp(self) dic['outgoing_bean_calculation_method'] = self.outBeamCalMethod or 0 dic['e0'] = self.E0 return dic def _setReconsPropFrmDict(self, dict): _ItReconsConfig._setReconsPropFrmDict(self, dict) assert('outgoing_bean_calculation_method' in dict['reconstruction_properties']) self.outBeamCalMethod = dict['reconstruction_properties']['outgoing_bean_calculation_method'] assert('e0' in dict['reconstruction_properties']) self.E0 = dict['reconstruction_properties']['e0'] def _getDetector(self): if self.detector is None: return structs.Detector(x=None, y=None, z=None, width=None).toDict() else: return self.detector.toDict()
[docs] def setFileInfoToH5File(self, refFile, save=False): """ Change all the fileInfo to point ot the given h5 file :param refFile: the h5 file to store information :param save: if true once the file info updated, save the dataset """ def dealWithSinograms(): if self.sinograms: sinograms = [] for sino in self.sinograms: sino.fileInfo = fileInfo.H5MatrixFileInfo( refFile + sino.h5defaultPath) if save is True: sino.save() if sino.selfAbsMat: sino.selfAbsMat.fileInfo = fileInfo.H5MatrixFileInfo( refFile + sino.selfAbsMat.h5defaultPath) if save is True: sino.selfAbsMat.save() sinograms.append(sino) self.sinograms = sinograms def dealWithMaterials(): if self.materials: if self.materials.materials: self.materials.materials.fileInfo = fileInfo.H5MatrixFileInfo( refFile + self.materials.materials.h5defaultPath) if save is True: self.materials.materials.save() if self.materials.matComposition: self.materials.matComposition.fileInfo = fileInfo.H5MatrixFileInfo( refFile + self.materials.matComposition.h5defaultPath) if save is True: self.materials.matComposition.save() def dealWithAbsMat(): if self.absMat: self.absMat.fileInfo = fileInfo.H5MatrixFileInfo( refFile + self.absMat.h5defaultPath) if save is True: self.absMat.save() _ItReconsConfig.setFileInfoToH5File(self, refFile, save) dealWithSinograms() dealWithMaterials() dealWithAbsMat()
def __eq__(self, other): return _SimpleSinoConfig.__eq__(self, other) and \ self.materials == other.materials and \ self.detector == other.detector and \ self.absMat == other.absMat and \ self.sinoI0 == other.sinoI0 and \ self.isAbsMatASinogram == other.isAbsMatASinogram def __str__(self): l = _ItReconsConfig.__str__(self) l += 'outgoing beam calculation meth = %s\n' % self.outBeamCalMethod l += str(self.materials) return l def checkSinoType(self, sino): assert(isinstance(sino, structs.FluoSino))
[docs]def retrieveInfoFile(file, index): """Simple function to get the adapted infoFile from a file and an index :param file: the file storing the data :param index: int or str location of the data in the file """ assert type(file) is str if file == '' or file is None or ord(file[0]) == 0: return None assert(type(file) is str) info_file = None if file.lower().endswith('.h5') or file.lower().endswith('.hdf5'): fp = str(file) + '::' + str(index) info_file = fileInfo.H5MatrixFileInfo(filePath=fp) elif file.lower().endswith('.npy') or file.lower().endswith('.dict') or file.lower().endswith('.ini'): info_file = fileInfo.MatrixFileInfo(filePath=file) elif file.lower().endswith('.edf'): if index == '' or index is None: _index = 0 else: _index = int(index) info_file = fileInfo.EDFMatrixFileInfo( filePath=str(file), index=int(_index)) else: raise ValueError('extension not managed (%s)' % os.path.basename(file)) return info_file