Index: src/sas/qtgui/Calculators/ResolutionCalculatorPanel.py
===================================================================
--- src/sas/qtgui/Calculators/ResolutionCalculatorPanel.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
+++ src/sas/qtgui/Calculators/ResolutionCalculatorPanel.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -0,0 +1,827 @@
+"""
+This object is a small tool to allow user to quickly
+determine the variance in q  from the
+instrumental parameters.
+"""
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+
+from twisted.internet import threads
+import sas.qtgui.Utilities.GuiUtils as GuiUtils
+from sas.qtgui.Plotting.PlotterData import Data2D
+from sas.qtgui.Plotting.Plotter2D import Plotter2DWidget
+from sas.sascalc.calculator.resolution_calculator import ResolutionCalculator
+import matplotlib.patches as patches
+
+import numpy
+import sys
+import logging
+import math
+import os
+import re
+
+from UI.ResolutionCalculatorPanelUI import Ui_ResolutionCalculatorPanel
+
+_SOURCE_MASS = {'Alpha': 6.64465620E-24,
+                'Deuteron': 3.34358320E-24,
+                'Neutron': 1.67492729E-24,
+                'Photon': 0.0,
+                'Proton': 1.67262137E-24,
+                'Triton': 5.00826667E-24}
+
+BG_WHITE = "background-color: rgb(255, 255, 255);"
+BG_RED = "background-color: rgb(244, 170, 164);"
+
+_INTENSITY = 368428
+_LAMBDA_ARRAY = [[0, 1e+16], [_INTENSITY, _INTENSITY]]
+
+
+class ResolutionCalculatorPanel(QtGui.QDialog, Ui_ResolutionCalculatorPanel):
+    """
+    compute resolution in 2D
+    """
+    def __init__(self, parent=None):
+        super(ResolutionCalculatorPanel, self).__init__()
+        self.setupUi(self)
+        self.manager = parent
+
+        # New font to display angstrom symbol
+        new_font = 'font-family: -apple-system, "Helvetica Neue", "Ubuntu";'
+        self.lblUnitWavelength.setStyleSheet(new_font)
+        self.lblUnitQx.setStyleSheet(new_font)
+        self.lblUnitQy.setStyleSheet(new_font)
+        self.lblUnitSigmax.setStyleSheet(new_font)
+        self.lblUnitSigmay.setStyleSheet(new_font)
+        self.lblUnitSigmalamd.setStyleSheet(new_font)
+        self.lblUnit1DSigma.setStyleSheet(new_font)
+
+        # by default Spectrum label and cbCustomSpectrum are not visible
+        self.cbCustomSpectrum.setVisible(False)
+        self.lblSpectrum.setVisible(False)
+        # self.onReset()
+
+        # change index of comboboxes
+        self.cbWaveColor.currentIndexChanged.connect(self.onSelectWaveColor)
+        self.cbCustomSpectrum.currentIndexChanged.connect(self.onSelectCustomSpectrum)
+
+        # push buttons
+        self.cmdClose.clicked.connect(self.accept)
+        self.cmdHelp.clicked.connect(self.onHelp)
+        self.cmdCompute.clicked.connect(self.onCompute)
+        self.cmdReset.clicked.connect(self.onReset)
+
+        # input defaults
+        self.qx = []
+        self.qy = []
+        # dQ defaults
+        self.sigma_r = None
+        self.sigma_phi = None
+        self.sigma_1d = None
+
+        # number of bins for wavelength and wavelength spread
+        self.num_wave = 10
+        self.spectrum_dic = {}
+
+        # dQ 2d image
+        self.image = None
+        # results of sigmas
+        self.sigma_strings = ' '
+        # Source selection dic
+        self.source_mass = _SOURCE_MASS
+        # detector coordinate of estimation of sigmas
+        self.det_coordinate = 'cartesian'
+
+        self.resolution = ResolutionCalculator()
+        self.spectrum_dic['Add new'] = ''
+        self.spectrum_dic['Flat'] = self.resolution.get_default_spectrum()
+        self.resolution.set_spectrum(self.spectrum_dic['Flat'])
+
+        # validators
+        self.txtWavelength.editingFinished.connect(self.checkWavelength)
+        self.txtWavelengthSpread.editingFinished.connect(self.checkWavelengthSpread)
+
+        self.txtDetectorPixSize.editingFinished.connect(self.checkPixels)
+        self.txtDetectorSize.editingFinished.connect(self.checkPixels)
+
+        self.txtSourceApertureSize.editingFinished.connect(self.checkAperture)
+        self.txtSampleApertureSize.editingFinished.connect(self.checkAperture)
+
+        self.txtQx.editingFinished.connect(self.checkQx_y)
+        self.txtQy.editingFinished.connect(self.checkQx_y)
+
+        # double validator
+        self.txtSource2SampleDistance.setValidator(QtGui.QDoubleValidator())
+        self.txtSample2DetectorDistance.setValidator(QtGui.QDoubleValidator())
+        self.txtSampleOffset.setValidator(QtGui.QDoubleValidator())
+
+        # call compute to calculate with default values
+        self.createTemplate2DPlot()
+        self.onCompute()
+
+    # #################################
+    # Validators: red background in line edits when wrong input
+    # and display of info logging message
+    # #################################
+
+    def checkWavelength(self):
+        """ Validator for Wavelength
+         if TOF, wavelength = min - max else only one number """
+        text_edit = self.txtWavelength  # self.sender()
+        if text_edit.isModified():
+            text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+            input_string = str(text_edit.text())
+            if self.cbWaveColor.currentText() != 'TOF':
+                input_wavelength = re.match('\d+\.?\d*', input_string)
+                if input_wavelength is None:
+                    text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                    self.cmdCompute.setEnabled(False)
+                    logging.info('Wavelength has to be a number.')
+                else:
+                    text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                    self.cmdCompute.setEnabled(True)
+            else:
+                interval_wavelength = re.match('^\d+\.?\d*\s*-\s*\d+\.?\d*$',
+                                               input_string)
+
+                if interval_wavelength is None:
+                    text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                    self.cmdCompute.setEnabled(False)
+                    logging.info("Wavelength's input has to be an interval: "
+                                 "min - max.")
+                else:
+                    # check on min < max
+                    [wavelength_min, wavelength_max] = \
+                        re.findall('\d+\.?\d*', interval_wavelength.group())
+
+                    if float(wavelength_min) >= float(wavelength_max):
+                        text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                        self.cmdCompute.setEnabled(False)
+                        logging.info("Wavelength: min must be smaller than max.")
+
+                    else:
+                        text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                        self.cmdCompute.setEnabled(True)
+
+    def checkWavelengthSpread(self):
+        """ Validator for WavelengthSpread
+         Input can be a 'number or min - max (; Number of bins)' """
+        text_edit = self.sender()
+
+        if text_edit.isModified():
+            text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+            if self.cbWaveColor.currentText() != 'TOF':
+                pattern = '^\d+\.?\d*(|;\s*\d+)$'
+                input_string = str(text_edit.text())
+                wavelength_spread_input = re.match(pattern, input_string)
+
+                if wavelength_spread_input is None:
+                    text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                    self.cmdCompute.setEnabled(False)
+                    logging.info('Wavelength spread has to be specified: '
+                                 'single value or value; integer number of bins.')
+
+                else:
+                    split_input = wavelength_spread_input.group().split(';')
+                    self.num_wave = split_input[1] if len(split_input) > 1 else 10
+                    text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                    self.cmdCompute.setEnabled(True)
+            else:
+                pattern = '^\d+\.?\d*\s*-\s*\d+\.?\d*(|;\s*\d+)$'
+                input_string = str(text_edit.text())
+                wavelength_spread_input = re.match(pattern, input_string)
+
+                if wavelength_spread_input is None:
+                    text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                    self.cmdCompute.setEnabled(False)
+                    logging.info("Wavelength spread has to be specified: "
+                                 "doublet separated by '-' with optional "
+                                 "number of bins (given after ';'). "
+                                 "For example, 0.1 - 0.1 (; 20).")
+
+                else:
+                    split_input = wavelength_spread_input.group().split(';')
+                    self.num_wave = split_input[1] if len(
+                        split_input) > 1 else 10
+                    text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                    self.cmdCompute.setEnabled(True)
+
+    def checkPixels(self):
+        """ Validator for detector pixel size and number """
+        text_edit = self.sender()
+
+        if text_edit.isModified():
+            text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+            pattern = '^\d+\.?\d*,\s*\d+\.?\d*$'
+            input_string = str(text_edit.text())
+            pixels_input = re.match(pattern, input_string)
+
+            if pixels_input is None:
+                text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                self.cmdCompute.setEnabled(False)
+                logging.info('The input for the detector should contain 2 '
+                             'values separated by a comma.')
+
+            else:
+                text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                self.cmdCompute.setEnabled(True)
+
+    def checkQx_y(self):
+        """ Validator for qx and qy inputs """
+        Q_modified = [self.txtQx.isModified(), self.txtQy.isModified()]
+        if any(Q_modified):
+            pattern = '^-?\d+\.?\d*(,\s*-?\d+\.?\d*)*$'
+            text_edit = self.txtQx if Q_modified[0] else self.txtQy
+            input_string = str(text_edit.text())
+            q_input = re.match(pattern, input_string)
+            if q_input is None:
+                text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                self.cmdCompute.setEnabled(False)
+                logging.info('Qx and Qy are lists of comma-separated numbers.')
+            else:
+                text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                self.cmdCompute.setEnabled(True)
+                qx = str(self.txtQx.text()).split(',')
+                qy = str(self.txtQy.text()).split(',')
+
+                if len(qx) == 1 and len(qy) > 1:
+                    fill_qx = ', '.join([qx[0]] * len(qy))
+                    self.txtQx.setText(fill_qx)
+
+                elif len(qy) == 1 and len(qx) > 1:
+                    fill_qy = ', '.join([qy[0]] * len(qx))
+                    self.txtQy.setText(fill_qy)
+
+                elif len(qx) != len(qy):
+                    text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                    self.cmdCompute.setEnabled(False)
+                    logging.info(
+                        'Qx and Qy have the same number of elements.')
+
+                else:
+                    text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                    self.cmdCompute.setEnabled(True)
+
+    def checkAperture(self):
+        """ Validator for Sample and Source apertures"""
+        text_edit = self.sender()
+
+        if text_edit.isModified():
+            text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+            input_string = str(text_edit.text())
+            pattern = '^\d+\.?\d*(|,\s*\d+)$'
+            aperture_input = re.match(pattern, input_string)
+
+            if aperture_input is None:
+                text_edit.setStyleSheet(QtCore.QString(BG_RED))
+                self.cmdCompute.setEnabled(False)
+                logging.info('A circular aperture is defined by a single '
+                             'value (diameter). A rectangular aperture is '
+                             'defined by 2 values separated by a comma.')
+
+            else:
+                text_edit.setStyleSheet(QtCore.QString(BG_WHITE))
+                self.cmdCompute.setEnabled(True)
+
+    # #################################
+    # Slots associated with signals from comboboxes
+    # #################################
+
+    def onSelectWaveColor(self):
+        """ Modify layout of GUI when TOF selected: add elements
+        and modify default entry of Wavelength """
+        list_wdata = self.resolution.get_wave_list()
+        min_lambda = min(list_wdata[0])
+
+        min_wspread = min(list_wdata[1])
+        max_wspread = max(list_wdata[1])
+
+        if self.cbWaveColor.currentText() == 'TOF':
+            self.cbCustomSpectrum.setVisible(True)
+            self.lblSpectrum.setVisible(True)
+            # Get information about wavelength and spread
+
+            if len(list_wdata[0]) < 2:
+                max_lambda = 2 * min_lambda
+            else:
+                max_lambda = max(list_wdata[0])
+            self.txtWavelength.setText('{} - {}'.format(min_lambda, max_lambda))
+            self.txtWavelengthSpread.setText('{} - {}'.format(min_wspread,
+                                                    max_wspread))
+
+        else:
+            self.cbCustomSpectrum.setVisible(False)
+            self.lblSpectrum.setVisible(False)
+            # modify Wavelength line edit only if set for TOF (2 elements)
+
+            if len(self.txtWavelength.text().split('-')) >= 2:
+                self.txtWavelength.setText(str(min_lambda))
+                self.txtWavelengthSpread.setText(str(min_wspread))
+
+    def onSelectCustomSpectrum(self):
+        """ On Spectrum Combobox event"""
+        if self.cbCustomSpectrum.currentText() == 'Add New':
+            datafile = QtGui.QFileDialog.getOpenFileName(
+                self, "Choose a spectral distribution file", "",
+                "All files (*.*)",
+                None, QtGui.QFileDialog.DontUseNativeDialog)
+
+            if datafile is None or str(datafile) == '':
+                logging.info("No spectral distribution data chosen.")
+                self.cbCustomSpectrum.setCurrentIndex(0)
+                self.resolution.set_spectrum(self.spectrum_dic['Flat'])
+                return
+
+            try:
+                basename = os.path.basename(datafile)
+                if basename not in self.spectrum_dic.keys():
+                    self.cbCustomSpectrum.addItem(basename)
+
+                input_f = open(datafile, 'r')
+                buff = input_f.read()
+                lines = buff.split('\n')
+
+                wavelength = []
+                intensity = []
+
+                for line in lines:
+                    toks = line.split()
+                    try:
+                        wave = float(toks[0])
+                        intens = float(toks[1])
+                        wavelength.append(wave)
+                        intensity.append(intens)
+                    except:
+                        logging.info('Could not extract values from file')
+            except:
+                raise
+
+            self.spectrum_dic[basename] = [wavelength, intensity]
+            self.resolution.set_spectrum(self.spectrum_dic[basename])
+        return
+
+    # #################################
+    # Slots associated with signals from push buttons
+    # #################################
+
+    def onHelp(self):
+        """
+        Bring up the Resolution Calculator Documentation whenever
+        the HELP button is clicked.
+        Calls Documentation Window with the path of the location within the
+        documentation tree (after /doc/ ....".
+        """
+        try:
+            location = GuiUtils.HELP_DIRECTORY_LOCATION + \
+                       "/user/sasgui/perspectives/calculator/resolution_calculator_help.html"
+            self.manager._helpView.load(QtCore.QUrl(location))
+            self.manager._helpView.show()
+
+        except AttributeError:
+            # No manager defined - testing and standalone runs
+            pass
+
+    def onReset(self):
+        # by default Spectrum label and cbCustomSpectrum are not visible
+        self.cbCustomSpectrum.setVisible(False)
+        self.lblSpectrum.setVisible(False)
+        # Comboboxes
+        self.cbCustomSpectrum.setCurrentIndex([self.cbCustomSpectrum.itemText(i)
+                                               for i in range(self.cbCustomSpectrum.count())].index('Flat'))
+        self.cbSource.setCurrentIndex([self.cbSource.itemText(i) for i in
+                                       range(self.cbSource.count())].index('Neutron'))
+        self.cbWaveColor.setCurrentIndex([self.cbWaveColor.itemText(i) for i
+                                          in range(self.cbWaveColor.count())].index('Monochromatic'))
+        # LineEdits
+        self.txtDetectorPixSize.setText('0.5, 0.5')
+        self.txtDetectorSize.setText('128, 128')
+        self.txtSample2DetectorDistance.setText('1000')
+        self.txtSampleApertureSize.setText('1.27')
+        self.txtSampleOffset.setText('0')
+        self.txtSource2SampleDistance.setText('1627')
+        self.txtSourceApertureSize.setText('3.81')
+        self.txtWavelength.setText('6.0')
+        self.txtWavelengthSpread.setText('0.125')
+        self.txtQx.setText('0.0')
+        self.txtQy.setText('0.0')
+        self.txt1DSigma.setText('0.0008289')
+        self.txtSigma_x.setText('0.0008288')
+        self.txtSigma_y.setText('0.0008288')
+        self.txtSigma_lamd.setText('3.168e-05')
+
+        self.image = None
+        self.sigma_strings = ' '
+        self.source_mass = _SOURCE_MASS
+        self.det_coordinate = 'cartesian'
+        self.num_wave = 10
+        self.spectrum_dic = {}
+        self.spectrum_dic['Add new'] = ''
+        self.spectrum_dic['Flat'] = self.resolution.get_default_spectrum()
+        self.resolution.set_spectrum(self.spectrum_dic['Flat'])
+        # Reset plot
+        self.onCompute()
+
+    # TODO Keep legacy validators??
+    def onCompute(self):
+        """
+        Execute the computation of resolution
+        """
+        # Q min max list default
+        qx_min = []
+        qx_max = []
+        qy_min = []
+        qy_max = []
+        # possible max qrange
+        self.resolution.qxmin_limit = 0
+        self.resolution.qxmax_limit = 0
+        self.resolution.qymin_limit = 0
+        self.resolution.qymax_limit = 0
+
+        try:
+            # Get all the values to compute
+            wavelength = self._str2longlist(self.txtWavelength.text())
+
+            source = self.cbSource.currentText()
+            mass = self.source_mass[str(source)]
+            self.resolution.set_neutron_mass(float(mass))
+
+            wavelength_spread = self._str2longlist(\
+                        self.txtWavelengthSpread.text().split(';')[0])
+            # Validate the wave inputs
+            wave_input = self._validate_q_input(wavelength, wavelength_spread)
+            if wave_input is not None:
+                wavelength, wavelength_spread = wave_input
+
+            self.resolution.set_wave(wavelength)
+            self.resolution.set_wave_spread(wavelength_spread)
+
+            # use legacy validator for correct input assignment
+
+            source_aperture_size = self.txtSourceApertureSize.text()
+            source_aperture_size = self._str2longlist(source_aperture_size)
+            self.resolution.set_source_aperture_size(source_aperture_size)
+
+            sample_aperture_size = self.txtSampleApertureSize.text()
+            sample_aperture_size = self._string2list(sample_aperture_size)
+            self.resolution.set_sample_aperture_size(sample_aperture_size)
+
+            source2sample_distance = self.txtSource2SampleDistance.text()
+            source2sample_distance = self._string2list(source2sample_distance)
+            self.resolution.set_source2sample_distance(source2sample_distance)
+
+            sample2sample_distance = self.txtSampleOffset.text()
+            sample2sample_distance = self._string2list(sample2sample_distance)
+            self.resolution.set_sample2sample_distance(sample2sample_distance)
+
+            sample2detector_distance = self.txtSample2DetectorDistance.text()
+            sample2detector_distance = self._string2list(
+                sample2detector_distance)
+            self.resolution.set_sample2detector_distance(
+                sample2detector_distance)
+
+            detector_size = self.txtDetectorSize.text()
+            detector_size = self._string2list(detector_size)
+            self.resolution.set_detector_size(detector_size)
+
+            detector_pix_size = self.txtDetectorPixSize.text()
+            detector_pix_size = self._string2list(detector_pix_size)
+            self.resolution.set_detector_pix_size(detector_pix_size)
+
+            self.qx = self._string2inputlist(self.txtQx.text())
+            self.qy = self._string2inputlist(self.txtQy.text())
+
+            # Find min max of qs
+            xmin = min(self.qx)
+            xmax = max(self.qx)
+            ymin = min(self.qy)
+            ymax = max(self.qy)
+            if not self._validate_q_input(self.qx, self.qy):
+                raise
+        except:
+            msg = "An error occurred during the resolution computation."
+            msg += "Please check your inputs..."
+            logging.warning(msg)
+            return
+            # raise ValueError, "Invalid Q Input..."
+
+        # Validate the q inputs
+        q_input = self._validate_q_input(self.qx, self.qy)
+        if q_input is not None:
+            self.qx, self.qy = q_input
+
+        # Make list of q min max for mapping
+        for i in range(len(self.qx)):
+            qx_min.append(xmin)
+            qx_max.append(xmax)
+        for i in range(len(self.qy)):
+            qy_min.append(ymin)
+            qy_max.append(ymax)
+
+        # Compute the resolution
+        if self.image is not None:
+            self.resolution.reset_image()
+
+        # Compute and get the image plot
+        try:
+            self.sigma_strings = '\nResolution: Computation is finished. \n'
+            cal_res = threads.deferToThread(self.complete,
+                                            map(self._map_func,
+                                                self.qx,
+                                                self.qy,
+                                                qx_min,
+                                                qx_max,
+                                                qy_min, qy_max)[0],
+                                            self.image)
+
+            cal_res.addCallback(self.new2DPlot)
+
+            logging.info("Computation is in progress...")
+            self.cmdCompute.setText('Wait...')
+            self.cmdCompute.setEnabled(False)
+        except:
+            raise
+
+    def complete(self, image, elapsed=None):
+        """
+        Complete computation
+        """
+        self.image = image
+
+        # Get and format the sigmas
+        sigma_r = self.formatNumber(self.resolution.sigma_1)
+        sigma_phi = self.formatNumber(self.resolution.sigma_2)
+        sigma_lamd = self.formatNumber(self.resolution.sigma_lamd)
+        sigma_1d = self.formatNumber(self.resolution.sigma_1d)
+
+        # Set output values
+        self.txtSigma_x.setText(str(sigma_r))
+        self.txtSigma_y.setText(str(sigma_phi))
+        self.txtSigma_lamd.setText(str(sigma_lamd))
+        self.txt1DSigma.setText(str(sigma_1d))
+
+        msg = self.sigma_strings
+        logging.info(msg + '\n stop')
+        self.cmdCompute.setText('Compute')
+        self.cmdCompute.setEnabled(True)
+        return
+
+    def _map_func(self, qx, qy, qx_min, qx_max, qy_min, qy_max):
+        """
+        Prepare the Mapping for the computation
+        : params qx, qy, qx_min, qx_max, qy_min, qy_max:
+        : return: image (numpy array)
+        """
+        try:
+            qx_value = float(qx)
+            qy_value = float(qy)
+        except:
+            raise
+        # calculate 2D resolution distribution image
+        image = self.resolution.compute_and_plot(qx_value, qy_value,
+                                                 qx_min, qx_max, qy_min,
+                                                 qy_max,
+                                                 self.det_coordinate)
+        # record sigmas
+        self.sigma_strings += " At Qx = %s, Qy = %s; \n" % (qx_value, qy_value)
+        self._sigma_strings()
+        logging.info(self.sigma_strings)
+
+        return image
+
+    # #################################
+    # Legacy validators
+    # #################################
+    def _sigma_strings(self):
+        """
+        Recode sigmas as strings
+        """
+        sigma_r = self.formatNumber(self.resolution.sigma_1)
+        sigma_phi = self.formatNumber(self.resolution.sigma_2)
+        sigma_lamd = self.formatNumber(self.resolution.sigma_lamd)
+        sigma_1d = self.formatNumber(self.resolution.sigma_1d)
+        # Set output values
+        self.sigma_strings += "   sigma_x = %s\n" % sigma_r
+        self.sigma_strings += "   sigma_y = %s\n" % sigma_phi
+        self.sigma_strings += "   sigma_lamd = %s\n" % sigma_lamd
+        self.sigma_strings += "   sigma_1D = %s\n" % sigma_1d
+
+    def _string2list(self, string):
+        """
+        Change NNN, NNN to list,ie. [NNN, NNN] where NNN is a number
+        """
+        new_string = []
+        # check the number of floats
+        try:
+            strg = float(string)
+            new_string.append(strg)
+        except:
+            string_split = string.split(',')
+            if len(string_split) == 2:
+                str_1 = string_split[0]
+                str_2 = string_split[1]
+                new_string.append(float(str_1))
+                new_string.append(float(str_2))
+            elif len(string_split) == 1:
+                str_1 = string_split[0]
+                new_string.append(float(str_1))
+            else:
+                msg = "The numbers must be one or two (separated by ',')..."
+                logging.info(msg)
+                raise RuntimeError, msg
+
+        return new_string
+
+    def _string2inputlist(self, string):
+        """
+        Change NNN, NNN,... to list,ie. [NNN, NNN,...] where NNN is a number
+        : return new_string: string like list
+        """
+        new_string = []
+        string_split = string.split(',')
+        length = len(string_split)
+        for ind in range(length):
+            try:
+                value = float(string_split[ind])
+                new_string.append(value)
+            except:
+                logging.error(sys.exc_value)
+
+        return new_string
+
+    def _str2longlist(self, string):
+        """
+        Change NNN, NNN,... to list, NNN - NNN ; NNN to list, or float to list
+        : return new_string: string like list
+        """
+        try:
+            # is float
+            out = [float(string)]
+            return out
+        except:
+            if self.cbWaveColor.currentText() == 'Monochromatic':
+                logging.warning("Wrong format of inputs.")
+            else:
+                try:
+                    # has a '-'
+                    if string.count('-') > 0:
+                        value = string.split('-')
+                        if value[1].count(';') > 0:
+                            # has a ';'
+                            last_list = value[1].split(';')
+                            num = math.ceil(float(last_list[1]))
+                            max_value = float(last_list[0])
+                            self.num_wave = num
+                        else:
+                            # default num
+                            num = self.num_wave
+                            max_value = float(value[1])
+                        min_value = float(value[0])
+                        # make a list
+                        bin_size = math.fabs(max_value - min_value) / (num - 1)
+                        out = [min_value + bin_size * bnum for bnum in
+                               range(num)]
+                        return out
+                    if string.count(',') > 0:
+                        out = self._string2inputlist(string)
+                        return out
+                except:
+                    logging.error(sys.exc_value)
+
+    def _validate_q_input(self, qx, qy):
+        """
+        Check if q inputs are valid
+        : params qx:  qx as a list
+        : params qy:  qy as a list
+        : return: True/False
+        """
+        # check qualifications
+        if qx.__class__.__name__ != 'list':
+            return None
+        if qy.__class__.__name__ != 'list':
+            return None
+        if len(qx) < 1:
+            return None
+        if len(qy) < 1:
+            return None
+        # allow one input
+        if len(qx) == 1 and len(qy) > 1:
+            qx = [qx[0] for ind in range(len(qy))]
+
+        if len(qy) == 1 and len(qx) > 1:
+            qy = [qy[0] for ind in range(len(qx))]
+        # check length
+        if len(qx) != len(qy):
+            return None
+        if qx is None or qy is None:
+            return None
+        return qx, qy
+
+    def formatNumber(self, value=None):
+        """
+        Return a float in a standardized, human-readable formatted string
+        """
+        try:
+            value = float(value)
+        except:
+            output = None
+            return output
+
+        output = "%-7.4g" % value
+        return output.lstrip().rstrip()
+
+    # #################################
+    # Plot
+    # #################################
+
+    def createTemplate2DPlot(self):
+        """
+        Create a template for 2D data
+        """
+        self.plotter = Plotter2DWidget(self, quickplot=True)
+        self.plotter.scale = 'linear'
+        layout = QtGui.QHBoxLayout()
+        layout.setContentsMargins(0, 0, 0, 0)
+        self.graphicsView.setLayout(layout)
+        layout.addWidget(self.plotter)
+
+    def new2DPlot(self, res_cal):
+        """
+        Create a new 2D data instance based on computing results
+        """
+        qx_min, qx_max, qy_min, qy_max = self.resolution.get_detector_qrange()
+
+        dx_size = (qx_max - qx_min) / (1000 - 1)
+        dy_size = (qy_max - qy_min) / (1000 - 1)
+        x_val = numpy.arange(qx_min, qx_max, dx_size)
+        y_val = numpy.arange(qy_max, qy_min, -dy_size)
+
+        self.drawLines()
+
+        self.plotter.data = Data2D(image=self.image,
+                      qx_data=x_val,
+                      qy_data=y_val,
+                      xmin=qx_min, xmax=qx_max,
+                      ymin=qy_min, ymax=qy_max)
+
+        self.plotter.plot()
+        self.plotter.show()
+
+    def drawLines(self):
+        """
+        Draw lines in image if applicable
+        """
+        wave_list, _ = self.resolution.get_wave_list()
+        if len(wave_list) > 1 and wave_list[-1] == max(wave_list):
+            color = 'g'
+            # draw a green rectangle(limit for the longest wavelength
+            # to be involved) for tof inputs
+            # Get the params from resolution
+            # plotting range for largest wavelength
+            qx_min = self.resolution.qx_min
+            qx_max = self.resolution.qx_max
+            qy_min = self.resolution.qy_min
+            qy_max = self.resolution.qy_max
+            # detector range
+            detector_qx_min = self.resolution.detector_qx_min
+            detector_qx_max = self.resolution.detector_qx_max
+            detector_qy_min = self.resolution.detector_qy_min
+            detector_qy_max = self.resolution.detector_qy_max
+
+            rect = patches.Rectangle((detector_qx_min + 0.0002,
+                                      detector_qy_min + 0.0002),
+                                     detector_qx_max - detector_qx_min,
+                                     detector_qy_max - detector_qy_min,
+                                     linewidth=2,
+                                     edgecolor=color, facecolor='none')
+            self.plotter.ax.add_patch(rect)
+        else:
+            qx_min, qx_max, qy_min, qy_max = self.resolution.get_detector_qrange()
+            # detector range
+            detector_qx_min = self.resolution.qxmin_limit
+            detector_qx_max = self.resolution.qxmax_limit
+            detector_qy_min = self.resolution.qymin_limit
+            detector_qy_max = self.resolution.qymax_limit
+
+            xmin = min(self.qx)
+            xmax = max(self.qx)
+            ymin = min(self.qy)
+            ymax = max(self.qy)
+
+            if xmin < detector_qx_min or xmax > detector_qx_max or \
+                            ymin < detector_qy_min or ymax > detector_qy_max:
+                # message
+                msg = 'At least one q value located out side of\n'
+                msg += " the detector range (%s < qx < %s, %s < qy < %s),\n" % \
+                       (self.formatNumber(detector_qx_min),
+                        self.formatNumber(detector_qx_max),
+                        self.formatNumber(detector_qy_min),
+                        self.formatNumber(detector_qy_max))
+                msg += " is ignored in computation.\n"
+
+                logging.warning(msg)
+
+        # Draw zero axis lines.
+        if qy_min < 0 <= qy_max:
+            self.plotter.ax.axhline(linewidth=1)
+
+        if qx_min < 0 <= qx_max:
+            self.plotter.ax.axvline(linewidth=1)
Index: src/sas/qtgui/Calculators/UI/ResolutionCalculatorPanelUI.ui
===================================================================
--- src/sas/qtgui/Calculators/UI/ResolutionCalculatorPanelUI.ui	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
+++ src/sas/qtgui/Calculators/UI/ResolutionCalculatorPanelUI.ui	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -0,0 +1,944 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ResolutionCalculatorPanel</class>
+ <widget class="QDialog" name="ResolutionCalculatorPanel">
+  <property name="enabled">
+   <bool>true</bool>
+  </property>
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1310</width>
+    <height>667</height>
+   </rect>
+  </property>
+  <property name="minimumSize">
+   <size>
+    <width>1310</width>
+    <height>667</height>
+   </size>
+  </property>
+  <property name="maximumSize">
+   <size>
+    <width>1310</width>
+    <height>667</height>
+   </size>
+  </property>
+  <property name="windowTitle">
+   <string>Q Resolution Estimator</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout_8">
+   <item row="0" column="0">
+    <widget class="QGroupBox" name="groupBox">
+     <property name="title">
+      <string>Instrumental Parameters</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_7">
+      <item row="0" column="0">
+       <layout class="QGridLayout" name="gridLayout_5">
+        <item row="8" column="3">
+         <widget class="QLineEdit" name="txtDetectorSize">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Number of Pixels on Detector.</string>
+          </property>
+          <property name="text">
+           <string>128, 128</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="3">
+         <widget class="QLineEdit" name="txtSampleApertureSize">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>23</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="focusPolicy">
+           <enum>Qt::StrongFocus</enum>
+          </property>
+          <property name="toolTip">
+           <string>Sample Aperture Size.</string>
+          </property>
+          <property name="text">
+           <string>1.27</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="2">
+         <widget class="QComboBox" name="cbWaveColor">
+          <item>
+           <property name="text">
+            <string>Monochromatic</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>TOF</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item row="0" column="0">
+         <widget class="QLabel" name="label_26">
+          <property name="text">
+           <string>Source:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="3">
+         <widget class="QLineEdit" name="txtWavelength">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="focusPolicy">
+           <enum>Qt::StrongFocus</enum>
+          </property>
+          <property name="toolTip">
+           <string>Wavelength of the Neutrons.</string>
+          </property>
+          <property name="text">
+           <string>6.0</string>
+          </property>
+          <property name="echoMode">
+           <enum>QLineEdit::Normal</enum>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="3">
+         <widget class="QLineEdit" name="txtSourceApertureSize">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="focusPolicy">
+           <enum>Qt::StrongFocus</enum>
+          </property>
+          <property name="toolTip">
+           <string>Source Aperture Size.</string>
+          </property>
+          <property name="text">
+           <string>3.81</string>
+          </property>
+         </widget>
+        </item>
+        <item row="7" column="0">
+         <widget class="QLabel" name="label_33">
+          <property name="text">
+           <string>Sample Offset:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="0" colspan="2">
+         <widget class="QLabel" name="label_30">
+          <property name="text">
+           <string>Sample Aperture Size:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="6" column="3">
+         <widget class="QLineEdit" name="txtSample2DetectorDistance">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Sample Aperture to Detector Distance.</string>
+          </property>
+          <property name="text">
+           <string>1000</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="label_27">
+          <property name="text">
+           <string>Wavelength:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="3" column="0" colspan="2">
+         <widget class="QLabel" name="label_29">
+          <property name="text">
+           <string>Source Aperture Size:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="7" column="3">
+         <widget class="QLineEdit" name="txtSampleOffset">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Sample Offset.</string>
+          </property>
+          <property name="text">
+           <string>0</string>
+          </property>
+         </widget>
+        </item>
+        <item row="9" column="3">
+         <widget class="QLineEdit" name="txtDetectorPixSize">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Detector Pixel Size.</string>
+          </property>
+          <property name="text">
+           <string>0.5, 0.5</string>
+          </property>
+         </widget>
+        </item>
+        <item row="9" column="0" colspan="2">
+         <widget class="QLabel" name="label_35">
+          <property name="text">
+           <string>Detector Pixel Size:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="5" column="3">
+         <widget class="QLineEdit" name="txtSource2SampleDistance">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="focusPolicy">
+           <enum>Qt::StrongFocus</enum>
+          </property>
+          <property name="toolTip">
+           <string>Source to Sample Aperture Distance.</string>
+          </property>
+          <property name="text">
+           <string>1627</string>
+          </property>
+         </widget>
+        </item>
+        <item row="8" column="0" colspan="2">
+         <widget class="QLabel" name="label_34">
+          <property name="text">
+           <string>Number of Pixels on Detector:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0" colspan="2">
+         <widget class="QLabel" name="label_28">
+          <property name="text">
+           <string>Wavelength Spread:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="QComboBox" name="cbSource">
+          <property name="toolTip">
+           <string>Source Selection: Affect on the gravitational contribution.</string>
+          </property>
+          <property name="currentIndex">
+           <number>2</number>
+          </property>
+          <item>
+           <property name="text">
+            <string>Alpha</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Deutron</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Neutron</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Photon</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Proton</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Triton</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item row="5" column="0" colspan="3">
+         <widget class="QLabel" name="label_31">
+          <property name="text">
+           <string>Source to Sample Aperture Distance:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="3">
+         <widget class="QLineEdit" name="txtWavelengthSpread">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="focusPolicy">
+           <enum>Qt::StrongFocus</enum>
+          </property>
+          <property name="toolTip">
+           <string>Wavelength Spread of Neutrons.</string>
+          </property>
+          <property name="text">
+           <string>0.125</string>
+          </property>
+         </widget>
+        </item>
+        <item row="6" column="0" colspan="3">
+         <widget class="QLabel" name="label_32">
+          <property name="text">
+           <string>Sample Aperture to Detector Distance:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="4" rowspan="10">
+         <layout class="QGridLayout" name="gridLayout_6">
+          <item row="1" column="0">
+           <widget class="QLabel" name="lblUnitWavelength">
+            <property name="text">
+             <string>Ã
+</string>
+            </property>
+           </widget>
+          </item>
+          <item row="2" column="0">
+           <widget class="QLabel" name="lblUnitWavelengthSpread">
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
+          </item>
+          <item row="3" column="0">
+           <widget class="QLabel" name="label_39">
+            <property name="text">
+             <string>cm</string>
+            </property>
+           </widget>
+          </item>
+          <item row="4" column="0">
+           <widget class="QLabel" name="label_40">
+            <property name="text">
+             <string>cm</string>
+            </property>
+           </widget>
+          </item>
+          <item row="5" column="0">
+           <widget class="QLabel" name="label_41">
+            <property name="text">
+             <string>cm</string>
+            </property>
+           </widget>
+          </item>
+          <item row="6" column="0">
+           <widget class="QLabel" name="label_42">
+            <property name="text">
+             <string>cm</string>
+            </property>
+           </widget>
+          </item>
+          <item row="7" column="0">
+           <widget class="QLabel" name="label_43">
+            <property name="text">
+             <string>cm</string>
+            </property>
+           </widget>
+          </item>
+          <item row="8" column="0">
+           <widget class="QLabel" name="label_44">
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
+          </item>
+          <item row="9" column="0">
+           <widget class="QLabel" name="label_45">
+            <property name="text">
+             <string>cm</string>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="0">
+           <widget class="QLabel" name="label_36">
+            <property name="text">
+             <string/>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item row="1" column="2">
+         <widget class="QComboBox" name="cbCustomSpectrum">
+          <property name="toolTip">
+           <string>Wavelength Spectrum: Intensity vs. wavelength.</string>
+          </property>
+          <item>
+           <property name="text">
+            <string>Flat</string>
+           </property>
+          </item>
+          <item>
+           <property name="text">
+            <string>Add New</string>
+           </property>
+          </item>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QLabel" name="lblSpectrum">
+          <property name="minimumSize">
+           <size>
+            <width>80</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>80</width>
+            <height>20</height>
+           </size>
+          </property>
+          <property name="text">
+           <string>Spectrum</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="0" column="1" rowspan="7">
+    <widget class="Line" name="line_4">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="2" rowspan="3">
+    <widget class="QGraphicsView" name="graphicsView">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="Line" name="line">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QGroupBox" name="groupBox_2">
+     <property name="title">
+      <string>Q Location of the Estimation</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_9">
+      <item row="0" column="0">
+       <layout class="QGridLayout" name="gridLayout">
+        <item row="0" column="0">
+         <widget class="QLabel" name="label_21">
+          <property name="text">
+           <string>Qx:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="QLineEdit" name="txtQx">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Type the Qx value.</string>
+          </property>
+          <property name="text">
+           <string>0.0</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="2">
+         <widget class="QLabel" name="lblUnitQx">
+          <property name="text">
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ã
+&lt;span style=&quot; vertical-align:super;&quot;&gt;-1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="label_22">
+          <property name="text">
+           <string>Qy:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QLineEdit" name="txtQy">
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Type the Qy value.</string>
+          </property>
+          <property name="text">
+           <string>0.0</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="2">
+         <widget class="QLabel" name="lblUnitQy">
+          <property name="text">
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ã
+&lt;span style=&quot; vertical-align:super;&quot;&gt;-1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="Line" name="line_2">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0">
+    <widget class="QGroupBox" name="groupBox_3">
+     <property name="title">
+      <string>Standard Deviation of the Resolution Distribtion</string>
+     </property>
+     <layout class="QGridLayout" name="gridLayout_4">
+      <item row="0" column="0">
+       <layout class="QGridLayout" name="gridLayout_2">
+        <item row="0" column="0">
+         <widget class="QLabel" name="label">
+          <property name="text">
+           <string>Sigma_x:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1">
+         <widget class="QLineEdit" name="txtSigma_x">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>The x component of the geometric resolution, excluding sigma_lamda.</string>
+          </property>
+          <property name="text">
+           <string>0.0008288</string>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="2">
+         <widget class="QLabel" name="lblUnitSigmax">
+          <property name="text">
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ã
+&lt;span style=&quot; vertical-align:super;&quot;&gt;-1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="3">
+         <spacer name="horizontalSpacer">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>78</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+        <item row="0" column="4">
+         <widget class="QLabel" name="label_5">
+          <property name="text">
+           <string>Sigma_y:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="5">
+         <widget class="QLineEdit" name="txtSigma_y">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>The y component of the geometric resolution, excluding sigma_lamda.</string>
+          </property>
+          <property name="text">
+           <string>0.0008288</string>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="6">
+         <widget class="QLabel" name="lblUnitSigmay">
+          <property name="text">
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ã
+&lt;span style=&quot; vertical-align:super;&quot;&gt;-1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0">
+         <widget class="QLabel" name="label_2">
+          <property name="text">
+           <string>Sigma_lamd:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="2">
+         <widget class="QLabel" name="lblUnitSigmalamd">
+          <property name="text">
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ã
+&lt;span style=&quot; vertical-align:super;&quot;&gt;-1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="4">
+         <widget class="QLabel" name="label_6">
+          <property name="text">
+           <string>(1D) Sigma:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="5">
+         <widget class="QLineEdit" name="txt1DSigma">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>Resolution in 1-dimension (for 1D data).</string>
+          </property>
+          <property name="text">
+           <string>0.0008289</string>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="6">
+         <widget class="QLabel" name="lblUnit1DSigma">
+          <property name="text">
+           <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Ã
+&lt;span style=&quot; vertical-align:super;&quot;&gt;-1&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1">
+         <widget class="QLineEdit" name="txtSigma_lamd">
+          <property name="enabled">
+           <bool>true</bool>
+          </property>
+          <property name="minimumSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="baseSize">
+           <size>
+            <width>100</width>
+            <height>21</height>
+           </size>
+          </property>
+          <property name="toolTip">
+           <string>The wavelength contribution in the radial direction. Note: The phi component is always zero.</string>
+          </property>
+          <property name="text">
+           <string>3.168e-05</string>
+          </property>
+          <property name="readOnly">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item row="5" column="0">
+    <widget class="Line" name="line_3">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="0">
+    <layout class="QGridLayout" name="gridLayout_3">
+     <item row="0" column="0">
+      <widget class="QPushButton" name="cmdReset">
+       <property name="toolTip">
+        <string>Reset to default SAS instrumental parameter</string>
+       </property>
+       <property name="text">
+        <string>Reset</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QPushButton" name="cmdCompute">
+       <property name="toolTip">
+        <string>Compute the resolution of Q from SAS instrumental parameter</string>
+       </property>
+       <property name="text">
+        <string>Compute</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="2">
+      <widget class="QPushButton" name="cmdClose">
+       <property name="toolTip">
+        <string>Close this window</string>
+       </property>
+       <property name="text">
+        <string>Close</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+     <item row="0" column="3">
+      <widget class="QPushButton" name="cmdHelp">
+       <property name="toolTip">
+        <string>Help on using the Resolution Calculator</string>
+       </property>
+       <property name="text">
+        <string>Help</string>
+       </property>
+       <property name="autoDefault">
+        <bool>false</bool>
+       </property>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item row="5" column="2">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>40</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+  <zorder>groupBox</zorder>
+  <zorder>groupBox_2</zorder>
+  <zorder>line</zorder>
+  <zorder>line_2</zorder>
+  <zorder>groupBox_3</zorder>
+  <zorder>line_3</zorder>
+  <zorder>graphicsView</zorder>
+  <zorder>line_4</zorder>
+  <zorder>horizontalSpacer_2</zorder>
+ </widget>
+ <tabstops>
+  <tabstop>cbSource</tabstop>
+  <tabstop>cbWaveColor</tabstop>
+  <tabstop>cbCustomSpectrum</tabstop>
+  <tabstop>txtWavelength</tabstop>
+  <tabstop>txtWavelengthSpread</tabstop>
+  <tabstop>txtSourceApertureSize</tabstop>
+  <tabstop>txtSampleApertureSize</tabstop>
+  <tabstop>txtSource2SampleDistance</tabstop>
+  <tabstop>txtSample2DetectorDistance</tabstop>
+  <tabstop>txtSampleOffset</tabstop>
+  <tabstop>txtDetectorSize</tabstop>
+  <tabstop>txtDetectorPixSize</tabstop>
+  <tabstop>txtQx</tabstop>
+  <tabstop>txtQy</tabstop>
+  <tabstop>cmdCompute</tabstop>
+  <tabstop>cmdClose</tabstop>
+  <tabstop>cmdHelp</tabstop>
+  <tabstop>cmdReset</tabstop>
+  <tabstop>txtSigma_x</tabstop>
+  <tabstop>txtSigma_lamd</tabstop>
+  <tabstop>txtSigma_y</tabstop>
+  <tabstop>txt1DSigma</tabstop>
+  <tabstop>graphicsView</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
Index: src/sas/qtgui/Calculators/UnitTesting/ResolutionCalculatorPanelTest.py
===================================================================
--- src/sas/qtgui/Calculators/UnitTesting/ResolutionCalculatorPanelTest.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
+++ src/sas/qtgui/Calculators/UnitTesting/ResolutionCalculatorPanelTest.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -0,0 +1,279 @@
+import sys
+import time
+import numpy
+import logging
+import unittest
+from PyQt4 import QtGui
+from PyQt4 import QtCore
+from PyQt4.QtTest import QTest
+from PyQt4.QtCore import Qt
+from mock import MagicMock
+from mock import patch
+
+from twisted.internet import threads
+
+# from UnitTesting.TestUtils import QtSignalSpy
+# from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
+from sas.qtgui.Calculators.ResolutionCalculatorPanel \
+    import ResolutionCalculatorPanel
+
+# from sas.qtgui.MainWindow.DataManager import DataManager
+# from sas.qtgui.MainWindow.GuiManager import GuiManager
+# from sas.qtgui.Utilities.GuiUtils import *
+
+
+BG_COLOR_ERR = 'background-color: rgb(244, 170, 164);'
+
+BG_COLOR_WARNING = 'background-color: rgb(244, 217, 164);'
+
+
+if not QtGui.QApplication.instance():
+    app = QtGui.QApplication(sys.argv)
+
+
+class ResolutionCalculatorPanelTest(unittest.TestCase):
+    """Test the ResolutionCalculator"""
+    def setUp(self):
+        """Create the ResolutionCalculator"""
+        self.widget = ResolutionCalculatorPanel(None)
+
+        # self.widget.onCompute = MagicMock()
+
+    def tearDown(self):
+        """Destroy the ResolutionCalculator"""
+        self.widget.close()
+        self.widget = None
+
+    def testDefaults(self):
+        """Test the GUI in its default state"""
+
+        self.assertIsInstance(self.widget, QtGui.QDialog)
+        self.assertEqual(self.widget.windowTitle(), "Q Resolution Estimator")
+        # size
+        self.assertEqual(self.widget.size().height(), 667)
+        self.assertEqual(self.widget.size().width(), 1310)
+
+        # visibility
+        self.assertFalse(self.widget.lblSpectrum.isVisible())
+        self.assertFalse(self.widget.cbCustomSpectrum.isVisible())
+
+        # content of line edits
+        self.assertEqual(self.widget.txtDetectorPixSize.text(), '0.5, 0.5')
+        self.assertEqual(self.widget.txtDetectorSize.text(), '128, 128')
+        self.assertEqual(self.widget.txtSample2DetectorDistance.text(), '1000')
+        self.assertEqual(self.widget.txtSampleApertureSize.text(), '1.27')
+        self.assertEqual(self.widget.txtSampleOffset.text(), '0')
+        self.assertEqual(self.widget.txtSource2SampleDistance.text(), '1627')
+        self.assertEqual(self.widget.txtSourceApertureSize.text(), '3.81')
+        self.assertEqual(self.widget.txtWavelength.text(), '6.0')
+        self.assertEqual(self.widget.txtWavelengthSpread.text(), '0.125')
+
+        self.assertEqual(self.widget.txtQx.text(), '0.0')
+        self.assertEqual(self.widget.txtQy.text(), '0.0')
+
+        self.assertEqual(self.widget.txt1DSigma.text(), '0.0008289')
+        self.assertEqual(self.widget.txtSigma_lamd.text(), '3.168e-05')
+        self.assertEqual(self.widget.txtSigma_x.text(), '0.0008288')
+        self.assertEqual(self.widget.txtSigma_x.text(), '0.0008288')
+
+        # items of comboboxes
+        self.assertFalse(self.widget.cbCustomSpectrum.isEditable())
+        self.assertEqual(self.widget.cbCustomSpectrum.currentText(), 'Flat')
+        self.assertEqual(self.widget.cbCustomSpectrum.currentIndex(), 0)
+        self.assertListEqual([self.widget.cbCustomSpectrum.itemText(i) for i in
+                              range(self.widget.cbCustomSpectrum.count())],
+                             ['Flat', 'Add New'])
+
+        self.assertFalse(self.widget.cbSource.isEditable())
+        self.assertEqual(self.widget.cbSource.count(), 6)
+        self.assertEqual(self.widget.cbSource.currentText(), 'Neutron')
+        self.assertListEqual([self.widget.cbSource.itemText(i) for i in
+                              range(self.widget.cbSource.count())],
+                             ['Alpha', 'Deutron', 'Neutron', 'Photon',
+                              'Proton', 'Triton'])
+
+        self.assertFalse(self.widget.cbWaveColor.isEditable())
+        self.assertEqual(self.widget.cbWaveColor.count(), 2)
+        self.assertEqual(self.widget.cbWaveColor.currentText(), 'Monochromatic')
+        self.assertListEqual([self.widget.cbWaveColor.itemText(i) for i in
+                              range(self.widget.cbWaveColor.count())],
+                             ['Monochromatic', 'TOF'])
+
+        # read only text edits
+        self.assertTrue(self.widget.txtSigma_x.isReadOnly())
+        self.assertTrue(self.widget.txtSigma_y.isReadOnly())
+        self.assertTrue(self.widget.txtSigma_lamd.isReadOnly())
+        self.assertTrue(self.widget.txt1DSigma.isReadOnly())
+
+        # tooltips
+        self.assertEqual(self.widget.cbSource.toolTip(),
+                         "Source Selection: "
+                         "Affect on the gravitational contribution.")
+        self.widget.cbCustomSpectrum.toolTip(), \
+        "Wavelength Spectrum: Intensity vs. wavelength."
+        # print self.widget.txtDetectorPixSize.toolTip()
+        self.assertEqual(self.widget.txtDetectorPixSize.toolTip(),
+                         "Detector Pixel Size.")
+        self.assertEqual(self.widget.txtDetectorSize.toolTip(),
+                         "Number of Pixels on Detector.")
+        self.assertEqual(self.widget.txtSample2DetectorDistance.toolTip(),
+                         "Sample Aperture to Detector Distance.")
+        self.assertEqual(self.widget.txtSampleApertureSize.toolTip(),
+                         "Sample Aperture Size.")
+        self.assertEqual(self.widget.txtSampleOffset.toolTip(),
+                         "Sample Offset.")
+        self.assertEqual(self.widget.txtSource2SampleDistance.toolTip(),
+                         "Source to Sample Aperture Distance.")
+        self.assertEqual(self.widget.txtSourceApertureSize.toolTip(),
+                         "Source Aperture Size.")
+        self.assertEqual(self.widget.txtWavelength.toolTip(),
+                         "Wavelength of the Neutrons.")
+        self.assertEqual(self.widget.txtWavelengthSpread.toolTip(),
+                         "Wavelength Spread of Neutrons.")
+        self.assertEqual(self.widget.txtQx.toolTip(), "Type the Qx value.")
+        self.assertEqual(self.widget.txtQy.toolTip(), "Type the Qy value.")
+        self.assertEqual(self.widget.txt1DSigma.toolTip(),
+                         "Resolution in 1-dimension (for 1D data).")
+        self.assertEqual(self.widget.txtSigma_lamd.toolTip(),
+                         "The wavelength contribution in the radial direction."
+                         " Note: The phi component is always zero.")
+        self.assertEqual(self.widget.txtSigma_x.toolTip(),
+                         "The x component of the geometric resolution, "
+                         "excluding sigma_lamda.")
+        self.assertEqual(self.widget.txtSigma_y.toolTip(),
+                         "The y component of the geometric resolution, "
+                         "excluding sigma_lamda.")
+
+    def testFormatNumber(self):
+        self.assertEqual(self.widget.formatNumber('  7.123456  '), '7.123')
+
+    def testCheckWavelength(self):
+        """ Test validator for Wavelength text edit"""
+        self.widget.txtWavelength.clear()
+        # Enter invalid input for Monochromatic spectrum
+        # check that background becomes red and Compute button is disabled
+        QTest.keyClicks(self.widget.txtWavelength, 'vcv ')
+        QTest.keyClick(self.widget.txtWavelength, QtCore.Qt.Key_Return)
+        self.assertIn(BG_COLOR_ERR, self.widget.txtWavelength.styleSheet())
+        self.assertFalse(self.widget.cmdCompute.isEnabled())
+
+        # Enter invalid input for TOF spectrum
+        # check that background becomes red and Compute button is disabled
+        self.widget.cbWaveColor.setCurrentIndex(1)
+
+        self.widget.txtWavelength.clear()
+        QTest.keyClicks(self.widget.txtWavelength, '4')
+        QTest.keyClick(self.widget.txtWavelength, QtCore.Qt.Key_Return)
+        self.assertIn(BG_COLOR_ERR, self.widget.txtWavelength.styleSheet())
+        self.assertFalse(self.widget.cmdCompute.isEnabled())
+
+    def testCheckWavelengthSpread(self):
+        """ Test validator for WavelengthSpread """
+        self.widget.txtWavelengthSpread.clear()
+        QTest.keyClicks(self.widget.txtWavelengthSpread, '0.12; 1.3')
+        QTest.keyClick(self.widget.txtWavelengthSpread, QtCore.Qt.Key_Return)
+        self.assertIn(BG_COLOR_ERR,
+                      self.widget.txtWavelengthSpread.styleSheet())
+
+    def testCheckPixels(self):
+        """ Test validator for pixel size and number """
+        self.widget.txtDetectorPixSize.clear()
+        QTest.keyClicks(self.widget.txtDetectorPixSize, '0.12; 1.3')
+        QTest.keyClick(self.widget.txtDetectorPixSize, QtCore.Qt.Key_Return)
+        self.assertIn(BG_COLOR_ERR,
+                      self.widget.txtDetectorPixSize.styleSheet())
+
+        self.widget.txtDetectorSize.clear()
+        QTest.keyClicks(self.widget.txtDetectorSize, '0.12')
+        QTest.keyClick(self.widget.txtDetectorSize, QtCore.Qt.Key_Return)
+        self.assertIn(BG_COLOR_ERR,
+                      self.widget.txtDetectorSize.styleSheet())
+
+    def testCheckQx_y(self):
+        """ Test validator for qx and qy inputs """
+        self.widget.txtQx.clear()
+        QTest.keyClicks(self.widget.txtQx, '0.12; 1.3')
+        QTest.keyClick(self.widget.txtQx, QtCore.Qt.Key_Return)
+        self.assertIn(BG_COLOR_ERR,
+                      self.widget.txtQx.styleSheet())
+        # put back default value
+        self.widget.txtQx.setText('0.0')
+
+        self.widget.txtQy.clear()
+        QTest.keyClicks(self.widget.txtQy, '0.12, a')
+        QTest.keyClick(self.widget.txtQy, QtCore.Qt.Key_Return)
+        self.assertIn(BG_COLOR_ERR, self.widget.txtQy.styleSheet())
+        # put back default value
+        self.widget.txtQy.setText('0.0')
+
+    def testOnSelectWaveColor(self):
+        """ Test change of layout if type of source is TOF """
+        # choose TOF
+        AllItems = [self.widget.cbWaveColor.itemText(i)
+                    for i in range(self.widget.cbWaveColor.count())]
+        self.widget.cbWaveColor.setCurrentIndex(AllItems.index('TOF'))
+
+        # call function
+        self.widget.onSelectWaveColor()
+        self.widget.show()
+
+        # check that TOF is selected
+        self.assertTrue(self.widget.cbWaveColor.currentText(), 'TOF')
+
+        # check modifications of Wavelength text edit: min - max
+        self.assertEqual(self.widget.txtWavelength.text(), '6.0 - 12.0')
+        self.assertEqual(self.widget.txtWavelengthSpread.text(), '0.125 - 0.125')
+
+        # check that Spectrum label and cbCustomSpectrum are visible
+        self.assertTrue(self.widget.lblSpectrum.isVisible())
+        self.assertTrue(self.widget.cbCustomSpectrum.isVisible())
+
+    def testOnSelectCustomSpectrum(self):
+        """ Test Custom Spectrum: load file if 'Add New' """
+        QtGui.QFileDialog.getOpenFileName = MagicMock(return_value=None)
+        self.widget.cbCustomSpectrum.setCurrentIndex(1)
+
+        # Test the getOpenFileName() dialog called once
+        self.assertTrue(QtGui.QFileDialog.getOpenFileName.called)
+        QtGui.QFileDialog.getOpenFileName.assert_called_once()
+
+    def testHelp(self):
+        """ Assure help file is shown """
+        # this should not rise
+        self.widget.onHelp()
+
+    def testOnReset(self):
+        """ Test onReset function"""
+        # modify gui
+        self.widget.txtQx.setText('33.0')
+        self.widget.cbSource.setCurrentIndex(0)
+
+        # check that GUI has been modified
+        self.assertNotEqual(self.widget.cbSource.currentText(), 'Neutron')
+        # apply reset
+        QTest.mouseClick(self.widget.cmdReset, Qt.LeftButton)
+        # check that we get back to the initial state
+        self.assertEqual(self.widget.txtQx.text(), '0.0')
+        self.assertEqual(self.widget.cbSource.currentText(), 'Neutron')
+
+    def testOnClose(self):
+        """ test Closing window """
+        closeButton = self.widget.cmdClose
+        QTest.mouseClick(closeButton, Qt.LeftButton)
+
+    def testOnCompute(self):
+        """ """
+        threads.deferToThread = MagicMock()
+        self.widget.onCompute()
+
+        # thread called
+        self.assertTrue(threads.deferToThread.called)
+        self.assertEqual(threads.deferToThread.call_args_list[0][0][0].__name__, 'complete')
+
+        # the Compute button changed caption and got disabled
+        self.assertEqual(self.widget.cmdCompute.text(), 'Wait...')
+        self.assertFalse(self.widget.cmdCompute.isEnabled())
+
+
+if __name__ == "__main__":
+    unittest.main()
Index: src/sas/qtgui/GUITests.py
===================================================================
--- src/sas/qtgui/GUITests.py	(revision 464cd0702ca4f47ed61d237d9acecd5975d8abac)
+++ src/sas/qtgui/GUITests.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -37,4 +37,5 @@
 from Calculators.UnitTesting import SLDCalculatorTest
 from Calculators.UnitTesting import SlitSizeCalculatorTest
