Index: docs/sphinx-docs/source/user/analysis.rst
===================================================================
--- docs/sphinx-docs/source/user/analysis.rst	(revision 0390040b591ef533f4c6596d96661baa943c6e3b)
+++ docs/sphinx-docs/source/user/analysis.rst	(revision 8f46df726332df42af2bcc5ae02e1e0979df4753)
@@ -6,10 +6,8 @@
 .. toctree::
    :maxdepth: 1
-
+   
    Model Fitting <sasgui/perspectives/fitting/fitting>
-
+   
    P(r) Inversion <sasgui/perspectives/pr/pr_help>
-
+   
    Invariant Calculation <sasgui/perspectives/invariant/invariant_help>
-
-   Correlation Function <sasgui/perspectives/corfunc/corfunc_help>
Index: cs/sphinx-docs/source/user/sasgui/perspectives/corfunc/corfunc_help.rst
===================================================================
--- docs/sphinx-docs/source/user/sasgui/perspectives/corfunc/corfunc_help.rst	(revision 815f7b81b7d6f6f2663e7ce8b764f7cda36d00d3)
+++ 	(revision )
@@ -1,174 +1,0 @@
-.. corfunc_help.rst
-
-Correlation Function Perspective
-================================
-
-Description
------------
-
-This perspective performs a correlation function analysis of one-dimensional
-SANS data, or generates a model-independent volume fraction profile from a
-one-dimensional SANS pattern of an adsorbed layer.
-
-The correlation function analysis is performed in 3 stages:
-
-*  Extrapolation of the scattering curve to :math:`Q = 0` and
-   :math:`Q = \infty`
-*  Fourier/Hilbert Transform of the extrapolated data to give the correlation
-   function/volume fraction profile
-*  Interpretation of the 1D correlation function based on an ideal lamellar
-   morphology
-
-.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
-
-Extrapolation
--------------
-
-To :math:`Q = 0`
-^^^^^^^^^^^^^^^^
-
-The data are extrapolated to Q = 0 by fitting a Guinier model to the data
-points in the lower Q range.
-The equation used is:
-
-.. math::
-    I(Q) = Ae^{Bq^2}
-
-The Guinier model assumes that the small angle scattering arises from particles
-and that parameter :math:`B` is related to the radius of gyration of those
-particles. This has dubious applicability to polymer systems. However, the
-correlation function is affected by the Guinier back-extrapolation to the
-greatest extent at large values of R and so the back-extrapolation only has a
-small effect on the analysis.
-
-To :math:`Q = \infty`
-^^^^^^^^^^^^^^^^^^^^^
-
-The data are extrapolated to Q = :math:`\infty` by fitting a Porod model to
-the data points in the upper Q range.
-
-The equation used is:
-
-.. math::
-    I(Q) = B + KQ^{-4}e^{-Q^2\sigma^2}
-
-Where :math:`B` is the Bonart thermal background, :math:`K` is the Porod
-constant, and :math:`\sigma` describes the electron (or neutron scattering
-length) density profile at the interface between crystalline and amorphous
-regions (see figure 1).
-
-.. figure:: fig1.gif
-   :align: center
-
-   **Figure 1** The value of :math:`\sigma` is a measure of the electron
-   density profile at the interface between crystalline and amorphous regions.
-
-Smoothing
-^^^^^^^^^
-
-The extrapolated data set consists of the Guinier back-extrapolation up to the
-highest Q value of the lower Q range, the original scattering data up to the
-highest value in the upper Q range, and the Porod tail-fit beyond this. The
-joins between the original data and the Guinier/Porod fits are smoothed using
-the algorithm below, to avoid the formation of ripples in the transformed data.
-
-Functions :math:`f(x_i)` and :math:`g(x_i)` where :math:`x_i \in \left\{
-{x_1, x_2, ..., x_n} \right\}`, are smoothed over the range :math:`[a, b]`
-to produce :math:`y(x_i)`, by the following equations:
-
-.. math::
-    y(x_i) = h_ig(x_i) + (1-h_i)f(x_i)
-
-where:
-
-.. math::
-    h_i = \frac{1}{1 + \frac{(x_i-b)^2}{(x_i-a)^2}}
-
-Transform
----------
-
-Fourier
-^^^^^^^
-
-If Fourier is selected for the transform type, the perspective will perform a
-discrete cosine transform on the extrapolated data in order to calculate the
-correlation function. The following algorithm is applied:
-
-.. math::
-    \Gamma(x_k) = 2 \sum_{n=0}^{N-1} x_n \cos{\left[ \frac{\pi}{N}
-    \left(n + \frac{1}{2} \right) k \right] } \text{ for } k = 0, 1, \ldots,
-    N-1, N
-
-Hilbert
-^^^^^^^
-If Hilbert is selected for the transform type, the perspective will perform a
-Hilbert transform on the extrapolated data in order to calculate the Volume
-Fraction Profile.
-
-Interpretation
---------------
-Once the correlation function has been calculated by transforming the
-extrapolated data, it may be interpreted by clicking the "Compute Parameters"
-button. The correlation function is interpreted in terms of an ideal lamellar
-morphology, and structural parameters are obtained as shown in Figure 2 below.
-It should be noted that a small beam size is assumed; no de-smearing is
-performed.
-
-.. figure:: fig2.gif
-   :align: center
-
-   **Figure 2** Interpretation of the correlation function.
-
-The structural parameters obtained are:
-
-*   Long Period :math:`= L_p`
-*   Average Hard Block Thickness :math:`= L_c`
-*   Average Core Thickness :math:`= D_0`
-*   Average Interface Thickness :math:`\text{} = D_{tr}`
-*   Polydispersity :math:`= \Gamma_{\text{min}}/\Gamma_{\text{max}}`
-*   Local Crystallinity :math:`= L_c/L_p`
-
-.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
-
-Usage
------
-Upon sending data to the correlation function perspective, it will plot the data
-, as well as a red bar indicating the lower Q range (used for
-back-extrapolation), and 2 purple bars indicating the upper qrange (used for
-forwards-extrapolation) [figure 3]. These bars may be moved my clicking and
-dragging, or by entering the appropriate value in the Q range input boxes.
-
-.. figure:: tutorial1.png
-   :align: center
-
-   **Figure 3** A plot of some data showing the Q range bars
-
-Once the Q ranges have been set, click the "Calculate" button next to the
-background input field to calculate the Bonart thermal background level.
-Alternatively, enter your own value into the field. Click the "Extrapolate"
-button to extrapolate the data and plot the extrapolation in the same figure
-as the original data. [figure 4]
-
-.. figure:: tutorial2.png
-   :align: center
-
-   **Figure 4** A plot showing the extrapolated data and the original data
-
-Then, select which type of transform you would like to perform, using the radio
-buttons:
-
-*   **Fourier** Perform a Fourier Transform to calculate the correlation
-    function of the extrapolated data
-*   **Hilbert** Perform a Hilbert Transform to calculate the volume fraction
-    profile of the extrapolated data
-
-Clicking the transform button will then perform the selected transform and plot
-it in a new figure. If a Fourier Transform was performed, the "Compute
-Parameters" button can also be clicked to calculate values for the output
-parameters [figure 5]
-
- .. figure:: tutorial3.png
-    :align: center
-
-    **Figure 5** The Fourier Transform (correlation function) of the
-    extrapolated data, and the parameters extracted from it.
Index: sasview/sasview.py
===================================================================
--- sasview/sasview.py	(revision cde6e52c62a26bad1dd50f25b4fea01ed9ffce87)
+++ sasview/sasview.py	(revision cde6e52c62a26bad1dd50f25b4fea01ed9ffce87)
@@ -148,12 +148,4 @@
             logging.error(traceback.format_exc())
 
-        # Corfunc perspective
-        try:
-            import sas.sasgui.perspectives.corfunc as module
-            corfunc_plug = module.Plugin()
-            self.gui.add_perspective(corfunc_plug)
-        except:
-            logging.error("Unable to load corfunc module")
-
         #Calculator perspective
         try:
