Пример #1
0
    def linearize_data(self, data):
        """
        Linearize data so that a linear fit can be performed.
        Filter out the data that can't be transformed.

        :param data: LoadData1D instance

        """
        # Check that the vector lengths are equal
        assert len(data.x) == len(data.y)
        if data.dy is not None:
            assert len(data.x) == len(data.dy)
            dy = data.dy
        else:
            dy = np.ones(len(data.y))

        # Transform the data
        data_points = zip(data.x, data.y, dy)

        output_points = [(self.linearize_q_value(p[0]),
                          math.log(p[1]),
                          p[2] / p[1]) for p in data_points if p[0] > 0 and \
                          p[1] > 0 and p[2] > 0]

        x_out, y_out, dy_out = zip(*output_points)

        # Create Data1D object
        x_out = np.asarray(x_out)
        y_out = np.asarray(y_out)
        dy_out = np.asarray(dy_out)
        linear_data = LoaderData1D(x=x_out, y=y_out, dy=dy_out)

        return linear_data
Пример #2
0
    def _get_extrapolated_data(self,
                               model,
                               npts=INTEGRATION_NSTEPS,
                               q_start=Q_MINIMUM,
                               q_end=Q_MAXIMUM):
        """
        :return: extrapolate data create from data
        """
        #create new Data1D to compute the invariant
        q = np.linspace(start=q_start, stop=q_end, num=npts, endpoint=True)
        iq = model.evaluate_model(q)
        diq = model.evaluate_model_errors(q)

        result_data = LoaderData1D(x=q, y=iq, dy=diq)
        if self._smeared is not None:
            result_data.dxl = self._smeared * np.ones(len(q))
        return result_data
Пример #3
0
    def fit(self, power=None, qmin=None, qmax=None):
        """
        Fit data for y = ax + b  return a and b

        :param power: a fixed, otherwise None
        :param qmin: Minimum Q-value
        :param qmax: Maximum Q-value
        """
        if qmin is None:
            qmin = self.qmin
        if qmax is None:
            qmax = self.qmax

        # Identify the bin range for the fit
        idx = (self.data.x >= qmin) & (self.data.x <= qmax)

        fx = np.zeros(len(self.data.x))

        # Uncertainty
        if type(self.data.dy) == np.ndarray and \
            len(self.data.dy) == len(self.data.x) and \
                np.all(self.data.dy > 0):
            sigma = self.data.dy
        else:
            sigma = np.ones(len(self.data.x))

        # Compute theory data f(x)
        fx[idx] = self.data.y[idx]

        # Linearize the data
        if self.model is not None:
            linearized_data = self.model.linearize_data(\
                                            LoaderData1D(self.data.x[idx],
                                                         fx[idx],
                                                         dy=sigma[idx]))
        else:
            linearized_data = LoaderData1D(self.data.x[idx],
                                           fx[idx],
                                           dy=sigma[idx])

        ##power is given only for function = power_law
        if power is not None:
            sigma2 = linearized_data.dy * linearized_data.dy
            a = -(power)
            b = (np.sum(linearized_data.y / sigma2) \
                 - a * np.sum(linearized_data.x / sigma2)) / np.sum(1.0 / sigma2)


            deltas = linearized_data.x * a + \
                     np.ones(len(linearized_data.x)) * b - linearized_data.y
            residuals = np.sum(deltas * deltas / sigma2)

            err = math.fabs(residuals) / np.sum(1.0 / sigma2)
            return [a, b], [0, math.sqrt(err)]
        else:
            A = np.vstack([
                linearized_data.x / linearized_data.dy,
                1.0 / linearized_data.dy
            ]).T
            # CRUFT: numpy>=1.14.0 allows rcond=None for the following default
            rcond = np.finfo(float).eps * max(A.shape)
            p, residuals, _, _ = np.linalg.lstsq(A,
                                                 linearized_data.y /
                                                 linearized_data.dy,
                                                 rcond=rcond)

            # Get the covariance matrix, defined as inv_cov = a_transposed * a
            err = np.zeros(2)
            try:
                inv_cov = np.dot(A.transpose(), A)
                cov = np.linalg.pinv(inv_cov)
                err_matrix = math.fabs(residuals) * cov
                err = [
                    math.sqrt(err_matrix[0][0]),
                    math.sqrt(err_matrix[1][1])
                ]
            except:
                err = [-1.0, -1.0]

            return p, err