diff --git a/src/PyMca5/PyMcaGui/pymca/QStackWidget.py b/src/PyMca5/PyMcaGui/pymca/QStackWidget.py index 6d79f275b..df754e34a 100644 --- a/src/PyMca5/PyMcaGui/pymca/QStackWidget.py +++ b/src/PyMca5/PyMcaGui/pymca/QStackWidget.py @@ -246,7 +246,8 @@ def setStack(self, *var, **kw): if (1 in self._stack.data.shape) and\ isinstance(self._stack.data, numpy.ndarray): oldshape = self._stack.data.shape - dialog = ImageShapeDialog(self, shape=oldshape[0:2]) + suggested = self._stack.info.get("SuggestedImageShape", oldshape[0:2]) + dialog = ImageShapeDialog(self, shape=suggested) dialog.setModal(True) ret = dialog.exec() if ret: diff --git a/src/PyMca5/PyMcaIO/HDF5Stack1D.py b/src/PyMca5/PyMcaIO/HDF5Stack1D.py index a90df4d3a..6c1ccaa81 100644 --- a/src/PyMca5/PyMcaIO/HDF5Stack1D.py +++ b/src/PyMca5/PyMcaIO/HDF5Stack1D.py @@ -330,7 +330,7 @@ def loadFileList(self, filelist, selection, scanlist=None): if self.__dtype0 is None: if (bytefactor == 8) and (neededMegaBytes < (2*physicalMemory)): # try reading as float32 - print("Forcing the use of float32 data") + _logger.info("Forcing the use of float32 data") self.__dtype = numpy.float32 else: raise MemoryError("Force dynamic loading") @@ -428,7 +428,7 @@ def loadFileList(self, filelist, selection, scanlist=None): else: del mcaObjectPaths["elapsed_time"] else: - # we have to have as many elpased times as MCA spectra + # we have to have as many elapsed times as MCA spectra _time = numpy.zeros((self.data.shape[0] * self.data.shape[1]), numpy.float32) if "calibration" in mcaObjectPaths: @@ -800,13 +800,46 @@ def loadFileList(self, filelist, selection, scanlist=None): # try to get scales scaleList = [] if xSelectionList is not None: + # McaIndex not always equal to mcaIndex + stackMcaIndex = self.info.get("McaIndex", mcaIndex) if len(xDatasetList) == 1: xDataset = xDatasetList[0] if xDataset.size == shape[self.info['McaIndex']]: # assuming providing channels self.x = [xDataset.reshape(-1)] else: + # user could not set coordiantes for one axis only _logger.warning("Ignoring channels selection %s" % xSelectionList) + + # for dataset of N*M self.data.shape = (1, N, M) + # if positions are flatten then both X, Y, coordinates should be of size N. + elif len(xDatasetList) in (2, 3) and len(xDatasetList[0]) == len(xDatasetList[1]) == self.data.shape[1]: + # assuming providing spatial coordinates (and maybe channels) + grid_x, grid_y = self.shortenScales(xDatasetList[0], xDatasetList[1]) + if grid_x.size > 1: + delta_x = numpy.mean(grid_x[1:] - grid_x[:-1], dtype=numpy.float32) + else: + delta_x = 1.0 + xScale = [grid_x[0], delta_x] + + if grid_y.size > 1: + delta_y = numpy.mean(grid_y[1:] - grid_y[:-1], dtype=numpy.float32) + else: + delta_y = 1.0 + yScale = [grid_y[0], delta_y] + scaleList = [xScale, yScale] + self.info["SuggestedImageShape"] = (len(grid_y), len(grid_x)) + + if len(xDatasetList) == 2: + pass + elif len(xDatasetList) == 3 and xDatasetList[2].size == shape[self.info['McaIndex']]: + # assuming providing spatial coordinates and channels + self.x = [xDatasetList[2].reshape(-1)] + else: + _logger.warning("Coordinates were applied, but channels could not be") + _logger.warning("Ignoring channels selection %s" % xSelectionList) + + elif len(xDatasetList) == len(self.data.shape): # assuming providing spatial coordinates and channels goodScale = 0 @@ -823,7 +856,7 @@ def loadFileList(self, filelist, selection, scanlist=None): for i in range(len(self.data.shape)): dataset = xDatasetList[i].reshape(-1) datasize = self.data.shape[i] - if i == mcaIndex: + if i == stackMcaIndex: self.x = [dataset] else: origin = dataset[0] @@ -842,8 +875,8 @@ def loadFileList(self, filelist, selection, scanlist=None): _logger.warning("Ignoring dimension selections %s" % xSelectionList) elif len(xDatasetList) == (len(self.data.shape) - 1): scaleList = [] - for i in range(len(self.data.shape)): - if i == mcaIndex: + for i in range(len(xDatasetList)): + if i == stackMcaIndex: continue dataset = xDatasetList[i].reshape(-1) datasize = self.data.shape[i] @@ -901,7 +934,7 @@ def loadFileList(self, filelist, selection, scanlist=None): if len(dims) == len(self.data.shape): scaleList = [] for i in range(len(self.data.shape)): - if i == mcaIndex: + if i == self.info['McaIndex']: continue dataset = dims[i] origin = dataset[0] @@ -921,6 +954,43 @@ def loadFileList(self, filelist, selection, scanlist=None): self.info["xScale"] = xScale self.info["yScale"] = yScale + def shortenScales(self, A, B): + A = numpy.asarray(A) + B = numpy.asarray(B) + + if len(A) == 0 or len(B) == 0: + raise ValueError("Arrays must not be empty") + + # Detect which array is related to the slow motor + if len(B) == 1 or (len(A)>1 and abs(A[1] - A[0]) > abs(B[1] - B[0])): + fast = A + slow = B + fast_is_A = True + else: + fast = B + slow = A + fast_is_A = False + + # Find repetition length n in the slow array + diff_idx = numpy.where(slow != slow[0])[0] + # Protection if one motor did not move at all + if len(diff_idx) == 0: + n = len(slow) + else: + n = diff_idx[0] + + short_fast = fast[:n] + short_slow = slow[::n] + + if fast_is_A: + X_sh = short_fast + Y_sh = short_slow + else: + X_sh = short_slow + Y_sh = short_fast + + return X_sh, Y_sh + def getDimensions(self, nFiles, nScans, shape, index=None): #somebody may want to overwrite this """