Beispiel #1
0
    def test_linear_fit(self):
        ''' Test of plotting fit
        '''
        X = e.MeasurementArray([1, 2, 3, 4, 5], [0.1])
        Y = e.MeasurementArray([3, 5, 7, 9, 11], [0.05])

        figure = p.MakePlot(xdata=X, ydata=Y)
        slope, intercept = figure.fit('linear', print_results=False)

        self.assertEqual(slope, 2)
        self.assertEqual(intercept, 1)
Beispiel #2
0
def test5():
    ''' Test of plotting fit
    '''
    X = e.MeasurementArray([1, 2, 3, 4, 5], [0.1])
    Y = e.MeasurementArray([3, 5, 7, 9, 11], [0.05])

    figure = p.Plot(X, Y)
    figure.fit('linear')
    intercept, slope = figure.fit_parameters

    assert slope.mean == 2
    assert intercept.mean == 1
Beispiel #3
0
    def test_delete(self):
        '''Tests inserting new values into a MeasurementArray.
        '''
        x = e.MeasurementArray([3, 2, 1], 1)
        x = x.delete(1)

        self.assertEqual(len(x), 2)
Beispiel #4
0
    def test_array_elementary(self):
        '''Tests elementary operations on Measurement objects
        '''
        x = e.MeasurementArray([4, 9, 2], error=[0.1, 0.2, 0.3])
        y = e.MeasurementArray([2, 3, 3], error=0.1)

        self.assertListEqual((x + y).means.tolist(), [6, 12, 5])
        self.assertListEqual((y + x).means.tolist(), [6, 12, 5])
        self.assertListEqual((x - y).means.tolist(), [2, 6, -1])
        self.assertListEqual((y - x).means.tolist(), [-2, -6, 1])
        self.assertListEqual((x * y).means.tolist(), [8, 27, 6])
        self.assertListEqual((y * x).means.tolist(), [8, 27, 6])
        self.assertListEqual((x / y).means.tolist(), [2, 3, 2 / 3])
        self.assertListEqual((y / x).means.tolist(), [0.5, 1 / 3, 3 / 2])
        self.assertListEqual((x**y).means.tolist(), [16, 729, 8])
        self.assertListEqual((y**x).means.tolist(), [16, 19683, 9])
Beispiel #5
0
    def test_insert(self):
        '''Tests inserting new values into a MeasurementArray.
        '''
        x = e.MeasurementArray([3, 1], 1)
        x = x.insert(1, 2)

        to_insert = e.Measurement(4, 1)
        x = x.insert(2, to_insert)

        self.assertEqual(x[1], 2)
        self.assertEqual(x[2], to_insert)
Beispiel #6
0
    def test_append(self):
        '''Tests appending new values to a MeasurementArray.
        '''
        x = e.MeasurementArray([3, 2], 1)
        x = x.append(1)

        to_append = e.Measurement(4, 1)
        x = x.append(to_append)

        self.assertEqual(x[2], 1)
        self.assertEqual(x[3], to_append)
Beispiel #7
0
    def test_array_functions(self):
        '''Tests mathematical functions on Measurement objects
        '''
        x = e.MeasurementArray([4, 9, 2], error=[0.1, 0.2, 0.3])
        y = e.MeasurementArray([0.3, 0.56, 0.2], error=0.01)

        self.assertEqual(e.sin(x).means.tolist(), np.sin(x.means).tolist())
        self.assertEqual(e.cos(x).means.tolist(), np.cos(x.means).tolist())
        self.assertEqual(e.tan(x).means.tolist(), np.tan(x.means).tolist())
        self.assertEqual(
            e.csc(x).means.tolist(), (1 / np.sin(x.means)).tolist())
        self.assertEqual(
            e.sec(x).means.tolist(), (1 / np.cos(x.means)).tolist())
        self.assertEqual(
            e.cot(x).means.tolist(), (1 / np.tan(x.means)).tolist())
        self.assertEqual(e.exp(x).means.tolist(), np.exp(x.means).tolist())
        self.assertEqual(e.log(x).means.tolist(), np.log(x.means).tolist())
        self.assertEqual(e.asin(y).means.tolist(), np.arcsin(y.means).tolist())
        self.assertEqual(e.acos(y).means.tolist(), np.arccos(y.means).tolist())
        self.assertEqual(e.atan(x).means.tolist(), np.arctan(x.means).tolist())