+from Calculators.UnitTesting import ResolutionCalculatorPanelTest
 
 # Utilities
@@ -92,4 +93,5 @@
         unittest.makeSuite(SLDCalculatorTest.SLDCalculatorTest, 'test'),
         unittest.makeSuite(SlitSizeCalculatorTest.SlitSizeCalculatorTest, 'test'),
+        unittest.makeSuite(ResolutionCalculatorPanelTest.ResolutionCalculatorPanelTest, 'test'),
 
         # Perspectives
@@ -100,5 +102,5 @@
         unittest.makeSuite(FitPageTest.FitPageTest,                       'test'),
         unittest.makeSuite(FittingOptionsTest.FittingOptionsTest,         'test'),
-    )
+     )
     return unittest.TestSuite(suites)
 
Index: src/sas/qtgui/MainWindow/GuiManager.py
===================================================================
--- src/sas/qtgui/MainWindow/GuiManager.py	(revision 3c8242cd1e4ba42495cb5b98d517720d1a82eec7)
+++ src/sas/qtgui/MainWindow/GuiManager.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -30,4 +30,6 @@
 from sas.qtgui.Calculators.SlitSizeCalculator import SlitSizeCalculator
 from sas.qtgui.Calculators.GenericScatteringCalculator import GenericScatteringCalculator