Index: c/sas/sascalc/corfunc/corfunc_calculator.py
===================================================================
--- src/sas/sascalc/corfunc/corfunc_calculator.py	(revision 20e09c61a4ffda6816fbc14d13be50328239ede6)
+++ 	(revision )
@@ -1,273 +1,0 @@
-"""
-This module implements corfunc
-"""
-import warnings
-import numpy as np
-from scipy.optimize import curve_fit
-from scipy.interpolate import interp1d
-from scipy.fftpack import dct
-from scipy.signal import argrelextrema
-from numpy.linalg import lstsq
-from sas.sascalc.dataloader.data_info import Data1D
-from sas.sascalc.corfunc.transform_thread import FourierThread
-from sas.sascalc.corfunc.transform_thread import HilbertThread
-
-class CorfuncCalculator(object):
-
-    class _Interpolator(object):
-        """
-        Interpolates between curve f and curve g over the range start:stop and
-        caches the result of the function when it's called
-
-        :param f: The first curve to interpolate
-        :param g: The second curve to interpolate
-        :param start: The value at which to start the interpolation
-        :param stop: The value at which to stop the interpolation
-        """
-        def __init__(self, f, g, start, stop):
-            self.f = f
-            self.g = g
-            self.start = start
-            self.stop = stop
-            self._lastx = []
-            self._lasty = []
-
-        def __call__(self, x):
-            if self._lastx == [] or x.tolist() != self._lastx.tolist():
-                self._lasty = self._smoothed_function(x)
-                self._lastx = x
-            return self._lasty
-
-        def _smoothed_function(self,x):
-            ys = np.zeros(x.shape)
-            ys[x <= self.start] = self.f(x[x <= self.start])
-            ys[x >= self.stop] = self.g(x[x >= self.stop])
-            with warnings.catch_warnings():
-                # Ignore divide by zero error
-                warnings.simplefilter('ignore')
-                h = 1/(1+(x-self.stop)**2/(self.start-x)**2)
-            mask = np.logical_and(x > self.start, x < self.stop)
-            ys[mask] = h[mask]*self.g(x[mask])+(1-h[mask])*self.f(x[mask])
-            return ys
-
-
-    def __init__(self, data=None, lowerq=None, upperq=None, scale=1):
-        """
-        Initialize the class.
-
-        :param data: Data of the type DataLoader.Data1D
-        :param lowerq: The Q value to use as the boundary for
-            Guinier extrapolation
-        :param upperq: A tuple of the form (lower, upper).
-            Values between lower and upper will be used for Porod extrapolation
-        :param scale: Scaling factor for I(q)
-        """
-        self._data = None
-        self.set_data(data, scale)
-        self.lowerq = lowerq
-        self.upperq = upperq
-        self.background = self.compute_background()
-        self._transform_thread = None
-
-    def set_data(self, data, scale=1):
-        """
-        Prepares the data for analysis
-
-        :return: new_data = data * scale - background
-        """
-        if data is None:
-            return
-        # Only process data of the class Data1D
-        if not issubclass(data.__class__, Data1D):
-            raise ValueError, "Data must be of the type DataLoader.Data1D"
-
-        # Prepare the data
-        new_data = Data1D(x=data.x, y=data.y)
-        new_data *= scale
-
-        # Ensure the errors are set correctly
-        if new_data.dy is None or len(new_data.x) != len(new_data.dy) or \
-            (min(new_data.dy) == 0 and max(new_data.dy) == 0):
-            new_data.dy = np.ones(len(new_data.x))
-
-        self._data = new_data
-
-    def compute_background(self, upperq=None):
-        """
-        Compute the background level from the Porod region of the data
-        """
-        if self._data is None: return 0
-        elif upperq is None and self.upperq is not None: upperq = self.upperq
-        elif upperq is None and self.upperq is None: return 0
-        q = self._data.x
-        mask = np.logical_and(q > upperq[0], q < upperq[1])
-        _, _, bg = self._fit_porod(q[mask], self._data.y[mask])
-
-        return bg
-
-    def compute_extrapolation(self):
-        """
-        Extrapolate and interpolate scattering data
-
-        :return: The extrapolated data
-        """
-        q = self._data.x
-        iq = self._data.y
-
-        s2 = self._fit_data(q, iq)
-        qs = np.arange(0, q[-1]*100, (q[1]-q[0]))
-        iqs = s2(qs)
-
-        extrapolation = Data1D(qs, iqs)
-
-        return extrapolation
-
-    def compute_transform(self, extrapolation, trans_type, background=None,
-        completefn=None, updatefn=None):
-        """
-        Transform an extrapolated scattering curve into a correlation function.
-
-        :param extrapolation: The extrapolated data
-        :param background: The background value (if not provided, previously
-            calculated value will be used)
-        :param completefn: The function to call when the transform calculation
-            is complete`
-        :param updatefn: The function to call to update the GUI with the status
-            of the transform calculation
-        :return: The transformed data
-        """
-        if self._transform_thread is not None:
-            if self._transform_thread.isrunning(): return
-
-        if background is None: background = self.background
-
-        if trans_type == 'fourier':
-            self._transform_thread = FourierThread(self._data, extrapolation,
-            background, completefn=completefn, updatefn=updatefn)
-        elif trans_type == 'hilbert':
-            self._transform_thread = HilbertThread(self._data, extrapolation,
-            background, completefn=completefn, updatefn=updatefn)
-        else:
-            err = ("Incorrect transform type supplied, must be 'fourier'",
-                " or 'hilbert'")
-            raise ValueError, err
-
-        self._transform_thread.queue()
-
-    def transform_isrunning(self):
-        if self._transform_thread is None: return False
-        return self._transform_thread.isrunning()
-
-    def stop_transform(self):
-        if self._transform_thread.isrunning():
-            self._transform_thread.stop()
-
-    def extract_parameters(self, transformed_data):
-        """
-        Extract the interesting measurements from a correlation function
-        :param transformed_data: Fourier transformation of the
-            extrapolated data
-        """
-        # Calculate indexes of maxima and minima
-        x = transformed_data.x
-        y = transformed_data.y
-        maxs = argrelextrema(y, np.greater)[0]
-        mins = argrelextrema(y, np.less)[0]
-
-        # If there are no maxima, return None
-        if len(maxs) == 0:
-            return None
-
-        GammaMin = y[mins[0]]  # The value at the first minimum
-
-        ddy = (y[:-2]+y[2:]-2*y[1:-1])/(x[2:]-x[:-2])**2  # 2nd derivative of y
-        dy = (y[2:]-y[:-2])/(x[2:]-x[:-2])  # 1st derivative of y
-        # Find where the second derivative goes to zero
-        zeros = argrelextrema(np.abs(ddy), np.less)[0]
-        # locate the first inflection point
-        linear_point = zeros[0]
-
-        # Try to calculate slope around linear_point using 80 data points
-        lower = linear_point - 40
-        upper = linear_point + 40
-
-        # If too few data points to the left, use linear_point*2 data points
-        if lower < 0:
-            lower = 0
-            upper = linear_point * 2
-        # If too few to right, use 2*(dy.size - linear_point) data points
-        elif upper > len(dy):
-            upper = len(dy)
-            width = len(dy) - linear_point
-            lower = 2*linear_point - dy.size
-
-        m = np.mean(dy[lower:upper])  # Linear slope
-        b = y[1:-1][linear_point]-m*x[1:-1][linear_point]  # Linear intercept
-
-        Lc = (GammaMin-b)/m  # Hard block thickness
-
-        # Find the data points where the graph is linear to within 1%
-        mask = np.where(np.abs((y-(m*x+b))/y) < 0.01)[0]
-        if len(mask) == 0:  # Return garbage for bad fits
-            return { 'max': self._round_sig_figs(x[maxs[0]], 6) }
-        dtr = x[mask[0]]  # Beginning of Linear Section
-        d0 = x[mask[-1]]  # End of Linear Section
-        GammaMax = y[mask[-1]]
-        A = np.abs(GammaMin/GammaMax)  # Normalized depth of minimum
-
-        params = {
-            'max': x[maxs[0]],
-            'dtr': dtr,
-            'Lc': Lc,
-            'd0': d0,
-            'A': A,
-            'fill': Lc/x[maxs[0]]
-        }
-
-        return params
-
-
-    def _porod(self, q, K, sigma, bg):
-        """Equation for the Porod region of the data"""
-        return bg + (K*q**(-4))*np.exp(-q**2*sigma**2)
-
-    def _fit_guinier(self, q, iq):
-        """Fit the Guinier region of the curve"""
-        A = np.vstack([q**2, np.ones(q.shape)]).T
-        return lstsq(A, np.log(iq))
-
-    def _fit_porod(self, q, iq):
-        """Fit the Porod region of the curve"""
-        fitp = curve_fit(lambda q, k, sig, bg: self._porod(q, k, sig, bg)*q**2,
-                         q, iq*q**2)[0]
-        k, sigma, bg = fitp
-        return k, sigma, bg
-
-    def _fit_data(self, q, iq):
-        """
-        Given a data set, extrapolate out to large q with Porod and
-        to q=0 with Guinier
-        """
-        mask = np.logical_and(q > self.upperq[0], q < self.upperq[1])
-
-        # Returns an array where the 1st and 2nd elements are the values of k
-        # and sigma for the best-fit Porod function
-        k, sigma, _ = self._fit_porod(q[mask], iq[mask])
-        bg = self.background
-
-        # Smooths between the best-fit porod function and the data to produce a
-        # better fitting curve
-        data = interp1d(q, iq)
-        s1 = self._Interpolator(data,
-            lambda x: self._porod(x, k, sigma, bg), self.upperq[0], q[-1])
-
-        mask = np.logical_and(q < self.lowerq, 0 < q)
-
-        # Returns parameters for the best-fit Guinier function
-        g = self._fit_guinier(q[mask], iq[mask])[0]
-
-        # Smooths between the best-fit Guinier function and the Porod curve
-        s2 = self._Interpolator((lambda x: (np.exp(g[1]+g[0]*x**2))), s1, q[0],
-            self.lowerq)
-
-        return s2
Index: c/sas/sascalc/corfunc/transform_thread.py
===================================================================
--- src/sas/sascalc/corfunc/transform_thread.py	(revision d03228e40acd75d47d8dad9f9401dcde8e5a280c)
+++ 	(revision )
@@ -1,66 +1,0 @@
-from sas.sascalc.data_util.calcthread import CalcThread
-from sas.sascalc.dataloader.data_info import Data1D
-from scipy.fftpack import dct
-import numpy as np
-from time import sleep
-
-class FourierThread(CalcThread):
-    def __init__(self, raw_data, extrapolated_data, bg, updatefn=None,
-        completefn=None):
-        CalcThread.__init__(self, updatefn=updatefn, completefn=completefn)
-        self.data = raw_data
-        self.background = bg
-        self.extrapolation = extrapolated_data
-
-    def compute(self):
-        qs = self.extrapolation.x
-        iqs = self.extrapolation.y
-        q = self.data.x
-        background = self.background
-
-        self.ready(delay=0.0)
-        self.update(msg="Starting Fourier transform.")
-        self.ready(delay=0.0)
-        if self.isquit():
-            return
-        try:
-            gamma = dct((iqs-background)*qs**2)
-            gamma = gamma / gamma.max()
-        except:
-            self.update(msg="Fourier transform failed.")
-            self.complete(transform=None)
-            return
-        if self.isquit():
-            return
-        self.update(msg="Fourier transform completed.")
-
-        xs = np.pi*np.arange(len(qs),dtype=np.float32)/(q[1]-q[0])/len(qs)
-        transform = Data1D(xs, gamma)
-
-        self.complete(transform=transform)
-
-class HilbertThread(CalcThread):
-    def __init__(self, raw_data, extrapolated_data, bg, updatefn=None,
-        completefn=None):
-        CalcThread.__init__(self, updatefn=updatefn, completefn=completefn)
-        self.data = raw_data
-        self.background = bg
-        self.extrapolation = extrapolated_data
-
-    def compute(self):
-        qs = self.extrapolation.x
-        iqs = self.extrapolation.y
-        q = self.data.x
-        background = self.background
-
-        self.ready(delay=0.0)
-        self.update(msg="Starting Hilbert transform.")
-        self.ready(delay=0.0)
-        if self.isquit():
-            return
-
-        # TODO: Implement hilbert transform
-
-        self.update(msg="Hilbert transform completed.")
-
-        self.complete(transform=None)
Index: src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py
===================================================================
--- src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py	(revision 895c9cb3dcc39d7f29513916f04e9863484692c8)
+++ src/sas/sasgui/guiframe/local_perspectives/plotting/Plotter1D.py	(revision 895c9cb3dcc39d7f29513916f04e9863484692c8)
@@ -95,7 +95,4 @@
         self.parent.SetFocus()
 
-        # If true, there are 3 qrange bars
-        self.is_corfunc = False
-
 
     def get_symbol_label(self):
@@ -217,6 +214,4 @@
         if active_ctrl == None:
             return
-        if hasattr(event, 'is_corfunc'):
-            self.is_corfunc = event.is_corfunc
         if event.id in self.plots.keys():
             ctrl = event.ctrl
@@ -227,7 +222,4 @@
             values = [max(x_data.min(), float(ctrl[0].GetValue())),
                       min(x_data.max(), float(ctrl[1].GetValue()))]
-            if len(ctrl) == 3:
-                colors.append('purple')
-                values.append(min(x_data.max(), float(ctrl[2].GetValue())))
             if self.ly == None:
                 self.ly = []
@@ -301,6 +293,4 @@
         ly0x = ly[0].get_xdata()
         ly1x = ly[1].get_xdata()
