Example #1
0
    def test_resolution_speed_comparator(self):
        fname = os.path.join(self.pth, "c_PLP0011859_q.txt")
        dataset = ReflectDataset(fname)

        sio2 = SLD(3.47, name="SiO2")
        si = SLD(2.07, name="Si")
        d2o = SLD(6.36, name="D2O")
        polymer = SLD(2.0, name="polymer")

        sio2_l = sio2(30, 3)
        polymer_l = polymer(125, 3)

        dx = dataset.x_err
        structure = si | sio2_l | polymer_l | polymer_l | d2o(0, 3)
        model = ReflectModel(structure, bkg=2e-6, dq_type="constant")
        objective = Objective(model,
                              dataset,
                              use_weights=False,
                              transform=Transform("logY"))

        # check that choose_resolution_approach doesn't change state
        # of model
        fastest_method = choose_dq_type(objective)
        assert model.dq_type == "constant"
        assert_equal(dx, objective.data.x_err)

        # check that the comparison worked
        const_time = time.time()
        for i in range(1000):
            objective.generative()
        const_time = time.time() - const_time

        model.dq_type = "pointwise"
        point_time = time.time()
        for i in range(1000):
            objective.generative()
        point_time = time.time() - point_time

        if fastest_method == "pointwise":
            assert point_time < const_time
        elif fastest_method == "constant":
            assert const_time < point_time

        # check that we could use the function to setup a reflectmodel
        ReflectModel(structure, bkg=2e-6, dq_type=choose_dq_type(objective))
Example #2
0
    def test_reflectivity_emcee(self):
        model = self.model361
        model.dq = 5.
        objective = Objective(model,
                              (self.qvals361, self.rvals361, self.evals361),
                              transform=Transform('logY'))
        fitter = CurveFitter(objective, nwalkers=100)

        assert_(len(objective.generative().shape) == 1)
        assert_(len(objective.residuals().shape) == 1)

        res = fitter.fit('least_squares')
        res_mcmc = fitter.sample(steps=5, nthin=10, random_state=1,
                                 verbose=False)

        mcmc_val = [mcmc_result.median for mcmc_result in res_mcmc]
        assert_allclose(mcmc_val, res.x, rtol=0.05)
Example #3
0
    def test_multidimensionality(self):
        # Check that ND data can be used with an objective/model/data
        # (or at least it doesn't stand in the way)
        rng = np.random.default_rng()
        x = rng.uniform(size=100).reshape(50, 2)

        desired = line_ND(x, self.p)
        assert desired.shape == (50, 2)
        data = Data1D((x, desired))

        model = Model(self.p, fitfunc=line_ND)
        y = model(x)
        assert_allclose(y, desired)

        objective = Objective(model, data)
        assert_allclose(objective.chisqr(), 0)
        assert_allclose(objective.generative(), desired)
        assert_allclose(objective.residuals(), 0)
        assert objective.residuals().shape == (50, 2)

        objective.logl()
        objective.logpost()
        covar = objective.covar()
        assert covar.shape == (2, 2)