Beispiel #8
0
    def test_polynomial_fit(self):
        ''' Test of plotting fit
        '''
        X = e.MeasurementArray([-2, -1, 0, 1, 2], [0.1])
        Y = 3 * X**2 + 2 * X + 1

        figure = p.MakePlot(xdata=X, ydata=Y)
        figure.fit('pol2', print_results=False)
        par0 = figure.get_dataset().xyfitter[0].fit_pars[0]
        par1 = figure.get_dataset().xyfitter[0].fit_pars[1]
        par2 = figure.get_dataset().xyfitter[0].fit_pars[2]

        self.assertAlmostEqual(par0, 1, places=7)
        self.assertAlmostEqual(par1, 2, places=7)
        self.assertAlmostEqual(par2, 3, places=7)
Beispiel #9
0
    def test_gaussian_fit(self):
        ''' Test of plotting fit
        '''
        X = e.MeasurementArray([-1, -1 / 3, 1 / 3, 1], [0.1])
        mean = 0.1
        std = 0.5
        norm = .5
        Y = norm * (2 * m.pi * std**2)**(-0.5) * np.exp(-0.5 *
                                                        (X - mean)**2 / std**2)

        figure = p.MakePlot(xdata=X, ydata=Y)
        figure.fit('gauss', print_results=False)

        par0 = figure.get_dataset().xyfitter[0].fit_pars[0]
        par1 = figure.get_dataset().xyfitter[0].fit_pars[1]
        par2 = figure.get_dataset().xyfitter[0].fit_pars[2]

        self.assertAlmostEqual(par0, mean, places=7)
        self.assertAlmostEqual(par1, std, places=7)
        self.assertAlmostEqual(par2, norm, places=7)
Beispiel #10
0
 def test_measurement_array(self):
     '''Tests creating a MeasurementArray from multiple measurements
     '''
     x = e.MeasurementArray([9, 10, 11], error=1)
     self.assertEqual(x.mean, 10)
     self.assertEqual(x.std(), 1)
Beispiel #11
0
    def __init__(self,
                 xdata,
                 ydata=None,
                 xerr=None,
                 yerr=None,
                 data_name=None,
                 xname=None,
                 xunits=None,
                 yname=None,
                 yunits=None,
                 is_histogram=False,
                 bins=50):
        '''Use MeasurementArray() to initialize a dataset'''
        if (data_name is None):
            self.name = "dataset{}".format(XYDataSet.unnamed_data_counter)
            '''A string of the name of the dataset.

            .. code-block:: python

                x = q.MeasurementArray([1, 2, 3, 4], error=0.5)
                y = q.MeasurementArray([5, 6.2, 7, 7.8], error=0.1)

                data = q.XYDataSet(x, y)
                data.name = 'x vs. y'
                print('Name:', data.name)

            .. nboutput:: ipython3

                Name = x vs. y
            '''
            XYDataSet.unnamed_data_counter += 1
        else:
            self.name = data_name

        if ydata is None and not is_histogram:
            print(
                "Error, if ydata is not given, explicitly specify that this is a histogram"
            )

        elif ydata is None:
            #this is a histogram
            self.hist_data = xdata
            hist, edges = np.histogram(xdata, bins=bins)
            self.hist_bins = edges
            _xdata = edges[:-1]
            _xerr = np.zeros(_xdata.size)
            _ydata = hist
            _yerr = np.sqrt(hist)
        else:
            _xdata = xdata
            _xerr = xerr
            _ydata = ydata
            _yerr = yerr

        self.x = qe.MeasurementArray(_xdata,
                                     error=_xerr,
                                     name=xname,
                                     units=xunits)
        self.xdata = self.x.means
        self.xerr = self.x.stds
        self.xunits = self.x.get_units_str()
        self.xname = self.x.name

        self.y = qe.MeasurementArray(_ydata,
                                     error=_yerr,
                                     name=yname,
                                     units=yunits)
        self.ydata = self.y.means
        self.yerr = self.y.stds
        self.yunits = self.y.get_units_str()
        self.yname = self.y.name

        self.is_histogram = is_histogram
        self.bins = bins

        if self.x.size != self.y.size:
            print("Error: x and y data should have the same number of points")
            #TODO raise an error!
        else:
            self.npoints = self.x.size

        self.xyfitter = []
        self.fit_pars = []  #stored as Measurement_Array
        self.fit_pcov = []
        self.fit_pcorr = []
        self.fit_function = []
        self.fit_function_name = []
        self.fit_npars = []
        self.fit_yres = []
        self.fit_chi2 = []
        self.fit_ndof = []
        self.fit_color = []
        self.nfits = 0
