def write_parameters(self): if self.entry.nxfilemode == 'r': display_message("NeXus file opened as readonly") return elif ('nxrefine' in self.entry or 'orientation_matrix' in self.entry['instrument/detector']): if not self.confirm_action('Overwrite existing refinement?'): return self.transfer_parameters() polar_angles, azimuthal_angles = self.refine.calculate_angles( self.refine.xp, self.refine.yp) self.refine.write_angles(polar_angles, azimuthal_angles) self.refine.write_parameters() reduce = NXReduce(self.entry) reduce.record_start('nxrefine') reduce.record('nxrefine', fit_report='\n'.join(self.fit_report)) reduce.logger.info('Orientation refined in NeXpy') reduce.record_end('nxrefine') root = self.entry.nxroot entries = [ entry for entry in root.entries if entry != 'entry' and entry != self.entry.nxname ] if entries and self.confirm_action( f'Copy orientation to other entries? ({", ".join(entries)})', answer='yes'): om = self.entry['instrument/detector/orientation_matrix'] for entry in entries: root[entry]['instrument/detector/orientation_matrix'] = om self.define_data() if len(self.paths) > 0: self.update_scaling()
class FindDialog(NXDialog): def __init__(self, parent=None): super().__init__(parent) self.select_entry(self.choose_entry) default = NXSettings().settings['nxreduce'] self.parameters = GridParameters() self.parameters.add('threshold', default['threshold'], 'Threshold') self.parameters.add('first', default['first'], 'First Frame') self.parameters.add('last', default['last'], 'Last Frame') self.parameters.add('min_pixels', default['min_pixels'], 'Minimum Pixels in Peak') self.parameters.grid() self.find_button = NXPushButton('Find Peaks', self.find_peaks) self.find_layout = self.make_layout(self.action_buttons( ('Find Peaks', self.find_peaks), ('List Peaks', self.list_peaks)), align='center') self.set_layout(self.entry_layout, self.close_layout(save=True, progress=True)) self.set_title('Find Peaks') self.reduce = None self.refine = None self.peaks_box = None def choose_entry(self): if self.layout.count() == 2: self.insert_layout(1, self.parameters.grid_layout) self.insert_layout(2, self.find_layout) self.reduce = NXReduce(self.entry) self.refine = NXRefine(self.entry) self.refine.polar_max = self.refine.two_theta_max() if self.reduce.first is not None: self.parameters['first'].value = self.reduce.first if self.reduce.last: self.parameters['last'].value = self.reduce.last else: try: self.parameters['last'].value = self.reduce.shape[0] except Exception: pass self.parameters['threshold'].value = self.reduce.threshold @property def threshold(self): try: return int(self.parameters['threshold'].value) except Exception as error: report_error("Finding Peaks", error) @property def first(self): try: return int(self.parameters['first'].value) except Exception as error: report_error("Finding Peaks", error) @property def last(self): try: return int(self.parameters['last'].value) except Exception as error: report_error("Finding Peaks", error) @property def min_pixels(self): try: return int(self.parameters['min_pixels'].value) except Exception as error: report_error("Finding Peaks", error) def find_peaks(self): if is_file_locked(self.reduce.data_file): return self.start_thread() self.reduce = NXReduce(self.entry, threshold=self.threshold, first=self.first, last=self.last, min_pixels=self.min_pixels, find=True, overwrite=True, gui=True) self.reduce.moveToThread(self.thread) self.reduce.start.connect(self.start_progress) self.reduce.update.connect(self.update_progress) self.reduce.result.connect(self.get_peaks) self.reduce.stop.connect(self.stop) self.thread.started.connect(self.reduce.nxfind) self.thread.start() def get_peaks(self, peaks): self.peaks = peaks self.status_message.setText(f'{len(self.peaks)} peaks found') self.status_message.setVisible(True) self.refine.xp = np.array([peak.x for peak in peaks]) self.refine.yp = np.array([peak.y for peak in peaks]) self.refine.zp = np.array([peak.z for peak in peaks]) self.refine.intensity = np.array([peak.intensity for peak in peaks]) self.refine.polar_angle, self.refine.azimuthal_angle = ( self.refine.calculate_angles(self.refine.xp, self.refine.yp)) self.update_table() def stop(self): self.stop_progress() if self.thread and self.thread.isRunning(): self.reduce.stopped = True self.stop_thread() def list_peaks(self): if self.peaks_box in self.mainwindow.dialogs: self.update_table() return self.peaks_box = NXDialog(self) self.peaks_box.setMinimumWidth(600) self.peaks_box.setMinimumHeight(600) header = [ 'i', 'x', 'y', 'z', 'Polar', 'Azi', 'Intensity', 'H', 'K', 'L', 'Diff' ] peak_list = self.refine.get_peaks() self.table_view = QtWidgets.QTableView() self.table_model = NXTableModel(self, peak_list, header) self.table_view.setModel(self.table_model) self.table_view.resizeColumnsToContents() self.table_view.horizontalHeader().stretchLastSection() self.table_view.setSelectionBehavior( QtWidgets.QAbstractItemView.SelectRows) self.table_view.doubleClicked.connect(self.plot_peak) self.table_view.setSortingEnabled(True) self.table_view.sortByColumn(0, QtCore.Qt.AscendingOrder) self.peaks_box.set_layout(self.table_view, self.close_buttons(close=True)) self.peaks_box.set_title(f'{self.refine.name} Peak Table') self.peaks_box.adjustSize() self.peaks_box.show() self.plotview = None def update_table(self): if self.peaks_box not in self.mainwindow.dialogs: return elif self.table_model is None: self.close_peaks_box() self.list_peaks() self.table_model.peak_list = self.refine.get_peaks() rows, columns = len(self.table_model.peak_list), 11 self.table_model.dataChanged.emit( self.table_model.createIndex(0, 0), self.table_model.createIndex(rows - 1, columns - 1)) self.table_view.resizeColumnsToContents() self.peaks_box.set_title(f'{self.refine.name} Peak Table') self.peaks_box.adjustSize() self.peaks_box.setVisible(True) def plot_peak(self): row = self.table_view.currentIndex().row() data = self.entry.data i, x, y, z = [ self.table_view.model().peak_list[row][i] for i in range(4) ] signal = data.nxsignal xmin, xmax = max(0, x - 200), min(x + 200, signal.shape[2]) ymin, ymax = max(0, y - 200), min(y + 200, signal.shape[1]) zmin, zmax = max(0, z - 20), min(z + 20, signal.shape[0]) zslab = np.s_[zmin:zmax, ymin:ymax, xmin:xmax] if 'Peak Plot' in self.plotviews: self.plotview = self.plotviews['Peak Plot'] else: self.plotview = NXPlotView('Peak Plot') self.plotview.plot(data[zslab], log=True) self.plotview.ax.set_title(f'{data.nxtitle}: Peak {i}') self.plotview.ztab.maxbox.setValue(z) self.plotview.aspect = 'equal' self.plotview.crosshairs(x, y, color='r', linewidth=0.5) def close_peaks_box(self): try: self.peaks_box.close() except Exception: pass self.peaks_box = None def accept(self): try: self.reduce.write_peaks(self.peaks) self.reduce.record('nxfind', threshold=self.threshold, first_frame=self.first, last_frame=self.last, min_pixels=self.min_pixels, peak_number=len(self.peaks)) self.reduce.record_end('nxfind') super().accept() except Exception as error: report_error("Finding Peaks", error) def reject(self): self.stop() super().reject()
class PrepareDialog(NXDialog): def __init__(self, parent=None): super().__init__(parent) self.select_entry(self.choose_entry) default = NXSettings().settings['nxreduce'] self.parameters = GridParameters() self.parameters.add('first', default['first'], 'First Frame') self.parameters.add('last', default['last'], 'Last Frame') self.parameters.add('threshold1', '2', 'Threshold 1') self.parameters.add('horizontal1', '11', 'Horizontal Size 1') self.parameters.add('threshold2', '0.8', 'Threshold 2') self.parameters.add('horizontal2', '51', 'Horizontal Size 2') self.parameters.grid() self.prepare_button = NXPushButton('Prepare Mask', self.prepare_mask) self.plot_button = NXPushButton('Plot Mask', self.plot_mask) self.prepare_layout = self.make_layout(self.prepare_button, self.plot_button, align='center') self.plot_button.setVisible(False) self.set_layout(self.entry_layout, self.close_layout(save=True, progress=True)) self.set_title('Prepare 3D Mask') self.reduce = None self.mask = None self.plotview = None def choose_entry(self): if self.layout.count() == 2: self.insert_layout(1, self.parameters.grid_layout) self.insert_layout(2, self.prepare_layout) self.reduce = NXReduce(self.entry) self.parameters['first'].value = self.reduce.first self.parameters['last'].value = self.reduce.last @property def first(self): try: return int(self.parameters['first'].value) except Exception as error: report_error("Preparing Mask", error) @property def last(self): try: return int(self.parameters['last'].value) except Exception as error: report_error("Preparing Mask", error) @property def threshold1(self): try: return float(self.parameters['threshold1'].value) except Exception as error: report_error("Preparing Mask", error) @property def horizontal1(self): try: return int(self.parameters['horizontal1'].value) except Exception as error: report_error("Preparing Mask", error) @property def threshold2(self): try: return float(self.parameters['threshold2'].value) except Exception as error: report_error("Preparing Mask", error) @property def horizontal2(self): try: return int(self.parameters['horizontal2'].value) except Exception as error: report_error("Preparing Mask", error) def prepare_mask(self): if is_file_locked(self.reduce.data_file): return self.start_thread() self.reduce = NXReduce(self.entry, prepare=True, first=self.first, last=self.last, overwrite=True, gui=True) self.reduce.mask_parameters['threshold_1'] = self.threshold1 self.reduce.mask_parameters['threshold_1'] = self.threshold1 self.reduce.mask_parameters['horizontal_size_1'] = self.horizontal1 self.reduce.mask_parameters['threshold_2'] = self.threshold2 self.reduce.mask_parameters['horizontal_size_2'] = self.horizontal2 self.reduce.moveToThread(self.thread) self.reduce.start.connect(self.start_progress) self.reduce.update.connect(self.update_progress) self.reduce.result.connect(self.get_mask) self.reduce.stop.connect(self.stop) self.thread.started.connect(self.reduce.nxprepare) self.thread.start() def get_mask(self, mask): self.mask = mask self.status_message.setText("Mask complete") self.status_message.setVisible(True) self.plot_button.setVisible(True) def plot_mask(self): self.plotview = NXPlotView('3D Mask') self.plotview.plot( NXdata(self.mask, self.reduce.data.nxaxes, title=f"3D Mask: {self.reduce.name}")) def stop(self): self.stop_progress() if self.thread and self.thread.isRunning(): self.reduce.stopped = True self.stop_thread() def accept(self): try: if self.mask is None: raise NeXusError("No mask has been created") elif self.entry.nxfilemode == 'r': raise NeXusError("NeXus file opened as readonly") self.reduce.write_mask(self.mask) self.reduce.record('nxprepare', masked_file=self.reduce.mask_file, threshold1=self.threshold1, horizontal1=self.horizontal1, threshold2=self.threshold2, horizontal2=self.horizontal2, process='nxprepare_mask') self.reduce.record_end('nxprepare') super().accept() except Exception as error: report_error("Preparing Mask", error) def reject(self): self.stop() super().reject()
class MaximumDialog(NXDialog): def __init__(self, parent=None): super().__init__(parent) self.select_entry(self.choose_entry) self.parameters = GridParameters() self.parameters.add('first', '', 'First Frame') self.parameters.add('last', '', 'Last Frame') self.output = NXLabel('Maximum Value:') self.set_layout( self.entry_layout, self.output, self.parameters.grid(), self.action_buttons(('Find Maximum', self.find_maximum)), self.progress_layout(save=True)) self.progress_bar.setVisible(False) self.progress_bar.setValue(0) self.set_title('Find Maximum Value') self.reduce = None def choose_entry(self): self.reduce = NXReduce(self.entry) self.maximum = self.reduce.maximum if self.reduce.first: self.parameters['first'].value = self.reduce.first if self.reduce.last: self.parameters['last'].value = self.reduce.last @property def first(self): try: _first = np.int32(self.parameters['first'].value) if _first >= 0: return _first else: return None except Exception as error: return None @property def last(self): try: _last = np.int32(self.parameters['last'].value) if _last > 0: return _last else: return None except Exception as error: return None @property def maximum(self): return np.float(self.output.text().split()[-1]) @maximum.setter def maximum(self, value): self.output.setText(f'Maximum Value: {value}') def find_maximum(self): if is_file_locked(self.reduce.data_file): return self.start_thread() self.reduce = NXReduce(self.entry, first=self.first, last=self.last, maxcount=True, overwrite=True, gui=True) self.reduce.moveToThread(self.thread) self.reduce.start.connect(self.start_progress) self.reduce.update.connect(self.update_progress) self.reduce.result.connect(self.get_maximum) self.reduce.stop.connect(self.stop) self.thread.started.connect(self.reduce.nxmax) self.thread.finished.connect(self.stop) self.thread.start(QtCore.QThread.LowestPriority) def get_maximum(self, maximum): self.maximum = maximum def stop(self): self.stop_progress() if self.thread and self.thread.isRunning(): self.reduce.stopped = True self.stop_thread() def accept(self): try: self.reduce.write_maximum(self.maximum) self.reduce.record('nxmax', maximum=self.maximum, first_frame=self.first, last_frame=self.last) self.reduce.record_end('nxmax') self.stop() super().accept() except Exception as error: report_error("Finding Maximum", error) def reject(self): self.stop() super().reject()