-        ly2x = None
-        if self.is_corfunc: ly2x = ly[2].get_xdata()
         self.q_ctrl[0].SetBackgroundColour('white')
         self.q_ctrl[1].SetBackgroundColour('white')
@@ -316,14 +306,4 @@
                 self.q_ctrl[0].SetValue(str(pos_x))
                 self.q_ctrl[1].SetBackgroundColour('pink')
-        elif ly2x is not None and ly1x >= ly2x:
-            if self.vl_ind == 1:
-                ly[2].set_xdata(posx)
-                ly[2].set_zorder(nop)
-                self.q_ctrl[2].SetValue(str(pos_x))
-            elif self.vl_ind == 2:
-                ly[1].set_xdata(posx)
-                ly[1].set_zorder(nop)
-                self.q_ctrl[1].SetValue(str(pos_x))
-
 
     def _get_cusor_lines(self, event):
@@ -345,14 +325,9 @@
             dqmin = math.fabs(event.xdata - self.ly[0].get_xdata())
             dqmax = math.fabs(event.xdata - self.ly[1].get_xdata())
-            if not self.is_corfunc:
-                is_qmax = dqmin > dqmax
-                if is_qmax:
-                    self.vl_ind = 1
-                else:
-                    self.vl_ind = 0
+            is_qmax = dqmin > dqmax
+            if is_qmax:
+                self.vl_ind = 1
             else:
-                dqmax2 = math.fabs(event.xdata - self.ly[2].get_xdata())
-                closest = min(dqmin, dqmax, dqmax2)
-                self.vl_ind = { dqmin: 0, dqmax: 1, dqmax2: 2 }.get(closest)
+                self.vl_ind = 0
 
     def cusor_line(self, event):
