def plot(self, x, y, *args, **kwargs): # set up infinity line and get its position self.plotItem.plot(x, y, *args, **kwargs) self.addItem(self.line) x_val = self.line.value() if x_val == 0: y_val = 0 else: idx = val2ind(x_val, self.wavenumbers) x_val = self.wavenumbers[idx] y_val = y[idx] if not self._meanSpec: txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ Spectrum #{self.spectrumInd}</div>' else: txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ {self._mean_title}</div>' txt_html += f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ X = {x_val: .2f}, Y = {y_val: .4f}</div>' self.txt = TextItem(html=txt_html, anchor=(0, 0)) ymax = max(y) self._y = y self.txt.setPos(1500, 0.95 * ymax) self.addItem(self.txt)
def plot(self, x, y, *args, **kwargs): # set up infinity line and get its position self.plotItem.plot(x, y, *args, **kwargs) self.addItem(self.line) self.addItem(self.cross) x_val = self.line.value() if x_val == 0: y_val = 0 else: idx = val2ind(x_val, self.wavenumbers) x_val = self.wavenumbers[idx] y_val = y[idx] if not self._meanSpec: txt_html = toHtml(f'Spectrum #{self.spectrumInd}') else: txt_html = toHtml(f'{self._mean_title}') txt_html += toHtml(f'X = {x_val: .2f}, Y = {y_val: .4f}') self.txt.setHtml(txt_html) ymax = np.max(y) self._y = y r = self.txtPosRatio self.txt.setPos(r * x[-1] + (1 - r) * x[0], ymax) self.cross.setData([x_val], [y_val]) self.addItem(self.txt)
def getEnergy(self): if self._y is not None: x_val = self.line.value() idx = val2ind(x_val, self._x) x_val = self._x[idx] y_val = self._y[idx] txt_html = toHtml(f'X = {x_val: .2f}, Y = {y_val: .4f}') self.txt.setHtml(txt_html) self.cross.setData([x_val], [y_val])
def getEnergy(self): if self._y is not None: x_val = self.line.value() idx = val2ind(x_val, self._x) x_val = self._x[idx] y_val = self._y[idx] txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ X = {x_val: .2f}, Y = {y_val: .4f}</div>' self.txt.setHtml(txt_html) self.cross.setData([x_val], [y_val])
def getEnergy(self, lineobject): if self._y is not None: x_val = lineobject.value() idx = val2ind(x_val, self.wavenumbers) x_val = self.wavenumbers[idx] y_val = self._y[idx] if not self._meanSpec: txt_html = toHtml(f'Spectrum #{self.spectrumInd}') else: txt_html = toHtml(f'{self._mean_title}') txt_html += toHtml(f'X = {x_val: .2f}, Y = {y_val: .4f}') self.txt.setHtml(txt_html) self.cross.setData([x_val], [y_val])
def getEnergy(self, lineobject): if self._y is not None: x_val = lineobject.value() idx = val2ind(x_val, self.wavenumbers) x_val = self.wavenumbers[idx] y_val = self._y[idx] if not self._meanSpec: txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ Spectrum #{self.spectrumInd}</div>' else: txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ {self._mean_title}</div>' txt_html += f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ X = {x_val: .2f}, Y = {y_val: .4f}</div>' self.txt.setHtml(txt_html)
def parse_anchors(self, anchors): """ parse anchor points str to real valued wavenumbers and confine energy range :return: None """ anchor_idx = [] for entry in anchors.split(','): try: anchor_idx.append(val2ind(int(entry.strip()), self.wavenumbers)) except: continue anchor_idx = sorted(anchor_idx) self.energy = self.wavenumbers[anchor_idx[0]: anchor_idx[-1] + 1] self.specTrim = self.spectrum[anchor_idx[0]: anchor_idx[-1] + 1] self.wav_anchor = self.wavenumbers[anchor_idx] self.spec_anchor = self.spectrum[anchor_idx] return None
def plot(self, x, y, *args, **kwargs): # set up infinity line and get its position plot_item = self.plotItem.plot(x, y, *args, **kwargs) self.addItem(self.line) self.addItem(self.cross) x_val = self.line.value() idx = val2ind(x_val, x) x_val = x[idx] y_val = y[idx] txt_html = toHtml(f'X = {x_val: .2f}, Y = {y_val: .4f}') self.txt = TextItem(html=txt_html, anchor=(0, 0)) self.txt.setZValue(self.zmax - 1) self.cross.setData([x_val], [y_val]) self.cross.setZValue(self.zmax) ymax = np.max(y) if ymax > self.ymax: self.ymax = ymax self._x, self._y = x, y r = self.txtPosRatio self.txt.setPos(r * x[-1] + (1 - r) * x[0], self.ymax) return plot_item
def plot(self, x, y, *args, **kwargs): # set up infinity line and get its position plot_item = self.plotItem.plot(x, y, *args, **kwargs) self.addItem(self.line) self.addItem(self.cross) x_val = self.line.value() idx = val2ind(x_val, x) x_val = x[idx] y_val = y[idx] txt_html = f'<div style="text-align: center"><span style="color: #FFF; font-size: 12pt">\ X = {x_val: .2f}, Y = {y_val: .4f}</div>' self.txt.setHtml(txt_html) self.txt.setZValue(self.zmax - 1) self.cross.setData([x_val], [y_val]) self.cross.setZValue(self.zmax) ymax = max(y) if ymax > self.ymax: self.ymax = ymax self._x, self._y = x, y r = self.txtPosRatio self.txt.setPos(r * x[-1] + (1 - r) * x[0], self.ymax) self.addItem(self.txt) return plot_item
def makeMask(self, thresholds): peak1550 = val2ind(1550, self.wavenumbers) thr1550 = thresholds[0] mask = self._data[peak1550] > thr1550 mask = mask.astype(np.int) return mask
def setEnergy(self, lineobject): E = lineobject.value() # map E to index i = val2ind(E, self.wavenumbers) # print('E:', E, 'wav:', self.wavenumbers[i]) self.setCurrentIndex(i)
def computeEmbedding(self): # get current map idx if not self.isMapOpen(): return msg.showMessage('Compute embedding.') # Select wavenumber region wavROIList = [] for entry in self.parameter['Wavenumber Range'].split(','): try: wavROIList.append(val2ind(int(entry), self.wavenumbers)) except: continue if len(wavROIList) % 2 == 0: wavROIList = sorted(wavROIList) wavROIidx = [] for i in range(len(wavROIList) // 2): wavROIidx += list( range(wavROIList[2 * i], wavROIList[2 * i + 1] + 1)) else: msg.logMessage('"Wavenumber Range" values must be in pairs', msg.ERROR) MsgBox('Clustering computation aborted.', 'error') return self.wavenumbers_select = self.wavenumbers[wavROIidx] self.N_w = len(self.wavenumbers_select) # get current dataset if self.selectedPixels is None: n_spectra = len(self.data) self.dataset = np.zeros((n_spectra, self.N_w)) for i in range(n_spectra): self.dataset[i, :] = self.data[i][wavROIidx] else: n_spectra = len(self.selectedPixels) self.dataset = np.zeros((n_spectra, self.N_w)) for i in range(n_spectra): # i: ith selected pixel row_col = tuple(self.selectedPixels[i]) self.dataset[i, :] = self.data[self.rc2ind[row_col]][wavROIidx] # get parameters and compute embedding n_components = self.parameter['Components'] if self.parameter['Embedding'] == 'UMAP': n_neighbors = self.parameter['Neighbors'] metric = self.parameter['Metric'] min_dist = np.clip(self.parameter['Min Dist'], 0, 1) self.umap = UMAP(n_neighbors=n_neighbors, min_dist=min_dist, n_components=n_components, metric=metric, random_state=0) self.embedding = self.umap.fit_transform(self.dataset) elif self.parameter['Embedding'] == 'PCA': # normalize and mean center if self.parameter['Normalization'] == 'L1': # normalize data_norm = Normalizer(norm='l1').fit_transform(self.dataset) elif self.parameter['Normalization'] == 'L2': data_norm = Normalizer(norm='l2').fit_transform(self.dataset) else: data_norm = self.dataset # subtract mean data_centered = StandardScaler( with_std=False).fit_transform(data_norm) # Do PCA self.PCA = PCA(n_components=n_components) self.PCA.fit(data_centered) self.embedding = self.PCA.transform(data_centered) # save embedding to standardModelItem self.item.embedding = self.embedding # update cluster map self.computeCluster()
def calculate(self): N = self.parameter['Components'] #set decompose method if self.parameter['Method'] == 'PCA': self.method = 'PCA' self.field = 'spectra' elif self.parameter['Method'] == 'NMF': self.method = 'NMF' self.field = 'volume' elif self.parameter['Method'] == 'MCR': self.method = 'MCR' self.field = 'spectra' if hasattr(self, '_dataSets'): wavROIList = [] for entry in self.parameter['Wavenumber Range'].split(','): try: wavROIList.append(val2ind(int(entry), self.wavenumbers)) except: continue # Select wavenumber region if len(wavROIList) % 2 == 0: wavROIList = sorted(wavROIList) wavROIidx = [] for i in range(len(wavROIList) // 2): wavROIidx += list( range(wavROIList[2 * i], wavROIList[2 * i + 1] + 1)) else: msg.logMessage('"Wavenumber Range" values must be in pairs', msg.ERROR) MsgBox('Factorization computation aborted.', 'error') return self.wavenumbers_select = self.wavenumbers[wavROIidx] # get map ROI selected region self.selectedPixelsList = [ self.headermodel.item(i).selectedPixels for i in range(self.headermodel.rowCount()) ] self.df_row_idx = [] # row index for dataframe data_fac msg.showMessage('Start computing', self.method + '. Image shape:', str(self.imgShapes)) self.dataRowSplit = [ 0 ] # remember the starting/end row positions of each dataset if self.field == 'spectra': # PCA workflow self.N_w = len(self.wavenumbers_select) self._allData = np.empty((0, self.N_w)) for i, data in enumerate( self._dataSets['spectra']): # i: map idx if self.selectedPixelsList[i] is None: n_spectra = len(data) tmp = np.zeros((n_spectra, self.N_w)) for j in range(n_spectra): tmp[j, :] = data[j][wavROIidx] self.df_row_idx.append((self.ind2rcList[i][j], j)) else: n_spectra = len(self.selectedPixelsList[i]) tmp = np.zeros((n_spectra, self.N_w)) for j in range(n_spectra): # j: jth selected pixel row_col = tuple(self.selectedPixelsList[i][j]) tmp[j, :] = data[self.rc2indList[i] [row_col]][wavROIidx] self.df_row_idx.append( (row_col, self.rc2indList[i][row_col])) self.dataRowSplit.append(self.dataRowSplit[-1] + n_spectra) self._allData = np.append(self._allData, tmp, axis=0) if len(self._allData) > 0: if self.method == 'PCA': self.data_fac_name = 'data_PCA' # define pop up plots labels # normalize and mean center if self.parameter[ 'Normalization'] == 'L1': # normalize data_norm = Normalizer(norm='l1').fit_transform( self._allData) elif self.parameter['Normalization'] == 'L2': data_norm = Normalizer(norm='l2').fit_transform( self._allData) else: data_norm = self._allData #subtract mean data_centered = StandardScaler( with_std=False).fit_transform(data_norm) # Do PCA self.PCA = PCA(n_components=N) self.PCA.fit(data_centered) self.data_PCA = self.PCA.transform(data_centered) # pop up plots self.popup_plots() elif self.method == 'MCR': self.data_fac_name = 'data_MCR' # define pop up plots labels # Do ICA to find initial estimate of ST matrix self.ICA = FastICA(n_components=N) self.ICA.fit(self._allData) # Do MCR self.MCR = McrAR(max_iter=100, c_regr=self.parameter['C regressor'], st_regr='NNLS', tol_err_change=1e-6, tol_increase=0.5) self.MCR.fit(self._allData, ST=self.ICA.components_) self.MCR.components_ = self.MCR.ST_opt_ self.data_MCR = self.MCR.C_opt_ #test ICA # self.MCR = self.ICA # self.data_MCR = self.ICA.transform(self._allData) # pop up plots self.popup_plots() else: msg.logMessage( 'The data matrix is empty. No PCA is performed.', msg.ERROR) MsgBox('The data matrix is empty. No PCA is performed.', 'error') self.PCA, self.data_PCA = None, None self.MCR, self.data_MCR = None, None # emit PCA and transformed data if self.method == 'PCA': self.sigPCA.emit((self.wavenumbers_select, self.PCA, self.data_PCA, self.dataRowSplit)) elif self.method == 'MCR': self.sigPCA.emit((self.wavenumbers_select, self.MCR, self.data_MCR, self.dataRowSplit)) elif self.field == 'volume': # NMF workflow data_files = [] wav_masks = [] row_idx = np.array([], dtype='int') self.allDataRowSplit = [0] # row split for complete datasets for i, file in enumerate(self._dataSets['volume']): ir_data, fmt = read_map.read_all_formats(file) n_spectra = ir_data.data.shape[0] self.allDataRowSplit.append(self.allDataRowSplit[-1] + n_spectra) data_files.append(ir_data) ds = data_prep.data_prepper(ir_data) wav_masks.append(ds.decent_bands) # row selection if self.selectedPixelsList[i] is None: row_idx = np.append( row_idx, np.arange(self.allDataRowSplit[-2], self.allDataRowSplit[-1])) for k, v in self.rc2indList[i].items(): self.df_row_idx.append((k, v)) else: n_spectra = len(self.selectedPixelsList[i]) for j in range(n_spectra): row_col = tuple(self.selectedPixelsList[i][j]) row_idx = np.append( row_idx, self.allDataRowSplit[-2] + self.rc2indList[i][row_col]) self.df_row_idx.append( (row_col, self.rc2indList[i][row_col])) self.dataRowSplit.append( self.dataRowSplit[-1] + n_spectra) # row split for ROI selected rows # define pop up plots labels self.data_fac_name = 'data_NMF' if len(self.df_row_idx) > 0: # aggregate datasets ir_data_agg = aggregate_data(self._dataSets['volume'], data_files, wav_masks) col_idx = list( set(wavROIidx) & set(ir_data_agg.master_wmask)) self.wavenumbers_select = self.wavenumbers[col_idx] ir_data_agg.data = ir_data_agg.data[:, col_idx] ir_data_agg.data = ir_data_agg.data[row_idx, :] # perform NMF self.NMF = NMF(n_components=N) self.data_NMF = self.NMF.fit_transform(ir_data_agg.data) # pop up plots self.popup_plots() else: msg.logMessage( 'The data matrix is empty. No NMF is performed.', msg.ERROR) MsgBox('The data matrix is empty. No NMF is performed.', 'error') self.NMF, self.data_NMF = None, None # emit NMF and transformed data : data_NMF self.sigPCA.emit((self.wavenumbers_select, self.NMF, self.data_NMF, self.dataRowSplit))
def setEnergy(self, lineobject): E = lineobject.value() # map E to index idx = val2ind(E, self.wavenumbers) self._image = self._data[idx] self.setCurrentIndex(idx)