Beispiel #12
0
    def fit(self, dataset, fit_range=None, fit_count=0, name=None):
        ''' Perform a fit of the fit_function to a data set.

        :param dataset: The dataset to be fit.
        :type dataset: XYDataSet
        :param fit_range: The range to plot the fit on.
        :type fit_range: list
        :param fit_count: The number of the fit.
        :type fit_count: int
        :param name: The name of the fit function.
        :type name: str

        :returns: The parameters of the fit.
        :rtype: Measurement_Array
        '''
        if self.fit_function is None:
            print("Error: fit function not set!")
            return

        #Grab the data
        xdata = dataset.xdata
        ydata = dataset.ydata
        xerr = dataset.xerr
        yerr = dataset.yerr

        nz = np.count_nonzero(yerr)
        if nz < ydata.size and nz != 0:
            print(
                "Warning: some errors on data are zero, switching to MC errors"
            )
            dataset.y.error_method = "MC"
            yerr = dataset.y.stds
            #now, check again
            nz = np.count_nonzero(yerr)
            if nz < ydata.size and nz != 0:
                yerr[yerr == 0] = ydata[yerr == 0] / 1000000
            #We're ok, modify the errors in the dataset to be the MC ones
            else:
                dataset.yerr = yerr

        #If user specified a fit range, reduce the data:
        if type(fit_range) in ARRAY and len(fit_range) is 2:
            indices = np.where(
                np.logical_and(xdata >= fit_range[0], xdata <= fit_range[1]))
            xdata = xdata[indices]
            ydata = ydata[indices]
            xerr = xerr[indices]
            yerr = yerr[indices]

        #if the x errors are not zero, convert them to equivalent errors in y
        #TODO: check the math on this...

        #The maximum number of function evaluations
        maxfev = 200 * (xdata.size + 1) if q.settings[
            "fit_max_fcn_calls"] == -1 else q.settings["fit_max_fcn_calls"]
        try:
            warns = []
            with warnings.catch_warnings(record=True) as w:
                warnings.simplefilter("always", sp.OptimizeWarning)
                self.fit_pars, self.fit_pcov = sp.curve_fit(self.fit_function,
                                                            xdata,
                                                            ydata,
                                                            sigma=yerr,
                                                            p0=self.parguess,
                                                            maxfev=maxfev)
                warns = w
            if len(warns) > 0 and (self.fit_function == Rlinear
                                   or self.fit_function == Rpolynomial):
                p, V = np.polyfit(x=xdata,
                                  y=ydata,
                                  deg=self.fit_npars - 1,
                                  cov=True,
                                  w=1 / yerr)
                self.fit_pars = p[::-1]
                self.fit_pcov = np.flipud(np.fliplr(V))

            self.fit_pars_err = np.sqrt(np.diag(self.fit_pcov))
        except RuntimeError:
            print(
                "Error: Fit could not converge; are the y errors too small? Is the function defined?"
            )
            print("Is the parameter guess good?")
            return None

        # Use derivative method to factor x error into fit
        if xerr.nonzero()[0].size:
            yerr_eff = np.sqrt((yerr**2 + np.multiply(
                xerr,
                num_der(lambda x: self.fit_function(x, *self.fit_pars), xdata))
                                **2))

            try:
                warns = []
                with warnings.catch_warnings(record=True) as w:
                    warnings.simplefilter("always", sp.OptimizeWarning)
                    self.fit_pars, self.fit_pcov = sp.curve_fit(
                        self.fit_function,
                        xdata,
                        ydata,
                        sigma=yerr_eff,
                        p0=self.parguess,
                        maxfev=maxfev)
                    warns = w
                if len(warns) == 1 and (self.fit_function == Rlinear
                                        or self.fit_function == Rpolynomial):
                    p, V = np.polyfit(x=xdata,
                                      y=ydata,
                                      deg=self.fit_npars - 1,
                                      cov=True,
                                      w=1 / yerr)
                    self.fit_pars = p[::-1]
                    self.fit_pcov = np.flipud(np.fliplr(V))

                self.fit_pars_err = np.sqrt(np.diag(self.fit_pcov))
            except RuntimeError:
                print(
                    "Error: Fit could not converge; are the y errors too small? Is the function defined?"
                )
                print("Is the parameter guess good?")
                return None

        #this should already be true, but let's be sure:
        self.fit_npars = self.fit_pars.size

        #This is to catch the case of scipy.optimize failing to determin
        #the covariance matrix

        for i in range(self.fit_npars):
            if self.fit_pars_err[i] == float(
                    'inf') or self.fit_pars_err[i] == float('nan'):
                #print("Warning: Error for fit parameter",i,"cannot be trusted")
                self.fit_pars_err[i] = 0
            for j in range(self.fit_npars):
                if self.fit_pcov[i][j] == float(
                        'inf') or self.fit_pcov[i][j] == float('nan'):
                    #print("Warning: Covariance between parameters",i,j,"cannot be trusted")
                    self.fit_pcov[i][j] = 0.

        parnames = dataset.name + "_" + self.fit_function_name + "_fit{}".format(
            fit_count) + "_fitpars"
        self.fit_parameters = qe.MeasurementArray(self.fit_npars,
                                                  name=parnames)

        for i in range(self.fit_npars):
            if self.fit_function_name is 'gaussian':
                if i is 0:
                    name = 'mean'
                elif i is 1:
                    name = 'sigma'
                elif i == 2:
                    name = 'normalization'
            elif self.fit_function_name is 'linear':
                if i is 0:
                    name = 'intercept'
                elif i is 1:
                    name = 'slope'
            elif self.fit_function_name is 'exponential':
                if i is 0:
                    name = 'amplitude'
                elif i is 1:
                    name = 'decay-constant'
            else:
                name = 'par%d' % (i)
            name = parnames + "_" + name
            self.fit_parameters[i] = qe.Measurement(self.fit_pars[i],
                                                    self.fit_pars_err[i],
                                                    name=name)

        for i in range(self.fit_npars):
            for j in range(i + 1, self.fit_npars):
                self.fit_parameters[i].set_covariance(self.fit_parameters[j],
                                                      self.fit_pcov[i][j])

        #Calculate the residuals:
        yfit = self.fit_function(dataset.xdata, *self.fit_pars)
        self.fit_yres = qe.MeasurementArray((dataset.ydata - yfit),
                                            dataset.yerr)
        #Calculate the chi-squared:
        self.fit_chi2 = 0
        for i in range(xdata.size):
            if self.fit_yres[i].std != 0:
                self.fit_chi2 += (self.fit_yres[i].mean /
                                  self.fit_yres[i].std)**2
        self.fit_ndof = self.fit_yres.size - self.fit_npars - 1

        return self.fit_parameters