Index: c/sas/sasgui/perspectives/corfunc/__init__.py
===================================================================
--- src/sas/sasgui/perspectives/corfunc/__init__.py	(revision c23f303448cfceb9e5a58e5d7da46258cdb3cbd8)
+++ 	(revision )
@@ -1,2 +1,0 @@
-PLUGIN_ID = "Corfunc Plug-In 0.1"
-from corfunc import *
Index: c/sas/sasgui/perspectives/corfunc/corfunc.py
===================================================================
--- src/sas/sasgui/perspectives/corfunc/corfunc.py	(revision 6f343e3a15884f25a9c9df31c2d674a355df473d)
+++ 	(revision )
@@ -1,201 +1,0 @@
-"""
-    Corfunc perspective
-"""
-import wx
-import sys
-import logging
-import copy
-from sas.sasgui.guiframe.plugin_base import PluginBase
-from sas.sasgui.guiframe.gui_manager import MDIFrame
-from sas.sasgui.guiframe.events import StatusEvent
-from sas.sasgui.guiframe.events import NewPlotEvent
-from sas.sasgui.guiframe.gui_style import GUIFRAME_ID
-from sas.sasgui.perspectives.corfunc.corfunc_panel import CorfuncPanel
-from sas.sasgui.guiframe.dataFitting import Data1D
-from sas.sasgui.perspectives.pr.pr_widgets import DataDialog
-from sas.sasgui.perspectives.corfunc.corfunc_state import Reader
-from sas.sascalc.dataloader.loader import Loader
-import sas.sascalc.dataloader
-from plot_labels import *
-
-
-class Plugin(PluginBase):
-    """
-    This class defines the interface for a plugin class for a correlation
-    function perspective
-    """
-
-    def __init__(self):
-        PluginBase.__init__(self, name="Correlation Function")
-        logging.info("Correlation function plug-in started")
-        self._always_active = True
-        self.state_reader = Reader(self.set_state)
-        self._extensions = '.cor'
-        l = Loader()
-        l.associate_file_reader('.cor', self.state_reader)
-
-    def get_panels(self, parent):
-        """
-        Define the GUI panels
-        """
-        self.parent = parent
-        self.frame = MDIFrame(self.parent, None, 'None', (100,200))
-        self.data_id = IQ_DATA_LABEL
-        self.corfunc_panel = CorfuncPanel(parent=self.frame)
-        self.frame.set_panel(self.corfunc_panel)
-        self.corfunc_panel.set_manager(self)
-        self._frame_set_helper()
-        self.perspective.append(self.corfunc_panel.window_name)
-
-        return [self.corfunc_panel]
-
-    def get_context_menu(self, plotpanel=None):
-        """
-        Get the context menu items available for Corfunc.
-
-        :param plotpanel: A Plotter1D panel
-
-        :return: a list of menu items with call-back function
-
-        :note: if Data1D was generated from Theory1D
-                the fitting option is not allowed
-        """
-        graph = plotpanel.graph
-        if graph.selected_plottable not in plotpanel.plots:
-            return []
-        data = plotpanel.plots[graph.selected_plottable]
-        if data.id == IQ_DATA_LABEL or data.id == IQ_EXTRAPOLATED_DATA_LABEL or data.id == TRANSFORM_LABEL:
-            return []
-        item = plotpanel.plots[graph.selected_plottable]
-        if item.__class__.__name__ is "Data2D":
-            return []
-        elif item.__class__.__name__ is "Data1D":
-            return [["Select data in corfunc",
-                "Send this data to the correlation function perspective",
-                self._on_select_data]]
-
-
-
-    def set_state(self, state=None, datainfo=None):
-        """
-        Callback for CorfuncState reader. Called when a .cor file is loaded
-        """
-        self.corfunc_panel.set_state(state=state, data=datainfo)
-
-    def set_data(self, data_list=None):
-        """
-        Load the data that's been selected
-
-        :param data_list: The data to load in
-        """
-        if data_list is None:
-            data_list = []
-        if len(data_list) >= 1:
-            msg = ""
-            if len(data_list) == 1:
-                data = data_list[0]
-            else:
-                data_1d_list = []
-                data_2d_list = []
-                err_msg = ""
-
-                for data in data_list:
-                    if data is not None:
-                        if issubclass(data.__class__, Data1D):
-                            data_1d_list.append(data)
-                        else:
-                            err_msg += "{} type {} \n".format(str(data.name),
-                                str(data.__class__))
-                            data_2d_list.append(data)
-                if len(data_2d_list) > 0:
-                    msg = "Corfunc doesn't support the following data types:\n"
-                    msg += err_msg
-                if len(data_1d_list) == 0:
-                    msg += "No data recieved"
-                    wx.PostEvent(self.parent, StatusEvent(status=msg,
-                                                info='error'))
-                    return
-                elif len(data_list) > 1:
-                    msg = "Corfunc does not allow multiple data\n"
-                    msg += "Please select one.\n"
-                    dlg = DataDialog(data_list=data_1d_list, text=msg)
-                    if dlg.ShowModal() == wx.ID_OK:
-                        data = dlg.get_data()
-                    else:
-                        data = None
-                    dlg.Destroy()
-
-            if data is None:
-                msg += "Corfunc recieved no data\n"
-                wx.PostEvent(self.parent, StatusEvent(status=msg,
-                                            info='error'))
-                return
-            if issubclass(data.__class__, Data1D):
-                try:
-                    wx.PostEvent(self.parent, NewPlotEvent(action='remove',
-                                                group_id=GROUP_ID_IQ_DATA,
-                                                id=self.data_id))
-                    self.data_id = data.id
-                    self.corfunc_panel.set_data(data)
-                except:
-                    msg = "Corfunc set_data: " + str(sys.exc_value)
-                    wx.PostEvent(self.parent, StatusEvent(status=msg,
-                        info='error'))
-
-    def delete_data(self, data):
-        """
-        Delete the data from the perspective
-        """
-        self.clear_data()
-        self.corfunc_panel.set_data(None)
-
-    def show_data(self, data, label, reset=False, active_ctrl=None):
-        """
-        Show data read from a file
-
-        :param data: The data to plot (Data1D)
-        :param label: What to label the plot. Also used as the plot ID
-        :param reset: If True, all other plottables will be cleared
-        """
-        new_plot = Data1D(data.x, copy.deepcopy(data.y), dy=data.dy)
-        group_id = ""
-        if label == IQ_DATA_LABEL or label == IQ_EXTRAPOLATED_DATA_LABEL:
-            new_plot.xaxis("\\rm{Q}", 'A^{-1}')
-            new_plot.yaxis("\\rm{Intensity} ", "cm^{-1}")
-            new_plot.y -= self.corfunc_panel.background
-            group_id = GROUP_ID_IQ_DATA
-            if label == IQ_EXTRAPOLATED_DATA_LABEL:
-                new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
-        elif label == TRANSFORM_LABEL:
-            new_plot.xaxis("{x}", 'A')
-            new_plot.yaxis("{\\Gamma}", '')
-            group_id = GROUP_ID_TRANSFORM
-            new_plot.symbol = GUIFRAME_ID.CURVE_SYMBOL_NUM
-        new_plot.id = label
-        new_plot.name = label
-        new_plot.group_id = group_id
-        new_plot.interactive = True
-        new_plot.title = group_id.replace('$', '').replace('\\', '')
-        # Show data on a linear scale
-        new_plot.xtransform = 'x'
-        new_plot.ytransform = 'y'
-        wx.PostEvent(self.parent,
-                     NewPlotEvent(plot=new_plot, title=new_plot.title,
-                        reset=reset))
-        if label == IQ_DATA_LABEL or label == IQ_EXTRAPOLATED_DATA_LABEL:
-            wx.CallAfter(self.corfunc_panel.plot_qrange, active=active_ctrl,
-                leftdown=True)
-
-    def clear_data(self):
-        wx.PostEvent(self.parent,
-            NewPlotEvent(action='delete', group_id=GROUP_ID_TRANSFORM))
-        wx.PostEvent(self.parent,
-            NewPlotEvent(action='clear', group_id=GROUP_ID_IQ_DATA))
-
-    def _on_select_data(self, event):
-        panel = event.GetEventObject()
-        if not panel.graph.selected_plottable in panel.plots:
-            return
-        data = panel.plots[panel.graph.selected_plottable]
-        print "Data id is: {}".format(data.id)
-        self.set_data([data])
Index: c/sas/sasgui/perspectives/corfunc/corfunc_panel.py
===================================================================
--- src/sas/sasgui/perspectives/corfunc/corfunc_panel.py	(revision e8418bb4b278ec748c5d913142fe060b6c1c4e4b)
+++ 	(revision )
@@ -1,654 +1,0 @@
-import wx
-import sys
-import numpy as np
-from wx.lib.scrolledpanel import ScrolledPanel
-from sas.sasgui.guiframe.events import PlotQrangeEvent
-from sas.sasgui.guiframe.events import StatusEvent
-from sas.sasgui.guiframe.panel_base import PanelBase
-from sas.sasgui.guiframe.utils import check_float
-from sas.sasgui.guiframe.dataFitting import Data1D
-from sas.sasgui.perspectives.invariant.invariant_widgets import OutputTextCtrl
-from sas.sasgui.perspectives.invariant.invariant_widgets import InvTextCtrl
-from sas.sasgui.perspectives.fitting.basepage import ModelTextCtrl
-from sas.sasgui.perspectives.corfunc.corfunc_state import CorfuncState
-import sas.sasgui.perspectives.corfunc.corfunc
-from sas.sascalc.corfunc.corfunc_calculator import CorfuncCalculator
-from sas.sasgui.guiframe.documentation_window import DocumentationWindow
-from plot_labels import *
-
-OUTPUT_STRINGS = {
-    'max': "Long Period (A): ",
-    'Lc': "Average Hard Block Thickness (A): ",
-    'dtr': "Average Interface Thickness (A): ",
-    'd0': "Average Core Thickness: ",
-    'A': "Polydispersity: ",
-    'fill': "Local Crystallinity: "
-}
-
-if sys.platform.count("win32") > 0:
-    _STATICBOX_WIDTH = 350
-    PANEL_WIDTH = 400
-    PANEL_HEIGHT = 700
-    FONT_VARIANT = 0
-else:
-    _STATICBOX_WIDTH = 390
-    PANEL_WIDTH = 430
-    PANEL_HEIGHT = 700
-    FONT_VARIANT = 1
-
-class CorfuncPanel(ScrolledPanel,PanelBase):
-    window_name = "Correlation Function"
-    window_caption = "Correlation Function"
-    CENTER_PANE = True
-
-    def __init__(self, parent, data=None, manager=None, *args, **kwds):
-        kwds["size"] = (PANEL_WIDTH, PANEL_HEIGHT)
-        kwds["style"] = wx.FULL_REPAINT_ON_RESIZE
-        ScrolledPanel.__init__(self, parent=parent, *args, **kwds)
-        PanelBase.__init__(self, parent)
-        self.SetupScrolling()
-        self.SetWindowVariant(variant=FONT_VARIANT)
-        self._manager = manager
-        # The data with no correction for background values
-        self._data = data # The data to be analysed (corrected fr background)
-        self._extrapolated_data = None # The extrapolated data set
-        self._transformed_data = None # Fourier trans. of the extrapolated data
-        self._calculator = CorfuncCalculator()
-        self._data_name_box = None # Text box to show name of file
-        self._background_input = None
-        self._qmin_input = None
-        self._qmax1_input = None
-        self._qmax2_input = None
-        self._extrapolate_btn = None
-        self._transform_btn = None
-        self._extract_btn = None
-        self.qmin = 0
-        self.qmax = (0, 0)
-        self.background = 0
-        self.extracted_params = None
-        self.transform_type = 'fourier'
-        # Dictionary for saving refs to text boxes used to display output data
-        self._output_boxes = None
-        self.state = None
-        self._do_layout()
-        self._disable_inputs()
-        self.set_state()
-        self._qmin_input.Bind(wx.EVT_TEXT, self._on_enter_input)
-        self._qmax1_input.Bind(wx.EVT_TEXT, self._on_enter_input)
-        self._qmax2_input.Bind(wx.EVT_TEXT, self._on_enter_input)
-        self._qmin_input.Bind(wx.EVT_MOUSE_EVENTS, self._on_click_qrange)
-        self._qmax1_input.Bind(wx.EVT_MOUSE_EVENTS, self._on_click_qrange)
-        self._qmax2_input.Bind(wx.EVT_MOUSE_EVENTS, self._on_click_qrange)
-        self._background_input.Bind(wx.EVT_TEXT, self._on_enter_input)
-
-    def set_state(self, state=None, data=None):
-        """
-        Set the state of the panel. If no state is provided, the panel will
-        be set to the default state.
-
-        :param state: A CorfuncState object
-        :param data: A Data1D object
-        """
-        if state is None:
-            self.state = CorfuncState()
-        else:
-            self.state = state
-        if data is not None:
-            self.state.data = data
-        self.set_data(data, set_qrange=False)
-        if self.state.qmin is not None:
-            self.set_qmin(self.state.qmin)
-        if self.state.qmax is not None and self.state.qmax != (None, None):
-            self.set_qmax(tuple(self.state.qmax))
-        if self.state.background is not None:
-            self.set_background(self.state.background)
-        if self.state.is_extrapolated:
-            self.compute_extrapolation()
-        else:
-            return
-        if self.state.is_transformed:
-            self.compute_transform()
-        else:
-            return
-        if self.state.outputs is not None and self.state.outputs != {}:
-            self.set_extracted_params(self.state.outputs, reset=True)
-
-    def get_state(self):
-        """
-        Return the state of the panel
-        """
-        state = CorfuncState()
-        state.set_saved_state('qmin_tcl', self.qmin)
-        state.set_saved_state('qmax1_tcl', self.qmax[0])
-        state.set_saved_state('qmax2_tcl', self.qmax[1])
-        state.set_saved_state('background_tcl', self.background)
-        state.outputs = self.extracted_params
-        if self._data is not None:
-            state.file = self._data.title
-            state.data = self._data
-        if self._extrapolated_data is not None:
-            state.is_extrapolated = True
-        if self._transformed_data is not None:
-            state.is_transformed = True
-        self.state = state
-
-        return self.state
-
-    def onSetFocus(self, evt):
-        if evt is not None:
-            evt.Skip()
-        self._validate_inputs()
-
-    def set_data(self, data=None, set_qrange=True):
-        """
-        Update the GUI to reflect new data that has been loaded in
-
-        :param data: The data that has been loaded
-        """
-        if data is None:
-            self._disable_inputs()
-            self.set_extracted_params(reset=True)
-            self._data = None
-            return
-        self._enable_inputs()
-        self._transform_btn.Disable()
-        self._extract_btn.Disable()
-        self._data_name_box.SetValue(str(data.title))
-        self._data = data
-        self._calculator.set_data(data)
-        # Reset the outputs
-        self.set_extracted_params(None, reset=True)
-        if self._manager is not None:
-            self._manager.clear_data()
-            self._manager.show_data(self._data, IQ_DATA_LABEL, reset=True)
-
-        if set_qrange:
-            lower = data.x[-1]*0.05
-            upper1 = data.x[-1] - lower*5
-            upper2 = data.x[-1]
-            self.set_qmin(lower)
-            self.set_qmax((upper1, upper2))
-            self.set_background(self._calculator.compute_background(self.qmax))
-
-    def get_data(self):
-        return self._data
-
-    def radio_changed(self, event=None):
-        if event is not None:
-            self.transform_type = event.GetEventObject().GetName()
-
-    def compute_extrapolation(self, event=None):
-        """
-        Compute and plot the extrapolated data.
-        Called when Extrapolate button is pressed.
-        """
-        if not self._validate_inputs:
-            msg = "Invalid Q range entered."
-            wx.PostEvent(self.parent.parent, StatusEvent(status=msg))
-            return
-        self._calculator.set_data(self._data)
-        self._calculator.lowerq = self.qmin
-        self._calculator.upperq = self.qmax
-        self._calculator.background = self.background
-        try:
-            self._extrapolated_data = self._calculator.compute_extrapolation()
-        except:
-            msg = "Error extrapolating data."
-            wx.PostEvent(self._manager.parent,
-                StatusEvent(status=msg, info="Error"))
-            self._transform_btn.Disable()
-            return
-        # TODO: Find way to set xlim and ylim so full range of data can be
-        # plotted but zoomed in
-        maxq = self._data.x.max()
-        mask = self._extrapolated_data.x <= maxq
-        numpts = len(self._extrapolated_data.x[mask]) + 250
-        plot_x = self._extrapolated_data.x[0:numpts]
-        plot_y = self._extrapolated_data.y[0:numpts]
-        to_plot = Data1D(plot_x, plot_y)
-        self._manager.show_data(to_plot, IQ_EXTRAPOLATED_DATA_LABEL)
-        # Update state of the GUI
-        self._transform_btn.Enable()
-        self._extract_btn.Disable()
-        self.set_extracted_params(reset=True)
-
-    def compute_transform(self, event=None):
-        """
-        Compute and plot the transformed data.
-        Called when Transform button is pressed.
-        """
-        if not self._calculator.transform_isrunning():
-            self._calculator.compute_transform(self._extrapolated_data,
-                self.transform_type, background=self.background,
-                completefn=self.transform_complete,
-                updatefn=self.transform_update)
-
-            self._transform_btn.SetLabel("Stop Transform")
-        else:
-            self._calculator.stop_transform()
-            self.transform_update("Transform cancelled.")
-            self._transform_btn.SetLabel("Transform")
-
-    def transform_update(self, msg=""):
-        """
-        Called from FourierThread to update on status of calculation
-        """
-        wx.PostEvent(self._manager.parent,
-            StatusEvent(status=msg))
-
-    def transform_complete(self, transform=None):
-        """
-        Called from FourierThread when calculation has completed
-        """
-        self._transform_btn.SetLabel("Transform")
-        if transform is None:
-            msg = "Error calculating Transform."
-            if self.transform_type == 'hilbert':
-                msg = "Not yet implemented"
-            wx.PostEvent(self._manager.parent,
-                StatusEvent(status=msg, info="Error"))
-            self._extract_btn.Disable()
-            return
-        self._transformed_data = transform
-        import numpy as np
-        plot_x = transform.x[np.where(transform.x <= 200)]
-        plot_y = transform.y[np.where(transform.x <= 200)]
-        self._manager.show_data(Data1D(plot_x, plot_y), TRANSFORM_LABEL)
-        # Only enable extract params button if a fourier trans. has been done
-        if self.transform_type == 'fourier':
-            self._extract_btn.Enable()
-        else:
-            self._extract_btn.Disable()
-
-    def extract_parameters(self, event=None):
-        try:
-            params = self._calculator.extract_parameters(self._transformed_data)
-        except:
-            params = None
-        if params is None:
-            msg = "Error extracting parameters."
-            wx.PostEvent(self._manager.parent,
-                StatusEvent(status=msg, info="Error"))
-            return
-        self.set_extracted_params(params)
-
-    def on_help(self, event=None):
-        """
-        Show the corfunc documentation
-        """
-        tree_location = "user/sasgui/perspectives/corfunc/corfunc_help.html"
-        doc_viewer = DocumentationWindow(self, -1, tree_location, "",
-                                          "Correlation Function Help")
-
-    def save_project(self, doc=None):
-        """
-        Return an XML node containing the state of the panel
-
-        :param doc: Am xml node to attach the project state to (optional)
-        """
-        data = self._data
-        state = self.get_state()
-        if data is not None:
-            new_doc, sasentry = self._manager.state_reader._to_xml_doc(data)
-            new_doc = state.toXML(doc=new_doc, entry_node=sasentry)
-            if new_doc is not None:
-                if doc is not None and hasattr(doc, "firstChild"):
-                    child = new_doc.getElementsByTagName("SASentry")
-                    for item in child:
-                        doc.firstChild.appendChild(item)
-                else:
-                    doc = new_doc
-        return doc
-
-    def set_qmin(self, qmin):
-        self.qmin = qmin
-        self._qmin_input.SetValue(str(qmin))
-
-    def set_qmax(self, qmax):
-        self.qmax = qmax
-        self._qmax1_input.SetValue(str(qmax[0]))
-        self._qmax2_input.SetValue(str(qmax[1]))
-
-    def set_background(self, bg):
-        self.background = bg
-        self._background_input.SetValue(str(bg))
-        self._calculator.background = bg
-
-    def set_extracted_params(self, params=None, reset=False):
-        self.extracted_params = params
-        error = False
-        if params is None:
-            if not reset: error = True
-            for key in OUTPUT_STRINGS.keys():
-                self._output_boxes[key].SetValue('-')
-        else:
-            if len(params) < len(OUTPUT_STRINGS):
-                # Not all parameters were calculated
-                error = True
-            for key, value in params.iteritems():
-                rounded = self._round_sig_figs(value, 6)
-                self._output_boxes[key].SetValue(rounded)
-        if error:
-            msg = 'Not all parameters were able to be calculated'
-            wx.PostEvent(self._manager.parent, StatusEvent(
-                status=msg, info='error'))
-
-
-    def plot_qrange(self, active=None, leftdown=False):
-        if active is None:
-            active = self._qmin_input
-        wx.PostEvent(self._manager.parent, PlotQrangeEvent(
-            ctrl=[self._qmin_input, self._qmax1_input, self._qmax2_input],
-            active=active, id=IQ_DATA_LABEL, is_corfunc=True,
-            group_id=GROUP_ID_IQ_DATA, leftdown=leftdown))
-
-
-    def _compute_background(self, event=None):
-        self.set_background(self._calculator.compute_background(self.qmax))
-
-    def _on_enter_input(self, event=None):
-        """
-        Read values from input boxes and save to memory.
-        """
-        if event is not None: event.Skip()
-        if not self._validate_inputs():
-            return
-        self.qmin = float(self._qmin_input.GetValue())
-        new_qmax1 = float(self._qmax1_input.GetValue())
-        new_qmax2 = float(self._qmax2_input.GetValue())
-        self.qmax = (new_qmax1, new_qmax2)
-        self.background = float(self._background_input.GetValue())
-        self._calculator.background = self.background
-        if event is not None:
-            active_ctrl = event.GetEventObject()
-            if active_ctrl == self._background_input:
-                self._manager.show_data(self._data, IQ_DATA_LABEL,
-                    reset=False, active_ctrl=active_ctrl)
-
-    def _on_click_qrange(self, event=None):
-        if event is None:
-            return
-        event.Skip()
-        if not self._validate_inputs(): return
-        self.plot_qrange(active=event.GetEventObject(),
-            leftdown=event.LeftDown())
-
-    def _validate_inputs(self):
-        """
-        Check that the values for qmin and qmax in the input boxes are valid
-        """
-        if self._data is None:
-            return False
-        qmin_valid = check_float(self._qmin_input)
-        qmax1_valid = check_float(self._qmax1_input)
-        qmax2_valid = check_float(self._qmax2_input)
-        qmax_valid = qmax1_valid and qmax2_valid
-        background_valid = check_float(self._background_input)
-        msg = ""
-        if (qmin_valid and qmax_valid and background_valid):
-            qmin = float(self._qmin_input.GetValue())
-            qmax1 = float(self._qmax1_input.GetValue())
-            qmax2 = float(self._qmax2_input.GetValue())
-            background = float(self._background_input.GetValue())
-            if not qmin > self._data.x.min():
-                msg = "qmin must be greater than the lowest q value"
-                qmin_valid = False
-            elif qmax2 < qmax1:
-                msg = "qmax1 must be less than qmax2"
-                qmax_valid = False
-            elif qmin > qmax1:
-                msg = "qmin must be less than qmax"
-                qmin_valid = False
-            elif background > self._data.y.max():
-                msg = "background must be less than highest I"
-                background_valid = False
-        if not qmin_valid:
-            self._qmin_input.SetBackgroundColour('pink')
-        if not qmax_valid:
-            self._qmax1_input.SetBackgroundColour('pink')
-            self._qmax2_input.SetBackgroundColour('pink')
-        if not background_valid:
-            self._background_input.SetBackgroundColour('pink')
-            if msg != "":
-                wx.PostEvent(self._manager.parent, StatusEvent(status=msg))
-        if (qmin_valid and qmax_valid and background_valid):
-            self._qmin_input.SetBackgroundColour(wx.WHITE)
-            self._qmax1_input.SetBackgroundColour(wx.WHITE)
-            self._qmax2_input.SetBackgroundColour(wx.WHITE)
-            self._background_input.SetBackgroundColour(wx.WHITE)
-        self._qmin_input.Refresh()
-        self._qmax1_input.Refresh()
-        self._qmax2_input.Refresh()
-        self._background_input.Refresh()
-        return (qmin_valid and qmax_valid and background_valid)
-
-    def _do_layout(self):
-        """
-        Draw the window content
-        """
-        vbox = wx.GridBagSizer(0,0)
-
-        # I(q) data box
-        databox = wx.StaticBox(self, -1, "I(Q) Data Source")
-        databox_sizer = wx.StaticBoxSizer(databox, wx.VERTICAL)
-
-        file_sizer = wx.GridBagSizer(5, 5)
-
-        file_name_label = wx.StaticText(self, -1, "Name:")
-        file_sizer.Add(file_name_label, (0, 0), (1, 1),
-            wx.LEFT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
-
-        self._data_name_box = OutputTextCtrl(self, -1,
-            size=(300,20))
-        file_sizer.Add(self._data_name_box, (0, 1), (1, 1),
-            wx.CENTER | wx.ADJUST_MINSIZE, 15)
-
-        file_sizer.AddSpacer((1, 25), pos=(0,2))
-        databox_sizer.Add(file_sizer, wx.TOP, 15)
-
-        vbox.Add(databox_sizer, (0, 0), (1, 1),
-            wx.LEFT | wx.RIGHT | wx.EXPAND | wx.ADJUST_MINSIZE | wx.TOP, 15)
-
-
-        # Parameters
-        qbox = wx.StaticBox(self, -1, "Input Parameters")
-        qbox_sizer = wx.StaticBoxSizer(qbox, wx.VERTICAL)
-        qbox_sizer.SetMinSize((_STATICBOX_WIDTH, 75))
-
-        q_sizer = wx.GridBagSizer(5, 5)
-
-        # Explanation
-        explanation_txt = ("Corfunc will use all values in the lower range for"
-            " Guinier back extrapolation, and all values in the upper range "
-            "for Porod forward extrapolation.")
-        explanation_label = wx.StaticText(self, -1, explanation_txt,
-            size=(_STATICBOX_WIDTH, 60))
-
-        q_sizer.Add(explanation_label, (0,0), (1,4), wx.LEFT | wx.EXPAND, 5)
-
-        qrange_label = wx.StaticText(self, -1, "Q Range:", size=(50,20))
-        q_sizer.Add(qrange_label, (1,0), (1,1), wx.LEFT | wx.EXPAND, 5)
-
-        # Lower Q Range
-        qmin_label = wx.StaticText(self, -1, "Lower:", size=(50,20))
-        qmin_dash_label = wx.StaticText(self, -1, "-", size=(10,20),
-            style=wx.ALIGN_CENTER_HORIZONTAL)
-
-        qmin_lower = OutputTextCtrl(self, -1, size=(75, 20), value="0.0")
-        self._qmin_input = ModelTextCtrl(self, -1, size=(75, 20),
-                        style=wx.TE_PROCESS_ENTER, name='qmin_input',
-                        text_enter_callback=self._on_enter_input)
-        self._qmin_input.SetToolTipString(("Values with q < qmin will be used "
-            "for Guinier back extrapolation"))
-
-        q_sizer.Add(qmin_label, (2, 0), (1, 1), wx.LEFT | wx.EXPAND, 5)
-        q_sizer.Add(qmin_lower, (2, 1), (1, 1), wx.LEFT, 5)
-        q_sizer.Add(qmin_dash_label, (2, 2), (1, 1), wx.CENTER | wx.EXPAND, 5)
-        q_sizer.Add(self._qmin_input, (2, 3), (1, 1), wx.LEFT, 5)
-
-        # Upper Q range
-        qmax_tooltip = ("Values with qmax1 < q < qmax2 will be used for Porod"
-            " forward extrapolation")
-
-        qmax_label = wx.StaticText(self, -1, "Upper:", size=(50,20))
-        qmax_dash_label = wx.StaticText(self, -1, "-", size=(10,20),
-            style=wx.ALIGN_CENTER_HORIZONTAL)
-
-        self._qmax1_input = ModelTextCtrl(self, -1, size=(75, 20),
-            style=wx.TE_PROCESS_ENTER, name="qmax1_input",
-            text_enter_callback=self._on_enter_input)
-        self._qmax1_input.SetToolTipString(qmax_tooltip)
-        self._qmax2_input = ModelTextCtrl(self, -1, size=(75, 20),
-            style=wx.TE_PROCESS_ENTER, name="qmax2_input",
-            text_enter_callback=self._on_enter_input)
-        self._qmax2_input.SetToolTipString(qmax_tooltip)
-
-        q_sizer.Add(qmax_label, (3, 0), (1, 1), wx.LEFT | wx.EXPAND, 5)
-        q_sizer.Add(self._qmax1_input, (3, 1), (1, 1), wx.LEFT, 5)
-        q_sizer.Add(qmax_dash_label, (3, 2), (1, 1), wx.CENTER | wx.EXPAND, 5)
-        q_sizer.Add(self._qmax2_input, (3,3), (1, 1), wx.LEFT, 5)
-
-        background_label = wx.StaticText(self, -1, "Background:", size=(80,20))
-        q_sizer.Add(background_label, (4,0), (1,1), wx.LEFT | wx.EXPAND, 5)
-
-        self._background_input = ModelTextCtrl(self, -1, size=(75,20),
-            style=wx.TE_PROCESS_ENTER, name='background_input',
-            text_enter_callback=self._on_enter_input)
-        self._background_input.SetToolTipString(("A background value to "
-            "subtract from all intensity values"))
-        q_sizer.Add(self._background_input, (4,1), (1,1),
-            wx.RIGHT, 5)
-
-        background_button = wx.Button(self, wx.NewId(), "Calculate",
-            size=(75, 20))
-        background_button.Bind(wx.EVT_BUTTON, self._compute_background)
-        q_sizer.Add(background_button, (4, 2), (1, 1), wx.RIGHT, 5)
-
-        qbox_sizer.Add(q_sizer, wx.TOP, 0)
-
-        vbox.Add(qbox_sizer, (1, 0), (1, 1),
-            wx.LEFT | wx.RIGHT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
-
-        # Transform type
-        transform_box = wx.StaticBox(self, -1, "Transform Type")
-        transform_sizer = wx.StaticBoxSizer(transform_box, wx.VERTICAL)
-
-        radio_sizer = wx.GridBagSizer(5,5)
-
-        fourier_btn = wx.RadioButton(self, -1, "Fourier", name='fourier',
-            style=wx.RB_GROUP)
-        hilbert_btn = wx.RadioButton(self, -1, "Hilbert", name='hilbert')
-
-        fourier_btn.Bind(wx.EVT_RADIOBUTTON, self.radio_changed)
-        hilbert_btn.Bind(wx.EVT_RADIOBUTTON, self.radio_changed)
-
-        radio_sizer.Add(fourier_btn, (0,0), (1,1), wx.LEFT | wx.EXPAND)
-        radio_sizer.Add(hilbert_btn, (0,1), (1,1), wx.RIGHT | wx.EXPAND)
-
-        transform_sizer.Add(radio_sizer, wx.TOP, 0)
-        vbox.Add(transform_sizer, (2, 0), (1, 1),
-            wx.LEFT | wx.RIGHT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
-
-        # Output data
-        outputbox = wx.StaticBox(self, -1, "Output Parameters")
-        outputbox_sizer = wx.StaticBoxSizer(outputbox, wx.VERTICAL)
-
-        output_sizer = wx.GridBagSizer(5, 5)
-
-        self._output_boxes = dict()
-        i = 0
-        for key, value in OUTPUT_STRINGS.iteritems():
-            # Create a label and a text box for each poperty
-            label = wx.StaticText(self, -1, value)
-            output_box = OutputTextCtrl(self, wx.NewId(),
-                value="-", style=wx.ALIGN_CENTER_HORIZONTAL)
-            # Save the ID of each of the text boxes for accessing after the
-            # output data has been calculated
-            self._output_boxes[key] = output_box
-            output_sizer.Add(label, (i, 0), (1, 1), wx.LEFT | wx.EXPAND, 15)
-            output_sizer.Add(output_box, (i, 2), (1, 1),
-                wx.RIGHT | wx.EXPAND, 15)
-            i += 1
-
-        outputbox_sizer.Add(output_sizer, wx.TOP, 0)
-
-        vbox.Add(outputbox_sizer, (3, 0), (1, 1),
-            wx.LEFT | wx.RIGHT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
-
-        # Controls
-        controlbox = wx.StaticBox(self, -1, "Controls")
-        controlbox_sizer = wx.StaticBoxSizer(controlbox, wx.VERTICAL)
-
-        controls_sizer = wx.BoxSizer(wx.VERTICAL)
-
-        self._extrapolate_btn = wx.Button(self, wx.NewId(), "Extrapolate")
-        self._transform_btn = wx.Button(self, wx.NewId(), "Transform")
-        self._extract_btn = wx.Button(self, wx.NewId(), "Compute Parameters")
-        help_btn = wx.Button(self, -1, "HELP")
-
-        self._transform_btn.Disable()
-        self._extract_btn.Disable()
-
-        self._extrapolate_btn.Bind(wx.EVT_BUTTON, self.compute_extrapolation)
-        self._transform_btn.Bind(wx.EVT_BUTTON, self.compute_transform)
-        self._extract_btn.Bind(wx.EVT_BUTTON, self.extract_parameters)
-        help_btn.Bind(wx.EVT_BUTTON, self.on_help)
-
-        controls_sizer.Add(self._extrapolate_btn, wx.CENTER | wx.EXPAND)
-        controls_sizer.Add(self._transform_btn, wx.CENTER | wx.EXPAND)
-        controls_sizer.Add(self._extract_btn, wx.CENTER | wx.EXPAND)
-        controls_sizer.Add(help_btn, wx.CENTER | wx.EXPAND)
-
-        controlbox_sizer.Add(controls_sizer, wx.TOP | wx.EXPAND, 0)
-        vbox.Add(controlbox_sizer, (4, 0), (1, 1),
-            wx.LEFT | wx.RIGHT | wx.EXPAND | wx.ADJUST_MINSIZE, 15)
-
-
-        self.SetSizer(vbox)
-
-    def _disable_inputs(self):
-        """
-        Disable all input fields
-        """
-        self._qmin_input.Disable()
-        self._qmax1_input.Disable()
-        self._qmax2_input.Disable()
-        self._background_input.Disable()
-        self._extrapolate_btn.Disable()
-
-    def _enable_inputs(self):
-        """
-        Enable all input fields
-        """
-        self._qmin_input.Enable()
-        self._qmax1_input.Enable()
-        self._qmax2_input.Enable()
-        self._background_input.Enable()
-        self._extrapolate_btn.Enable()
-
-    def _round_sig_figs(self, x, sigfigs):
-        """
-        Round a number to a given number of significant figures.
-
-        :param x: The value to round
-        :param sigfigs: How many significant figures to round to
-        :return rounded_str: x rounded to the given number of significant
-            figures, as a string
-        """
-        rounded_str = ""
-        try:
-            # Index of first significant digit
-            significant_digit = -int(np.floor(np.log10(np.abs(x))))
-            # Number of digits required for correct number of sig figs
-            digits = significant_digit + (sigfigs - 1)
-            rounded = np.round(x, decimals=digits)
-            rounded_str = "{1:.{0}f}".format(sigfigs -1  + significant_digit,
-                rounded)
-        except:
-            # Method for finding significant_digit fails if x is 0 (since log10(0)=inf)
-            if x == 0.0:
-                rounded_str = "0.0"
-            else:
-                rounded_str = "-"
-
-        return rounded_str
Index: c/sas/sasgui/perspectives/corfunc/corfunc_state.py
===================================================================
--- src/sas/sasgui/perspectives/corfunc/corfunc_state.py	(revision e73e7235b94ab326147835ff01c27fe01e60cdb7)
+++ 	(revision )
@@ -1,358 +1,0 @@
-import time
-import sys
-import os
-import logging
-import sas.sascalc.dataloader
-from lxml import etree
-from sas.sascalc.dataloader.readers.cansas_reader import Reader as CansasReader
-from sas.sascalc.dataloader.readers.cansas_reader import get_content
-from sas.sasgui.guiframe.utils import format_number
-from sas.sasgui.guiframe.gui_style import GUIFRAME_ID
-from sas.sasgui.guiframe.dataFitting import Data1D
-from sas.sascalc.dataloader.loader import Loader
-
-CORNODE_NAME = 'corfunc'
-CANSAS_NS = 'cansas1d/1.0'
-
-# The default state
-DEFAULT_STATE = {
-    'qmin_tcl': None,
-    'qmax1_tcl': None,
-    'qmax2_tcl': None,
-    'background_tcl': None
-}
-
-# List of output parameters, used by __str__
-output_list = [
-    ['max', "Long Period (A): "],
-    ['Lc', "Average Hard Block Thickness (A): "],
-    ['dtr', "Average Interface Thickness (A): "],
-    ['d0', "Average Core Thickness: "],
-    ['A', "PolyDispersity: "],
-    ['fill', "Filling Fraction: "]
-]
-
-class CorfuncState(object):
-    """
-    Stores information about the state of CorfuncPanel
-    """
-
-    def __init__(self):
-        # Inputs
-        self.file = None
-        self.data = None
-        self.qmin = None
-        self.qmax = [0, 0]
-        self.background = None
-        self.outputs = {}
-        self.is_extrapolated = False
-        self.is_transformed = False
-
-        self.saved_state = DEFAULT_STATE
-        # Will be filled on panel init as number of states increases
-        self.state_list = {}
-        self.timestamp = time.time()
-
-        # Raw Data
-        self.q = None
-        self.iq = None
-        # TODO: Add extrapolated data and transformed data (when implemented)
-
-    def __str__(self):
-        """
-        Pretty print the state
-
-        :return: A string representing the state
-        """
-        state = "File:         {}\n".format(self.file)
-        state += "Timestamp:    {}\n".format(self.timestamp)
-        state += "Qmin:         {}\n".format(str(self.qmin))
-        state += "Qmax:         {}\n".format(str(self.qmax))
-        state += "Background:   {}\n".format(str(self.background))
-        if self.outputs is None:
-            return state
-        state += "\nOutputs:\n"
-        for output in output_list:
-            key = output[0]
-            name = output[1]
-            state += "{}: {}\n".format(name, str(self.outputs[key]))
-
-        return state
-
-    def set_saved_state(self, name, value):
-        """
-        Set a value in the current state.
-
-        :param name: The name of the parameter to set
-        :param value: The value to set the parameter to
-        """
-        self.saved_state[name] = value
-        if name == 'qmin_tcl':
-            self.qmin = value
-        elif name == 'qmax1_tcl':
-            self.qmax[0] = value
-        elif name == 'qmax2_tcl':
-            self.qmax[1] = value
-        elif name == 'background_tcl':
-            self.background = value
-
-    def toXML(self, filename='corfunc_state.cor', doc=None, entry_node=None):
-        """
-        Writes the state of the CorfuncPanel panel to file, as XML.
-
-        Compatible with standalone writing, or appending to an
-        already existing XML document. In that case, the XML document
-        is required. An optional entry node in the XML document
-        may also be given.
-
-        :param file: file to write to
-        :param doc: XML document object [optional]
-        :param entry_node: XML node within the XML document at which
-            we will append the data [optional]
-
-        :return: None if no doc is provided, modified XML document if doc!=None
-        """
-        from xml.dom.minidom import getDOMImplementation
-
-        top_element = None
-        new_doc = None
-        if doc is None:
-            # Create a new XML document
-            impl = getDOMImplementation()
-            doc_type = impl.createDocumentType(CORNODE_NAME, "1.0", "1.0")
-            new_doc = impl.createDocument(None, CORNODE_NAME, doc_type)
-            top_element = new_doc.documentElement
-        else:
-            # Create a new element in the document provided
-            top_element = doc.createElement(CORNODE_NAME)
-            if entry_node is None:
-                doc.documentElement.appendChild(top_element)
-            else:
-                entry_node.appendChild(top_element)
-            new_doc = doc
-
-        # Version
-        attr = new_doc.createAttribute("version")
-        attr.nodeValue = '1.0'
-        top_element.setAttributeNode(attr)
-
-        # Filename
-        element = new_doc.createElement("filename")
-        if self.file is not None and self.file != '':
-            element.appendChild(new_doc.createTextNode(str(self.file)))
-        else:
-            element.appendChild(new_doc.createTextNode(str(filename)))
-        top_element.appendChild(element)
-
-        # Timestamp
-        element = new_doc.createElement("timestamp")
-        # Pretty printed format
-        element.appendChild(new_doc.createTextNode(time.ctime(self.timestamp)))
-        attr = new_doc.createAttribute("epoch")
-        # Epoch value (used in self.fromXML)
-        attr.nodeValue = str(self.timestamp)
-        element.setAttributeNode(attr)
-        top_element.appendChild(element)
-
-        # Current state
-        state = new_doc.createElement("state")
-        top_element.appendChild(state)
-        for name, value in self.saved_state.iteritems():
-            element = new_doc.createElement(name)
-            element.appendChild(new_doc.createTextNode(str(value)))
-            state.appendChild(element)
-
-        # Whether or not the extrapolate & transform buttons have been clicked
-        element = new_doc.createElement("is_extrapolated")
-        top_element.appendChild(element)
-        element.appendChild(new_doc.createTextNode(str(int(self.is_extrapolated))))
-
-        element = new_doc.createElement("is_transformed")
-        top_element.appendChild(element)
-        element.appendChild(new_doc.createTextNode(str(int(self.is_transformed))))
-
-        # Output parameters
-        if self.outputs != {} and self.outputs is not None:
-            output = new_doc.createElement("output")
-            top_element.appendChild(output)
-            for item in output_list:
-                element = new_doc.createElement(item[0])
-                value = self.outputs[item[0]]
-                element.appendChild(new_doc.createTextNode(str(value)))
-                output.appendChild(element)
-
-        # Save the file or return the original document with the state
-        # data appended
-        if doc is None:
-            fd = open(filename, 'w')
-            fd.write(new_doc.toprettyxml())
-            fd.close()
-            return None
-        else:
-            return new_doc
-
-
-    def fromXML(self, node):
-        """
-        Load corfunc states from a file
-
-        :param node: node of an XML document to read from (optional)
-        """
-        if node.get('version') and node.get('version') == '1.0':
-            # Parse filename
-            entry = get_content('ns:filename', node)
-            if entry is not None:
-                self.file = entry.text.strip()
-
-            # Parse timestamp
-            entry = get_content('ns:timestamp', node)
-            if entry is not None and entry.get('epoch'):
-                try:
-                    self.timestamp = (entry.get('epoch'))
-                except:
-                    msg = ("CorfuncState.fromXML: Could not read timestamp",
-                        "\n{}").format(sys.exc_value)
-                    logging.error(msg)
-
-            # Parse current state
-            entry = get_content('ns:state', node)
-            if entry is not None:
-                for item in DEFAULT_STATE.iterkeys():
-                    input_field = get_content("ns:{}".format(item), entry)
-                    if input_field is not None:
-                        try:
-                            value = float(input_field.text.strip())
-                        except:
-                            value = None
-                        self.set_saved_state(name=item, value=value)
-
-            # Parse is_extrapolated and is_transformed
-            entry = get_content('ns:is_extrapolated', node)
-            if entry is not None:
-                self.is_extrapolated = bool(int(entry.text.strip()))
-            entry = get_content('ns:is_transformed', node)
-            if entry is not None:
-                self.is_transformed = bool(int(entry.text.strip()))
-
-            # Parse outputs
-            entry = get_content('ns:output', node)
-            if entry is not None:
-                for item in output_list:
-                    parameter = get_content("ns:{}".format(item[0]), entry)
-                    if parameter is not None:
-                        self.outputs[item[0]] = float(parameter.text.strip())
-
-
-
-class Reader(CansasReader):
-    """
-    Reads a CanSAS file containing the state of a CorfuncPanel
-    """
-
-    type_name = "Corfunc"
-
-    type = ["Invariant file (*.inv)|*.inv",
-            "SASView file (*.svs)|*.svs"]
-
-    ext = ['.cor', '.COR', '.svs', '.SVS']
-
-    def __init__(self, callback):
-        self.callback = callback
-        self.state = None
-
-    def read(self, path):
-        """
-        Load data and corfunc information frmo a CanSAS file.
-
-        :param path: The file path to read from
-        :return: Data1D object, a list of Data1D objects, or None
-        :raise IOError: When the file can't be found
-        :raise IOError: When the file is an invalid file type
-        :raise ValueError: When the length of the data vectors are inconsistent
-        """
-        output = []
-        if os.path.isfile(path):
-            # Load file
-            basename = os.path.basename(path)
-            root, ext = os.path.splitext(basename)
-            if not ext.lower() in self.ext:
-                raise IOError, "{} is not a supported file type".format(ext)
-            tree = etree.parse(path, parser=etree.ETCompatXMLParser())
-            root = tree.getroot()
-            entry_list = root.xpath('/ns:SASroot/ns:SASentry',
-                namespaces={'ns': CANSAS_NS})
-            for entry in entry_list:
-                sas_entry, _ = self._parse_entry(entry)
-                corstate = self._parse_state(entry)
-
-                if corstate != None:
-                    sas_entry.meta_data['corstate'] = corstate
-                    sas_entry.filename = corstate.file
-                    output.append(sas_entry)
-        else:
-            # File not found
-            msg = "{} is not a valid file path or doesn't exist".format(path)
-            raise IOError, msg
-
-        if len(output) == 0:
-            return None
-        elif len(output) == 1:
-            self.callback(output[0].meta_data['corstate'], datainfo=output[0])
-            return output[0]
-        else:
-            return output
-
-    def write(self, filename, datainfo=None, state=None):
-        """
-        Write the content of a Data1D as a CanSAS file.
-
-        : param filename: Name of the file to write
-        : param datainfo: Data1D object
-        : param state: CorfuncState object
-        """
-        # Prepare datainfo
-        if datainfo is None:
-            datainfo = Data1D(x=[], y=[])
-        elif not issubclass(datainfo.__class__, Data1D):
-            msg = ("The CanSAS writer expects a Data1D instance. {} was ",
-                "provided").format(datainfo.__class__.__name__)
-            raise RuntimeError, msg
-        if datainfo.title is None or datainfo.title == '':
-            datainfo.title = datainfo.name
-        if datainfo.run_name == None or datainfo.run_name == '':
-            datainfo.run = [str(datainfo.name)]
-            datainfo.run_name[0] = datainfo.name
-
-        # Create the XMl doc
-        doc, sasentry = self._to_xml_doc(datainfo)
-        if state is not None:
-            doc = state.toXML(doc=doc, entry_node=sasentry)
-
-        # Write the XML doc to a file
-        fd = open(filename, 'w')
-        fd.write(doc.toprettyxml())
-        fd.close()
-
-    def get_state(self):
-        return self.state
-
-
-    def _parse_state(self, entry):
-        """
-        Read state data from an XML node
-
-        :param entry: The XML node to read from
-        :return: CorfuncState object
-        """
-        state = None
-        try:
-            nodes = entry.xpath('ns:{}'.format(CORNODE_NAME),
-                namespaces={'ns': CANSAS_NS})
-            if nodes != []:
-                state = CorfuncState()
-                state.fromXML(nodes[0])
-        except:
-            msg = "XML document does not contain CorfuncState information\n{}"
-            msg.format(sys.exc_value)
-            logging.info(msg)
-        return state
Index: c/sas/sasgui/perspectives/corfunc/media/corfunc_help.rst
===================================================================
--- src/sas/sasgui/perspectives/corfunc/media/corfunc_help.rst	(revision 32c598316de30846e425496049ad449bb2ba7de4)
+++ 	(revision )
@@ -1,174 +1,0 @@
-.. corfunc_help.rst
-
-Correlation Function Analysis
-=============================
-
-Description
------------
-
-This performs a correlation function analysis of one-dimensional
-SANS data, or generates a model-independent volume fraction profile from a
-one-dimensional SANS pattern of an adsorbed layer.
-
-The correlation function analysis is performed in 3 stages:
-
-*  Extrapolation of the scattering curve to :math:`Q = 0` and
-   :math:`Q = \infty`
-*  Fourier/Hilbert Transform of the extrapolated data to give the correlation
-   function/volume fraction profile
-*  Interpretation of the 1D correlation function based on an ideal lamellar
-   morphology
-
-.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
-
-Extrapolation
--------------
-
-To :math:`Q = 0`
-^^^^^^^^^^^^^^^^
-
-The data are extrapolated to Q = 0 by fitting a Guinier model to the data
-points in the lower Q range.
-The equation used is:
-
-.. math::
-    I(Q) = Ae^{Bq^2}
-
-The Guinier model assumes that the small angle scattering arises from particles
-and that parameter :math:`B` is related to the radius of gyration of those
-particles. This has dubious applicability to polymer systems. However, the
-correlation function is affected by the Guinier back-extrapolation to the
-greatest extent at large values of R and so the back-extrapolation only has a
-small effect on the analysis.
-
-To :math:`Q = \infty`
-^^^^^^^^^^^^^^^^^^^^^
-
-The data are extrapolated to Q = :math:`\infty` by fitting a Porod model to
-the data points in the upper Q range.
-
-The equation used is:
-
-.. math::
-    I(Q) = B + KQ^{-4}e^{-Q^2\sigma^2}
-
-Where :math:`B` is the Bonart thermal background, :math:`K` is the Porod
-constant, and :math:`\sigma` describes the electron (or neutron scattering
-length) density profile at the interface between crystalline and amorphous
-regions (see figure 1).
-
-.. figure:: fig1.gif
-   :align: center
-
-   **Figure 1** The value of :math:`\sigma` is a measure of the electron
-   density profile at the interface between crystalline and amorphous regions.
-
-Smoothing
-^^^^^^^^^
-
-The extrapolated data set consists of the Guinier back-extrapolation up to the
-highest Q value of the lower Q range, the original scattering data up to the
-highest value in the upper Q range, and the Porod tail-fit beyond this. The
-joins between the original data and the Guinier/Porod fits are smoothed using
-the algorithm below, to avoid the formation of ripples in the transformed data.
-
-Functions :math:`f(x_i)` and :math:`g(x_i)` where :math:`x_i \in \left\{
-{x_1, x_2, ..., x_n} \right\}`, are smoothed over the range :math:`[a, b]`
-to produce :math:`y(x_i)`, by the following equations:
-
-.. math::
-    y(x_i) = h_ig(x_i) + (1-h_i)f(x_i)
-
-where:
-
-.. math::
-    h_i = \frac{1}{1 + \frac{(x_i-b)^2}{(x_i-a)^2}}
-
-Transform
----------
-
-Fourier
-^^^^^^^
-
-If Fourier is selected for the transform type, the analysis will perform a
-discrete cosine transform on the extrapolated data in order to calculate the
-correlation function. The following algorithm is applied:
-
-.. math::
-    \Gamma(x_k) = 2 \sum_{n=0}^{N-1} x_n \cos{\left[ \frac{\pi}{N}
-    \left(n + \frac{1}{2} \right) k \right] } \text{ for } k = 0, 1, \ldots,
-    N-1, N
-
-Hilbert
-^^^^^^^
-If Hilbert is selected for the transform type, the analysis will perform a
-Hilbert transform on the extrapolated data in order to calculate the Volume
-Fraction Profile.
-
-Interpretation
---------------
-Once the correlation function has been calculated by transforming the
-extrapolated data, it may be interpreted by clicking the "Compute Parameters"
-button. The correlation function is interpreted in terms of an ideal lamellar
-morphology, and structural parameters are obtained as shown in Figure 2 below.
-It should be noted that a small beam size is assumed; no de-smearing is
-performed.
-
-.. figure:: fig2.gif
-   :align: center
-
-   **Figure 2** Interpretation of the correlation function.
-
-The structural parameters obtained are:
-
-*   Long Period :math:`= L_p`
-*   Average Hard Block Thickness :math:`= L_c`
-*   Average Core Thickness :math:`= D_0`
-*   Average Interface Thickness :math:`\text{} = D_{tr}`
-*   Polydispersity :math:`= \Gamma_{\text{min}}/\Gamma_{\text{max}}`
-*   Local Crystallinity :math:`= L_c/L_p`
-
-.. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
-
-Usage
------
-Upon sending data for correlation function analysis, it will be plotted,  
-along with a red bar indicating the lower Q range (used for back-extrapolation), 
-and 2 purple bars indicating the upper qrange (used for forward-extrapolation) 
-[figure 3]. These bars may be moved my clicking and dragging, or by entering 
-the appropriate value in the Q range input boxes.
-
-.. figure:: tutorial1.png
-   :align: center
-
-   **Figure 3** A plot of some data showing the Q range bars
-
-Once the Q ranges have been set, click the "Calculate" button next to the
-background input field to calculate the Bonart thermal background level.
-Alternatively, enter your own value into the field. Click the "Extrapolate"
-button to extrapolate the data and plot the extrapolation in the same figure
-as the original data. [figure 4]
-
-.. figure:: tutorial2.png
-   :align: center
-
-   **Figure 4** A plot showing the extrapolated data and the original data
-
-Then, select which type of transform you would like to perform, using the radio
-buttons:
-
-*   **Fourier** Perform a Fourier Transform to calculate the correlation
-    function of the extrapolated data
-*   **Hilbert** Perform a Hilbert Transform to calculate the volume fraction
-    profile of the extrapolated data
-
-Clicking the transform button will then perform the selected transform and plot
-it in a new figure. If a Fourier Transform was performed, the "Compute
-Parameters" button can also be clicked to calculate values for the output
-parameters [figure 5]
-
- .. figure:: tutorial3.png
-    :align: center
-
-    **Figure 5** The Fourier Transform (correlation function) of the
-    extrapolated data, and the parameters extracted from it.
Index: c/sas/sasgui/perspectives/corfunc/plot_labels.py
===================================================================
--- src/sas/sasgui/perspectives/corfunc/plot_labels.py	(revision 37e7223a22d16209976ec4fbdfeb349e05786de1)
+++ 	(revision )
@@ -1,6 +1,0 @@
-GROUP_ID_IQ_DATA = r"$I(q)$"
-IQ_DATA_LABEL = r"$I_{obs}(q)$"
-IQ_EXTRAPOLATED_DATA_LABEL = r"$I_{extrap}(q)$"
-
-GROUP_ID_TRANSFORM = r"$\Gamma(x)$"
-TRANSFORM_LABEL = r"$\Gamma(x)$"
Index: st/corfunc/test/98929.txt
===================================================================
--- test/corfunc/test/98929.txt	(revision 0bc068325a6539d7d9fbd96156da277fd6103a77)
+++ 	(revision )
@@ -1,140 +1,0 @@
-0.007	2.11E+01
-0.009	6.91E+00
-0.011	3.30E+00
-0.013	1.95E+00
-0.015	1.37E+00
-0.017	9.86E-01
-0.019	8.56E-01
-0.021	8.00E-01
-0.023	7.40E-01
-0.025	7.03E-01
-0.027	6.65E-01
-0.029	6.67E-01
-0.031	6.63E-01
-0.033	6.90E-01
-0.035	6.97E-01
-0.037	7.13E-01
-0.039	7.02E-01
-0.041	7.49E-01
-0.043	7.58E-01
-0.045	7.84E-01
-0.047	8.41E-01
-0.049	8.84E-01
-0.051	9.26E-01
-0.053	9.74E-01
-0.055	1.02E+00
-0.057	1.06E+00
-0.059	1.09E+00
-0.061	1.11E+00
-0.063	1.16E+00
-0.065	1.16E+00
-0.067	1.17E+00
-0.069	1.15E+00
-0.071	1.15E+00
-0.073	1.13E+00
-0.075	1.11E+00
-0.077	1.07E+00
-0.079	1.04E+00
-0.081	1.03E+00
-0.083	9.79E-01
-0.085	9.27E-01
-0.087	8.77E-01
-0.089	8.38E-01
-0.091	8.00E-01
-0.093	7.68E-01
-0.095	7.24E-01
-0.097	6.80E-01
-0.099	6.45E-01
-0.101	6.18E-01
-0.103	5.87E-01
-0.105	5.70E-01
-0.107	5.51E-01
-0.109	5.40E-01
-0.111	5.23E-01
-0.113	4.99E-01
-0.115	4.84E-01
-0.117	4.69E-01
-0.119	4.54E-01
-0.121	4.44E-01
-0.123	4.37E-01
-0.125	4.32E-01
-0.127	4.27E-01
-0.129	4.26E-01
-0.131	4.16E-01
-0.133	4.13E-01
-0.135	4.11E-01
-0.137	4.05E-01
-0.139	4.03E-01
-0.141	4.01E-01
-0.143	4.01E-01
-0.145	3.95E-01
-0.147	3.86E-01
-0.149	3.79E-01
-0.151	3.80E-01
-0.153	3.74E-01
-0.155	3.71E-01
-0.157	3.68E-01
-0.159	3.72E-01
-0.161	3.69E-01
-0.163	3.69E-01
-0.165	3.66E-01
-0.167	3.59E-01
-0.169	3.56E-01
-0.171	3.58E-01
-0.173	3.57E-01
-0.175	3.57E-01
-0.177	3.51E-01
-0.179	3.55E-01
-0.181	3.59E-01
-0.183	3.51E-01
-0.185	3.48E-01
-0.187	3.43E-01
-0.189	3.46E-01
-0.191	3.49E-01
-0.193	3.41E-01
-0.195	3.44E-01
-0.197	3.38E-01
-0.199	3.41E-01
-0.201	3.39E-01
-0.203	3.38E-01
-0.205	3.37E-01
-0.207	3.33E-01
-0.209	3.28E-01
-0.211	3.27E-01
-0.213	3.23E-01
-0.215	3.23E-01
-0.217	3.27E-01
-0.219	3.30E-01
-0.221	3.33E-01
-0.223	3.33E-01
-0.225	3.28E-01
-0.227	3.26E-01
-0.229	3.19E-01
-0.231	3.11E-01
-0.233	3.12E-01
-0.235	3.02E-01
-0.237	3.12E-01
-0.239	3.23E-01
-0.241	3.24E-01
-0.243	3.45E-01
-0.245	3.49E-01
-0.247	3.50E-01
-0.249	3.55E-01
-0.251	3.50E-01
-0.253	3.47E-01
-0.255	3.47E-01
-0.257	3.18E-01
-0.259	3.10E-01
-0.261	2.90E-01
-0.263	2.80E-01
-0.265	2.90E-01
-0.267	3.09E-01
-0.269	3.04E-01
-0.271	3.36E-01
-0.273	3.17E-01
-0.275	3.19E-01
-0.277	2.94E-01
-0.279	3.11E-01
-0.281	2.21E-01
-0.283	1.66E-01
-0.285	1.62E-01
Index: st/corfunc/test/utest_corfunc.py
===================================================================
--- test/corfunc/test/utest_corfunc.py	(revision 0bc068325a6539d7d9fbd96156da277fd6103a77)
+++ 	(revision )
@@ -1,85 +1,0 @@
-"""
-Unit Tests for CorfuncCalculator class
-"""
-
-import unittest
-import time
-import numpy as np
-from sas.sascalc.corfunc.corfunc_calculator import CorfuncCalculator
-from sas.sascalc.dataloader.data_info import Data1D
-import matplotlib.pyplot as plt
-
-class TestCalculator(unittest.TestCase):
-
-    def setUp(self):
-        self.data = load_data()
-        self.calculator = CorfuncCalculator(data=self.data, lowerq=0.013,
-            upperq=(0.15, 0.24))
-        self.extrapolation = None
-
-    def extrapolate(self):
-        extrapolation = self.calculator.compute_extrapolation()
-
-        # Ensure the extraplation tends to the background value
-        self.assertAlmostEqual(extrapolation.y[-1], self.calculator.background)
-
-        # Test extrapolation for q values between 0.02 and 0.24
-        mask = np.logical_and(self.data.x > 0.02, self.data.x < 0.24)
-        qs = self.data.x[mask]
-        iqs = self.data.y[mask]
-
-        for q, iq in zip(qs, iqs):
-            # Find the q value in the extraplation nearest to the value in
-            # the data
-            q_extrap = min(extrapolation.x, key=lambda x:abs(x-q))
-            # Find the index of this value in the extrapolation
-            index = list(extrapolation.x).index(q_extrap)
-            # Find it's corresponding intensity value
-            iq_extrap = extrapolation.y[index]
-            # Check the extrapolation agrees to the data at this point to 1 d.p
-            self.assertAlmostEqual(iq_extrap, iq, 1)
-
-        self.extrapolation = extrapolation
-
-    def transform(self):
-        self.calculator.compute_transform(self.extrapolation, 'fourier',
-            completefn=self.transform_callback)
-        # Transform is performed asynchronously; give it time to run
-        while True:
-            time.sleep(0.001)
-            if not self.calculator.transform_isrunning():
-                break
-
-    def transform_callback(self, transform):
-        self.assertIsNotNone(transform)
-        self.assertAlmostEqual(transform.y[0], 1)
-        self.assertAlmostEqual(transform.y[-1], 0, 5)
-        self.transformation = transform
-
-    def extract_params(self):
-        params = self.calculator.extract_parameters(self.transformation)
-        self.assertIsNotNone(params)
-        self.assertEqual(len(params), 6)
-        self.assertLess(abs(params['max']-75), 2.5) # L_p ~= 75
-        self.assertLess(abs(params['dtr']-6), 2.5) # D_tr ~= 6
-
-
-    # Ensure tests are ran in correct order;
-    # Each test depends on the one before it
-    def test_calculator(self):
-        steps = [self.extrapolate, self.transform, self.extract_params]
-        for test in steps:
-            try:
-                test()
-            except Exception as e:
-                self.fail("{} failed ({}: {})".format(test, type(e), e))
-
-
-def load_data(filename="98929.txt"):
-    data = np.loadtxt(filename, dtype=np.float32)
-    q = data[:,0]
-    iq = data[:,1]
-    return Data1D(x=q, y=iq)
-
-if __name__ == '__main__':
-    unittest.main()
