class MakeDialog(BaseDialog): def __init__(self, parent=None): super(MakeDialog, self).__init__(parent) self.scans = None self.set_layout( self.directorybox("Choose Sample Directory", self.choose_sample), self.textboxes(('Scan Command', 'Pil2Mscan')), self.action_buttons(('Select All', self.select_scans), ('Reverse All', self.reverse_scans), ('Clear All', self.clear_scans), ('Make Scan Macro', self.make_scans)), self.close_buttons(close=True)) self.set_title('Make Scans') def choose_sample(self): super(MakeDialog, self).choose_directory() self.sample_directory = self.get_directory() self.experiment_directory = os.path.dirname( os.path.dirname(self.sample_directory)) self.macro_directory = os.path.join(self.experiment_directory, 'macros') self.label = os.path.basename(self.sample_directory) self.sample = os.path.basename(os.path.dirname(self.sample_directory)) self.experiment = os.path.basename(self.experiment_directory) self.experiment_path = self.experiment self.scan_path = os.path.join(self.experiment, self.sample, self.label) self.setup_scans() def setup_scans(self): if self.scans: self.scans.delete_grid() self.scans = GridParameters() all_files = [ self.sample + '_' + d + '.nxs' for d in os.listdir(self.sample_directory) if os.path.isdir(os.path.join(self.sample_directory, d)) ] filenames = sorted([ f for f in all_files if os.path.exists(os.path.join(self.sample_directory, f)) ], key=natural_sort) for i, f in enumerate(filenames): scan = 'f%d' % i self.scans.add(scan, i + 1, f, True, self.update_scans) self.scans[scan].checkbox.stateChanged.connect(self.update_scans) self.insert_layout(2, self.scans.grid(header=False)) @property def scan_list(self): scan_list = [] for scan in self.scans.values(): if scan.checkbox.isChecked() and scan.value > 0: scan_list.append(scan) else: scan.value = 0 return sorted(scan_list, key=attrgetter('value')) def update_scans(self): scan_list = self.scan_list scan_number = 0 for scan in scan_list: scan_number += 1 scan.value = scan_number for scan in self.scans.values(): if scan.checkbox.isChecked() and scan.value == 0: scan.value = scan_number + 1 scan_number += 1 def select_scans(self): for i, scan in enumerate(self.scans): self.scans[scan].value = i + 1 self.scans[scan].checkbox.setChecked(True) def reverse_scans(self): for i, scan in enumerate(reversed(self.scan_list)): scan.value = i + 1 scan.checkbox.setChecked(True) def clear_scans(self): for scan in self.scans: self.scans[scan].value = 0 self.scans[scan].checkbox.setChecked(False) def make_scans(self): scans = [scan.label.text() for scan in self.scan_list] scan_command = self.textbox['Scan Command'].text() scan_parameters = [ '#command path filename temperature detx dety ' + 'phi_start phi_step phi_end chi omega frame_rate' ] for scan in self.scan_list: nexus_file = scan.label.text() root = nxload(os.path.join(self.sample_directory, nexus_file)) temperature = root.entry.sample.temperature base_name = os.path.basename(os.path.splitext(nexus_file)[0]) scan_dir = base_name.replace(self.sample + '_', '') for entry in [root[e] for e in root if e != 'entry']: if 'phi_set' in entry['instrument/goniometer']: phi_start = entry['instrument/goniometer/phi_set'] else: phi_start = entry['instrument/goniometer/phi'] phi_step = entry['instrument/goniometer/phi'].attrs['step'] phi_end = entry['instrument/goniometer/phi'].attrs['end'] if 'chi_set' in entry['instrument/goniometer']: chi = entry['instrument/goniometer/chi_set'] else: chi = entry['instrument/goniometer/chi'] if 'omega_set' in entry['instrument/goniometer']: omega = entry['instrument/goniometer/omega_set'] else: omega = entry['instrument/goniometer/omega'] dx = entry['instrument/detector/translation_x'] dy = entry['instrument/detector/translation_y'] if ('frame_time' in entry['instrument/detector'] and entry['instrument/detector/frame_time'] > 0.0): frame_rate = 1.0 / entry['instrument/detector/frame_time'] else: frame_rate = 10.0 scan_file = entry.nxname if scan_command == 'Pil2Mscan': scan_parameters.append( '%s %s %s %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g' % (scan_command, os.path.join(self.scan_path, scan_dir), scan_file, temperature, dx, dy, phi_start, phi_step, phi_end, chi, omega, frame_rate)) if scan_command == 'Pil2Mstring': scan_parameters.append('Pil2Mstring("%s")' % scan_dir) elif scan_command != 'Pil2Mscan': scan_parameters.append('%s %s' % (scan_command, temperature)) if not os.path.exists(self.macro_directory): os.mkdir(os.path.join(self.experiment_directory, 'macros')) macro_filter = ';;'.join(("SPEC Macro (*.mac)", "Any Files (*.* *)")) macro = getSaveFileName(self, 'Open Macro', self.macro_directory, macro_filter) if macro: with open(macro, 'w') as f: f.write('\n'.join(scan_parameters))
class OrientationDialog(BaseDialog): def __init__(self, parent=None): super(OrientationDialog, self).__init__(parent) self.select_entry(self.choose_entry) self.refine = NXRefine(self.entry) self.refine.read_parameters() self.parameters = GridParameters() self.parameters.add('phi_start', self.refine.phi, 'Phi Start (deg)') self.parameters.add('phi_step', self.refine.phi_step, 'Phi Step (deg)') self.parameters.add('chi', self.refine.chi, 'Chi (deg)') self.parameters.add('omega', self.refine.omega, 'Omega (deg)') self.parameters.add('polar', self.refine.polar_max, 'Max. Polar Angle (deg)') self.parameters.add('polar_tolerance', self.refine.polar_tolerance, 'Polar Angle Tolerance') self.parameters.add('peak_tolerance', self.refine.peak_tolerance, 'Peak Angle Tolerance') action_buttons = self.action_buttons( ('Generate Grains', self.generate_grains), ('List Peaks', self.list_peaks)) self.grain_layout = QtWidgets.QHBoxLayout() self.grain_combo = QtWidgets.QComboBox() self.grain_combo.setSizeAdjustPolicy( QtWidgets.QComboBox.AdjustToContents) self.grain_combo.currentIndexChanged.connect(self.set_grain) self.grain_textbox = QtWidgets.QLabel() self.grain_layout.addWidget(self.grain_combo) self.grain_layout.addStretch() self.grain_layout.addWidget(self.grain_textbox) bottom_layout = QtWidgets.QHBoxLayout() self.result_textbox = QtWidgets.QLabel() bottom_layout.addWidget(self.result_textbox) bottom_layout.addStretch() bottom_layout.addWidget(self.close_buttons()) self.set_layout(self.entry_layout, self.parameters.grid(), action_buttons, bottom_layout) self.set_title('Defining Orientation') def choose_entry(self): self.refine = NXRefine(self.entry) self.update_parameters() def update_parameters(self): self.parameters['phi_start'].value = self.refine.phi self.parameters['phi_step'].value = self.refine.phi_step self.parameters['chi'].value = self.refine.chi self.parameters['omega'].value = self.refine.omega self.parameters['polar'].value = self.refine.polar_max self.parameters['polar_tolerance'].value = self.refine.polar_tolerance self.parameters['peak_tolerance'].value = self.refine.peak_tolerance def get_phi(self): return (self.parameters['phi_start'].value, self.parameters['phi_step'].value) def set_phi(self): self.refine.phi_start, self.refine.phi_step = self.get_phi() def get_chi(self): return self.parameters['chi'].value def set_chi(self): self.refine.chi = self.get_chi() def get_omega(self): return self.parameters['omega'].value def set_omega(self): self.refine.omega = self.get_omega() @property def polar_max(self): return self.parameters['polar'].value def set_polar_max(self): self.refine.polar_max = self.polar_max def get_polar_tolerance(self): return self.parameters['polar_tolerance'].value def set_polar_tolerance(self): self.refine.polar_tolerance = self.get_polar_tolerance() def get_peak_tolerance(self): return self.parameters['peak_tolerance'].value def set_peak_tolerance(self): self.refine.peak_tolerance = self.get_peak_tolerance() def generate_grains(self): self.set_polar_max() self.refine.generate_grains() if self.refine.grains is not None: self.layout.insertLayout(2, self.grain_layout) self.grain_combo.clear() for i in range(len(self.refine.grains)): self.grain_combo.addItem('Grain %s' % i) self.grain_combo.setCurrentIndex(0) self.set_grain() def set_grain(self): try: grain = self.refine.grains[self.get_grain()] self.grain_textbox.setText('%s peaks; Score: %.4f' % (len(grain), grain.score)) self.refine.Umat = grain.Umat self.refine.primary = grain.primary self.refine.secondary = grain.secondary self.get_score() except: self.grain_textbox.setText('') def get_grain(self): return int(self.grain_combo.currentText().split()[-1]) def list_peaks(self): self.refine.phi = self.get_phi() self.refine.chi = self.get_chi() self.refine.omega = self.get_omega() if self.refine.grains is not None: grain = self.refine.grains[self.get_grain()] self.refine.Umat = grain.Umat self.list_orientations() else: self.list_orientations() def get_score(self): if self.refine.Umat is not None: self.score = self.refine.score() self.result_textbox.setText('%s peaks; Score: %.4f' % (len(self.refine.idx), self.score)) def list_orientations(self): message_box = BaseDialog(self) message_box.setMinimumWidth(600) message_box.setMinimumHeight(600) header = [ 'i', 'x', 'y', 'z', 'Polar', 'Azi', 'Intensity', 'H', 'K', 'L', 'Diff' ] peak_list = self.refine.get_peaks() self.refine.assign_rings() self.rings = self.refine.get_ring_hkls() orient_layout = QtWidgets.QHBoxLayout() if self.refine.primary is None: self.refine.primary = 0 if self.refine.secondary is None: self.refine.secondary = 1 self.primary_box = QtWidgets.QLineEdit(str(self.refine.primary)) self.primary_box.setAlignment(QtCore.Qt.AlignRight) self.primary_box.setFixedWidth(80) self.secondary_box = QtWidgets.QLineEdit(str(self.refine.secondary)) self.secondary_box.setAlignment(QtCore.Qt.AlignRight) self.secondary_box.setFixedWidth(80) orient_button = QtWidgets.QPushButton('Orient') orient_button.clicked.connect(self.orient) refine_button = QtWidgets.QPushButton('Refine') refine_button.clicked.connect(self.refine_orientation) restore_button = QtWidgets.QPushButton('Restore') restore_button.clicked.connect(self.restore_orientation) orient_layout.addStretch() orient_layout.addWidget(QtWidgets.QLabel('Primary')) orient_layout.addWidget(self.primary_box) orient_layout.addWidget(QtWidgets.QLabel('Secondary')) orient_layout.addWidget(self.secondary_box) orient_layout.addStretch() orient_layout.addWidget(orient_button) orient_layout.addWidget(refine_button) orient_layout.addWidget(restore_button) grid = QtWidgets.QGridLayout() grid.setSpacing(10) self.lattice = GridParameters() self.lattice.add('a', self.refine.a, 'a', False) self.lattice.add('b', self.refine.b, 'b', False) self.lattice.add('c', self.refine.c, 'c', False) self.lattice.add('alpha', self.refine.alpha, 'alpha', False) self.lattice.add('beta', self.refine.beta, 'beta', False) self.lattice.add('gamma', self.refine.gamma, 'gamma', False) p = self.lattice['a'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 0, 0, QtCore.Qt.AlignRight) grid.addWidget(p.box, 0, 1, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 0, 2, QtCore.Qt.AlignHCenter) p = self.lattice['b'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 0, 3, QtCore.Qt.AlignRight) grid.addWidget(p.box, 0, 4, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 0, 5, QtCore.Qt.AlignHCenter) p = self.lattice['c'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 0, 6, QtCore.Qt.AlignRight) grid.addWidget(p.box, 0, 7, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 0, 8, QtCore.Qt.AlignHCenter) p = self.lattice['alpha'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 1, 0, QtCore.Qt.AlignRight) grid.addWidget(p.box, 1, 1, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 1, 2, QtCore.Qt.AlignHCenter) p = self.lattice['beta'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 1, 3, QtCore.Qt.AlignRight) grid.addWidget(p.box, 1, 4, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 1, 5, QtCore.Qt.AlignHCenter) p = self.lattice['gamma'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 1, 6, QtCore.Qt.AlignRight) grid.addWidget(p.box, 1, 7, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 1, 8, QtCore.Qt.AlignHCenter) 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) layout = QtWidgets.QVBoxLayout() layout.addLayout(orient_layout) layout.addLayout(grid) layout.addWidget(self.table_view) close_layout = QtWidgets.QHBoxLayout() self.status_text = QtWidgets.QLabel('Score: %.4f' % self.refine.score()) self.tolerance_box = QtWidgets.QLineEdit(str( self.refine.hkl_tolerance)) self.tolerance_box.setAlignment(QtCore.Qt.AlignRight) self.tolerance_box.setMaxLength(5) self.tolerance_box.editingFinished.connect(self.update_table) self.tolerance_box.setFixedWidth(80) save_button = QtWidgets.QPushButton('Save Orientation') save_button.clicked.connect(self.save_orientation) close_button = QtWidgets.QPushButton('Close Window') close_button.clicked.connect(message_box.close) close_layout.addWidget(self.status_text) close_layout.addStretch() close_layout.addWidget(QtWidgets.QLabel('Threshold')) close_layout.addWidget(self.tolerance_box) close_layout.addStretch() close_layout.addWidget(save_button) close_layout.addStretch() close_layout.addWidget(close_button) layout.addLayout(close_layout) message_box.setLayout(layout) message_box.setWindowTitle('%s Peak Table' % self.entry.nxtitle) message_box.adjustSize() message_box.show() self.plotview = None def plot_peak(self): row = self.table_view.currentIndex().row() data = self.entry.data x, y, z = [ self.table_view.model().peak_list[row][i] for i in range(1, 4) ] xmin, xmax = max(0, x - 200), min(x + 200, data.nxsignal.shape[2]) ymin, ymax = max(0, y - 200), min(y + 200, data.nxsignal.shape[1]) zmin, zmax = max(0, z - 200), min(z + 200, data.nxsignal.shape[0]) zslab = np.s_[z, ymin:ymax, xmin:xmax] if self.plotview is None: self.plotview = NXPlotView('X-Y Projection') self.plotview.plot(data[zslab], log=True) self.plotview.crosshairs(x, y) def orient(self): self.refine.primary = int(self.primary_box.text()) self.refine.secondary = int(self.secondary_box.text()) self.refine.Umat = self.refine.get_UBmat(self.refine.primary, self.refine.secondary) \ * self.refine.Bimat self.update_table() def refine_orientation(self): idx = self.refine.idx intensities = self.refine.intensity[idx] sigma = np.average(intensities) / intensities p0 = self.set_parameters(idx) def diffs(p): self.get_parameters(p) UBimat = np.linalg.inv(self.refine.UBmat) Q = [UBimat * self.Gvec[i] for i in idx] dQ = Q - np.rint(Q) return np.array([ np.linalg.norm(self.refine.Bmat * np.matrix(dQ[i])) for i in idx ]) / sigma popt, C, info, msg, success = leastsq(diffs, p0, full_output=1) self.get_parameters(popt) self.update_lattice() self.update_table() self.status_text.setText('Score: %.4f' % self.refine.score()) def restore_orientation(self): self.refine.Umat = self.Umat for par in self.lattice.values(): par.value = par.init_value self.update_table() def update_table(self): self.refine.hkl_tolerance = np.float32(self.tolerance_box.text()) 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.status_text.setText('Score: %.4f' % self.refine.score()) def update_lattice(self): self.lattice['a'].value = self.refine.a self.lattice['b'].value = self.refine.b self.lattice['c'].value = self.refine.c self.lattice['alpha'].value = self.refine.alpha self.lattice['beta'].value = self.refine.beta self.lattice['gamma'].value = self.refine.gamma def set_parameters(self, idx): x, y, z = self.refine.xp[idx], self.refine.yp[idx], self.refine.zp[idx] self.Gvec = [ self.refine.Gvec(xx, yy, zz) for xx, yy, zz in zip(x, y, z) ] self.Umat = self.refine.Umat pars = [] for par in self.lattice.values(): par.init_value = par.value if par.vary: pars.append(par.value) p0 = np.zeros(shape=(len(pars) + 9), dtype=np.float32) p0[:len(pars)] = pars p0[len(pars):] = np.ravel(self.refine.Umat) return p0 def get_parameters(self, p): i = 0 for par in self.lattice.values(): if par.vary: par.value = p[i] i += 1 self.refine.a, self.refine.b, self.refine.c, \ self.refine.alpha, self.refine.beta, self.refine.gamma = \ [par.value for par in self.lattice.values()] self.refine.set_symmetry() self.refine.Umat = np.matrix(p[i:]).reshape(3, 3) def save_orientation(self): self.write_parameters() def write_parameters(self): try: self.refine.write_parameters() except NeXusError as error: report_error('Defining Orientation', error)
class OrientationDialog(BaseDialog): def __init__(self, parent=None): super(OrientationDialog, self).__init__(parent) self.select_entry(self.choose_entry) self.refine = NXRefine(self.entry) self.refine.read_parameters() self.parameters = GridParameters() self.parameters.add('phi_start', self.refine.phi, 'Phi Start (deg)') self.parameters.add('phi_step', self.refine.phi_step, 'Phi Step (deg)') self.parameters.add('chi', self.refine.chi, 'Chi (deg)') self.parameters.add('omega', self.refine.omega, 'Omega (deg)') self.parameters.add('polar', self.refine.polar_max, 'Max. Polar Angle (deg)') self.parameters.add('polar_tolerance', self.refine.polar_tolerance, 'Polar Angle Tolerance') self.parameters.add('peak_tolerance', self.refine.peak_tolerance, 'Peak Angle Tolerance') action_buttons = self.action_buttons( ('Generate Grains', self.generate_grains), ('List Peaks', self.list_peaks)) self.grain_layout = QtWidgets.QHBoxLayout() self.grain_combo = QtWidgets.QComboBox() self.grain_combo.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents) self.grain_combo.currentIndexChanged.connect(self.set_grain) self.grain_textbox = QtWidgets.QLabel() self.grain_layout.addWidget(self.grain_combo) self.grain_layout.addStretch() self.grain_layout.addWidget(self.grain_textbox) bottom_layout = QtWidgets.QHBoxLayout() self.result_textbox = QtWidgets.QLabel() bottom_layout.addWidget(self.result_textbox) bottom_layout.addStretch() bottom_layout.addWidget(self.close_buttons()) self.set_layout(self.entry_layout, self.parameters.grid(), action_buttons, bottom_layout) self.set_title('Defining Orientation') def choose_entry(self): self.refine = NXRefine(self.entry) self.update_parameters() def update_parameters(self): self.parameters['phi_start'].value = self.refine.phi self.parameters['phi_step'].value = self.refine.phi_step self.parameters['chi'].value = self.refine.chi self.parameters['omega'].value = self.refine.omega self.parameters['polar'].value = self.refine.polar_max self.parameters['polar_tolerance'].value = self.refine.polar_tolerance self.parameters['peak_tolerance'].value = self.refine.peak_tolerance def get_phi(self): return (self.parameters['phi_start'].value, self.parameters['phi_step'].value) def set_phi(self): self.refine.phi_start, self.refine.phi_step = self.get_phi() def get_chi(self): return self.parameters['chi'].value def set_chi(self): self.refine.chi = self.get_chi() def get_omega(self): return self.parameters['omega'].value def set_omega(self): self.refine.omega = self.get_omega() @property def polar_max(self): return self.parameters['polar'].value def set_polar_max(self): self.refine.polar_max = self.polar_max def get_polar_tolerance(self): return self.parameters['polar_tolerance'].value def set_polar_tolerance(self): self.refine.polar_tolerance = self.get_polar_tolerance() def get_peak_tolerance(self): return self.parameters['peak_tolerance'].value def set_peak_tolerance(self): self.refine.peak_tolerance = self.get_peak_tolerance() def generate_grains(self): self.set_polar_max() self.refine.generate_grains() if self.refine.grains is not None: self.layout.insertLayout(2, self.grain_layout) self.grain_combo.clear() for i in range(len(self.refine.grains)): self.grain_combo.addItem('Grain %s' % i) self.grain_combo.setCurrentIndex(0) self.set_grain() def set_grain(self): try: grain = self.refine.grains[self.get_grain()] self.grain_textbox.setText('%s peaks; Score: %.4f' % (len(grain), grain.score)) self.refine.Umat = grain.Umat self.refine.primary = grain.primary self.refine.secondary = grain.secondary self.get_score() except: self.grain_textbox.setText('') def get_grain(self): return int(self.grain_combo.currentText().split()[-1]) def list_peaks(self): self.refine.phi = self.get_phi() self.refine.chi = self.get_chi() self.refine.omega = self.get_omega() if self.refine.grains is not None: grain = self.refine.grains[self.get_grain()] self.refine.Umat = grain.Umat self.list_orientations() else: self.list_orientations() def get_score(self): if self.refine.Umat is not None: self.score = self.refine.score() self.result_textbox.setText('%s peaks; Score: %.4f' % (len(self.refine.idx), self.score)) def list_orientations(self): message_box = BaseDialog(self) message_box.setMinimumWidth(600) message_box.setMinimumHeight(600) header = ['i', 'x', 'y', 'z', 'Polar', 'Azi', 'Intensity', 'H', 'K', 'L', 'Diff'] peak_list = self.refine.get_peaks() self.refine.assign_rings() self.rings = self.refine.get_ring_hkls() orient_layout = QtWidgets.QHBoxLayout() if self.refine.primary is None: self.refine.primary = 0 if self.refine.secondary is None: self.refine.secondary = 1 self.primary_box = QtWidgets.QLineEdit(str(self.refine.primary)) self.primary_box.setAlignment(QtCore.Qt.AlignRight) self.primary_box.setFixedWidth(80) self.secondary_box = QtWidgets.QLineEdit(str(self.refine.secondary)) self.secondary_box.setAlignment(QtCore.Qt.AlignRight) self.secondary_box.setFixedWidth(80) orient_button = QtWidgets.QPushButton('Orient') orient_button.clicked.connect(self.orient) refine_button = QtWidgets.QPushButton('Refine') refine_button.clicked.connect(self.refine_orientation) restore_button = QtWidgets.QPushButton('Restore') restore_button.clicked.connect(self.restore_orientation) orient_layout.addStretch() orient_layout.addWidget(QtWidgets.QLabel('Primary')) orient_layout.addWidget(self.primary_box) orient_layout.addWidget(QtWidgets.QLabel('Secondary')) orient_layout.addWidget(self.secondary_box) orient_layout.addStretch() orient_layout.addWidget(orient_button) orient_layout.addWidget(refine_button) orient_layout.addWidget(restore_button) grid = QtWidgets.QGridLayout() grid.setSpacing(10) self.lattice = GridParameters() self.lattice.add('a', self.refine.a, 'a', False) self.lattice.add('b', self.refine.b, 'b', False) self.lattice.add('c', self.refine.c, 'c', False) self.lattice.add('alpha', self.refine.alpha, 'alpha', False) self.lattice.add('beta', self.refine.beta, 'beta', False) self.lattice.add('gamma', self.refine.gamma, 'gamma', False) p = self.lattice['a'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 0, 0, QtCore.Qt.AlignRight) grid.addWidget(p.box, 0, 1, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 0, 2, QtCore.Qt.AlignHCenter) p = self.lattice['b'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 0, 3, QtCore.Qt.AlignRight) grid.addWidget(p.box, 0, 4, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 0, 5, QtCore.Qt.AlignHCenter) p = self.lattice['c'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 0, 6, QtCore.Qt.AlignRight) grid.addWidget(p.box, 0, 7, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 0, 8, QtCore.Qt.AlignHCenter) p = self.lattice['alpha'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 1, 0, QtCore.Qt.AlignRight) grid.addWidget(p.box, 1, 1, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 1, 2, QtCore.Qt.AlignHCenter) p = self.lattice['beta'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 1, 3, QtCore.Qt.AlignRight) grid.addWidget(p.box, 1, 4, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 1, 5, QtCore.Qt.AlignHCenter) p = self.lattice['gamma'] p.box.setFixedWidth(80) label, value, checkbox = p.label, p.value, p.vary grid.addWidget(p.label, 1, 6, QtCore.Qt.AlignRight) grid.addWidget(p.box, 1, 7, QtCore.Qt.AlignHCenter) grid.addWidget(p.checkbox, 1, 8, QtCore.Qt.AlignHCenter) 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) layout = QtWidgets.QVBoxLayout() layout.addLayout(orient_layout) layout.addLayout(grid) layout.addWidget(self.table_view) close_layout = QtWidgets.QHBoxLayout() self.status_text = QtWidgets.QLabel('Score: %.4f' % self.refine.score()) self.tolerance_box = QtWidgets.QLineEdit(str(self.refine.hkl_tolerance)) self.tolerance_box.setAlignment(QtCore.Qt.AlignRight) self.tolerance_box.setMaxLength(5) self.tolerance_box.editingFinished.connect(self.update_table) self.tolerance_box.setFixedWidth(80) save_button = QtWidgets.QPushButton('Save Orientation') save_button.clicked.connect(self.save_orientation) close_button = QtWidgets.QPushButton('Close Window') close_button.clicked.connect(message_box.close) close_layout.addWidget(self.status_text) close_layout.addStretch() close_layout.addWidget(QtWidgets.QLabel('Threshold')) close_layout.addWidget(self.tolerance_box) close_layout.addStretch() close_layout.addWidget(save_button) close_layout.addStretch() close_layout.addWidget(close_button) layout.addLayout(close_layout) message_box.setLayout(layout) message_box.setWindowTitle('%s Peak Table' % self.entry.nxtitle) message_box.adjustSize() message_box.show() self.plotview = None def plot_peak(self): row = self.table_view.currentIndex().row() data = self.entry.data x, y, z = [self.table_view.model().peak_list[row][i] for i in range(1, 4)] xmin, xmax = max(0,x-200), min(x+200,data.nxsignal.shape[2]) ymin, ymax = max(0,y-200), min(y+200,data.nxsignal.shape[1]) zmin, zmax = max(0,z-200), min(z+200,data.nxsignal.shape[0]) zslab=np.s_[z,ymin:ymax,xmin:xmax] if self.plotview is None: self.plotview = NXPlotView('X-Y Projection') self.plotview.plot(data[zslab], log=True) self.plotview.crosshairs(x, y) def orient(self): self.refine.primary = int(self.primary_box.text()) self.refine.secondary = int(self.secondary_box.text()) self.refine.Umat = self.refine.get_UBmat(self.refine.primary, self.refine.secondary) \ * self.refine.Bimat self.update_table() def refine_orientation(self): idx = self.refine.idx intensities = self.refine.intensity[idx] sigma = np.average(intensities) / intensities p0 = self.set_parameters(idx) def diffs(p): self.get_parameters(p) UBimat = np.linalg.inv(self.refine.UBmat) Q = [UBimat * self.Gvec[i] for i in idx] dQ = Q - np.rint(Q) return np.array([np.linalg.norm(self.refine.Bmat*np.matrix(dQ[i])) for i in idx]) / sigma popt, C, info, msg, success = leastsq(diffs, p0, full_output=1) self.get_parameters(popt) self.update_lattice() self.update_table() self.status_text.setText('Score: %.4f' % self.refine.score()) def restore_orientation(self): self.refine.Umat = self.Umat for par in self.lattice.values(): par.value = par.init_value self.update_table() def update_table(self): self.refine.hkl_tolerance = np.float32(self.tolerance_box.text()) 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.status_text.setText('Score: %.4f' % self.refine.score()) def update_lattice(self): self.lattice['a'].value = self.refine.a self.lattice['b'].value = self.refine.b self.lattice['c'].value = self.refine.c self.lattice['alpha'].value = self.refine.alpha self.lattice['beta'].value = self.refine.beta self.lattice['gamma'].value = self.refine.gamma def set_parameters(self, idx): x, y, z = self.refine.xp[idx], self.refine.yp[idx], self.refine.zp[idx] self.Gvec = [self.refine.Gvec(xx,yy,zz) for xx,yy,zz in zip(x,y,z)] self.Umat = self.refine.Umat pars = [] for par in self.lattice.values(): par.init_value = par.value if par.vary: pars.append(par.value) p0 = np.zeros(shape=(len(pars)+9), dtype=np.float32) p0[:len(pars)] = pars p0[len(pars):] = np.ravel(self.refine.Umat) return p0 def get_parameters(self, p): i = 0 for par in self.lattice.values(): if par.vary: par.value = p[i] i += 1 self.refine.a, self.refine.b, self.refine.c, \ self.refine.alpha, self.refine.beta, self.refine.gamma = \ [par.value for par in self.lattice.values()] self.refine.set_symmetry() self.refine.Umat = np.matrix(p[i:]).reshape(3,3) def save_orientation(self): self.write_parameters() def write_parameters(self): try: self.refine.write_parameters() except NeXusError as error: report_error('Defining Orientation', error)
class MakeDialog(BaseDialog): def __init__(self, parent=None): super(MakeDialog, self).__init__(parent) self.scans = None self.set_layout(self.directorybox("Choose Sample Directory", self.choose_sample), self.textboxes(('Scan Command', 'Pil2Mscan')), self.action_buttons(('Select All', self.select_scans), ('Reverse All', self.reverse_scans), ('Clear All', self.clear_scans), ('Make Scan Macro', self.make_scans)), self.close_buttons(close=True)) self.set_title('Make Scans') def choose_sample(self): super(MakeDialog, self).choose_directory() self.sample_directory = self.get_directory() self.experiment_directory = os.path.dirname(os.path.dirname(self.sample_directory)) self.macro_directory = os.path.join(self.experiment_directory, 'macros') self.label = os.path.basename(self.sample_directory) self.sample = os.path.basename(os.path.dirname(self.sample_directory)) self.experiment = os.path.basename(self.experiment_directory) self.experiment_path = self.experiment self.scan_path = os.path.join(self.experiment, self.sample, self.label) self.setup_scans() def setup_scans(self): if self.scans: self.scans.delete_grid() self.scans = GridParameters() all_files = [self.sample+'_'+d+'.nxs' for d in os.listdir(self.sample_directory) if os.path.isdir(os.path.join(self.sample_directory, d))] filenames = sorted([f for f in all_files if os.path.exists(os.path.join(self.sample_directory, f))], key=natural_sort) for i, f in enumerate(filenames): scan = 'f%d' % i self.scans.add(scan, i+1, f, True, self.update_scans) self.scans[scan].checkbox.stateChanged.connect(self.update_scans) self.insert_layout(2, self.scans.grid(header=False)) @property def scan_list(self): scan_list = [] for scan in self.scans.values(): if scan.checkbox.isChecked() and scan.value > 0: scan_list.append(scan) else: scan.value = 0 return sorted(scan_list, key=attrgetter('value')) def update_scans(self): scan_list = self.scan_list scan_number = 0 for scan in scan_list: scan_number += 1 scan.value = scan_number for scan in self.scans.values(): if scan.checkbox.isChecked() and scan.value == 0: scan.value = scan_number + 1 scan_number += 1 def select_scans(self): for i, scan in enumerate(self.scans): self.scans[scan].value = i+1 self.scans[scan].checkbox.setChecked(True) def reverse_scans(self): for i, scan in enumerate(reversed(self.scan_list)): scan.value = i+1 scan.checkbox.setChecked(True) def clear_scans(self): for scan in self.scans: self.scans[scan].value = 0 self.scans[scan].checkbox.setChecked(False) def make_scans(self): scans = [scan.label.text() for scan in self.scan_list] scan_command = self.textbox['Scan Command'].text() scan_parameters = ['#command path filename temperature detx dety ' + 'phi_start phi_step phi_end chi omega frame_rate'] for scan in self.scan_list: nexus_file = scan.label.text() root = nxload(os.path.join(self.sample_directory, nexus_file)) temperature = root.entry.sample.temperature base_name = os.path.basename(os.path.splitext(nexus_file)[0]) scan_dir = base_name.replace(self.sample+'_', '') for entry in [root[e] for e in root if e != 'entry']: if 'phi_set' in entry['instrument/goniometer']: phi_start = entry['instrument/goniometer/phi_set'] else: phi_start = entry['instrument/goniometer/phi'] phi_step = entry['instrument/goniometer/phi'].attrs['step'] phi_end = entry['instrument/goniometer/phi'].attrs['end'] if 'chi_set' in entry['instrument/goniometer']: chi = entry['instrument/goniometer/chi_set'] else: chi = entry['instrument/goniometer/chi'] if 'omega_set' in entry['instrument/goniometer']: omega = entry['instrument/goniometer/omega_set'] else: omega = entry['instrument/goniometer/omega'] dx = entry['instrument/detector/translation_x'] dy = entry['instrument/detector/translation_y'] if ('frame_time' in entry['instrument/detector'] and entry['instrument/detector/frame_time'] > 0.0): frame_rate = 1.0 / entry['instrument/detector/frame_time'] else: frame_rate = 10.0 scan_file = entry.nxname if scan_command == 'Pil2Mscan': scan_parameters.append( '%s %s %s %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g %.6g' % (scan_command, os.path.join(self.scan_path, scan_dir), scan_file, temperature, dx, dy, phi_start, phi_step, phi_end, chi, omega, frame_rate)) if scan_command == 'Pil2Mstring': scan_parameters.append('Pil2Mstring("%s")' % scan_dir) elif scan_command != 'Pil2Mscan': scan_parameters.append('%s %s' % (scan_command, temperature)) if not os.path.exists(self.macro_directory): os.mkdir(os.path.join(self.experiment_directory, 'macros')) macro_filter = ';;'.join(("SPEC Macro (*.mac)", "Any Files (*.* *)")) macro = getSaveFileName(self, 'Open Macro', self.macro_directory, macro_filter) if macro: with open(macro, 'w') as f: f.write('\n'.join(scan_parameters))