def do_define_2theta_fwhm_function(self): """ pop out a dialog for user to input the 2theta-FWHM formula :return: """ formula = guiutility.get_value_from_dialog( parent=self, title='Input 2theta-FWHM function', details='Example: y = 4.0 * x**2 - 1.2 * x + 1./x]=\n' 'where y is FWHM and x is 2theta', label_name='Equation: ') if formula is None: # return if user cancels operation return print('[DB...BAT] User input 2theta formula: {}'.format(formula)) state, error_message = self._controller.check_2theta_fwhm_formula( formula) if not state: guiutility.show_message(self, message=error_message, message_type='error') return return
def do_retrieve_fwhm(self): """ Get FWHM from integrated 'STRONG' peaks according to 2theta value :return: """ row_number = self.ui.tableView_summary.rowCount() error_messages = '' for row_index in range(row_number): # check whether FWHM value is set up fwhm_i = self.ui.tableView_summary.get_fwhm(row_index) if fwhm_i is not None and fwhm_i > 1.E-10: continue # use interpolation to curve two_theta = self.ui.tableView_summary.get_two_theta(row_index) try: gauss_sigma = self._controller.calculate_peak_integration_sigma(two_theta) scan_number = self.ui.tableView_summary.get_scan_number(row_index) pt_number = 1 roi_name = self.ui.tableView_summary.get_region_of_interest_name(row_index) self.ui.tableView_summary.set_gaussian_sigma(row_index, gauss_sigma) self._controller.set_single_measure_peak_width(self._exp_number, scan_number, pt_number, roi_name, gauss_sigma, is_fhwm=False) except RuntimeError as err: # error! error_messages += 'Unable to calculate sigma of row {0} due to {1}\n'.format(row_index, err) continue # END-IF-ELSE # show error message if necessary if len(error_messages) > 0: guiutility.show_message(self, error_messages)
def do_integrate_single_pt(self): """ integrate the 2D data inside region of interest along both axis-0 and axis-1 individually. and the result (as 1D data) will be saved to ascii file. the X values will be the corresponding pixel index either along axis-0 or axis-1 :return: """ # get ROI roi_name = str(self.ui.comboBox_roiList.currentText()) if roi_name is None or roi_name == '': guiutility.show_message('A region-of-interest must be chosen in order to integrate detector counts.') return for row_number in range(self.ui.tableView_summary.rowCount()): # integrate counts on detector scan_number = self.ui.tableView_summary.get_scan_number(row_number) pt_number = self.ui.tableView_summary.get_pt_number(row_number) # calculate peak intensity ref_fwhm = self.ui.tableView_summary.get_fwhm(row_number) intensity = self._controller.calculate_intensity_single_pt(self._exp_number, scan_number, pt_number, roi_name, ref_fwhm=ref_fwhm, is_fwhm=False) # add to table self.ui.tableView_summary.set_intensity(scan_number, pt_number, intensity) # END-FOR return
def do_export_to_movie(self): """ export the complete list of single-pt experiment to a movie :return: """ # find out the directory to save the PNG files for making a move movie_dir = self._controller.get_working_directory() roi_name = str(self.ui.comboBox_roiList.currentText()) direction = str(self.ui.comboBox_integrateDirection.currentText()).lower() movie_dir = os.path.join(movie_dir, '{}_{}'.format(roi_name, direction)) os.mkdir(movie_dir) # go through each line to plot and save the data num_rows = self.ui.tableView_summary.rowCount() file_list_str = '' for i_row in range(num_rows): # get run number and set to plot scan_number = self.ui.tableView_summary.get_scan_number(i_row) self.ui.lineEdit_Scan.setText('{}'.format(scan_number)) png_file_name = os.path.join(movie_dir, 'Scan{0:04d}_ROI{1}_{2}.png'.format(scan_number, roi_name, direction)) self.do_plot_integrated_pt(show_plot=False, save_plot_to=png_file_name) file_list_str += '{}\n'.format(png_file_name) # END-IF # write out png_list_file = open(os.path.join(movie_dir, 'MoviePNGList.txt'), 'w') png_list_file.write(file_list_str) png_list_file.close() # prompt how to make a movie command_linux = 'ffmpeg -framerate 8 -pattern_type glob -i "*.png" -r 30 test.mp4' guiutility.show_message(self, command_linux) return
def do_integrate_detector_counts(self): """ sum over the (selected) scan's detector counts by ROI :return: """ # get ROI roi_name = str(self.ui.comboBox_roiList.currentText()) if roi_name is None or roi_name == '': guiutility.show_message( 'A region-of-interest must be chosen in order to integrate detector counts.' ) return # integration direction and fit direction = str( self.ui.comboBox_integrateDirection.currentText()).lower() fit_gaussian = self.ui.checkBox_fitPeaks.isChecked() num_rows = self.ui.tableView_summary.rowCount() print('[DB...BAT] Number of rows = {}'.format(num_rows)) scan_number_list = list() for row_number in range(num_rows): # integrate counts on detector scan_number = self.ui.tableView_summary.get_scan_number(row_number) scan_number_list.append(scan_number) # END-FOR print('[DB...BAT] Scan numbers: {}'.format(scan_number_list)) peak_height_dict = self._controller.integrate_single_pt_scans_detectors_counts( self._exp_number, scan_number_list, roi_name, direction, fit_gaussian) # set the value to the row to table for row_number in range(self.ui.tableView_summary.rowCount()): scan_number = self.ui.tableView_summary.get_scan_number(row_number) pt_number = 1 peak_height = peak_height_dict[scan_number] self.ui.tableView_summary.set_peak_height(scan_number, pt_number, peak_height, roi_name) # END-FOR (row_number) return
def menu_load_gauss_sigma_file(self): """ load a Gaussian sigma curve for interpolation or matching :return: """ # get the column ascii file name file_filter = 'Data Files (*.dat);;All Files (*.*)' twotheta_sigma_file_name = QFileDialog.getOpenFileName(self, self._working_dir, '2theta Gaussian-Sigma File', file_filter) if not twotheta_sigma_file_name: return if isinstance(twotheta_sigma_file_name, tuple): twotheta_sigma_file_name = twotheta_sigma_file_name[0] # set the file to controller try: vec_x, vec_y = self._controller.import_2theta_gauss_sigma_file(twotheta_sigma_file_name) self.ui.graphicsView_integration1DView.plot_2theta_model(vec_x, vec_y) except RuntimeError as run_err: guiutility.show_message(self, str(run_err))
def do_browse_output_dir(self): """ browse the output directory :return: """ # get scan number or numbers try: exp_number = self.get_exp_number() except RuntimeError as run_err: gui_util.show_message(self, '[ERROR] {0}'.format(run_err)) return default_dir = os.path.join( '/HFIR/HB3A/Exp{0}/shared/'.format(exp_number)) # get output directory output_dir = QFileDialog.getExistingDirectory( self, 'Outputs for pre-processed scans', default_dir) if not output_dir: return if isinstance(output_dir, tuple): output_dir = output_dir[0] self.ui.lineEdit_outputDir.setText(output_dir)
def set_calibration_to_reduction_controller(self, exp_number): """set user-specified instrument calibrations to the my controller :param exp_number: :return: """ # set up the experiment number if it is different if exp_number != self._myController.get_experiment(): self._myController.set_exp_number(exp_number) self._myController.set_default_detector_sample_distance(0.3750) self._myController.set_default_pixel_number(256, 256) # set up the calibration # wave length user_wavelength_str = str( self.ui.lineEdit_infoWavelength.text()).strip() if len(user_wavelength_str) > 0: try: user_wavelength = float(user_wavelength_str) self._myController.set_user_wave_length( exp_number, user_wavelength) except ValueError: gui_util.show_message( self, '[ERROR] User-specified wave length {0} cannot be converted to float.' ''.format(user_wavelength_str)) return # END-IF # detector center user_det_center_str = str( self.ui.lineEdit_infoDetCenter.text()).strip() user_det_center_str = user_det_center_str.replace('x', ',') if len(user_det_center_str) > 0: try: det_center = gui_util.parse_integer_list( user_det_center_str, 2) except RuntimeError as run_err: gui_util.show_message( self, 'Unable to parse detector center {0} due to {1}' ''.format(user_det_center_str, run_err)) return self._myController.set_detector_center(exp_number, det_center[0], det_center[1]) # END-IF # detector sample distance status, ret_obj = gui_util.parse_float_editors( [self.ui.lineEdit_infoDetSampleDistance], allow_blank=True) if not status: error_message = ret_obj gui_util.show_message(self, '[ERROR] {0}'.format(error_message)) return user_det_sample_distance = ret_obj[0] if user_det_sample_distance is not None: self._myController.set_detector_sample_distance( exp_number, user_det_sample_distance) # detector size curr_det_size_index = self.ui.comboBox_detSize.currentIndex() if curr_det_size_index > 2: gui_util.show_message( self, 'Detector {0} is not supported by now!' ''.format(str(self.ui.comboBox_detSize.currentText()))) return det_size = [256, 512][curr_det_size_index] self._myController.set_detector_geometry(det_size, det_size)