Beispiel #13
0
    def __init__(self,
                 xdata,
                 ydata=None,
                 xerr=None,
                 yerr=None,
                 data_name=None,
                 xname=None,
                 xunits=None,
                 yname=None,
                 yunits=None,
                 is_histogram=False,
                 bins=50):
        '''Use MeasurementArray() to initialize a dataset'''
        if (data_name is None):
            self.name = "dataset{}".format(XYDataSet.unnamed_data_counter)
            XYDataSet.unnamed_data_counter += 1
        else:
            self.name = data_name

        if ydata is None and not is_histogram:
            print(
                "Error, if ydata is not given, explicitly specify that this is a histogram"
            )

        elif ydata is None:
            #this is a histogram
            self.hist_data = xdata
            hist, edges = np.histogram(xdata, bins=bins)
            self.hist_bins = edges
            _xdata = edges[:-1]
            _xerr = np.zeros(_xdata.size)
            _ydata = hist
            _yerr = np.sqrt(hist)
        else:
            _xdata = xdata
            _xerr = xerr
            _ydata = ydata
            _yerr = yerr

        self.x = qe.MeasurementArray(_xdata,
                                     error=_xerr,
                                     name=xname,
                                     units=xunits)
        self.xdata = self.x.get_means()
        self.xerr = self.x.get_stds()
        self.xunits = self.x.get_units_str()
        self.xname = self.x.name

        self.y = qe.MeasurementArray(_ydata,
                                     error=_yerr,
                                     name=yname,
                                     units=yunits)
        self.ydata = self.y.get_means()
        self.yerr = self.y.get_stds()
        self.yunits = self.y.get_units_str()
        self.yname = self.y.name

        self.is_histogram = is_histogram

        if self.x.size != self.y.size:
            print("Error: x and y data should have the same number of points")
            #TODO raise an error!
        else:
            self.npoints = self.x.size

        self.xyfitter = []
        self.fit_pars = []  #stored as Measurement_Array
        self.fit_pcov = []
        self.fit_pcorr = []
        self.fit_function = []
        self.fit_function_name = []
        self.fit_npars = []
        self.fit_yres = []
        self.fit_chi2 = []
        self.fit_ndof = []
        self.fit_color = []
        self.nfits = 0