Ejemplo n.º 1
0
    def __init__(self, filename):
        """Initialize class

        Parameters
        ----------
        filename : string
            Path to the spec file
        """
        self.filename = filename
        self.source = SpecFileDataSource.SpecFileDataSource(filename)
Ejemplo n.º 2
0
    def loadFileList(self, filelist, fileindex=0, shape=None):
        if type(filelist) == type(''):
            filelist = [filelist]
        self.__keyList = []
        self.sourceName = filelist
        self.__indexedStack = True
        self.sourceType = SOURCE_TYPE
        self.info = {}
        self.nbFiles = len(filelist)

        # read first file
        # get information
        tempInstance = SpecFileDataSource.SpecFileDataSource(filelist[0])
        keylist = tempInstance.getSourceInfo()['KeyList']
        nscans = len(keylist)  # that is the number of scans
        nmca = 0
        numberofdetectors = 0
        for key in keylist:
            info = tempInstance.getKeyInfo(key)
            numberofmca = info['NbMca']
            if numberofmca > 0:
                numberofdetectors = info['NbMcaDet']
            scantype = info["ScanType"]
            if numberofmca:
                nmca += numberofmca
        if numberofdetectors == 0:
            raise ValueError("No MCA found in file %s" % filelist[0])

        if (nscans > 1) and ((nmca // numberofdetectors) == nscans):
            SLOW_METHOD = True
        else:
            SLOW_METHOD = False
        # get last mca of first point
        key = "%s.1.%s" % (keylist[-1], numberofmca)
        dataObject = tempInstance._getMcaData(key)
        self.info.update(dataObject.info)
        arrRet = dataObject.data
        self.onBegin(self.nbFiles * nmca // numberofdetectors)

        self.incrProgressBar = 0
        if info['NbMcaDet'] > 1:
            # Should I generate a map for each mca and not just for the last one as I am doing?
            iterlist = range(info['NbMcaDet'], info['NbMca'] + 1,
                             info['NbMcaDet'])
        else:
            iterlist = [1]
        if SLOW_METHOD and shape is None:
            self.data = numpy.zeros(
                (self.nbFiles, nmca // numberofdetectors, arrRet.shape[0]),
                arrRet.dtype.char)
            nTimes = self.nbFiles * (nmca // numberofdetectors)
            filecounter = 0
            for key in ["McaLiveTime", "McaElapsedTime"]:
                if key in dataObject.info:
                    self.info[key] = numpy.zeros((nTimes, ), numpy.float32)

            # positioners
            key = "MotorNames"
            positioners = None
            if key in dataObject.info:
                positioners = {}
                for mne in dataObject.info[key]:
                    positioners[mne] = numpy.zeros((nTimes, ), numpy.float32)

            nTimes = -1
            for tempFileName in filelist:
                tempInstance = SpecFileDataSource.SpecFileDataSource(
                    tempFileName)
                mca_number = -1
                for keyindex in keylist:
                    info = tempInstance.getKeyInfo(keyindex)
                    numberofmca = info['NbMca']
                    if numberofmca <= 0:
                        continue
                    # the positioners are for all the mca in the scan

                    # only the last mca is read
                    key = "%s.1.%s" % (keyindex, numberofmca)
                    dataObject = tempInstance._getMcaData(key)
                    arrRet = dataObject.data
                    mca_number += 1
                    nTimes += 1
                    for i in iterlist:
                        # mcadata = scan_obj.mca(i)
                        self.data[filecounter, mca_number, :] = arrRet[:]
                        self.incrProgressBar += 1
                        for timeKey in ["McaElapsedTime", "McaLiveTime"]:
                            if timeKey in dataObject.info:
                                self.info[timeKey][nTimes] = \
                                    dataObject.info[timeKey]

                        if positioners and "MotorNames" in dataObject.info:
                            for mne in positioners:
                                if mne in dataObject.info["MotorNames"]:
                                    mneIdx = \
                                           dataObject.info["MotorNames"].index(mne)
                                    positioners[mne][nTimes] = \
                                             dataObject.info["MotorValues"][mneIdx]
                        self.onProgress(self.incrProgressBar)
                filecounter += 1
            if positioners:
                self.info["positioners"] = positioners
        elif shape is None and (self.nbFiles == 1) and (iterlist == [1]):
            # it can only be here if there is one file
            # it can only be here if there is only one scan
            # it can only be here if there is only one detector
            self.data = numpy.zeros((1, numberofmca, arrRet.shape[0]),
                                    arrRet.dtype.char)
            # when reading fast we do not read the time information
            # therefore we have to remove it from the info
            self._cleanupTimeInfo()
            for tempFileName in filelist:
                tempInstance = specfile.Specfile(tempFileName)
                # it can only be here if there is one scan per file
                # prevent problems if the scan number is different
                # scan = tempInstance.select(keylist[-1])
                scan = tempInstance[-1]
                iterationList = range(scan.nbmca())
                for i in iterationList:
                    # mcadata = scan_obj.mca(i)
                    self.data[0, i, :] = scan.mca(i + 1)[:]
                    self.incrProgressBar += 1
                    self.onProgress(self.incrProgressBar)
                filecounter = 1
        elif shape is None:
            # it can only be here if there is one scan per file
            # when reading fast we do not read the time information
            # therefore we have to remove it from the info
            self._cleanupTimeInfo()
            try:
                self.data = numpy.zeros(
                    (self.nbFiles, numberofmca // numberofdetectors,
                     arrRet.shape[0]), arrRet.dtype.char)
                filecounter = 0
                for tempFileName in filelist:
                    tempInstance = specfile.Specfile(tempFileName)
                    # it can only be here if there is one scan per file
                    # prevent problems if the scan number is different
                    # scan = tempInstance.select(keylist[-1])
                    scan = tempInstance[-1]
                    for i in iterlist:
                        # mcadata = scan_obj.mca(i)
                        self.data[filecounter, 0, :] = scan.mca(i)[:]
                        self.incrProgressBar += 1
                        self.onProgress(self.incrProgressBar)
                    filecounter += 1
            except MemoryError:
                qtflag = False
                if ('PyQt4.QtCore' in sys.modules) or \
                   ('PySide' in sys.modules) or \
                   ('PyMca5.PyMcaGui.PyMcaQt' in sys.modules):
                    qtflag = True
                hdf5done = False
                if HDF5 and qtflag:
                    from PyMca5.PyMcaGui import PyMcaQt as qt
                    from PyMca5.PyMcaIO import ArraySave
                    msg = qt.QMessageBox.information( \
                             None,
                             "Memory error\n",
                             "Do you want to convert your data to HDF5?\n",
                             qt.QMessageBox.Yes,qt.QMessageBox.No)
                    if msg != qt.QMessageBox.No:
                        hdf5file = qt.QFileDialog.getSaveFileName( \
                                      None,
                                      "Please select output file name",
                                      os.path.dirname(filelist[0]),
                                      "HDF5 files *.h5")
                        if not len(hdf5file):
                            raise IOError("Invalid output file")
                        hdf5file = qt.safe_str(hdf5file)
                        if not hdf5file.endswith(".h5"):
                            hdf5file += ".h5"

                        # get the final shape
                        from PyMca5.RGBCorrelatorWidget import ImageShapeDialog
                        stackImageShape = self.nbFiles,\
                                     int(numberofmca/numberofdetectors)
                        dialog = ImageShapeDialog(None, shape=stackImageShape)
                        dialog.setModal(True)
                        ret = dialog.exec()
                        if ret:
                            stackImageShape = dialog.getImageShape()
                            dialog.close()
                            del dialog
                        hdf, self.data = ArraySave.getHDF5FileInstanceAndBuffer( \
                                       hdf5file,
                                       (stackImageShape[0],
                                        stackImageShape[1],
                                        arrRet.shape[0]),
                                       compression=None,
                                       interpretation="spectrum")
                        nRow = 0
                        nCol = 0
                        for tempFileName in filelist:
                            tempInstance = specfile.Specfile(tempFileName)
                            # it can only be here if there is one scan per file
                            # prevent problems if the scan number is different
                            # scan = tempInstance.select(keylist[-1])
                            scan = tempInstance[-1]
                            nRow = int(self.incrProgressBar /
                                       stackImageShape[1])
                            nCol = self.incrProgressBar % stackImageShape[1]
                            for i in iterlist:
                                # mcadata = scan_obj.mca(i)
                                self.data[nRow, nCol, :] = scan.mca(i)[:]
                                self.incrProgressBar += 1
                                self.onProgress(self.incrProgressBar)
                        hdf5done = True
                        hdf.flush()
                    self.onEnd()
                    self.info["SourceType"] = "HDF5Stack1D"
                    self.info["McaIndex"] = 2
                    self.info["FileIndex"] = 0
                    self.info["SourceName"] = [hdf5file]
                    self.info["NumberOfFiles"] = 1
                    self.info["Size"] = 1
                    return
                else:
                    raise
        else:
            # time information not read
            self._cleanupTimeInfo()
            sampling_order = 1
            s0 = shape[0]
            s1 = shape[1]
            MEMORY_ERROR = False
            try:
                self.data = numpy.zeros((shape[0], shape[1], arrRet.shape[0]),
                                        arrRet.dtype.char)
            except MemoryError:
                try:
                    self.data = numpy.zeros(
                        (shape[0], shape[1], arrRet.shape[0]), numpy.float32)
                except MemoryError:
                    MEMORY_ERROR = True
            while MEMORY_ERROR:
                try:
                    for i in range(5):
                        print("\7")
                    sampling_order += 1
                    _logger.warning(
                        "**************************************************")
                    _logger.warning(
                        " Memory error!, attempting %dx%d sub-sampling ",
                        sampling_order, sampling_order)
                    _logger.warning(
                        "**************************************************")
                    s0 = int(shape[0] / sampling_order)
                    s1 = int(shape[1] / sampling_order)
                    #if shape[0] % sampling_order:
                    #    s0 = s0 + 1
                    #if shape[1] % sampling_order:
                    #    s1 = s1 + 1
                    self.data = numpy.zeros((s0, s1, arrRet.shape[0]),
                                            numpy.float32)
                    MEMORY_ERROR = False
                except MemoryError:
                    pass
            filecounter = 0
            for j in range(s0):
                filecounter = (j * sampling_order) * shape[1]
                for k in range(s1):
                    tempFileName = filelist[filecounter]
                    tempInstance = specfile.Specfile(tempFileName)
                    if tempInstance is None:
                        if not os.path.exists(tempFileName):
                            _logger.error("File %s does not exists",
                                          tempFileName)
                            raise IOError("File %s does not exists" %
                                          tempFileName)
                    scan = tempInstance.select(keylist[-1])
                    for i in iterlist:
                        # sum the present mcas
                        self.data[j, k, :] += scan.mca(i)[:]
                        self.incrProgressBar += 1
                        self.onProgress(self.incrProgressBar)
                    filecounter += sampling_order
            self.nbFiles = s0 * s1
        self.onEnd()
        """
        # Scan types
        # ----------
        #SF_EMPTY       = 0        # empty scan
        #SF_SCAN        = 1        # non-empty scan
        #SF_MESH        = 2        # mesh scan
        #SF_MCA         = 4        # single mca
        #SF_NMCA        = 8        # multi mca (more than 1 mca per acq)

        case = None
        if scantype == (SpecFileDataSource.SF_MESH + \
                        SpecFileDataSource.SF_MCA):
            # SINGLE MESH + SINGLE MCA
            # nfiles  = 1
            # nscans  = 1
            # nmca    = 1
            # there is a danger if it can be considered an indexed file ...
            pass

        elif scantype == (SpecFileDataSource.SF_MESH + \
                        SpecFileDataSource.SF_NMCA):
            # SINGLE MESH + MULTIPLE MCA
            # nfiles  = 1
            # nscans  = 1
            # nmca    > 1
            # there is a danger if it can be considered an indexed file ...
            #for the time being I take last mca
            pass

        elif scantype == (SpecFileDataSource.SF_SCAN+ \
                          SpecFileDataSource.SF_MCA):
            #Assumed scans containing always 1 detector
            pass

        elif scantype == (SpecFileDataSource.SF_MCA):
            #Assumed scans containing always 1 detector
            pass

        elif scantype == (SpecFileDataSource.SF_SCAN+ \
                          SpecFileDataSource.SF_NMCA):
            #Assumed scans containing the same number of detectors
            #for the time being I take last mca
            pass

        elif scantype == (SpecFileDataSource.SF_NMCA):
            #Assumed scans containing the same number of detectors
            #for the time being I take last mca
            pass

        else:
            raise ValueError, "Unhandled scan type = %s" % scantype

        """

        self.__nFiles = self.nbFiles
        self.__nImagesPerFile = 1
        shape = self.data.shape
        for i in range(len(shape)):
            key = 'Dim_%d' % (i + 1, )
            self.info[key] = shape[i]
        self.info["SourceType"] = SOURCE_TYPE
        self.info["SourceName"] = self.sourceName
        self.info["Size"] = self.__nFiles * self.__nImagesPerFile
        self.info["NumberOfFiles"] = self.__nFiles * 1
        self.info["FileIndex"] = fileindex