Example #4
0
class Model():
    """The Model class represents a refnx model using predictions made by the classifier and regressors.

    Class Attributes:
        roughness (int): the default roughness between each layer in Angstrom.
        rough_bounds (tuple): the range of values to fit for roughness.
        si_sld (float): the substrate SLD (silicon).
        dq (float): the instrument resolution parameter.
        scale (float): the instrument scale parameter.
        bkg (float): value for the background parameter.

    """
    roughness    = 8
    rough_bounds = CurveGenerator.rough_bounds
    si_sld       = NeutronGenerator.substrate_sld
    dq           = CurveGenerator.dq
    scale        = CurveGenerator.scale
    bkg          = 2e-7

    def __init__(self, file_path, layers, predicted_slds, predicted_depths, xray):
        """Initialises the Model class by creating a refnx model with given predicted values.

        Args:
            file_path (string): a path to the file with the data to construct the model for.
            layers (int): the number of layers for the model predicted by the classifier.
            predicted_slds (ndarray): an array of predicted SLDs for each layer.
            predicted_depths (ndarray): an array of predicted depths for each layer.
            xray (Boolean): whether the model should use a neutron or x-ray probe.

        """
        self.structure = SLD(0, name='Air') #Model starts with air.

        if xray: #Use x-ray probe
            for i in range(layers):
                density = predicted_slds[i] / XRayGenerator.density_constant
                SLD_layer = MaterialSLD(XRayGenerator.material, density, probe='x-ray', wavelength=XRayGenerator.wavelength, name='Layer {}'.format(i+1))
                layer = SLD_layer(thick=predicted_depths[i], rough=Model.roughness)
                layer.density.setp(bounds=XRayGenerator.density_bounds, vary=True)
                layer.thick.setp(bounds=ImageGenerator.depth_bounds, vary=True)
                layer.rough.setp(bounds=Model.rough_bounds, vary=True)
                self.structure = self.structure | layer  #Next comes each layer.
            #Then substrate
            si_substrate = MaterialSLD(XRayGenerator.material, XRayGenerator.substrate_density, probe='x-ray', name='Si Substrate')(thick=0, rough=Model.roughness)

        else: #Use neutron probe
            for i in range(layers):
                layer = SLD(predicted_slds[i], name='Layer {}'.format(i+1))(thick=predicted_depths[i], rough=Model.roughness)
                layer.sld.real.setp(bounds=ImageGenerator.sld_neutron_bounds, vary=True)
                layer.thick.setp(bounds=ImageGenerator.depth_bounds, vary=True)
                layer.rough.setp(bounds=Model.rough_bounds, vary=True)
                self.structure = self.structure | layer  #Next comes each layer.
            #Then substrate
            si_substrate = SLD(Model.si_sld, name='Si Substrate')(thick=0, rough=Model.roughness)

        si_substrate.rough.setp(bounds=Model.rough_bounds, vary=True)
        self.structure = self.structure | si_substrate

        data = self.__load_data(file_path) #Pre-process and load given dataset.
        self.model = ReflectModel(self.structure, scale=Model.scale, dq=Model.dq, bkg=Model.bkg)
        self.objective = Objective(self.model, data)

    def __load_data(self, file_path):
        """Loads a reflectivity dataset from a given file path and applies scaling.

        Args:
            file_path (string): a path to the file with the data to construct the model for.

        """
        data = ReflectDataset(file_path) #Load the data for which the model is designed for.
        self.filename = os.path.basename(data.filename)
        data.scale(np.max(data.data[1])) #Normalise Y and Error by dividing by max R point.

        x, y, y_err = data.x.tolist(), data.y.tolist(), data.y_err.tolist()
        removed = [] #Remove any points containing 0 values as these cause NaNs when fitting.
        for i in range(len(x)):
            if x[i] == 0 or y[i] == 0 or y_err[i] == 0:
                removed.append(i)

        #Remove the identified points and return the processed dataset.
        x     = np.delete(np.array(x),     removed)
        y     = np.delete(np.array(y),     removed)
        y_err = np.delete(np.array(y_err), removed)
        data_new = np.array([x, y, y_err])
        return ReflectDataset(data_new)

    def fit(self):
        """Fits the model to the data using differential evolution."""
        fitter = CurveFitter(self.objective)
        fitter.fit('differential_evolution', verbose=False)

    def plot_objective(self, prediction=True):
        """Plots the current objective for the model against given dataset.

        Args:
            prediction (Boolean): whether the plot is a prediction or fit.

        """
        if prediction:
            title='Reflectivity Plot using Predicted Values'
            label="Predicted"
        else:
            title='Reflectivity Plot using Fitted Values'
            label="Fitted"
        fig = plt.figure(figsize=[9,7], dpi=600)
        ax = fig.add_subplot(111)

        y, y_err, model = self.objective._data_transform(model=self.objective.generative())
        # Add the data in a transformed fashion.
        ax.errorbar(self.objective.data.x, y, y_err, label=self.filename,
                    color="blue", marker="o", ms=3, lw=0, elinewidth=1, capsize=1.5)
        #Add the prediction/fit
        ax.plot(self.objective.data.x, model, color="red", label=label, zorder=20)

        plt.xlabel("$\mathregular{Q\ (Å^{-1})}$", fontsize=11, weight='bold')
        plt.ylabel('Reflectivity (arb.)',         fontsize=11, weight='bold')
        plt.yscale('log')
        plt.legend()
        if title:
            plt.title(title, fontsize=15, pad=15)