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_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 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 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))
Example #6
0
    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 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
Example #8
0
    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)