def init_internals(self): """ Initialize internal variables """ self.data = Mosaic() self.data_list = [] # List of list [pth, fname, dsetname] self.h5dlist = [] # List of dataset pointers self.pix = None self.wl = None self.freq = None self.last_path = None self.last_fname = None self.last_dsetname = None self.imported_calib_vec = None self.imported_spatial_vec = None
def test_hdf2(hdf_dataset2): filename, fid = hdf_dataset2 dset_list = lazy5.inspect.get_datasets(fid) mos = Mosaic() for n in range(10): mos.append(fid[dset_list[n]]) # assert mos.shape is None assert mos.size == 10 assert mos.issamedim mos.parameters['Order'] = 'R' assert mos.mosaic2d((5, 2)).shape == (5 * 3, 2 * 4) mos.parameters['Order'] = 'C' assert mos.mosaic2d((5, 2)).shape == (5 * 3, 2 * 4)
def test_big_to_small_3d_output_given(): orig_data_np = np.random.randn(40, 10, 3) filename_in = 'test_h5mosaic_in.h5' dset_in_prefix = 'dset_' fid_in = h5py.File(filename_in, 'w') m_unit_size = 10 n_unit_size = 5 m_ct = orig_data_np.shape[0] // m_unit_size n_ct = orig_data_np.shape[1] // n_unit_size ct = 0 for ni in range(n_ct): for mi in range(m_ct): temp = orig_data_np[mi * m_unit_size:(mi + 1) * m_unit_size, ni * n_unit_size:(ni + 1) * n_unit_size, :] fid_in.create_dataset(dset_in_prefix + '{}'.format(ct), shape=temp.shape, data=temp) ct += 1 fid_in.close() fid_in = h5py.File(filename_in, 'r') mos = Mosaic() ct = 0 for ni in range(n_ct): for mi in range(m_ct): mos.append(fid_in[dset_in_prefix + '{}'.format(ct)]) ct += 1 filename_out = 'test_h5mosaic_out.h5' dset_out_name = 'dset' fid_out = h5py.File(filename_out, 'w') fid_out.create_dataset(dset_out_name, shape=orig_data_np.shape, data=np.zeros(orig_data_np.shape)) mos.parameters['Order'] = 'R' mos.mosaicfull((m_ct, n_ct), out=fid_out[dset_out_name]) assert np.allclose(fid_out[dset_out_name], orig_data_np) fid_in.close() fid_out.close() time.sleep(1) try: os.remove(filename_in) except: print('Could not delete {}'.format(filename_in)) time.sleep(1) try: os.remove(filename_out) except: print('Could not delete {}'.format(filename_out))
def test_big_to_small_3d_output_given_crop_transpose_flips(): """ 3D big dataset, divied up into small chunks -- WITH CROPPING, TRANSPOSING AND FLIPPING H & V Note: This test does not assert anything, but rather just ensures the methods can run without raising errors """ orig_data_np = np.random.randn(40, 10, 3) filename_in = 'test_h5mosaic_in.h5' dset_in_prefix = 'dset_' fid_in = h5py.File(filename_in, 'w') m_unit_size = 10 n_unit_size = 5 m_ct = orig_data_np.shape[0] // m_unit_size n_ct = orig_data_np.shape[1] // n_unit_size ct = 0 for ni in range(n_ct): for mi in range(m_ct): temp = orig_data_np[mi * m_unit_size:(mi + 1) * m_unit_size, ni * n_unit_size:(ni + 1) * n_unit_size, :] fid_in.create_dataset(dset_in_prefix + '{}'.format(ct), shape=temp.shape, data=temp) ct += 1 fid_in.close() fid_in = h5py.File(filename_in, 'r') mos = Mosaic() mos.parameters['StartR'] = 1 mos.parameters['EndR'] = -1 mos.parameters['StartC'] = 1 mos.parameters['EndC'] = -1 mos.parameters['Transpose'] = True mos.parameters['FlipVertical'] = True mos.parameters['FlipHorizontally'] = True ct = 0 for ni in range(n_ct): for mi in range(m_ct): mos.append(fid_in[dset_in_prefix + '{}'.format(ct)]) ct += 1 filename_out = 'test_h5mosaic_out.h5' dset_out_name = 'dset' fid_out = h5py.File(filename_out, 'w') fid_out.create_dataset(dset_out_name, shape=mos.mosaic_shape((m_ct, n_ct)), dtype=orig_data_np.dtype) mos.parameters['Order'] = 'R' mos.mosaicfull((m_ct, n_ct), out=fid_out[dset_out_name]) fid_in.close() fid_out.close() time.sleep(1) try: os.remove(filename_in) except: print('Could not delete {}'.format(filename_in)) time.sleep(1) try: os.remove(filename_out) except: print('Could not delete {}'.format(filename_out))
def test_big_to_small_3d_output_given_crop(): """ 3D big dataset, divied up into small chunks -- WITH CROPPING """ orig_data_np = np.random.randn(40, 10, 3) filename_in = 'test_h5mosaic_in.h5' dset_in_prefix = 'dset_' fid_in = h5py.File(filename_in, 'w') m_unit_size = 10 n_unit_size = 5 m_ct = orig_data_np.shape[0] // m_unit_size n_ct = orig_data_np.shape[1] // n_unit_size ct = 0 for ni in range(n_ct): for mi in range(m_ct): temp = orig_data_np[mi * m_unit_size:(mi + 1) * m_unit_size, ni * n_unit_size:(ni + 1) * n_unit_size, :] fid_in.create_dataset(dset_in_prefix + '{}'.format(ct), shape=temp.shape, data=temp) ct += 1 fid_in.close() fid_in = h5py.File(filename_in, 'r') mos = Mosaic() mos.parameters['StartR'] = 1 mos.parameters['EndR'] = -1 mos.parameters['StartC'] = 1 mos.parameters['EndC'] = -1 ct = 0 for ni in range(n_ct): for mi in range(m_ct): mos.append(fid_in[dset_in_prefix + '{}'.format(ct)]) ct += 1 filename_out = 'test_h5mosaic_out.h5' dset_out_name = 'dset' fid_out = h5py.File(filename_out, 'w') fid_out.create_dataset(dset_out_name, shape=mos.mosaic_shape((m_ct, n_ct)), dtype=orig_data_np.dtype) mos.parameters['Order'] = 'R' mos.mosaicfull((m_ct, n_ct), out=fid_out[dset_out_name]) assert np.allclose(fid_out[dset_out_name][0:3, 0:3, :], orig_data_np[1:4, 1:4, :]) assert np.allclose(fid_out[dset_out_name][8:11, 0:3, :], orig_data_np[11:14, 1:4, :]) assert np.allclose(fid_out[dset_out_name][0:3, 8:11, :], orig_data_np[1:4, 11:14, :]) fid_in.close() fid_out.close() time.sleep(1) try: os.remove(filename_in) except: print('Could not delete {}'.format(filename_in)) time.sleep(1) try: os.remove(filename_out) except: print('Could not delete {}'.format(filename_out))
class MainWindowMosaic(_QMainWindow): """ """ frequency_calib = { 'Slope': -0.165955456, 'Intercept': 832.5510120093941, 'Probe': 771.461, 'Calib_WL': 700.0, 'Center_WL': 700.0 } config = {'allow_duplicates': False} def __init__(self, parent=None): super(MainWindowMosaic, self).__init__(parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setupListWidget() self.ui.spinBoxIntercept.setValue(self.frequency_calib['Intercept']) self.ui.spinBoxSlope.setValue(self.frequency_calib['Slope']) self.ui.spinBoxProbe.setValue(self.frequency_calib['Probe']) self.ui.spinBoxCalibWL.setValue(self.frequency_calib['Calib_WL']) self.ui.spinBoxCenterWL.setValue(self.frequency_calib['Center_WL']) # Internal data self.init_internals() self.mpl = _MplCanvas(parent=self) self.ui.verticalLayoutMPL.insertWidget(0, self.mpl, _QtCore.Qt.AlignCenter) self.ui.verticalLayoutMPL.insertWidget(0, self.mpl.toolbar, _QtCore.Qt.AlignHCenter) # SIGNALS AND SLOTS self.ui.actionAddFromHDF.triggered.connect(self.addDataset) self.ui.pushButtonAddDataset.pressed.connect(self.addDataset) self.ui.actionSaveToHDF5.triggered.connect(self.save) self.ui.sliderFreq.valueChanged.connect(self.updateSlider) self.ui.sliderFreq.sliderReleased.connect(self.updateMosaicImage) self.ui.lineEditPix.editingFinished.connect(self.lineEditPixChange) self.ui.spinBoxMRows.editingFinished.connect(self.updateParams) self.ui.spinBoxNCols.editingFinished.connect(self.updateParams) self.ui.comboBoxRowCol.currentIndexChanged.connect(self.updateParams) self.ui.checkBoxFlipH.stateChanged.connect(self.updateParams) self.ui.checkBoxFlipV.stateChanged.connect(self.updateParams) self.ui.checkBoxTranspose.stateChanged.connect(self.updateParams) self.ui.spinBoxStartRow.editingFinished.connect(self.updateParams) self.ui.spinBoxStartCol.editingFinished.connect(self.updateParams) self.ui.spinBoxEndRow.editingFinished.connect(self.updateParams) self.ui.spinBoxEndCol.editingFinished.connect(self.updateParams) # ! Currently, cannot save compress in HDF5 self.ui.checkBoxCompress.setEnabled(False) # self.ui.checkBoxCompress.stateChanged.connect(self.updateParams) self.ui.spinBoxSlope.editingFinished.connect(self.updateFrequency) self.ui.spinBoxIntercept.editingFinished.connect(self.updateFrequency) self.ui.spinBoxProbe.editingFinished.connect(self.updateFrequency) self.ui.spinBoxCalibWL.editingFinished.connect(self.updateFrequency) self.ui.spinBoxCenterWL.editingFinished.connect(self.updateFrequency) # self.ui.spinBoxXStepSize.editingFinished.connect(self.updateSpace) # self.ui.spinBoxYStepSize.editingFinished.connect(self.updateSpace) self.ui.pushButtonMoveUp.pressed.connect(self.promote_demote_list_item) self.ui.pushButtonMoveDown.pressed.connect( self.promote_demote_list_item) self.ui.pushButtonDeleteDataset.pressed.connect(self.deleteDataset) self.ui.listWidgetDatasets.reordered.connect(self.list_reordered) # Close event self.ui.closeEvent = self.closeEvent self.ui.actionExit.triggered.connect(self.closeEvent) def setupListWidget(self): self.ui.listWidgetDatasets = DnDReorderListWidget(parent=self.ui.frame) self.ui.verticalLayout_4.insertWidget(2, self.ui.listWidgetDatasets) def deleteDataset(self): if self.data._data: row = self.ui.listWidgetDatasets.currentRow() if row < 0: # print('No selection') pass else: # print('Current row: {}'.format(row)) it = self.ui.listWidgetDatasets.takeItem(row) out = self.data_list.pop(row) out = self.data._data.pop(row) out = self.h5dlist.pop(row) out.file.close() if self.data.size > 0: self.list_reordered() else: self.init_internals() self.mpl.ax.clear() self.mpl.draw() def promote_demote_list_item(self): if self.data._data: sndr = self.sender() row = self.ui.listWidgetDatasets.currentRow() isup = None if sndr == self.ui.pushButtonMoveUp: isup = True elif sndr == self.ui.pushButtonMoveDown: isup = False if row < 0: # print('No selection') pass else: # print('Current row: {}'.format(row)) pass if isup & (row == 0): # print('Can\'t promote first') pass elif (isup == False) & (row + 1 == self.ui.listWidgetDatasets.count()): # print('Can\'t demote last') pass elif row < 0: # print('Can\'t promote/demote no selection') pass elif isup: # print('Promoting') it = self.ui.listWidgetDatasets.takeItem(row) self.ui.listWidgetDatasets.insertItem(row - 1, it) self.list_reordered() elif not isup: # print('Demoting') it = self.ui.listWidgetDatasets.takeItem(row) self.ui.listWidgetDatasets.insertItem(row + 1, it) self.list_reordered() def list_reordered(self): if self.data._data: if self.data.size >= 1: dset_list = [] for num in range(self.ui.listWidgetDatasets.count()): dset_list.append( self.ui.listWidgetDatasets.item(num).text().split( ' : ')) new_order = [] for q in self.data_list: new_order.append(dset_list.index(q)) assert len(new_order) == self.data.size assert len(new_order) == _np.unique(new_order).size self.data_list = [self.data_list[idx] for idx in new_order] self.data._data = [self.data._data[idx] for idx in new_order] self.h5dlist = [self.h5dlist[idx] for idx in new_order] self.updateMosaicImage() else: pass def init_internals(self): """ Initialize internal variables """ self.data = Mosaic() self.data_list = [] # List of list [pth, fname, dsetname] self.h5dlist = [] # List of dataset pointers self.pix = None self.wl = None self.freq = None self.last_path = None self.last_fname = None self.last_dsetname = None self.imported_calib_vec = None self.imported_spatial_vec = None def lineEditPixChange(self): """ Frequency manually entered in frequency-slider-display """ freq_in = int(float(self.ui.lineEditPix.text())) max_freq = self.ui.sliderFreq.maximum() min_freq = self.ui.sliderFreq.minimum() if freq_in > max_freq: freq_in = max_freq elif freq_in < min_freq: freq_in = min_freq else: pass self.ui.sliderFreq.setValue(freq_in) def updateSlider(self): idx = self.ui.sliderFreq.value() self.ui.lineEditPix.setText(str(idx)) if self.freq is not None: self.ui.lineEditFreq.setText(str(self.freq[idx])) # In case incremented by the arrow buttons if not self.ui.sliderFreq.isSliderDown(): self.updateMosaicImage() def addDataset(self): if (self.last_path is None) | (self.last_fname is None) | (self.last_dsetname is None): first_dset = True to_open = HdfLoad.getFileDataSets(parent=self) else: first_dset = False to_open = HdfLoad.getFileDataSets(pth=_os.path.join( self.last_path, self.last_fname), parent=self) if to_open is not None: temp_last_path, temp_last_fname, _ = to_open # Since to_open's dsets will be lists, this is an unraveled version to_import = [[temp_last_path, temp_last_fname, q] for q in to_open[-1]] to_import2 = [] # Duplicates removed if NOT allowing duplicates for q in to_import: if not self.config['allow_duplicates']: if self.is_duplicate_import([q[0], q[1], q[2]]): msg = _QMessageBox(self) msg.setIcon(_QMessageBox.Critical) str1 = 'Cannot import duplicate image:\n\n' str2 = '{} : {} : {}\n\n'.format(*q) str3 = '\n\nNot importing this dataset' msg.setText(str1 + str2 + str3) msg.setWindowTitle('Duplicate Image Found.') msg.setStandardButtons(_QMessageBox.Ok) msg.setDefaultButton(_QMessageBox.Ok) out = msg.exec() else: to_import2.append(q) else: to_import2.append(q) for q in to_import2: fof = FidOrFile(fullpath(pth=q[0], filename=q[1])) if fof.fid[q[-1]].ndim != 3: msg = _QMessageBox(self) msg.setIcon(_QMessageBox.Critical) str1 = 'Dataset is not 3D:\n\n' str2 = '{} : {} : {}'.format(*q) str3 = '\n\nNot importing this dataset' msg.setText(str1 + str2 + str3) msg.setWindowTitle('Cannot Load Non-3D Datasets.') msg.setStandardButtons(_QMessageBox.Ok) msg.setDefaultButton(_QMessageBox.Ok) out = msg.exec() fof.fid.close() else: self.h5dlist.append(fof.fid[q[-1]]) self.data.append(fof.fid[q[-1]]) self.last_path = q[0] self.last_fname = q[1] self.last_dsetname = q[2] self.data_list.append(q) if first_dset: flen = self.data.unitshape_orig[-1] self.ui.sliderFreq.setMinimum(0) self.ui.sliderFreq.setMaximum(flen - 1) self.ui.sliderFreq.setValue(0) self.pix = _np.arange(flen) calib_vec = self.check_for_spectral_calib( fof.fid[q[-1]]) self.check_for_spatial_calib(fof.fid[q[-1]]) self.updateFrequency(calib_vec) first_dset = False self.updateDatasets() def check_for_spatial_calib(self, dset): """ See if dataset has spatial calibration meta data """ if not isinstance(dset, h5py.Dataset): return None if not hasattr(dset, 'attrs'): return None spatial_vec = [] # X, Y attrs_dict = lazy5.inspect.get_attrs_dset(dset.file, dset.name) list_of_keys = list(attrs_dict) ct = 0 temp = [] to_check = ['Raster.Fast.StepSize', 'Raster.Slow.StepSize'] # X, Y for num, tc in enumerate(to_check): if list_of_keys.count(tc) > 0: ct += 1 temp.append(attrs_dict[tc]) if ct == len(to_check): print('Has StepSize info (New)') spatial_vec = temp else: ct = 0 temp = [] to_check = [ 'RasterScanParams.FastAxisStepSize', 'RasterScanParams.SlowAxisStepSize' ] # X, Y for num, tc in enumerate(to_check): if list_of_keys.count(tc) > 0: ct += 1 temp.append(attrs_dict[tc]) if ct == len(to_check): print('Has StepSize info (Old)') spatial_vec = temp else: ct = 0 temp = [] to_check = [ 'Raster.Fast.Start', 'Raster.Fast.Stop', 'Raster.Fast.Steps', 'Raster.Slow.Start', 'Raster.Slow.Stop', 'Raster.Slow.Steps' ] for num, tc in enumerate(to_check): if list_of_keys.count(tc) > 0: ct += 1 temp.append(attrs_dict[tc]) if ct == len(to_check): print('Has Start-Stop-Steps info (New)') x_stepsize = (temp[1] - temp[0]) / (temp[2] - 1) y_stepsize = (temp[4] - temp[3]) / (temp[5] - 1) spatial_vec = [x_stepsize, y_stepsize] else: ct = 0 temp = [] to_check = [ 'RasterScanParams.FastAxisStart', 'RasterScanParams.FastAxisStop', 'RasterScanParams.FastAxisSteps', 'RasterScanParams.SlowAxisStart', 'RasterScanParams.SlowAxisStop', 'RasterScanParams.SlowAxisSteps' ] for num, tc in enumerate(to_check): if list_of_keys.count(tc) > 0: ct += 1 temp.append(attrs_dict[tc]) if ct == len(to_check): print('Has Start-Stop-Steps info (Old)') x_stepsize = (temp[1] - temp[0]) / (temp[2] - 1) y_stepsize = (temp[4] - temp[3]) / (temp[5] - 1) spatial_vec = [x_stepsize, y_stepsize] if spatial_vec: self.imported_spatial_vec = spatial_vec self.ui.checkBoxSpaceFromData.setChecked(True) self.ui.spinBoxXStepSize.setValue(spatial_vec[0]) self.ui.spinBoxYStepSize.setValue(spatial_vec[1]) def check_for_spectral_calib(self, dset): """ See if dataset has spectral calibration meta data """ if not isinstance(dset, h5py.Dataset): return None if not hasattr(dset, 'attrs'): return None calib_vec = [] attrs_dict = lazy5.inspect.get_attrs_dset(dset.file, dset.name) list_of_keys = list(attrs_dict) ct = 0 temp = [] to_check = [ 'Calib.a_vec', 'Calib.ctr_wl', 'Calib.ctr_wl0', 'Calib.n_pix', 'Calib.probe' ] for num, tc in enumerate(to_check): if list_of_keys.count(tc) > 0: ct += 1 temp.append(attrs_dict[tc]) if ct == len(to_check): print('Has Calib series') calib_vec = temp else: ct = 0 temp = [] to_check = [ 'Spectro.Avec', 'Spectro.CurrentWavelength', 'Spectro.CalibWavelength', 'Spectro.SpectralPixels', 'Spectro.ProbeWavelength' ] for num, tc in enumerate(to_check): if list_of_keys.count(tc) > 0: ct += 1 temp.append(attrs_dict[tc]) if ct == len(to_check): print('Has Spectro series') calib_vec = temp if calib_vec: self.ui.checkBoxSpectFromData.setChecked(True) return calib_vec def is_duplicate_import(self, to_open): if self.data._data: return self.data_list.count(to_open) > 0 else: return False def updateFrequency(self, calib_vec=None): if self.pix is not None: if calib_vec is None: probe = self.ui.spinBoxProbe.value() * 1e-9 intercept = self.ui.spinBoxIntercept.value() * 1e-9 slope = self.ui.spinBoxSlope.value() * 1e-9 ctr_wl = self.ui.spinBoxCenterWL.value() * 1e-9 calib_wl = self.ui.spinBoxCalibWL.value() * 1e-9 self.frequency_calib['Probe'] = probe self.frequency_calib['Intercept'] = intercept self.frequency_calib['Slope'] = slope self.frequency_calib['Center_WL'] = ctr_wl self.frequency_calib['Calib_WL'] = calib_wl self.wl = slope * self.pix + intercept + (ctr_wl - calib_wl) if probe != 0.0: self.freq = 0.01 / self.wl - 0.01 / probe else: self.freq = 0.01 / self.wl else: a_vec = calib_vec[0] if len(a_vec) == 2: slope = a_vec[0] * 1e-9 intercept = a_vec[1] * 1e-9 else: # Linearizes higher order polynomial a_vec = _np.polyfit(self.pix, _np.polyval(a_vec, self.pix), 1) slope = a_vec[0] * 1e-9 intercept = a_vec[1] * 1e-9 ctr_wl = calib_vec[1] * 1e-9 calib_wl = calib_vec[2] * 1e-9 local_pix = calib_vec[3] probe = calib_vec[4] * 1e-9 self.ui.spinBoxProbe.setValue(probe * 1e9) self.ui.spinBoxIntercept.setValue(intercept * 1e9) self.ui.spinBoxSlope.setValue(slope * 1e9) self.ui.spinBoxCenterWL.setValue(ctr_wl * 1e9) self.ui.spinBoxCalibWL.setValue(calib_wl * 1e9) self.wl = slope * self.pix + intercept + (ctr_wl - calib_wl) if probe != 0.0: self.freq = 0.01 / self.wl - 0.01 / probe else: self.freq = 0.01 / self.wl self.imported_calib_vec = _copy.deepcopy(calib_vec) self.updateSlider() @staticmethod def _create_list_names(item_list): temp = [] for q in item_list: temp.append(q[0] + ' : ' + q[1] + ' : ' + q[-1]) return temp def updateDatasets(self): """ Update the listWidget of datasets """ self.ui.listWidgetDatasets.clear() temp = self._create_list_names(self.data_list) for q in temp: self.ui.listWidgetDatasets.addItem(q) self.updateParams() # self.updateMosaicImage() def updateMosaicImage(self): if self.data._data: idx = self.ui.sliderFreq.value() self.ui.lineEditPix.setText(str(idx)) if self.freq is not None: self.ui.lineEditFreq.setText(str(self.freq[idx])) self.mpl.ax.clear() temp = self.data.mosaic2d(idx=idx) if _np.iscomplexobj(temp): self.mpl.ax.imshow(temp.imag) else: self.mpl.ax.imshow(temp) self.mpl.draw() def closeEvent(self, event): print('Closing') if self.h5dlist: for q in self.h5dlist: print('Closing: {}'.format(q)) q.file.close() self.init_internals() self.close() # app = _QApplication.instance() # app.closeAllWindows() # app.quit() def updateParams(self): """ Update Mosaic object parameters """ self.data.parameters['StartC'] = self.ui.spinBoxStartCol.value() self.data.parameters['StartR'] = self.ui.spinBoxStartRow.value() self.data.parameters['EndC'] = -1 * self.ui.spinBoxEndCol.value() self.data.parameters['EndR'] = -1 * self.ui.spinBoxEndRow.value() self.data.parameters[ 'Transpose'] = self.ui.checkBoxTranspose.isChecked() self.data.parameters['FlipVertical'] = self.ui.checkBoxFlipV.isChecked( ) self.data.parameters[ 'FlipHorizontally'] = self.ui.checkBoxFlipH.isChecked() self.data.parameters['Compress'] = self.ui.checkBoxCompress.isChecked() self.data.parameters['Shape'] = [ self.ui.spinBoxMRows.value(), self.ui.spinBoxNCols.value() ] idx = self.ui.comboBoxRowCol.currentIndex() if idx == 0: self.data.parameters['Order'] = 'R' else: self.data.parameters['Order'] = 'C' mrows = self.ui.spinBoxMRows.value() ncols = self.ui.spinBoxNCols.value() n_dsets = len(self.data_list) if (mrows * ncols) < n_dsets: mrows = int(_np.ceil(n_dsets / ncols)) self.ui.spinBoxMRows.setValue(mrows) self.ui.spinBoxNCols.setValue(ncols) self.data.parameters['Shape'] = [mrows, ncols] if self.data._data: self.updateMosaicImage() def save(self): if self.data.parameters['Compress']: msg = _QMessageBox(self) msg.setIcon(_QMessageBox.Information) str1 = 'Currently, HDF5-saving with compression is not supported. Saving full data.' msg.setText(str1) msg.setWindowTitle('Compression not supported.') msg.setStandardButtons(_QMessageBox.Ok) msg.setDefaultButton(_QMessageBox.Ok) msg.exec() ret = DialogSave.dialogSave(parent=self, current_filename='MOSAIC_' + self.last_fname, current_path=self.last_path, current_dataset_name=self.last_dsetname, suffix='') if ret is None: pass # Save canceled else: save_filename = ret[0] save_path = ret[1] save_dataset_name = ret[2] save_grp = save_dataset_name.rpartition('/')[0] save_dataset_name_no_grp = save_dataset_name.rpartition('/')[-1] save_dataset_mask = save_grp + '/' + 'MASK_' + save_dataset_name_no_grp mask = self.data.mosaic_mask() new_attrs = OrderedDict() new_attrs.update(self.data.attr_dict()) if self.imported_calib_vec: new_attrs.update({ 'Calib.a_vec': self.imported_calib_vec[0], 'Calib.ctr_wl': self.imported_calib_vec[1], 'Calib.ctr_wl0': self.imported_calib_vec[2], 'Calib.n_pix': self.imported_calib_vec[3], 'Calib.probe': self.imported_calib_vec[4], 'Calib.units': 'nm' }) if self.imported_spatial_vec: temp = self.data.mosaic_shape() x_stepsize = self.imported_spatial_vec[0] y_stepsize = self.imported_spatial_vec[0] x_start = 0 y_start = 0 x_stop = (temp[1] - 1) * x_stepsize y_stop = (temp[0] - 1) * y_stepsize x_steps = temp[1] y_steps = temp[0] # ['Raster.Fast.Start', 'Raster.Fast.Stop', 'Raster.Fast.Steps', # 'Raster.Slow.Start', 'Raster.Slow.Stop', 'Raster.Slow.Steps'] new_attrs.update({ 'Raster.Fast.StepSize': x_stepsize, 'Raster.Fast.Steps': x_steps, 'Raster.Fast.Start': x_start, 'Raster.Fast.Stop': x_stop, 'Raster.Slow.StepSize': y_stepsize, 'Raster.Slow.Steps': y_steps, 'Raster.Slow.Start': y_start, 'Raster.Slow.Stop': y_stop }) for num, q in enumerate(self.data._data): curr_shape = [(mask == num).sum(axis=0).max(), (mask == num).sum(axis=1).max()] new_attrs.update({'Mosaic.shape.{}'.format(num): curr_shape}) new_attrs.update( {'Mosaic.path.{}'.format(num): self.data_list[num][0]}) new_attrs.update( {'Mosaic.filename.{}'.format(num): self.data_list[num][1]}) new_attrs.update({ 'Mosaic.datasetname.{}'.format(num): self.data_list[num][2] }) if hasattr(q, 'attrs'): orig_attrs = lazy5.inspect.get_attrs_dset(q.file, q.name) for k in orig_attrs: new_attrs.update( {'Mosaic.{}.{}'.format(num, k): orig_attrs[k]}) # try: fid = h5py.File(_os.path.join(save_path, save_filename), 'a') fid.require_group(save_grp) fid.create_dataset(save_dataset_name, shape=self.data.mosaic_shape(), dtype=self.data.dtype, chunks=True) self.data.mosaicfull(out=fid[save_dataset_name]) lazy5.alter.write_attr_dict(fid[save_dataset_name], new_attrs) fid.close() lazy5.create.save(save_filename, save_dataset_mask, self.data.mosaic_mask(), pth=save_path, attr_dict=new_attrs)