+from sas.qtgui.Calculators.ResolutionCalculatorPanel import ResolutionCalculatorPanel
+
 
 # Perspectives
@@ -136,8 +138,8 @@
         self.SLDCalculator = SldPanel(self)
         self.DVCalculator = DensityPanel(self)
-        #self.KIESSIGCalculator = DensityPanel(self)#KiessigPanel(self)
         self.KIESSIGCalculator = KiessigPanel(self)
         self.SlitSizeCalculator = SlitSizeCalculator(self)
         self.GENSASCalculator = GenericScatteringCalculator(self)
+        self.ResolutionCalculator = ResolutionCalculatorPanel(self)
 
     def statusBarSetup(self):
@@ -556,6 +558,5 @@
         """
         """
-        print("actionSAS_Resolution_Estimator TRIGGERED")
-        pass
+        self.ResolutionCalculator.show()
 
     def actionGeneric_Scattering_Calculator(self):
Index: src/sas/qtgui/Plotting/Plotter2D.py
===================================================================
--- src/sas/qtgui/Plotting/Plotter2D.py	(revision dc5ef150e8b37e01a3b7e253eb5b66d3b82de99c)
+++ src/sas/qtgui/Plotting/Plotter2D.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -429,5 +429,5 @@
 
             im = self.ax.imshow(output, interpolation='nearest',
-                                origin='lower',
+                                # origin='lower',
                                 vmin=zmin_temp, vmax=zmax_temp,
                                 cmap=self.cmap,
@@ -494,5 +494,5 @@
         """
         Replace data in current chart.
-        This effectlvely refreshes the chart with changes to one of its plots
+        This effectively refreshes the chart with changes to one of its plots
         """
         self.plot(data=new_plot)
Index: src/sas/sascalc/calculator/resolution_calculator.py
===================================================================
--- src/sas/sascalc/calculator/resolution_calculator.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
+++ src/sas/sascalc/calculator/resolution_calculator.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -93,4 +93,5 @@
         : qy_value: y component of q
         """
+
         # make sure to update all the variables need.
         # except lambda, dlambda, and intensity
@@ -152,7 +153,4 @@
                                  sig2_list[ind], sigr_list[ind],
                                  qx_min, qx_max, qy_min, qy_max, coord)
-            # this is the case of q being outside the detector
-            #if numpy.all(out==0.0):
-            #    continue
             image = out
             # set variance as sigmas
@@ -186,4 +184,5 @@
             sigma_2 = 0
             sigma1d = 0
+
         if len(self.image) > 0:
             self.image += image_out
@@ -192,5 +191,5 @@
 
         # plot image
-        return self.plot_image(self.image)
+        return self.image  # self.plot_image(self.image)
 
     def setup_tof(self, wavelength, wavelength_spread):
@@ -214,5 +213,5 @@
                 coord='cartesian', tof=False):
         """
-        Compute the Q resoltuion in || and + direction of 2D
+        Compute the Q resolution in || and + direction of 2D
         : qx_value: x component of q
         : qy_value: y component of q
Index: src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py
===================================================================
--- src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
+++ src/sas/sasgui/perspectives/calculator/resolution_calculator_panel.py	(revision 01cda57b9e14ce69f0153005140f08837b90f28e)
@@ -934,5 +934,5 @@
     def _sigma_strings(self):
         """
-        Recode sigmas as strins
+        Recode sigmas as strings
         """
         sigma_r = self.format_number(self.resolution.sigma_1)
@@ -1208,5 +1208,5 @@
         source_hint += "Mass of %s: m = %s [g]" % \
                             (selection, str(self.resolution.get_neutron_mass()))
-        #source_tip.SetTip(source_hint)
+        # source_tip.SetTip(source_hint)
         self.mass_txt.ToolTip.SetTip(source_hint)
 
